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 /* 23 * Copyright 2006 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 <libxml/parser.h> 30 #include <fm/libtopo.h> 31 #include <topo_alloc.h> 32 #include <topo_error.h> 33 #include <topo_parse.h> 34 35 extern const char * const Name; 36 const char * const Min = "min"; 37 const char * const Max = "max"; 38 39 40 tf_info_t * 41 tf_info_new(topo_mod_t *mp, const char *fn, xmlDocPtr doc, xmlChar *scheme) 42 { 43 tf_info_t *r; 44 45 if ((r = topo_mod_zalloc(mp, sizeof (tf_info_t))) == NULL) 46 return (NULL); 47 r->tf_flags = TF_LIVE; 48 if ((r->tf_fn = topo_mod_strdup(mp, fn)) == NULL) { 49 tf_info_free(mp, r); 50 return (NULL); 51 } 52 if ((r->tf_scheme = topo_mod_strdup(mp, (char *)scheme)) == NULL) { 53 tf_info_free(mp, r); 54 return (NULL); 55 } 56 r->tf_xdoc = doc; 57 return (r); 58 } 59 60 void 61 tf_info_free(topo_mod_t *mp, tf_info_t *p) 62 { 63 if (p->tf_xdoc != NULL) 64 xmlFreeDoc(p->tf_xdoc); 65 if (p->tf_fn != NULL) 66 topo_mod_strfree(mp, p->tf_fn); 67 if (p->tf_scheme != NULL) 68 topo_mod_strfree(mp, p->tf_scheme); 69 tf_rdata_free(mp, p->tf_rd); 70 topo_mod_free(mp, p, sizeof (tf_info_t)); 71 } 72 73 tf_rdata_t * 74 tf_rdata_new(topo_mod_t *mp, tf_info_t *xinfo, xmlNodePtr n, tnode_t *troot) 75 { 76 tf_rdata_t *r; 77 uint64_t ui; 78 xmlChar *name = NULL; 79 80 topo_mod_dprintf(mp, "new rdata\n"); 81 if ((r = topo_mod_zalloc(mp, sizeof (tf_rdata_t))) == NULL) { 82 (void) topo_mod_seterrno(mp, ETOPO_NOMEM); 83 return (NULL); 84 } 85 r->rd_pn = troot; 86 if ((name = xmlGetProp(n, (xmlChar *)Name)) == NULL) { 87 (void) topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR); 88 goto rdata_nogood; 89 } 90 if ((r->rd_name = topo_mod_strdup(mp, (char *)name)) == NULL) { 91 (void) topo_mod_seterrno(mp, ETOPO_NOMEM); 92 goto rdata_nogood; 93 } 94 if (xmlattr_to_int(mp, n, Min, &ui) < 0) 95 goto rdata_nogood; 96 r->rd_min = (int)ui; 97 if (xmlattr_to_int(mp, n, Max, &ui) < 0) 98 goto rdata_nogood; 99 r->rd_max = (int)ui; 100 if (r->rd_min < 0 || r->rd_max < 0 || r->rd_max < r->rd_min) { 101 (void) topo_mod_seterrno(mp, ETOPO_PRSR_BADRNG); 102 goto rdata_nogood; 103 } 104 r->rd_finfo = xinfo; 105 r->rd_mod = mp; 106 107 if (topo_xml_range_process(mp, n, r) < 0) 108 goto rdata_nogood; 109 110 xmlFree(name); 111 return (r); 112 113 rdata_nogood: 114 if (name != NULL) 115 xmlFree(name); 116 tf_rdata_free(mp, r); 117 return (NULL); 118 } 119 120 void 121 tf_rdata_free(topo_mod_t *mp, tf_rdata_t *p) 122 { 123 if (p == NULL) 124 return; 125 tf_rdata_free(mp, p->rd_next); 126 if (p->rd_name != NULL) 127 topo_mod_strfree(mp, p->rd_name); 128 tf_edata_free(mp, p->rd_einfo); 129 tf_idata_free(mp, p->rd_instances); 130 tf_pad_free(mp, p->rd_pad); 131 topo_mod_free(mp, p, sizeof (tf_rdata_t)); 132 } 133 134 tf_idata_t * 135 tf_idata_new(topo_mod_t *mp, topo_instance_t i, tnode_t *tn) 136 { 137 tf_idata_t *r; 138 139 topo_mod_dprintf(mp, "new idata %d\n", i); 140 if ((r = topo_mod_zalloc(mp, sizeof (tf_idata_t))) == NULL) 141 return (NULL); 142 r->ti_tn = tn; 143 r->ti_i = i; 144 return (r); 145 } 146 147 void 148 tf_idata_free(topo_mod_t *mp, tf_idata_t *p) 149 { 150 if (p == NULL) 151 return; 152 tf_idata_free(mp, p->ti_next); 153 tf_pad_free(mp, p->ti_pad); 154 topo_mod_free(mp, p, sizeof (tf_idata_t)); 155 } 156 157 int 158 tf_idata_insert(topo_mod_t *mp, tf_idata_t **head, tf_idata_t *ni) 159 { 160 tf_idata_t *l, *p; 161 162 topo_mod_dprintf(mp, "idata insert %d\n", ni->ti_i); 163 p = NULL; 164 for (l = *head; l != NULL; l = l->ti_next) { 165 if (ni->ti_i < l->ti_i) 166 break; 167 p = l; 168 } 169 ni->ti_next = l; 170 if (p == NULL) 171 *head = ni; 172 else 173 p->ti_next = ni; 174 return (0); 175 } 176 177 tf_idata_t * 178 tf_idata_lookup(topo_mod_t *mp, tf_idata_t *head, topo_instance_t i) 179 { 180 tf_idata_t *f; 181 topo_mod_dprintf(mp, "idata lookup %d\n", i); 182 for (f = head; f != NULL; f = f->ti_next) 183 if (i == f->ti_i) 184 break; 185 return (f); 186 } 187 188 tf_pad_t * 189 tf_pad_new(topo_mod_t *mp, int pcnt, int dcnt) 190 { 191 tf_pad_t *r; 192 193 topo_mod_dprintf(mp, "new pad p=%d, d=%d\n", pcnt, dcnt); 194 if ((r = topo_mod_zalloc(mp, sizeof (tf_pad_t))) == NULL) 195 return (NULL); 196 r->tpad_pgcnt = pcnt; 197 r->tpad_dcnt = dcnt; 198 return (r); 199 } 200 201 void 202 tf_pad_free(topo_mod_t *mp, tf_pad_t *p) 203 { 204 int n; 205 if (p == NULL) 206 return; 207 if (p->tpad_pgs != NULL) { 208 for (n = 0; n < p->tpad_pgcnt; n++) 209 if (p->tpad_pgs[n] != NULL) 210 nvlist_free(p->tpad_pgs[n]); 211 topo_mod_free(mp, 212 p->tpad_pgs, p->tpad_pgcnt * sizeof (nvlist_t *)); 213 } 214 tf_rdata_free(mp, p->tpad_child); 215 tf_rdata_free(mp, p->tpad_sibs); 216 topo_mod_free(mp, p, sizeof (tf_pad_t)); 217 } 218 219 void 220 tf_edata_free(topo_mod_t *mp, tf_edata_t *p) 221 { 222 if (p == NULL) 223 return; 224 if (p->te_name != NULL) 225 xmlFree(p->te_name); 226 if (p->te_path != NULL) 227 xmlFree(p->te_path); 228 topo_mod_free(mp, p, sizeof (tf_edata_t)); 229 } 230