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 * Subroutines used by the i86pc Generic Topology Enumerator 29*074bb90dSTom Pothier */ 30*074bb90dSTom Pothier 31*074bb90dSTom Pothier #include <sys/types.h> 32*074bb90dSTom Pothier #include <strings.h> 33*074bb90dSTom Pothier #include <deflt.h> 34*074bb90dSTom Pothier #include <fcntl.h> 35*074bb90dSTom Pothier #include <unistd.h> 36*074bb90dSTom Pothier #include <fm/topo_mod.h> 37*074bb90dSTom Pothier #include <fm/topo_hc.h> 38*074bb90dSTom Pothier #include <sys/devfm.h> 39*074bb90dSTom Pothier #include <sys/systeminfo.h> 40*074bb90dSTom Pothier #include <sys/fm/protocol.h> 41*074bb90dSTom Pothier #include <sys/utsname.h> 42*074bb90dSTom Pothier #include <sys/smbios.h> 43*074bb90dSTom Pothier #include <sys/smbios_impl.h> 44*074bb90dSTom Pothier #include <x86pi_impl.h> 45*074bb90dSTom Pothier 46*074bb90dSTom Pothier 47*074bb90dSTom Pothier static const topo_pgroup_info_t sys_pgroup = { 48*074bb90dSTom Pothier TOPO_PGROUP_SYSTEM, 49*074bb90dSTom Pothier TOPO_STABILITY_PRIVATE, 50*074bb90dSTom Pothier TOPO_STABILITY_PRIVATE, 51*074bb90dSTom Pothier 1 52*074bb90dSTom Pothier }; 53*074bb90dSTom Pothier 54*074bb90dSTom Pothier static const topo_pgroup_info_t auth_pgroup = { 55*074bb90dSTom Pothier FM_FMRI_AUTHORITY, 56*074bb90dSTom Pothier TOPO_STABILITY_PRIVATE, 57*074bb90dSTom Pothier TOPO_STABILITY_PRIVATE, 58*074bb90dSTom Pothier 1 59*074bb90dSTom Pothier }; 60*074bb90dSTom Pothier 61*074bb90dSTom Pothier 62*074bb90dSTom Pothier /* 63*074bb90dSTom Pothier * Free hcfmri strings. 64*074bb90dSTom Pothier */ 65*074bb90dSTom Pothier void 66*074bb90dSTom Pothier x86pi_hcfmri_info_fini(topo_mod_t *mod, x86pi_hcfmri_t *hc) 67*074bb90dSTom Pothier { 68*074bb90dSTom Pothier if (hc->hc_name != NULL) 69*074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->hc_name); 70*074bb90dSTom Pothier if (hc->manufacturer != NULL) 71*074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->manufacturer); 72*074bb90dSTom Pothier if (hc->product != NULL) 73*074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->product); 74*074bb90dSTom Pothier if (hc->version != NULL) 75*074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->version); 76*074bb90dSTom Pothier if (hc->serial_number != NULL) 77*074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->serial_number); 78*074bb90dSTom Pothier if (hc->asset_tag != NULL) 79*074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->asset_tag); 80*074bb90dSTom Pothier if (hc->location != NULL) 81*074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->location); 82*074bb90dSTom Pothier if (hc->part_number != NULL) 83*074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->part_number); 84*074bb90dSTom Pothier } 85*074bb90dSTom Pothier 86*074bb90dSTom Pothier 87*074bb90dSTom Pothier /* 88*074bb90dSTom Pothier * Get the server hostname (the ID as far as the topo authority is 89*074bb90dSTom Pothier * concerned) from sysinfo and return a copy to the caller. 90*074bb90dSTom Pothier * 91*074bb90dSTom Pothier * The string must be freed with topo_mod_strfree() 92*074bb90dSTom Pothier */ 93*074bb90dSTom Pothier char * 94*074bb90dSTom Pothier x86pi_get_serverid(topo_mod_t *mod) 95*074bb90dSTom Pothier { 96*074bb90dSTom Pothier int result; 97*074bb90dSTom Pothier char hostname[MAXNAMELEN]; 98*074bb90dSTom Pothier 99*074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_get_serverid\n"); 100*074bb90dSTom Pothier 101*074bb90dSTom Pothier result = sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); 102*074bb90dSTom Pothier /* Everything is freed up and it's time to return the platform-id */ 103*074bb90dSTom Pothier if (result == -1) { 104*074bb90dSTom Pothier return (NULL); 105*074bb90dSTom Pothier } 106*074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_get_serverid: hostname = %s\n", hostname); 107*074bb90dSTom Pothier 108*074bb90dSTom Pothier return (topo_mod_strdup(mod, hostname)); 109*074bb90dSTom Pothier } 110*074bb90dSTom Pothier 111*074bb90dSTom Pothier 112*074bb90dSTom Pothier /* 113*074bb90dSTom Pothier * Get copy of SMBIOS. 114*074bb90dSTom Pothier */ 115*074bb90dSTom Pothier smbios_hdl_t * 116*074bb90dSTom Pothier x86pi_smb_open(topo_mod_t *mod) 117*074bb90dSTom Pothier { 118*074bb90dSTom Pothier smbios_hdl_t *smb_hdl; 119*074bb90dSTom Pothier char *f = "x86pi_smb_open"; 120*074bb90dSTom Pothier 121*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s\n", f); 122*074bb90dSTom Pothier 123*074bb90dSTom Pothier smb_hdl = topo_mod_smbios(mod); 124*074bb90dSTom Pothier if (smb_hdl == NULL) { 125*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f); 126*074bb90dSTom Pothier return (NULL); 127*074bb90dSTom Pothier } 128*074bb90dSTom Pothier 129*074bb90dSTom Pothier return (smb_hdl); 130*074bb90dSTom Pothier } 131*074bb90dSTom Pothier 132*074bb90dSTom Pothier 133*074bb90dSTom Pothier /* 134*074bb90dSTom Pothier * Go through the smbios structures looking for a type. Fill in 135*074bb90dSTom Pothier * the structure count as well as the id(s) of the struct types. 136*074bb90dSTom Pothier */ 137*074bb90dSTom Pothier void 138*074bb90dSTom Pothier x86pi_smb_strcnt(smbios_hdl_t *shp, smbs_cnt_t *stype) 139*074bb90dSTom Pothier { 140*074bb90dSTom Pothier const smb_struct_t *sp = shp->sh_structs; 141*074bb90dSTom Pothier int nstructs = shp->sh_nstructs; 142*074bb90dSTom Pothier int i, cnt; 143*074bb90dSTom Pothier 144*074bb90dSTom Pothier for (i = 0, cnt = 0; i < nstructs; i++, sp++) { 145*074bb90dSTom Pothier if (sp->smbst_hdr->smbh_type == stype->type) { 146*074bb90dSTom Pothier stype->ids[cnt].node = NULL; 147*074bb90dSTom Pothier stype->ids[cnt].id = sp->smbst_hdr->smbh_hdl; 148*074bb90dSTom Pothier cnt++; 149*074bb90dSTom Pothier } 150*074bb90dSTom Pothier } 151*074bb90dSTom Pothier 152*074bb90dSTom Pothier stype->count = cnt; 153*074bb90dSTom Pothier } 154*074bb90dSTom Pothier 155*074bb90dSTom Pothier 156*074bb90dSTom Pothier /* 157*074bb90dSTom Pothier * Calculate the authority information for a node. Inherit the data if 158*074bb90dSTom Pothier * possible, but always create an appropriate property group. 159*074bb90dSTom Pothier */ 160*074bb90dSTom Pothier int 161*074bb90dSTom Pothier x86pi_set_auth(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent, 162*074bb90dSTom Pothier tnode_t *t_node) 163*074bb90dSTom Pothier { 164*074bb90dSTom Pothier int result; 165*074bb90dSTom Pothier int err; 166*074bb90dSTom Pothier int is_chassis = 0; 167*074bb90dSTom Pothier int chassis_instance = 0; 168*074bb90dSTom Pothier nvlist_t *auth; 169*074bb90dSTom Pothier char *val = NULL; 170*074bb90dSTom Pothier char *prod = NULL; 171*074bb90dSTom Pothier char *psn = NULL; 172*074bb90dSTom Pothier char *csn = NULL; 173*074bb90dSTom Pothier char *server = NULL; 174*074bb90dSTom Pothier char *f = "x86pi_set_auth"; 175*074bb90dSTom Pothier 176*074bb90dSTom Pothier if (mod == NULL || t_parent == NULL || t_node == NULL) { 177*074bb90dSTom Pothier return (-1); 178*074bb90dSTom Pothier } 179*074bb90dSTom Pothier 180*074bb90dSTom Pothier result = topo_pgroup_create(t_node, &auth_pgroup, &err); 181*074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 182*074bb90dSTom Pothier /* 183*074bb90dSTom Pothier * We failed to create the property group and it was not 184*074bb90dSTom Pothier * already defined. Set the err code and return failure. 185*074bb90dSTom Pothier */ 186*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 187*074bb90dSTom Pothier return (-1); 188*074bb90dSTom Pothier } 189*074bb90dSTom Pothier 190*074bb90dSTom Pothier /* Get the authority information already available from the parent */ 191*074bb90dSTom Pothier auth = topo_mod_auth(mod, t_parent); 192*074bb90dSTom Pothier 193*074bb90dSTom Pothier /* Determnine if this is a chassis node and set it's instance */ 194*074bb90dSTom Pothier if ((strlen(hcfmri->hc_name) == strlen(CHASSIS)) && 195*074bb90dSTom Pothier strncmp(hcfmri->hc_name, CHASSIS, strlen(CHASSIS)) == 0) { 196*074bb90dSTom Pothier is_chassis = 1; 197*074bb90dSTom Pothier chassis_instance = hcfmri->instance; 198*074bb90dSTom Pothier } 199*074bb90dSTom Pothier 200*074bb90dSTom Pothier /* 201*074bb90dSTom Pothier * Set the authority data, inheriting it if possible, but creating it 202*074bb90dSTom Pothier * if necessary. 203*074bb90dSTom Pothier */ 204*074bb90dSTom Pothier 205*074bb90dSTom Pothier /* product-id */ 206*074bb90dSTom Pothier result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, 207*074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT, &err); 208*074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 209*074bb90dSTom Pothier result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, 210*074bb90dSTom Pothier &prod); 211*074bb90dSTom Pothier if (result != 0 || prod == NULL) { 212*074bb90dSTom Pothier /* 213*074bb90dSTom Pothier * No product information in the parent node or auth 214*074bb90dSTom Pothier * list. Use the product information in the hcfrmi 215*074bb90dSTom Pothier * struct. 216*074bb90dSTom Pothier */ 217*074bb90dSTom Pothier prod = (char *)hcfmri->product; 218*074bb90dSTom Pothier if (prod == NULL) { 219*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: product name not " 220*074bb90dSTom Pothier "found for %s node\n", f, hcfmri->hc_name); 221*074bb90dSTom Pothier } 222*074bb90dSTom Pothier } 223*074bb90dSTom Pothier 224*074bb90dSTom Pothier /* 225*074bb90dSTom Pothier * We continue even if the product information is not available 226*074bb90dSTom Pothier * to enumerate as much as possible. 227*074bb90dSTom Pothier */ 228*074bb90dSTom Pothier if (prod != NULL) { 229*074bb90dSTom Pothier result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, 230*074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod, 231*074bb90dSTom Pothier &err); 232*074bb90dSTom Pothier if (result != 0) { 233*074bb90dSTom Pothier /* Preserve the error and continue */ 234*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 235*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to set " 236*074bb90dSTom Pothier "property %s (%d) : %s\n", f, 237*074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT, err, 238*074bb90dSTom Pothier topo_strerror(err)); 239*074bb90dSTom Pothier } 240*074bb90dSTom Pothier } 241*074bb90dSTom Pothier } 242*074bb90dSTom Pothier 243*074bb90dSTom Pothier /* product-sn */ 244*074bb90dSTom Pothier result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, 245*074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT_SN, &err); 246*074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 247*074bb90dSTom Pothier result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, 248*074bb90dSTom Pothier &psn); 249*074bb90dSTom Pothier if (result != 0 || psn == NULL) { 250*074bb90dSTom Pothier /* 251*074bb90dSTom Pothier * No product-sn information in the parent node or auth 252*074bb90dSTom Pothier * list. 253*074bb90dSTom Pothier */ 254*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: psn not found\n", f); 255*074bb90dSTom Pothier } else { 256*074bb90dSTom Pothier /* 257*074bb90dSTom Pothier * We continue even if the product-sn information is 258*074bb90dSTom Pothier * not available to enumerate as much as possible. 259*074bb90dSTom Pothier */ 260*074bb90dSTom Pothier result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, 261*074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn, 262*074bb90dSTom Pothier &err); 263*074bb90dSTom Pothier if (result != 0) { 264*074bb90dSTom Pothier /* Preserve the error and continue */ 265*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 266*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to " 267*074bb90dSTom Pothier "set property %s (%d) : %s\n", f, 268*074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT_SN, err, 269*074bb90dSTom Pothier topo_strerror(err)); 270*074bb90dSTom Pothier } 271*074bb90dSTom Pothier } 272*074bb90dSTom Pothier } 273*074bb90dSTom Pothier 274*074bb90dSTom Pothier /* chassis-id */ 275*074bb90dSTom Pothier if (is_chassis == 0 || (is_chassis == 1 && chassis_instance == 0)) { 276*074bb90dSTom Pothier /* either not a chassis node, or chassis #0 */ 277*074bb90dSTom Pothier result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, 278*074bb90dSTom Pothier FM_FMRI_AUTH_CHASSIS, &err); 279*074bb90dSTom Pothier } else { 280*074bb90dSTom Pothier /* chassis 'n' in a >1 chassis system */ 281*074bb90dSTom Pothier result = err = -1; 282*074bb90dSTom Pothier } 283*074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 284*074bb90dSTom Pothier if (is_chassis == 0) { 285*074bb90dSTom Pothier result = nvlist_lookup_string(auth, 286*074bb90dSTom Pothier FM_FMRI_AUTH_CHASSIS, &csn); 287*074bb90dSTom Pothier if (result != 0 || csn == NULL) { 288*074bb90dSTom Pothier /* 289*074bb90dSTom Pothier * No chassis information in the parent 290*074bb90dSTom Pothier * node or auth list. 291*074bb90dSTom Pothier */ 292*074bb90dSTom Pothier topo_mod_dprintf(mod, 293*074bb90dSTom Pothier "%s: csn name not found\n", f); 294*074bb90dSTom Pothier } 295*074bb90dSTom Pothier } else { 296*074bb90dSTom Pothier /* 297*074bb90dSTom Pothier * So as not to blindly set the chassis-id to 298*074bb90dSTom Pothier * chassis #0's serial number. 299*074bb90dSTom Pothier */ 300*074bb90dSTom Pothier csn = val = topo_mod_strdup(mod, hcfmri->serial_number); 301*074bb90dSTom Pothier } 302*074bb90dSTom Pothier 303*074bb90dSTom Pothier /* 304*074bb90dSTom Pothier * We continue even if the chassis information is not available 305*074bb90dSTom Pothier * to enumerate as much as possible. 306*074bb90dSTom Pothier */ 307*074bb90dSTom Pothier if (csn != NULL) { 308*074bb90dSTom Pothier if (is_chassis == 1) 309*074bb90dSTom Pothier result = topo_prop_set_string(t_node, 310*074bb90dSTom Pothier FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, 311*074bb90dSTom Pothier TOPO_PROP_MUTABLE, csn, &err); 312*074bb90dSTom Pothier else 313*074bb90dSTom Pothier result = topo_prop_set_string(t_node, 314*074bb90dSTom Pothier FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, 315*074bb90dSTom Pothier TOPO_PROP_IMMUTABLE, csn, &err); 316*074bb90dSTom Pothier 317*074bb90dSTom Pothier if (result != 0) { 318*074bb90dSTom Pothier /* Preserve the error and continue */ 319*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 320*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to " 321*074bb90dSTom Pothier "set property %s (%d) : %s\n", f, 322*074bb90dSTom Pothier FM_FMRI_AUTH_CHASSIS, err, 323*074bb90dSTom Pothier topo_strerror(err)); 324*074bb90dSTom Pothier } 325*074bb90dSTom Pothier } 326*074bb90dSTom Pothier 327*074bb90dSTom Pothier if (val != NULL) { 328*074bb90dSTom Pothier topo_mod_strfree(mod, val); 329*074bb90dSTom Pothier val = NULL; 330*074bb90dSTom Pothier } 331*074bb90dSTom Pothier } 332*074bb90dSTom Pothier 333*074bb90dSTom Pothier /* server-id */ 334*074bb90dSTom Pothier result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, 335*074bb90dSTom Pothier FM_FMRI_AUTH_SERVER, &err); 336*074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 337*074bb90dSTom Pothier result = nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, 338*074bb90dSTom Pothier &server); 339*074bb90dSTom Pothier if (result != 0 || server == NULL) { 340*074bb90dSTom Pothier /* 341*074bb90dSTom Pothier * No server information in the parent node or auth 342*074bb90dSTom Pothier * list. Find the server information in hostname. 343*074bb90dSTom Pothier */ 344*074bb90dSTom Pothier server = val = x86pi_get_serverid(mod); 345*074bb90dSTom Pothier if (server == NULL) { 346*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: server " 347*074bb90dSTom Pothier "name not found for %s node\n", f, 348*074bb90dSTom Pothier hcfmri->hc_name); 349*074bb90dSTom Pothier } 350*074bb90dSTom Pothier } 351*074bb90dSTom Pothier 352*074bb90dSTom Pothier /* 353*074bb90dSTom Pothier * We continue even if the server information is not available 354*074bb90dSTom Pothier * to enumerate as much as possible. 355*074bb90dSTom Pothier */ 356*074bb90dSTom Pothier if (server != NULL) { 357*074bb90dSTom Pothier result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, 358*074bb90dSTom Pothier FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server, 359*074bb90dSTom Pothier &err); 360*074bb90dSTom Pothier if (result != 0) { 361*074bb90dSTom Pothier /* Preserve the error and continue */ 362*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 363*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to " 364*074bb90dSTom Pothier "set property %s (%d) : %s\n", f, 365*074bb90dSTom Pothier FM_FMRI_AUTH_SERVER, err, 366*074bb90dSTom Pothier topo_strerror(err)); 367*074bb90dSTom Pothier } 368*074bb90dSTom Pothier } 369*074bb90dSTom Pothier 370*074bb90dSTom Pothier if (val != NULL) 371*074bb90dSTom Pothier topo_mod_strfree(mod, val); 372*074bb90dSTom Pothier } 373*074bb90dSTom Pothier 374*074bb90dSTom Pothier nvlist_free(auth); 375*074bb90dSTom Pothier 376*074bb90dSTom Pothier return (0); 377*074bb90dSTom Pothier } 378*074bb90dSTom Pothier 379*074bb90dSTom Pothier 380*074bb90dSTom Pothier /* 381*074bb90dSTom Pothier * Calculate a generic FRU for the given node. If the node is not a FRU, 382*074bb90dSTom Pothier * then inherit the FRU data from the nodes parent. 383*074bb90dSTom Pothier */ 384*074bb90dSTom Pothier int 385*074bb90dSTom Pothier x86pi_set_frufmri(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent, 386*074bb90dSTom Pothier tnode_t *t_node, int flag) 387*074bb90dSTom Pothier { 388*074bb90dSTom Pothier int result; 389*074bb90dSTom Pothier int err; 390*074bb90dSTom Pothier 391*074bb90dSTom Pothier nvlist_t *auth = NULL; 392*074bb90dSTom Pothier nvlist_t *frufmri = NULL; 393*074bb90dSTom Pothier 394*074bb90dSTom Pothier if (t_node == NULL || mod == NULL) { 395*074bb90dSTom Pothier return (-1); 396*074bb90dSTom Pothier } 397*074bb90dSTom Pothier 398*074bb90dSTom Pothier /* 399*074bb90dSTom Pothier * Determine if this node is a FRU 400*074bb90dSTom Pothier */ 401*074bb90dSTom Pothier if (!(flag & X86PI_ENUM_FRU)) { 402*074bb90dSTom Pothier /* This node is not a FRU. Inherit from parent and return */ 403*074bb90dSTom Pothier topo_node_fru_set(t_node, NULL, 0, &result); 404*074bb90dSTom Pothier return (0); 405*074bb90dSTom Pothier } 406*074bb90dSTom Pothier 407*074bb90dSTom Pothier /* 408*074bb90dSTom Pothier * This node is a FRU. Create an FMRI. 409*074bb90dSTom Pothier */ 410*074bb90dSTom Pothier auth = topo_mod_auth(mod, t_parent); 411*074bb90dSTom Pothier frufmri = topo_mod_hcfmri(mod, t_parent, FM_HC_SCHEME_VERSION, 412*074bb90dSTom Pothier hcfmri->hc_name, hcfmri->instance, NULL, auth, 413*074bb90dSTom Pothier hcfmri->part_number, hcfmri->version, hcfmri->serial_number); 414*074bb90dSTom Pothier if (frufmri == NULL) { 415*074bb90dSTom Pothier topo_mod_dprintf(mod, "failed to create FRU: %s\n", 416*074bb90dSTom Pothier topo_strerror(topo_mod_errno(mod))); 417*074bb90dSTom Pothier } 418*074bb90dSTom Pothier nvlist_free(auth); 419*074bb90dSTom Pothier 420*074bb90dSTom Pothier /* Set the FRU, whether NULL or not */ 421*074bb90dSTom Pothier result = topo_node_fru_set(t_node, frufmri, 0, &err); 422*074bb90dSTom Pothier if (result != 0) { 423*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 424*074bb90dSTom Pothier } 425*074bb90dSTom Pothier nvlist_free(frufmri); 426*074bb90dSTom Pothier 427*074bb90dSTom Pothier return (result); 428*074bb90dSTom Pothier } 429*074bb90dSTom Pothier 430*074bb90dSTom Pothier 431*074bb90dSTom Pothier /* 432*074bb90dSTom Pothier * Set the label for a topo node. 433*074bb90dSTom Pothier */ 434*074bb90dSTom Pothier int 435*074bb90dSTom Pothier x86pi_set_label(topo_mod_t *mod, const char *label, const char *name, 436*074bb90dSTom Pothier tnode_t *t_node) 437*074bb90dSTom Pothier { 438*074bb90dSTom Pothier int result; 439*074bb90dSTom Pothier int err; 440*074bb90dSTom Pothier 441*074bb90dSTom Pothier if (mod == NULL) { 442*074bb90dSTom Pothier return (-1); 443*074bb90dSTom Pothier } 444*074bb90dSTom Pothier 445*074bb90dSTom Pothier /* 446*074bb90dSTom Pothier * Set the label for this topology node. 447*074bb90dSTom Pothier * Note that a NULL label will inherit the label from topology 448*074bb90dSTom Pothier * node's parent. 449*074bb90dSTom Pothier */ 450*074bb90dSTom Pothier result = topo_node_label_set(t_node, (char *)label, &err); 451*074bb90dSTom Pothier if (result != 0) { 452*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 453*074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_set_label: failed with label %s " 454*074bb90dSTom Pothier "on %s node: %s\n", (label == NULL ? "NULL" : label), 455*074bb90dSTom Pothier name, topo_strerror(err)); 456*074bb90dSTom Pothier } 457*074bb90dSTom Pothier 458*074bb90dSTom Pothier return (result); 459*074bb90dSTom Pothier } 460*074bb90dSTom Pothier 461*074bb90dSTom Pothier 462*074bb90dSTom Pothier /* 463*074bb90dSTom Pothier * Calculate the system information for a node. Inherit the data if 464*074bb90dSTom Pothier * possible, but always create an appropriate property group. 465*074bb90dSTom Pothier */ 466*074bb90dSTom Pothier int 467*074bb90dSTom Pothier x86pi_set_system(topo_mod_t *mod, tnode_t *t_node) 468*074bb90dSTom Pothier { 469*074bb90dSTom Pothier int result; 470*074bb90dSTom Pothier int err; 471*074bb90dSTom Pothier struct utsname uts; 472*074bb90dSTom Pothier char isa[MAXNAMELEN]; 473*074bb90dSTom Pothier 474*074bb90dSTom Pothier if (mod == NULL || t_node == NULL) { 475*074bb90dSTom Pothier return (-1); 476*074bb90dSTom Pothier } 477*074bb90dSTom Pothier 478*074bb90dSTom Pothier result = topo_pgroup_create(t_node, &sys_pgroup, &err); 479*074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 480*074bb90dSTom Pothier /* 481*074bb90dSTom Pothier * We failed to create the property group and it was not 482*074bb90dSTom Pothier * already defined. Set the err code and return failure. 483*074bb90dSTom Pothier */ 484*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 485*074bb90dSTom Pothier return (-1); 486*074bb90dSTom Pothier } 487*074bb90dSTom Pothier 488*074bb90dSTom Pothier result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, 489*074bb90dSTom Pothier &err); 490*074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 491*074bb90dSTom Pothier isa[0] = '\0'; 492*074bb90dSTom Pothier result = sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)); 493*074bb90dSTom Pothier if (result == -1) { 494*074bb90dSTom Pothier /* Preserve the error and continue */ 495*074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_set_system: failed to " 496*074bb90dSTom Pothier "read SI_ARCHITECTURE: %d\n", errno); 497*074bb90dSTom Pothier } 498*074bb90dSTom Pothier if (strnlen(isa, MAXNAMELEN) > 0) { 499*074bb90dSTom Pothier result = topo_prop_set_string(t_node, 500*074bb90dSTom Pothier TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, 501*074bb90dSTom Pothier TOPO_PROP_IMMUTABLE, isa, &err); 502*074bb90dSTom Pothier if (result != 0) { 503*074bb90dSTom Pothier /* Preserve the error and continue */ 504*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 505*074bb90dSTom Pothier topo_mod_dprintf(mod, 506*074bb90dSTom Pothier "x86pi_set_auth: failed to " 507*074bb90dSTom Pothier "set property %s (%d) : %s\n", 508*074bb90dSTom Pothier TOPO_PROP_ISA, err, topo_strerror(err)); 509*074bb90dSTom Pothier } 510*074bb90dSTom Pothier } 511*074bb90dSTom Pothier } 512*074bb90dSTom Pothier 513*074bb90dSTom Pothier result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, 514*074bb90dSTom Pothier TOPO_PROP_MACHINE, &err); 515*074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 516*074bb90dSTom Pothier result = uname(&uts); 517*074bb90dSTom Pothier if (result == -1) { 518*074bb90dSTom Pothier /* Preserve the error and continue */ 519*074bb90dSTom Pothier topo_mod_seterrno(mod, errno); 520*074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_set_system: failed to " 521*074bb90dSTom Pothier "read uname: %d\n", errno); 522*074bb90dSTom Pothier } 523*074bb90dSTom Pothier if (strnlen(uts.machine, sizeof (uts.machine)) > 0) { 524*074bb90dSTom Pothier result = topo_prop_set_string(t_node, 525*074bb90dSTom Pothier TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, 526*074bb90dSTom Pothier TOPO_PROP_IMMUTABLE, uts.machine, &err); 527*074bb90dSTom Pothier if (result != 0) { 528*074bb90dSTom Pothier /* Preserve the error and continue */ 529*074bb90dSTom Pothier topo_mod_seterrno(mod, err); 530*074bb90dSTom Pothier topo_mod_dprintf(mod, 531*074bb90dSTom Pothier "x86pi_set_auth: failed to " 532*074bb90dSTom Pothier "set property %s (%d) : %s\n", 533*074bb90dSTom Pothier TOPO_PROP_MACHINE, err, topo_strerror(err)); 534*074bb90dSTom Pothier } 535*074bb90dSTom Pothier } 536*074bb90dSTom Pothier } 537*074bb90dSTom Pothier 538*074bb90dSTom Pothier return (0); 539*074bb90dSTom Pothier } 540*074bb90dSTom Pothier 541*074bb90dSTom Pothier /* 542*074bb90dSTom Pothier * All the checks for compatibility are done within the kernel where the 543*074bb90dSTom Pothier * ereport generators are. They'll determine first if there's a problem 544*074bb90dSTom Pothier * and the topo enum will follow suit. The /dev/fm ioclt returns the value 545*074bb90dSTom Pothier * of the x86gentopo_legacy kernel variable which determines if this platform 546*074bb90dSTom Pothier * will provide an x86 generic topo or legacy topo enumeration. 547*074bb90dSTom Pothier */ 548*074bb90dSTom Pothier /* ARGSUSED */ 549*074bb90dSTom Pothier int 550*074bb90dSTom Pothier x86pi_check_comp(topo_mod_t *mod, smbios_hdl_t *shp) 551*074bb90dSTom Pothier { 552*074bb90dSTom Pothier int rv; 553*074bb90dSTom Pothier int fd; 554*074bb90dSTom Pothier int32_t legacy; 555*074bb90dSTom Pothier nvlist_t *nvl = NULL; 556*074bb90dSTom Pothier fm_ioc_data_t fid; 557*074bb90dSTom Pothier char *ibuf = NULL, *obuf = NULL; 558*074bb90dSTom Pothier size_t insz = 0, outsz = 0; 559*074bb90dSTom Pothier char *f = "x86pi_check_comp"; 560*074bb90dSTom Pothier 561*074bb90dSTom Pothier /* open /dev/fm */ 562*074bb90dSTom Pothier fd = open("/dev/fm", O_RDONLY); 563*074bb90dSTom Pothier if (fd < 0) { 564*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to open /dev/fm.\n", f); 565*074bb90dSTom Pothier return (X86PI_NONE); 566*074bb90dSTom Pothier } 567*074bb90dSTom Pothier 568*074bb90dSTom Pothier /* set up buffers and ioctl data structure */ 569*074bb90dSTom Pothier outsz = FM_IOC_MAXBUFSZ; 570*074bb90dSTom Pothier obuf = topo_mod_alloc(mod, outsz); 571*074bb90dSTom Pothier if (obuf == NULL) { 572*074bb90dSTom Pothier perror("umem_alloc"); 573*074bb90dSTom Pothier return (X86PI_NONE); 574*074bb90dSTom Pothier } 575*074bb90dSTom Pothier 576*074bb90dSTom Pothier fid.fid_version = 1; 577*074bb90dSTom Pothier fid.fid_insz = insz; 578*074bb90dSTom Pothier fid.fid_inbuf = ibuf; 579*074bb90dSTom Pothier fid.fid_outsz = outsz; 580*074bb90dSTom Pothier fid.fid_outbuf = obuf; 581*074bb90dSTom Pothier 582*074bb90dSTom Pothier /* send the ioctl to /dev/fm to retrieve legacy variable */ 583*074bb90dSTom Pothier rv = ioctl(fd, FM_IOC_GENTOPO_LEGACY, &fid); 584*074bb90dSTom Pothier if (rv < 0) { 585*074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: ioctl to /dev/fm failed", f); 586*074bb90dSTom Pothier perror("fm_ioctl"); 587*074bb90dSTom Pothier (void) close(fd); 588*074bb90dSTom Pothier return (X86PI_NONE); 589*074bb90dSTom Pothier } 590*074bb90dSTom Pothier (void) close(fd); 591*074bb90dSTom Pothier 592*074bb90dSTom Pothier (void) nvlist_unpack(fid.fid_outbuf, fid.fid_outsz, &nvl, 0); 593*074bb90dSTom Pothier (void) nvlist_lookup_int32(nvl, FM_GENTOPO_LEGACY, &legacy); 594*074bb90dSTom Pothier 595*074bb90dSTom Pothier nvlist_free(nvl); 596*074bb90dSTom Pothier topo_mod_free(mod, obuf, outsz); 597*074bb90dSTom Pothier 598*074bb90dSTom Pothier if (legacy == 1) { 599*074bb90dSTom Pothier /* legacy kernel variable set; will do the same */ 600*074bb90dSTom Pothier return (X86PI_NONE); 601*074bb90dSTom Pothier } 602*074bb90dSTom Pothier 603*074bb90dSTom Pothier /* legacy kernel variable not set; generic topo enum */ 604*074bb90dSTom Pothier return (X86PI_FULL); 605*074bb90dSTom Pothier } 606*074bb90dSTom Pothier 607*074bb90dSTom Pothier const char * 608*074bb90dSTom Pothier x86pi_cleanup_smbios_str(topo_mod_t *mod, const char *begin, int str_type) 609*074bb90dSTom Pothier { 610*074bb90dSTom Pothier char buf[MAXNAMELEN]; 611*074bb90dSTom Pothier const char *end, *cp; 612*074bb90dSTom Pothier char *pp; 613*074bb90dSTom Pothier char c; 614*074bb90dSTom Pothier int i; 615*074bb90dSTom Pothier 616*074bb90dSTom Pothier end = begin + strlen(begin); 617*074bb90dSTom Pothier 618*074bb90dSTom Pothier while (begin < end && isspace(*begin)) 619*074bb90dSTom Pothier begin++; 620*074bb90dSTom Pothier while (begin < end && isspace(*(end - 1))) 621*074bb90dSTom Pothier end--; 622*074bb90dSTom Pothier 623*074bb90dSTom Pothier if (begin >= end) 624*074bb90dSTom Pothier return (NULL); 625*074bb90dSTom Pothier 626*074bb90dSTom Pothier cp = begin; 627*074bb90dSTom Pothier for (i = 0; i < MAXNAMELEN - 1; i++) { 628*074bb90dSTom Pothier if (cp >= end) 629*074bb90dSTom Pothier break; 630*074bb90dSTom Pothier c = *cp; 631*074bb90dSTom Pothier if (str_type == LABEL) { 632*074bb90dSTom Pothier if (!isprint(c)) 633*074bb90dSTom Pothier buf[i] = '-'; 634*074bb90dSTom Pothier else 635*074bb90dSTom Pothier buf[i] = c; 636*074bb90dSTom Pothier } else { 637*074bb90dSTom Pothier if (c == ':' || c == '=' || c == '/' || 638*074bb90dSTom Pothier isspace(c) || !isprint(c)) 639*074bb90dSTom Pothier buf[i] = '-'; 640*074bb90dSTom Pothier else 641*074bb90dSTom Pothier buf[i] = c; 642*074bb90dSTom Pothier } 643*074bb90dSTom Pothier cp++; 644*074bb90dSTom Pothier } 645*074bb90dSTom Pothier buf[i] = 0; 646*074bb90dSTom Pothier 647*074bb90dSTom Pothier pp = topo_mod_strdup(mod, buf); 648*074bb90dSTom Pothier 649*074bb90dSTom Pothier if (str_type == LABEL) 650*074bb90dSTom Pothier topo_mod_strfree(mod, (char *)begin); 651*074bb90dSTom Pothier 652*074bb90dSTom Pothier return (pp); 653*074bb90dSTom Pothier } 654