xref: /illumos-gate/usr/src/lib/libfruutils/fru_tag.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <errno.h>
30 
31 #include "fru_tag.h"
32 
33 char *
34 get_tagtype_str(fru_tagtype_t e)
35 {
36 	switch (e) {
37 		case FRU_A:
38 			return ("A");
39 		case FRU_B:
40 			return ("B");
41 		case FRU_C:
42 			return ("C");
43 		case FRU_D:
44 			return ("D");
45 		case FRU_E:
46 			return ("E");
47 		case FRU_F:
48 			return ("F");
49 		case FRU_G:
50 			return ("G");
51 		case FRU_X:
52 			return ("X");
53 	}
54 	return ("?");
55 }
56 
57 size_t
58 get_tag_size(fru_tagtype_t tag)
59 {
60 	switch (tag) {
61 		case FRU_A:
62 			return (1);
63 		case FRU_B:
64 		case FRU_C:
65 			return (2);
66 		case FRU_D:
67 		case FRU_E:
68 			return (3);
69 		case FRU_F:
70 			return (4);
71 		case FRU_G:
72 			return (6);
73 	}
74 	errno = EINVAL;
75 	return (-1);
76 }
77 
78 int
79 mk_tag(fru_tagtype_t type, uint32_t dense, size_t pl_len,
80 	fru_tag_t *tag)
81 {
82 	static fru_tag_t max = { 0xFFFFFFFFFFFFFFFFULL };
83 	/* make sure the tag is clear. */
84 	tag->raw_data = 0;
85 
86 	/* then fill it in with data. */
87 	switch (type) {
88 		case FRU_A:
89 			if ((dense > max.a.dense) || (pl_len > max.a.pl_len)) {
90 				errno = EINVAL;
91 				return (-1);
92 			}
93 			tag->a.type = FRU_A_ID;
94 			tag->a.dense = dense;
95 			tag->a.pl_len = pl_len;
96 			break;
97 		case FRU_B:
98 			if ((dense > max.b.dense) || (pl_len > max.b.pl_len)) {
99 				errno = EINVAL;
100 				return (-1);
101 			}
102 			tag->b.type = FRU_B_ID;
103 			tag->b.dense = dense;
104 			tag->b.pl_len = pl_len;
105 			break;
106 		case FRU_C:
107 			if ((dense > max.c.dense) || (pl_len > max.c.pl_len)) {
108 				errno = EINVAL;
109 				return (-1);
110 			}
111 			tag->c.type = FRU_C_ID;
112 			tag->c.dense = dense;
113 			tag->c.pl_len = pl_len;
114 			break;
115 		case FRU_D:
116 			if ((dense > max.d.dense) || (pl_len > max.d.pl_len)) {
117 				errno = EINVAL;
118 				return (-1);
119 			}
120 			tag->d.type = FRU_D_ID;
121 			tag->d.dense = dense;
122 			tag->d.pl_len = pl_len;
123 			break;
124 		case FRU_E:
125 			if ((dense > max.e.dense) || (pl_len > max.e.pl_len)) {
126 				errno = EINVAL;
127 				return (-1);
128 			}
129 			tag->e.type = FRU_E_ID;
130 			tag->e.dense = dense;
131 			tag->e.pl_len = pl_len;
132 			break;
133 		case FRU_F:
134 			if ((dense > max.f.dense) || (pl_len > max.f.pl_len)) {
135 				errno = EINVAL;
136 				return (-1);
137 			}
138 			tag->f.type = FRU_F_ID;
139 			tag->f.dense = dense;
140 			tag->f.pl_len = pl_len;
141 			break;
142 		case FRU_G:
143 			if ((dense > max.g.dense) || (pl_len > max.g.pl_len)) {
144 				errno = EINVAL;
145 				return (-1);
146 			}
147 			tag->g.type = FRU_G_ID;
148 			tag->g.dense = dense;
149 			tag->g.pl_len = pl_len;
150 			break;
151 		default:
152 			errno = EINVAL;
153 			return (-1);
154 	}
155 
156 	return (get_tag_size(type));
157 }
158 
159 fru_tagtype_t
160 get_tag_type(fru_tag_t *tag)
161 {
162 	if (tag->a.type == FRU_A_ID)
163 		return (FRU_A);
164 	else if (tag->b.type  == FRU_B_ID)
165 		return (FRU_B);
166 	else if (tag->c.type == FRU_C_ID)
167 		return (FRU_C);
168 	else if (tag->d.type == FRU_D_ID)
169 		return (FRU_D);
170 	else if (tag->e.type == FRU_E_ID)
171 		return (FRU_E);
172 	else if (tag->f.type == FRU_F_ID)
173 		return (FRU_F);
174 	else if (tag->g.type == FRU_G_ID)
175 		return (FRU_G);
176 	else
177 		errno = EINVAL;
178 		return (-1);
179 }
180 
181 uint32_t
182 get_tag_dense(fru_tag_t *tag)
183 {
184 	switch (get_tag_type(tag)) {
185 		case FRU_A:
186 			return (tag->a.dense);
187 		case FRU_B:
188 			return (tag->b.dense);
189 		case FRU_C:
190 			return (tag->c.dense);
191 		case FRU_D:
192 			return (tag->d.dense);
193 		case FRU_E:
194 			return (tag->e.dense);
195 		case FRU_F:
196 			return (tag->f.dense);
197 		case FRU_G:
198 			return (tag->g.dense);
199 		default:
200 			errno = EINVAL;
201 			return ((uint32_t)-1);
202 	}
203 }
204 
205 size_t
206 get_payload_length(fru_tag_t *tag)
207 {
208 	switch (get_tag_type(tag)) {
209 		case FRU_A:
210 			return (tag->a.pl_len);
211 		case FRU_B:
212 			return (tag->b.pl_len);
213 		case FRU_C:
214 			return (tag->c.pl_len);
215 		case FRU_D:
216 			return (tag->d.pl_len);
217 		case FRU_E:
218 			return (tag->e.pl_len);
219 		case FRU_F:
220 			return (tag->f.pl_len);
221 		case FRU_G:
222 			return (tag->g.pl_len);
223 		default:
224 			errno = EINVAL;
225 			return ((uint32_t)-1);
226 	}
227 }
228 
229 int
230 tags_equal(fru_tag_t t1, fru_tag_t t2)
231 {
232 	return ((get_tag_type(&t1) == get_tag_type(&t2)) &&
233 		(get_tag_dense(&t1) == get_tag_dense(&t2)) &&
234 		(get_payload_length(&t1) == get_payload_length(&t2)));
235 }
236