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