1*074bb90dSTom Pothier /*
2*074bb90dSTom Pothier * CDDL HEADER START
3*074bb90dSTom Pothier *
4*074bb90dSTom Pothier * The contents of this file are subject to the terms of the
5*074bb90dSTom Pothier * Common Development and Distribution License (the "License").
6*074bb90dSTom Pothier * You may not use this file except in compliance with the License.
7*074bb90dSTom Pothier *
8*074bb90dSTom Pothier * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*074bb90dSTom Pothier * or http://www.opensolaris.org/os/licensing.
10*074bb90dSTom Pothier * See the License for the specific language governing permissions
11*074bb90dSTom Pothier * and limitations under the License.
12*074bb90dSTom Pothier *
13*074bb90dSTom Pothier * When distributing Covered Code, include this CDDL HEADER in each
14*074bb90dSTom Pothier * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*074bb90dSTom Pothier * If applicable, add the following below this CDDL HEADER, with the
16*074bb90dSTom Pothier * fields enclosed by brackets "[]" replaced with your own identifying
17*074bb90dSTom Pothier * information: Portions Copyright [yyyy] [name of copyright owner]
18*074bb90dSTom Pothier *
19*074bb90dSTom Pothier * CDDL HEADER END
20*074bb90dSTom Pothier */
21*074bb90dSTom Pothier
22*074bb90dSTom Pothier /*
23*074bb90dSTom Pothier * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24*074bb90dSTom Pothier * Use is subject to license terms.
25*074bb90dSTom Pothier */
26*074bb90dSTom Pothier
27*074bb90dSTom Pothier /*
28*074bb90dSTom Pothier * Create a generic topology node.
29*074bb90dSTom Pothier */
30*074bb90dSTom Pothier #include <sys/types.h>
31*074bb90dSTom Pothier #include <strings.h>
32*074bb90dSTom Pothier #include <sys/fm/protocol.h>
33*074bb90dSTom Pothier #include <fm/topo_mod.h>
34*074bb90dSTom Pothier #include <fm/topo_hc.h>
35*074bb90dSTom Pothier #include <x86pi_impl.h>
36*074bb90dSTom Pothier
37*074bb90dSTom Pothier #define _ENUM_NAME "enum_generic"
38*074bb90dSTom Pothier #define _FAC_PROV "fac_prov_ipmi"
39*074bb90dSTom Pothier
40*074bb90dSTom Pothier /*
41*074bb90dSTom Pothier * Create a generic topo node based on the hcfmri strcuture passed in.
42*074bb90dSTom Pothier */
43*074bb90dSTom Pothier int
x86pi_enum_generic(topo_mod_t * mod,x86pi_hcfmri_t * hcfmri,tnode_t * t_bindparent,tnode_t * t_fmriparent,tnode_t ** t_node,int flag)44*074bb90dSTom Pothier x86pi_enum_generic(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri,
45*074bb90dSTom Pothier tnode_t *t_bindparent, tnode_t *t_fmriparent, tnode_t **t_node, int flag)
46*074bb90dSTom Pothier {
47*074bb90dSTom Pothier int rv;
48*074bb90dSTom Pothier int err;
49*074bb90dSTom Pothier nvlist_t *out;
50*074bb90dSTom Pothier nvlist_t *fmri;
51*074bb90dSTom Pothier nvlist_t *auth;
52*074bb90dSTom Pothier
53*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s adding entry for type (%s)\n",
54*074bb90dSTom Pothier _ENUM_NAME, hcfmri->hc_name);
55*074bb90dSTom Pothier
56*074bb90dSTom Pothier if (t_bindparent == NULL) {
57*074bb90dSTom Pothier topo_mod_dprintf(mod,
58*074bb90dSTom Pothier "%s called with NULL parent for type %s\n",
59*074bb90dSTom Pothier _ENUM_NAME, hcfmri->hc_name);
60*074bb90dSTom Pothier return (-1);
61*074bb90dSTom Pothier }
62*074bb90dSTom Pothier
63*074bb90dSTom Pothier /* Create the FMRI for this node */
64*074bb90dSTom Pothier auth = topo_mod_auth(mod, t_bindparent);
65*074bb90dSTom Pothier fmri = topo_mod_hcfmri(mod, t_fmriparent, FM_HC_SCHEME_VERSION,
66*074bb90dSTom Pothier hcfmri->hc_name, hcfmri->instance, NULL, auth,
67*074bb90dSTom Pothier hcfmri->part_number, hcfmri->version, hcfmri->serial_number);
68*074bb90dSTom Pothier
69*074bb90dSTom Pothier nvlist_free(auth);
70*074bb90dSTom Pothier
71*074bb90dSTom Pothier if (fmri == NULL) {
72*074bb90dSTom Pothier topo_mod_dprintf(mod,
73*074bb90dSTom Pothier "%s failed to create %s fmri : %s\n", _ENUM_NAME,
74*074bb90dSTom Pothier hcfmri->hc_name, topo_strerror(topo_mod_errno(mod)));
75*074bb90dSTom Pothier return (-1);
76*074bb90dSTom Pothier }
77*074bb90dSTom Pothier
78*074bb90dSTom Pothier rv = topo_node_range_create(mod, t_bindparent, hcfmri->hc_name, 0, 4);
79*074bb90dSTom Pothier if (rv != 0 && topo_mod_errno(mod) != EMOD_NODE_DUP) {
80*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s range create failed for node %s\n",
81*074bb90dSTom Pothier _ENUM_NAME, hcfmri->hc_name);
82*074bb90dSTom Pothier }
83*074bb90dSTom Pothier
84*074bb90dSTom Pothier /* Bind this node to the parent */
85*074bb90dSTom Pothier *t_node = x86pi_node_bind(mod, t_bindparent, hcfmri, fmri, flag);
86*074bb90dSTom Pothier nvlist_free(fmri);
87*074bb90dSTom Pothier if (*t_node == NULL) {
88*074bb90dSTom Pothier topo_mod_dprintf(mod,
89*074bb90dSTom Pothier "%s failed to bind %s node instance %d: %s\n",
90*074bb90dSTom Pothier _ENUM_NAME, hcfmri->hc_name, hcfmri->instance,
91*074bb90dSTom Pothier topo_strerror(topo_mod_errno(mod)));
92*074bb90dSTom Pothier return (-1);
93*074bb90dSTom Pothier }
94*074bb90dSTom Pothier
95*074bb90dSTom Pothier /* call IPMI facility provider to register fac methods */
96*074bb90dSTom Pothier if (topo_mod_load(mod, _FAC_PROV, TOPO_VERSION) == NULL) {
97*074bb90dSTom Pothier topo_mod_dprintf(mod,
98*074bb90dSTom Pothier "%s: Failed to load %s module: %s\n", _ENUM_NAME, _FAC_PROV,
99*074bb90dSTom Pothier topo_mod_errmsg(mod));
100*074bb90dSTom Pothier return (-1);
101*074bb90dSTom Pothier }
102*074bb90dSTom Pothier
103*074bb90dSTom Pothier rv = topo_mod_enumerate(mod, *t_node, _FAC_PROV, _FAC_PROV, 0, 0, NULL);
104*074bb90dSTom Pothier if (rv != 0) {
105*074bb90dSTom Pothier topo_mod_dprintf(mod,
106*074bb90dSTom Pothier "%s: %s failed: %s\n", _ENUM_NAME, _FAC_PROV,
107*074bb90dSTom Pothier topo_mod_errmsg(mod));
108*074bb90dSTom Pothier return (-1);
109*074bb90dSTom Pothier }
110*074bb90dSTom Pothier
111*074bb90dSTom Pothier /* invoke fac_prov_ipmi_enum method */
112*074bb90dSTom Pothier if (topo_method_supported(*t_node, TOPO_METH_FAC_ENUM, 0)) {
113*074bb90dSTom Pothier if (topo_method_invoke(*t_node, TOPO_METH_FAC_ENUM, 0, NULL,
114*074bb90dSTom Pothier &out, &err) != 0) {
115*074bb90dSTom Pothier /* log the error and drive on */
116*074bb90dSTom Pothier topo_mod_dprintf(mod,
117*074bb90dSTom Pothier "%s: TOPO_METH_FAC_ENUM failed\n", _ENUM_NAME);
118*074bb90dSTom Pothier } else {
119*074bb90dSTom Pothier fac_done = 1;
120*074bb90dSTom Pothier }
121*074bb90dSTom Pothier }
122*074bb90dSTom Pothier
123*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s added (%s) node\n", _ENUM_NAME,
124*074bb90dSTom Pothier topo_node_name(*t_node));
125*074bb90dSTom Pothier
126*074bb90dSTom Pothier return (0);
127*074bb90dSTom Pothier }
128*074bb90dSTom Pothier
129*074bb90dSTom Pothier
130*074bb90dSTom Pothier tnode_t *
x86pi_node_bind(topo_mod_t * mod,tnode_t * t_parent,x86pi_hcfmri_t * hcfmri,nvlist_t * fmri,int flag)131*074bb90dSTom Pothier x86pi_node_bind(topo_mod_t *mod, tnode_t *t_parent, x86pi_hcfmri_t *hcfmri,
132*074bb90dSTom Pothier nvlist_t *fmri, int flag)
133*074bb90dSTom Pothier {
134*074bb90dSTom Pothier int result;
135*074bb90dSTom Pothier tnode_t *t_node;
136*074bb90dSTom Pothier char *f = "x86pi_node_bind";
137*074bb90dSTom Pothier
138*074bb90dSTom Pothier if (t_parent == NULL) {
139*074bb90dSTom Pothier topo_mod_dprintf(mod,
140*074bb90dSTom Pothier "%s: NULL parent for %s node instance %d\n",
141*074bb90dSTom Pothier f, hcfmri->hc_name, hcfmri->instance);
142*074bb90dSTom Pothier return (NULL);
143*074bb90dSTom Pothier }
144*074bb90dSTom Pothier
145*074bb90dSTom Pothier /* Bind this node to the parent */
146*074bb90dSTom Pothier t_node = topo_node_bind(mod, t_parent, hcfmri->hc_name,
147*074bb90dSTom Pothier hcfmri->instance, fmri);
148*074bb90dSTom Pothier if (t_node == NULL) {
149*074bb90dSTom Pothier topo_mod_dprintf(mod,
150*074bb90dSTom Pothier "%s: failed to bind %s node instance %d: %s\n",
151*074bb90dSTom Pothier f, hcfmri->hc_name, (uint32_t)hcfmri->instance,
152*074bb90dSTom Pothier topo_strerror(topo_mod_errno(mod)));
153*074bb90dSTom Pothier return (NULL);
154*074bb90dSTom Pothier }
155*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: bound %s node instance %d type %s\n",
156*074bb90dSTom Pothier f, hcfmri->hc_name, hcfmri->instance, hcfmri->hc_name);
157*074bb90dSTom Pothier
158*074bb90dSTom Pothier /*
159*074bb90dSTom Pothier * We have bound the node. Now decorate it with an appropriate
160*074bb90dSTom Pothier * FRU and label (which may be inherited from the parent).
161*074bb90dSTom Pothier */
162*074bb90dSTom Pothier result = x86pi_set_frufmri(mod, hcfmri, t_parent, t_node, flag);
163*074bb90dSTom Pothier if (result != 0) {
164*074bb90dSTom Pothier /*
165*074bb90dSTom Pothier * Though we have failed to set the FRU FMRI we still continue.
166*074bb90dSTom Pothier * The module errno is set by the called routine, so we report
167*074bb90dSTom Pothier * the problem and move on.
168*074bb90dSTom Pothier */
169*074bb90dSTom Pothier topo_mod_dprintf(mod,
170*074bb90dSTom Pothier "%s: failed to set FRU FMRI for %s node\n",
171*074bb90dSTom Pothier f, hcfmri->hc_name);
172*074bb90dSTom Pothier }
173*074bb90dSTom Pothier
174*074bb90dSTom Pothier result = x86pi_set_label(mod, hcfmri->location, hcfmri->hc_name,
175*074bb90dSTom Pothier t_node);
176*074bb90dSTom Pothier if (result != 0) {
177*074bb90dSTom Pothier /*
178*074bb90dSTom Pothier * Though we have failed to set the label, we still continue.
179*074bb90dSTom Pothier * The module errno is set by the called routine, so we report
180*074bb90dSTom Pothier * the problem and move on.
181*074bb90dSTom Pothier */
182*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: no label for %s node\n",
183*074bb90dSTom Pothier f, hcfmri->hc_name);
184*074bb90dSTom Pothier }
185*074bb90dSTom Pothier
186*074bb90dSTom Pothier result = x86pi_set_auth(mod, hcfmri, t_parent, t_node);
187*074bb90dSTom Pothier if (result != 0) {
188*074bb90dSTom Pothier /*
189*074bb90dSTom Pothier * Though we have failed to set the authority, we still
190*074bb90dSTom Pothier * continue. The module errno is set by the called routine, so
191*074bb90dSTom Pothier * we report the problem and move on.
192*074bb90dSTom Pothier */
193*074bb90dSTom Pothier topo_mod_dprintf(mod,
194*074bb90dSTom Pothier "%s: no authority information for %s node\n",
195*074bb90dSTom Pothier f, hcfmri->hc_name);
196*074bb90dSTom Pothier }
197*074bb90dSTom Pothier
198*074bb90dSTom Pothier result = x86pi_set_system(mod, t_node);
199*074bb90dSTom Pothier if (result != 0) {
200*074bb90dSTom Pothier /*
201*074bb90dSTom Pothier * Though we have failed to set the system group, we still
202*074bb90dSTom Pothier * continue. The module errno is set by the called routine, so
203*074bb90dSTom Pothier * we report the problem and move on.
204*074bb90dSTom Pothier */
205*074bb90dSTom Pothier topo_mod_dprintf(mod,
206*074bb90dSTom Pothier "%s: no system information for %s node\n",
207*074bb90dSTom Pothier f, hcfmri->hc_name);
208*074bb90dSTom Pothier }
209*074bb90dSTom Pothier
210*074bb90dSTom Pothier return (t_node);
211*074bb90dSTom Pothier }
212