xref: /titanic_52/usr/src/cmd/fm/modules/sun4v/generic-mem/gmem_util.c (revision 1529f529004c61fcfd0d95ab79b0f257d6ad4451)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <gmem.h>
27 #include <gmem_util.h>
28 
29 #include <errno.h>
30 #include <stdarg.h>
31 #include <string.h>
32 #include <fm/fmd_api.h>
33 #include <sys/fm/protocol.h>
34 
35 int
36 gmem_set_errno(int err)
37 {
38 	errno = err;
39 	return (-1);
40 }
41 
42 void *
43 gmem_buf_read(fmd_hdl_t *hdl, fmd_case_t *cp, const char *bufname, size_t bufsz)
44 {
45 	void *buf;
46 	size_t sz;
47 
48 	if ((sz = fmd_buf_size(hdl, cp, bufname)) == 0) {
49 		(void) gmem_set_errno(ENOENT);
50 		return (NULL);
51 	} else if (sz != bufsz) {
52 		(void) gmem_set_errno(EINVAL);
53 		return (NULL);
54 	}
55 
56 	buf = fmd_hdl_alloc(hdl, bufsz, FMD_SLEEP);
57 	fmd_buf_read(hdl, cp, bufname, buf, bufsz);
58 
59 	return (buf);
60 }
61 
62 void
63 gmem_vbufname(char *buf, size_t bufsz, const char *fmt, va_list ap)
64 {
65 	char *c;
66 
67 	(void) vsnprintf(buf, bufsz, fmt, ap);
68 
69 	for (c = buf; *c != '\0'; c++) {
70 		if (*c == ' ' || *c == '/' || *c == ':')
71 			*c = '_';
72 	}
73 }
74 
75 void
76 gmem_bufname(char *buf, size_t bufsz, const char *fmt, ...)
77 {
78 	va_list ap;
79 
80 	va_start(ap, fmt);
81 	gmem_vbufname(buf, bufsz, fmt, ap);
82 	va_end(ap);
83 }
84 
85 void
86 gmem_list_append(gmem_list_t *lp, void *new)
87 {
88 	gmem_list_t *p = lp->l_prev;	/* p = tail list element */
89 	gmem_list_t *q = new;		/* q = new list element */
90 
91 	lp->l_prev = q;
92 	q->l_prev = p;
93 	q->l_next = NULL;
94 
95 	if (p != NULL)
96 		p->l_next = q;
97 	else
98 		lp->l_next = q;
99 }
100 
101 void
102 gmem_list_prepend(gmem_list_t *lp, void *new)
103 {
104 	gmem_list_t *p = new;		/* p = new list element */
105 	gmem_list_t *q = lp->l_next;	/* q = head list element */
106 
107 	lp->l_next = p;
108 	p->l_prev = NULL;
109 	p->l_next = q;
110 
111 	if (q != NULL)
112 		q->l_prev = p;
113 	else
114 		lp->l_prev = p;
115 }
116 
117 void
118 gmem_list_insert_before(gmem_list_t *lp, void *before_me, void *new)
119 {
120 	gmem_list_t *p = before_me;
121 	gmem_list_t *q = new;
122 
123 	if (p == NULL || p->l_prev == NULL) {
124 		gmem_list_prepend(lp, new);
125 		return;
126 	}
127 
128 	q->l_prev = p->l_prev;
129 	q->l_next = p;
130 	p->l_prev = q;
131 	q->l_prev->l_next = q;
132 }
133 
134 void
135 gmem_list_insert_after(gmem_list_t *lp, void *after_me, void *new)
136 {
137 	gmem_list_t *p = after_me;
138 	gmem_list_t *q = new;
139 
140 	if (p == NULL || p->l_next == NULL) {
141 		gmem_list_append(lp, new);
142 		return;
143 	}
144 
145 	q->l_next = p->l_next;
146 	q->l_prev = p;
147 	p->l_next = q;
148 	q->l_next->l_prev = q;
149 }
150 
151 void
152 gmem_list_delete(gmem_list_t *lp, void *existing)
153 {
154 	gmem_list_t *p = existing;
155 
156 	if (p->l_prev != NULL)
157 		p->l_prev->l_next = p->l_next;
158 	else
159 		lp->l_next = p->l_next;
160 
161 	if (p->l_next != NULL)
162 		p->l_next->l_prev = p->l_prev;
163 	else
164 		lp->l_prev = p->l_prev;
165 }
166