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