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