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