Home | History | Annotate | Download | only in libfruutils
      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