4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/types.h>
28 #include <sys/cmn_err.h>
29 #include <sys/param.h> /* for NULL */
30 #include <sys/sbd_ioctl.h>
31 #include <sys/dr_util.h>
32 #include <sys/varargs.h>
33 #include <sys/sysmacros.h>
34 #include <sys/systm.h>
36 /* sbd_etab[] and sbd_etab_len provided by sbdgenerr.pl */
37 extern sbd_etab_t sbd_etab
[];
38 extern int sbd_etab_len
;
41 sbd_err_new(int e_code
, char *fmt
, va_list args
)
45 new = GETSTRUCT(sbd_error_t
, 1);
49 (void) vsnprintf(new->e_rsc
, sizeof (new->e_rsc
), fmt
, args
);
55 sbd_err_log(sbd_error_t
*ep
, int ce
)
66 if (ep
->e_rsc
[0] == '\0')
71 for (tp
= sbd_etab
, i
= 0; i
< sbd_etab_len
; i
++, tp
++)
72 if (ep
->e_code
>= tp
->t_base
&& ep
->e_code
<= tp
->t_bnd
)
76 txt
= tp
->t_text
[ep
->e_code
- tp
->t_base
];
78 (void) snprintf(buf
, sizeof (buf
), "error %d", ep
->e_code
);
82 cmn_err(ce
, fmt
, txt
, ep
->e_rsc
);
86 sbd_err_clear(sbd_error_t
**ep
)
88 FREESTRUCT(*ep
, sbd_error_t
, 1);
93 sbd_err_set_c(sbd_error_t
**ep
, int ce
, int e_code
, char *fmt
, ...)
100 tmp
= sbd_err_new(e_code
, fmt
, args
);
102 sbd_err_log(tmp
, ce
);
113 sbd_err_set(sbd_error_t
**ep
, int ce
, int e_code
, char *fmt
, ...)
120 tmp
= sbd_err_new(e_code
, fmt
, args
);
122 sbd_err_log(tmp
, ce
);
130 drerr_new_v(int e_code
, char *fmt
, va_list args
)
132 return (sbd_err_new(e_code
, fmt
, args
));
136 drerr_new(int log
, int e_code
, char *fmt
, ...)
142 ep
= sbd_err_new(e_code
, fmt
, args
);
146 sbd_err_log(ep
, CE_WARN
);
152 drerr_set_c(int log
, sbd_error_t
**ep
, int e_code
, char *fmt
, ...)
158 err
= sbd_err_new(e_code
, fmt
, args
);
162 sbd_err_log(err
, CE_WARN
);
175 dr_memlist_delete(struct memlist
*mlist
)
177 register struct memlist
*ml
;
179 for (ml
= mlist
; ml
; ml
= mlist
) {
181 FREESTRUCT(ml
, struct memlist
, 1);
186 dr_memlist_intersect(struct memlist
*al
, struct memlist
*bl
)
188 uint64_t astart
, aend
, bstart
, bend
;
190 if ((al
== NULL
) || (bl
== NULL
))
193 aend
= al
->ml_address
+ al
->ml_size
;
194 bstart
= bl
->ml_address
;
195 bend
= bl
->ml_address
+ bl
->ml_size
;
198 while (al
&& (aend
<= bstart
))
199 if ((al
= al
->ml_next
) != NULL
)
200 aend
= al
->ml_address
+ al
->ml_size
;
204 if ((astart
= al
->ml_address
) <= bstart
)
207 while (bl
&& (bend
<= astart
))
208 if ((bl
= bl
->ml_next
) != NULL
)
209 bend
= bl
->ml_address
+ bl
->ml_size
;
213 if ((bstart
= bl
->ml_address
) <= astart
)
221 dr_memlist_coalesce(struct memlist
*mlist
)
225 if ((mlist
== NULL
) || (mlist
->ml_next
== NULL
))
228 while (mlist
->ml_next
) {
229 end
= mlist
->ml_address
+ mlist
->ml_size
;
230 if (mlist
->ml_next
->ml_address
<= end
) {
233 nend
= mlist
->ml_next
->ml_address
+
234 mlist
->ml_next
->ml_size
;
236 mlist
->ml_size
+= (nend
- end
);
238 mlist
->ml_next
= mlist
->ml_next
->ml_next
;
240 FREESTRUCT(nl
, struct memlist
, 1);
243 mlist
->ml_next
->ml_prev
= mlist
;
245 mlist
= mlist
->ml_next
;
252 memlist_dump(struct memlist
*mlist
)
254 register struct memlist
*ml
;
257 printf("memlist> EMPTY\n");
258 else for (ml
= mlist
; ml
; ml
= ml
->ml_next
)
259 printf("memlist> 0x%" PRIx64
", 0x%" PRIx64
"\n",
260 ml
->ml_address
, ml
->ml_size
);
265 dr_memlist_dup(struct memlist
*mlist
)
267 struct memlist
*hl
= NULL
, *tl
, **mlp
;
274 for (; mlist
; mlist
= mlist
->ml_next
) {
275 *mlp
= GETSTRUCT(struct memlist
, 1);
276 (*mlp
)->ml_address
= mlist
->ml_address
;
277 (*mlp
)->ml_size
= mlist
->ml_size
;
278 (*mlp
)->ml_prev
= tl
;
280 mlp
= &((*mlp
)->ml_next
);
288 dr_memlist_add_span(struct memlist
*mlist
, uint64_t base
, uint64_t len
)
290 struct memlist
*ml
, *tl
, *nl
;
296 mlist
= GETSTRUCT(struct memlist
, 1);
297 mlist
->ml_address
= base
;
298 mlist
->ml_size
= len
;
299 mlist
->ml_next
= mlist
->ml_prev
= NULL
;
304 for (tl
= ml
= mlist
; ml
; tl
= ml
, ml
= ml
->ml_next
) {
305 if (base
< ml
->ml_address
) {
306 if ((base
+ len
) < ml
->ml_address
) {
307 nl
= GETSTRUCT(struct memlist
, 1);
308 nl
->ml_address
= base
;
311 if ((nl
->ml_prev
= ml
->ml_prev
) != NULL
)
312 nl
->ml_prev
->ml_next
= nl
;
317 ml
->ml_size
= MAX((base
+ len
),
318 (ml
->ml_address
+ ml
->ml_size
)) - base
;
319 ml
->ml_address
= base
;
323 } else if (base
<= (ml
->ml_address
+ ml
->ml_size
)) {
324 ml
->ml_size
= MAX((base
+ len
),
325 (ml
->ml_address
+ ml
->ml_size
)) -
326 MIN(ml
->ml_address
, base
);
327 ml
->ml_address
= MIN(ml
->ml_address
, base
);
332 nl
= GETSTRUCT(struct memlist
, 1);
333 nl
->ml_address
= base
;
340 dr_memlist_coalesce(mlist
);
346 dr_memlist_del_span(struct memlist
*mlist
, uint64_t base
, uint64_t len
)
349 struct memlist
*ml
, *tl
, *nlp
;
355 if ((end
<= mlist
->ml_address
) || (base
== end
))
358 for (tl
= ml
= mlist
; ml
; tl
= ml
, ml
= nlp
) {
363 if (end
<= ml
->ml_address
)
366 mend
= ml
->ml_address
+ ml
->ml_size
;
368 if (base
<= ml
->ml_address
) {
369 ml
->ml_address
= end
;
373 ml
->ml_size
= mend
- ml
->ml_address
;
375 ml
->ml_size
= base
- ml
->ml_address
;
379 * splitting an memlist entry.
381 nl
= GETSTRUCT(struct memlist
, 1);
382 nl
->ml_address
= end
;
383 nl
->ml_size
= mend
- nl
->ml_address
;
384 if ((nl
->ml_next
= nlp
) != NULL
)
391 if (ml
->ml_size
== 0ull) {
393 if ((mlist
= nlp
) != NULL
)
395 FREESTRUCT(ml
, struct memlist
, 1);
400 if ((tl
->ml_next
= nlp
) != NULL
)
402 FREESTRUCT(ml
, struct memlist
, 1);
413 * add span without merging
416 dr_memlist_cat_span(struct memlist
*mlist
, uint64_t base
, uint64_t len
)
418 struct memlist
*ml
, *tl
, *nl
;
424 mlist
= GETSTRUCT(struct memlist
, 1);
425 mlist
->ml_address
= base
;
426 mlist
->ml_size
= len
;
427 mlist
->ml_next
= mlist
->ml_prev
= NULL
;
432 for (tl
= ml
= mlist
; ml
; tl
= ml
, ml
= ml
->ml_next
) {
433 if (base
< ml
->ml_address
) {
434 nl
= GETSTRUCT(struct memlist
, 1);
435 nl
->ml_address
= base
;
438 if ((nl
->ml_prev
= ml
->ml_prev
) != NULL
)
439 nl
->ml_prev
->ml_next
= nl
;
448 nl
= GETSTRUCT(struct memlist
, 1);
449 nl
->ml_address
= base
;