1074bb90dSTom Pothier /* 2074bb90dSTom Pothier * CDDL HEADER START 3074bb90dSTom Pothier * 4074bb90dSTom Pothier * The contents of this file are subject to the terms of the 5074bb90dSTom Pothier * Common Development and Distribution License (the "License"). 6074bb90dSTom Pothier * You may not use this file except in compliance with the License. 7074bb90dSTom Pothier * 8074bb90dSTom Pothier * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9074bb90dSTom Pothier * or http://www.opensolaris.org/os/licensing. 10074bb90dSTom Pothier * See the License for the specific language governing permissions 11074bb90dSTom Pothier * and limitations under the License. 12074bb90dSTom Pothier * 13074bb90dSTom Pothier * When distributing Covered Code, include this CDDL HEADER in each 14074bb90dSTom Pothier * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15074bb90dSTom Pothier * If applicable, add the following below this CDDL HEADER, with the 16074bb90dSTom Pothier * fields enclosed by brackets "[]" replaced with your own identifying 17074bb90dSTom Pothier * information: Portions Copyright [yyyy] [name of copyright owner] 18074bb90dSTom Pothier * 19074bb90dSTom Pothier * CDDL HEADER END 20074bb90dSTom Pothier */ 21074bb90dSTom Pothier 22074bb90dSTom Pothier /* 23074bb90dSTom Pothier * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24074bb90dSTom Pothier * Use is subject to license terms. 25074bb90dSTom Pothier */ 26074bb90dSTom Pothier 27074bb90dSTom Pothier /* 28074bb90dSTom Pothier * Subroutines used by the i86pc Generic Topology Enumerator 29074bb90dSTom Pothier */ 30074bb90dSTom Pothier 31074bb90dSTom Pothier #include <sys/types.h> 32074bb90dSTom Pothier #include <strings.h> 33074bb90dSTom Pothier #include <deflt.h> 34074bb90dSTom Pothier #include <fcntl.h> 35074bb90dSTom Pothier #include <unistd.h> 36074bb90dSTom Pothier #include <fm/topo_mod.h> 37074bb90dSTom Pothier #include <fm/topo_hc.h> 38074bb90dSTom Pothier #include <sys/devfm.h> 39074bb90dSTom Pothier #include <sys/systeminfo.h> 40074bb90dSTom Pothier #include <sys/fm/protocol.h> 41074bb90dSTom Pothier #include <sys/utsname.h> 42074bb90dSTom Pothier #include <sys/smbios.h> 43074bb90dSTom Pothier #include <sys/smbios_impl.h> 44074bb90dSTom Pothier #include <x86pi_impl.h> 45074bb90dSTom Pothier 46074bb90dSTom Pothier 47074bb90dSTom Pothier static const topo_pgroup_info_t sys_pgroup = { 48074bb90dSTom Pothier TOPO_PGROUP_SYSTEM, 49074bb90dSTom Pothier TOPO_STABILITY_PRIVATE, 50074bb90dSTom Pothier TOPO_STABILITY_PRIVATE, 51074bb90dSTom Pothier 1 52074bb90dSTom Pothier }; 53074bb90dSTom Pothier 54074bb90dSTom Pothier static const topo_pgroup_info_t auth_pgroup = { 55074bb90dSTom Pothier FM_FMRI_AUTHORITY, 56074bb90dSTom Pothier TOPO_STABILITY_PRIVATE, 57074bb90dSTom Pothier TOPO_STABILITY_PRIVATE, 58074bb90dSTom Pothier 1 59074bb90dSTom Pothier }; 60074bb90dSTom Pothier 61074bb90dSTom Pothier 62074bb90dSTom Pothier /* 63074bb90dSTom Pothier * Free hcfmri strings. 64074bb90dSTom Pothier */ 65074bb90dSTom Pothier void 66074bb90dSTom Pothier x86pi_hcfmri_info_fini(topo_mod_t *mod, x86pi_hcfmri_t *hc) 67074bb90dSTom Pothier { 68074bb90dSTom Pothier if (hc->hc_name != NULL) 69074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->hc_name); 70074bb90dSTom Pothier if (hc->manufacturer != NULL) 71074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->manufacturer); 72074bb90dSTom Pothier if (hc->product != NULL) 73074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->product); 74074bb90dSTom Pothier if (hc->version != NULL) 75074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->version); 76074bb90dSTom Pothier if (hc->serial_number != NULL) 77074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->serial_number); 78074bb90dSTom Pothier if (hc->asset_tag != NULL) 79074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->asset_tag); 80074bb90dSTom Pothier if (hc->location != NULL) 81074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->location); 82074bb90dSTom Pothier if (hc->part_number != NULL) 83074bb90dSTom Pothier topo_mod_strfree(mod, (char *)hc->part_number); 84074bb90dSTom Pothier } 85074bb90dSTom Pothier 86074bb90dSTom Pothier 87074bb90dSTom Pothier /* 88074bb90dSTom Pothier * Get the server hostname (the ID as far as the topo authority is 89074bb90dSTom Pothier * concerned) from sysinfo and return a copy to the caller. 90074bb90dSTom Pothier * 91074bb90dSTom Pothier * The string must be freed with topo_mod_strfree() 92074bb90dSTom Pothier */ 93074bb90dSTom Pothier char * 94074bb90dSTom Pothier x86pi_get_serverid(topo_mod_t *mod) 95074bb90dSTom Pothier { 96074bb90dSTom Pothier int result; 97074bb90dSTom Pothier char hostname[MAXNAMELEN]; 98074bb90dSTom Pothier 99074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_get_serverid\n"); 100074bb90dSTom Pothier 101074bb90dSTom Pothier result = sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); 102074bb90dSTom Pothier /* Everything is freed up and it's time to return the platform-id */ 103074bb90dSTom Pothier if (result == -1) { 104074bb90dSTom Pothier return (NULL); 105074bb90dSTom Pothier } 106074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_get_serverid: hostname = %s\n", hostname); 107074bb90dSTom Pothier 108074bb90dSTom Pothier return (topo_mod_strdup(mod, hostname)); 109074bb90dSTom Pothier } 110074bb90dSTom Pothier 111074bb90dSTom Pothier 112074bb90dSTom Pothier /* 113074bb90dSTom Pothier * Get copy of SMBIOS. 114074bb90dSTom Pothier */ 115074bb90dSTom Pothier smbios_hdl_t * 116074bb90dSTom Pothier x86pi_smb_open(topo_mod_t *mod) 117074bb90dSTom Pothier { 118074bb90dSTom Pothier smbios_hdl_t *smb_hdl; 119074bb90dSTom Pothier char *f = "x86pi_smb_open"; 120074bb90dSTom Pothier 121074bb90dSTom Pothier topo_mod_dprintf(mod, "%s\n", f); 122074bb90dSTom Pothier 123074bb90dSTom Pothier smb_hdl = topo_mod_smbios(mod); 124074bb90dSTom Pothier if (smb_hdl == NULL) { 125074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f); 126074bb90dSTom Pothier return (NULL); 127074bb90dSTom Pothier } 128074bb90dSTom Pothier 129074bb90dSTom Pothier return (smb_hdl); 130074bb90dSTom Pothier } 131074bb90dSTom Pothier 132074bb90dSTom Pothier 133074bb90dSTom Pothier /* 134074bb90dSTom Pothier * Go through the smbios structures looking for a type. Fill in 135074bb90dSTom Pothier * the structure count as well as the id(s) of the struct types. 136074bb90dSTom Pothier */ 137074bb90dSTom Pothier void 138074bb90dSTom Pothier x86pi_smb_strcnt(smbios_hdl_t *shp, smbs_cnt_t *stype) 139074bb90dSTom Pothier { 140074bb90dSTom Pothier const smb_struct_t *sp = shp->sh_structs; 141074bb90dSTom Pothier int nstructs = shp->sh_nstructs; 142074bb90dSTom Pothier int i, cnt; 143074bb90dSTom Pothier 144074bb90dSTom Pothier for (i = 0, cnt = 0; i < nstructs; i++, sp++) { 145074bb90dSTom Pothier if (sp->smbst_hdr->smbh_type == stype->type) { 146074bb90dSTom Pothier stype->ids[cnt].node = NULL; 147074bb90dSTom Pothier stype->ids[cnt].id = sp->smbst_hdr->smbh_hdl; 148074bb90dSTom Pothier cnt++; 149074bb90dSTom Pothier } 150074bb90dSTom Pothier } 151074bb90dSTom Pothier 152074bb90dSTom Pothier stype->count = cnt; 153074bb90dSTom Pothier } 154074bb90dSTom Pothier 155074bb90dSTom Pothier 156074bb90dSTom Pothier /* 157074bb90dSTom Pothier * Calculate the authority information for a node. Inherit the data if 158074bb90dSTom Pothier * possible, but always create an appropriate property group. 159074bb90dSTom Pothier */ 160074bb90dSTom Pothier int 161074bb90dSTom Pothier x86pi_set_auth(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent, 162074bb90dSTom Pothier tnode_t *t_node) 163074bb90dSTom Pothier { 164074bb90dSTom Pothier int result; 165074bb90dSTom Pothier int err; 166074bb90dSTom Pothier int is_chassis = 0; 167074bb90dSTom Pothier int chassis_instance = 0; 168074bb90dSTom Pothier nvlist_t *auth; 169074bb90dSTom Pothier char *val = NULL; 170074bb90dSTom Pothier char *prod = NULL; 171074bb90dSTom Pothier char *psn = NULL; 172074bb90dSTom Pothier char *csn = NULL; 173074bb90dSTom Pothier char *server = NULL; 174074bb90dSTom Pothier char *f = "x86pi_set_auth"; 175074bb90dSTom Pothier 176074bb90dSTom Pothier if (mod == NULL || t_parent == NULL || t_node == NULL) { 177074bb90dSTom Pothier return (-1); 178074bb90dSTom Pothier } 179074bb90dSTom Pothier 180074bb90dSTom Pothier result = topo_pgroup_create(t_node, &auth_pgroup, &err); 181074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 182074bb90dSTom Pothier /* 183074bb90dSTom Pothier * We failed to create the property group and it was not 184074bb90dSTom Pothier * already defined. Set the err code and return failure. 185074bb90dSTom Pothier */ 186*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 187074bb90dSTom Pothier return (-1); 188074bb90dSTom Pothier } 189074bb90dSTom Pothier 190074bb90dSTom Pothier /* Get the authority information already available from the parent */ 191074bb90dSTom Pothier auth = topo_mod_auth(mod, t_parent); 192074bb90dSTom Pothier 193074bb90dSTom Pothier /* Determnine if this is a chassis node and set it's instance */ 194074bb90dSTom Pothier if ((strlen(hcfmri->hc_name) == strlen(CHASSIS)) && 195074bb90dSTom Pothier strncmp(hcfmri->hc_name, CHASSIS, strlen(CHASSIS)) == 0) { 196074bb90dSTom Pothier is_chassis = 1; 197074bb90dSTom Pothier chassis_instance = hcfmri->instance; 198074bb90dSTom Pothier } 199074bb90dSTom Pothier 200074bb90dSTom Pothier /* 201074bb90dSTom Pothier * Set the authority data, inheriting it if possible, but creating it 202074bb90dSTom Pothier * if necessary. 203074bb90dSTom Pothier */ 204074bb90dSTom Pothier 205074bb90dSTom Pothier /* product-id */ 206074bb90dSTom Pothier result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, 207074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT, &err); 208074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 209074bb90dSTom Pothier result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, 210074bb90dSTom Pothier &prod); 211074bb90dSTom Pothier if (result != 0 || prod == NULL) { 212074bb90dSTom Pothier /* 213074bb90dSTom Pothier * No product information in the parent node or auth 214074bb90dSTom Pothier * list. Use the product information in the hcfrmi 215074bb90dSTom Pothier * struct. 216074bb90dSTom Pothier */ 217074bb90dSTom Pothier prod = (char *)hcfmri->product; 218074bb90dSTom Pothier if (prod == NULL) { 219074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: product name not " 220074bb90dSTom Pothier "found for %s node\n", f, hcfmri->hc_name); 221074bb90dSTom Pothier } 222074bb90dSTom Pothier } 223074bb90dSTom Pothier 224074bb90dSTom Pothier /* 225074bb90dSTom Pothier * We continue even if the product information is not available 226074bb90dSTom Pothier * to enumerate as much as possible. 227074bb90dSTom Pothier */ 228074bb90dSTom Pothier if (prod != NULL) { 229074bb90dSTom Pothier result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, 230074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod, 231074bb90dSTom Pothier &err); 232074bb90dSTom Pothier if (result != 0) { 233074bb90dSTom Pothier /* Preserve the error and continue */ 234*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 235074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to set " 236074bb90dSTom Pothier "property %s (%d) : %s\n", f, 237074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT, err, 238074bb90dSTom Pothier topo_strerror(err)); 239074bb90dSTom Pothier } 240074bb90dSTom Pothier } 241074bb90dSTom Pothier } 242074bb90dSTom Pothier 243074bb90dSTom Pothier /* product-sn */ 244074bb90dSTom Pothier result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, 245074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT_SN, &err); 246074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 247074bb90dSTom Pothier result = nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, 248074bb90dSTom Pothier &psn); 249074bb90dSTom Pothier if (result != 0 || psn == NULL) { 250074bb90dSTom Pothier /* 251074bb90dSTom Pothier * No product-sn information in the parent node or auth 252074bb90dSTom Pothier * list. 253074bb90dSTom Pothier */ 254074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: psn not found\n", f); 255074bb90dSTom Pothier } else { 256074bb90dSTom Pothier /* 257074bb90dSTom Pothier * We continue even if the product-sn information is 258074bb90dSTom Pothier * not available to enumerate as much as possible. 259074bb90dSTom Pothier */ 260074bb90dSTom Pothier result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, 261074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT_SN, TOPO_PROP_IMMUTABLE, psn, 262074bb90dSTom Pothier &err); 263074bb90dSTom Pothier if (result != 0) { 264074bb90dSTom Pothier /* Preserve the error and continue */ 265*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 266074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to " 267074bb90dSTom Pothier "set property %s (%d) : %s\n", f, 268074bb90dSTom Pothier FM_FMRI_AUTH_PRODUCT_SN, err, 269074bb90dSTom Pothier topo_strerror(err)); 270074bb90dSTom Pothier } 271074bb90dSTom Pothier } 272074bb90dSTom Pothier } 273074bb90dSTom Pothier 274074bb90dSTom Pothier /* chassis-id */ 275074bb90dSTom Pothier if (is_chassis == 0 || (is_chassis == 1 && chassis_instance == 0)) { 276074bb90dSTom Pothier /* either not a chassis node, or chassis #0 */ 277074bb90dSTom Pothier result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, 278074bb90dSTom Pothier FM_FMRI_AUTH_CHASSIS, &err); 279074bb90dSTom Pothier } else { 280074bb90dSTom Pothier /* chassis 'n' in a >1 chassis system */ 281074bb90dSTom Pothier result = err = -1; 282074bb90dSTom Pothier } 283074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 284074bb90dSTom Pothier if (is_chassis == 0) { 285074bb90dSTom Pothier result = nvlist_lookup_string(auth, 286074bb90dSTom Pothier FM_FMRI_AUTH_CHASSIS, &csn); 287074bb90dSTom Pothier if (result != 0 || csn == NULL) { 288074bb90dSTom Pothier /* 289074bb90dSTom Pothier * No chassis information in the parent 290074bb90dSTom Pothier * node or auth list. 291074bb90dSTom Pothier */ 292074bb90dSTom Pothier topo_mod_dprintf(mod, 293074bb90dSTom Pothier "%s: csn name not found\n", f); 294074bb90dSTom Pothier } 295074bb90dSTom Pothier } else { 296074bb90dSTom Pothier /* 297074bb90dSTom Pothier * So as not to blindly set the chassis-id to 298074bb90dSTom Pothier * chassis #0's serial number. 299074bb90dSTom Pothier */ 300074bb90dSTom Pothier csn = val = topo_mod_strdup(mod, hcfmri->serial_number); 301074bb90dSTom Pothier } 302074bb90dSTom Pothier 303074bb90dSTom Pothier /* 304074bb90dSTom Pothier * We continue even if the chassis information is not available 305074bb90dSTom Pothier * to enumerate as much as possible. 306074bb90dSTom Pothier */ 307074bb90dSTom Pothier if (csn != NULL) { 308074bb90dSTom Pothier if (is_chassis == 1) 309074bb90dSTom Pothier result = topo_prop_set_string(t_node, 310074bb90dSTom Pothier FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, 311074bb90dSTom Pothier TOPO_PROP_MUTABLE, csn, &err); 312074bb90dSTom Pothier else 313074bb90dSTom Pothier result = topo_prop_set_string(t_node, 314074bb90dSTom Pothier FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, 315074bb90dSTom Pothier TOPO_PROP_IMMUTABLE, csn, &err); 316074bb90dSTom Pothier 317074bb90dSTom Pothier if (result != 0) { 318074bb90dSTom Pothier /* Preserve the error and continue */ 319*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 320074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to " 321074bb90dSTom Pothier "set property %s (%d) : %s\n", f, 322074bb90dSTom Pothier FM_FMRI_AUTH_CHASSIS, err, 323074bb90dSTom Pothier topo_strerror(err)); 324074bb90dSTom Pothier } 325074bb90dSTom Pothier } 326074bb90dSTom Pothier 327074bb90dSTom Pothier if (val != NULL) { 328074bb90dSTom Pothier topo_mod_strfree(mod, val); 329074bb90dSTom Pothier val = NULL; 330074bb90dSTom Pothier } 331074bb90dSTom Pothier } 332074bb90dSTom Pothier 333074bb90dSTom Pothier /* server-id */ 334074bb90dSTom Pothier result = topo_prop_inherit(t_node, FM_FMRI_AUTHORITY, 335074bb90dSTom Pothier FM_FMRI_AUTH_SERVER, &err); 336074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 337074bb90dSTom Pothier result = nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, 338074bb90dSTom Pothier &server); 339074bb90dSTom Pothier if (result != 0 || server == NULL) { 340074bb90dSTom Pothier /* 341074bb90dSTom Pothier * No server information in the parent node or auth 342074bb90dSTom Pothier * list. Find the server information in hostname. 343074bb90dSTom Pothier */ 344074bb90dSTom Pothier server = val = x86pi_get_serverid(mod); 345074bb90dSTom Pothier if (server == NULL) { 346074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: server " 347074bb90dSTom Pothier "name not found for %s node\n", f, 348074bb90dSTom Pothier hcfmri->hc_name); 349074bb90dSTom Pothier } 350074bb90dSTom Pothier } 351074bb90dSTom Pothier 352074bb90dSTom Pothier /* 353074bb90dSTom Pothier * We continue even if the server information is not available 354074bb90dSTom Pothier * to enumerate as much as possible. 355074bb90dSTom Pothier */ 356074bb90dSTom Pothier if (server != NULL) { 357074bb90dSTom Pothier result = topo_prop_set_string(t_node, FM_FMRI_AUTHORITY, 358074bb90dSTom Pothier FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server, 359074bb90dSTom Pothier &err); 360074bb90dSTom Pothier if (result != 0) { 361074bb90dSTom Pothier /* Preserve the error and continue */ 362*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 363074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to " 364074bb90dSTom Pothier "set property %s (%d) : %s\n", f, 365074bb90dSTom Pothier FM_FMRI_AUTH_SERVER, err, 366074bb90dSTom Pothier topo_strerror(err)); 367074bb90dSTom Pothier } 368074bb90dSTom Pothier } 369074bb90dSTom Pothier 370074bb90dSTom Pothier if (val != NULL) 371074bb90dSTom Pothier topo_mod_strfree(mod, val); 372074bb90dSTom Pothier } 373074bb90dSTom Pothier 374074bb90dSTom Pothier nvlist_free(auth); 375074bb90dSTom Pothier 376074bb90dSTom Pothier return (0); 377074bb90dSTom Pothier } 378074bb90dSTom Pothier 379074bb90dSTom Pothier 380074bb90dSTom Pothier /* 381074bb90dSTom Pothier * Calculate a generic FRU for the given node. If the node is not a FRU, 382074bb90dSTom Pothier * then inherit the FRU data from the nodes parent. 383074bb90dSTom Pothier */ 384074bb90dSTom Pothier int 385074bb90dSTom Pothier x86pi_set_frufmri(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent, 386074bb90dSTom Pothier tnode_t *t_node, int flag) 387074bb90dSTom Pothier { 388074bb90dSTom Pothier int result; 389074bb90dSTom Pothier int err; 390074bb90dSTom Pothier 391074bb90dSTom Pothier nvlist_t *auth = NULL; 392074bb90dSTom Pothier nvlist_t *frufmri = NULL; 393074bb90dSTom Pothier 394074bb90dSTom Pothier if (t_node == NULL || mod == NULL) { 395074bb90dSTom Pothier return (-1); 396074bb90dSTom Pothier } 397074bb90dSTom Pothier 398074bb90dSTom Pothier /* 399074bb90dSTom Pothier * Determine if this node is a FRU 400074bb90dSTom Pothier */ 401074bb90dSTom Pothier if (!(flag & X86PI_ENUM_FRU)) { 402074bb90dSTom Pothier /* This node is not a FRU. Inherit from parent and return */ 403*d3c57c1fSTom Pothier (void) topo_node_fru_set(t_node, NULL, 0, &result); 404074bb90dSTom Pothier return (0); 405074bb90dSTom Pothier } 406074bb90dSTom Pothier 407074bb90dSTom Pothier /* 408074bb90dSTom Pothier * This node is a FRU. Create an FMRI. 409074bb90dSTom Pothier */ 410074bb90dSTom Pothier auth = topo_mod_auth(mod, t_parent); 411074bb90dSTom Pothier frufmri = topo_mod_hcfmri(mod, t_parent, FM_HC_SCHEME_VERSION, 412074bb90dSTom Pothier hcfmri->hc_name, hcfmri->instance, NULL, auth, 413074bb90dSTom Pothier hcfmri->part_number, hcfmri->version, hcfmri->serial_number); 414074bb90dSTom Pothier if (frufmri == NULL) { 415074bb90dSTom Pothier topo_mod_dprintf(mod, "failed to create FRU: %s\n", 416074bb90dSTom Pothier topo_strerror(topo_mod_errno(mod))); 417074bb90dSTom Pothier } 418074bb90dSTom Pothier nvlist_free(auth); 419074bb90dSTom Pothier 420074bb90dSTom Pothier /* Set the FRU, whether NULL or not */ 421074bb90dSTom Pothier result = topo_node_fru_set(t_node, frufmri, 0, &err); 422074bb90dSTom Pothier if (result != 0) { 423*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 424074bb90dSTom Pothier } 425074bb90dSTom Pothier nvlist_free(frufmri); 426074bb90dSTom Pothier 427074bb90dSTom Pothier return (result); 428074bb90dSTom Pothier } 429074bb90dSTom Pothier 430074bb90dSTom Pothier 431074bb90dSTom Pothier /* 432074bb90dSTom Pothier * Set the label for a topo node. 433074bb90dSTom Pothier */ 434074bb90dSTom Pothier int 435074bb90dSTom Pothier x86pi_set_label(topo_mod_t *mod, const char *label, const char *name, 436074bb90dSTom Pothier tnode_t *t_node) 437074bb90dSTom Pothier { 438074bb90dSTom Pothier int result; 439074bb90dSTom Pothier int err; 440074bb90dSTom Pothier 441074bb90dSTom Pothier if (mod == NULL) { 442074bb90dSTom Pothier return (-1); 443074bb90dSTom Pothier } 444074bb90dSTom Pothier 445074bb90dSTom Pothier /* 446074bb90dSTom Pothier * Set the label for this topology node. 447074bb90dSTom Pothier * Note that a NULL label will inherit the label from topology 448074bb90dSTom Pothier * node's parent. 449074bb90dSTom Pothier */ 450074bb90dSTom Pothier result = topo_node_label_set(t_node, (char *)label, &err); 451074bb90dSTom Pothier if (result != 0) { 452*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 453074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_set_label: failed with label %s " 454074bb90dSTom Pothier "on %s node: %s\n", (label == NULL ? "NULL" : label), 455074bb90dSTom Pothier name, topo_strerror(err)); 456074bb90dSTom Pothier } 457074bb90dSTom Pothier 458074bb90dSTom Pothier return (result); 459074bb90dSTom Pothier } 460074bb90dSTom Pothier 461074bb90dSTom Pothier 462074bb90dSTom Pothier /* 463074bb90dSTom Pothier * Calculate the system information for a node. Inherit the data if 464074bb90dSTom Pothier * possible, but always create an appropriate property group. 465074bb90dSTom Pothier */ 466074bb90dSTom Pothier int 467074bb90dSTom Pothier x86pi_set_system(topo_mod_t *mod, tnode_t *t_node) 468074bb90dSTom Pothier { 469074bb90dSTom Pothier int result; 470074bb90dSTom Pothier int err; 471074bb90dSTom Pothier struct utsname uts; 472074bb90dSTom Pothier char isa[MAXNAMELEN]; 473074bb90dSTom Pothier 474074bb90dSTom Pothier if (mod == NULL || t_node == NULL) { 475074bb90dSTom Pothier return (-1); 476074bb90dSTom Pothier } 477074bb90dSTom Pothier 478074bb90dSTom Pothier result = topo_pgroup_create(t_node, &sys_pgroup, &err); 479074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 480074bb90dSTom Pothier /* 481074bb90dSTom Pothier * We failed to create the property group and it was not 482074bb90dSTom Pothier * already defined. Set the err code and return failure. 483074bb90dSTom Pothier */ 484*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 485074bb90dSTom Pothier return (-1); 486074bb90dSTom Pothier } 487074bb90dSTom Pothier 488074bb90dSTom Pothier result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, 489074bb90dSTom Pothier &err); 490074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 491074bb90dSTom Pothier isa[0] = '\0'; 492074bb90dSTom Pothier result = sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)); 493074bb90dSTom Pothier if (result == -1) { 494074bb90dSTom Pothier /* Preserve the error and continue */ 495074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_set_system: failed to " 496074bb90dSTom Pothier "read SI_ARCHITECTURE: %d\n", errno); 497074bb90dSTom Pothier } 498074bb90dSTom Pothier if (strnlen(isa, MAXNAMELEN) > 0) { 499074bb90dSTom Pothier result = topo_prop_set_string(t_node, 500074bb90dSTom Pothier TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, 501074bb90dSTom Pothier TOPO_PROP_IMMUTABLE, isa, &err); 502074bb90dSTom Pothier if (result != 0) { 503074bb90dSTom Pothier /* Preserve the error and continue */ 504*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 505074bb90dSTom Pothier topo_mod_dprintf(mod, 506074bb90dSTom Pothier "x86pi_set_auth: failed to " 507074bb90dSTom Pothier "set property %s (%d) : %s\n", 508074bb90dSTom Pothier TOPO_PROP_ISA, err, topo_strerror(err)); 509074bb90dSTom Pothier } 510074bb90dSTom Pothier } 511074bb90dSTom Pothier } 512074bb90dSTom Pothier 513074bb90dSTom Pothier result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, 514074bb90dSTom Pothier TOPO_PROP_MACHINE, &err); 515074bb90dSTom Pothier if (result != 0 && err != ETOPO_PROP_DEFD) { 516074bb90dSTom Pothier result = uname(&uts); 517074bb90dSTom Pothier if (result == -1) { 518074bb90dSTom Pothier /* Preserve the error and continue */ 519*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, errno); 520074bb90dSTom Pothier topo_mod_dprintf(mod, "x86pi_set_system: failed to " 521074bb90dSTom Pothier "read uname: %d\n", errno); 522074bb90dSTom Pothier } 523074bb90dSTom Pothier if (strnlen(uts.machine, sizeof (uts.machine)) > 0) { 524074bb90dSTom Pothier result = topo_prop_set_string(t_node, 525074bb90dSTom Pothier TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, 526074bb90dSTom Pothier TOPO_PROP_IMMUTABLE, uts.machine, &err); 527074bb90dSTom Pothier if (result != 0) { 528074bb90dSTom Pothier /* Preserve the error and continue */ 529*d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, err); 530074bb90dSTom Pothier topo_mod_dprintf(mod, 531074bb90dSTom Pothier "x86pi_set_auth: failed to " 532074bb90dSTom Pothier "set property %s (%d) : %s\n", 533074bb90dSTom Pothier TOPO_PROP_MACHINE, err, topo_strerror(err)); 534074bb90dSTom Pothier } 535074bb90dSTom Pothier } 536074bb90dSTom Pothier } 537074bb90dSTom Pothier 538074bb90dSTom Pothier return (0); 539074bb90dSTom Pothier } 540074bb90dSTom Pothier 541074bb90dSTom Pothier /* 542074bb90dSTom Pothier * All the checks for compatibility are done within the kernel where the 543074bb90dSTom Pothier * ereport generators are. They'll determine first if there's a problem 544074bb90dSTom Pothier * and the topo enum will follow suit. The /dev/fm ioclt returns the value 545074bb90dSTom Pothier * of the x86gentopo_legacy kernel variable which determines if this platform 546074bb90dSTom Pothier * will provide an x86 generic topo or legacy topo enumeration. 547074bb90dSTom Pothier */ 548074bb90dSTom Pothier /* ARGSUSED */ 549074bb90dSTom Pothier int 550074bb90dSTom Pothier x86pi_check_comp(topo_mod_t *mod, smbios_hdl_t *shp) 551074bb90dSTom Pothier { 552074bb90dSTom Pothier int rv; 553074bb90dSTom Pothier int fd; 554074bb90dSTom Pothier int32_t legacy; 555074bb90dSTom Pothier nvlist_t *nvl = NULL; 556074bb90dSTom Pothier fm_ioc_data_t fid; 557074bb90dSTom Pothier char *ibuf = NULL, *obuf = NULL; 558074bb90dSTom Pothier size_t insz = 0, outsz = 0; 559074bb90dSTom Pothier char *f = "x86pi_check_comp"; 560074bb90dSTom Pothier 561074bb90dSTom Pothier /* open /dev/fm */ 562074bb90dSTom Pothier fd = open("/dev/fm", O_RDONLY); 563074bb90dSTom Pothier if (fd < 0) { 564074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to open /dev/fm.\n", f); 565074bb90dSTom Pothier return (X86PI_NONE); 566074bb90dSTom Pothier } 567074bb90dSTom Pothier 568074bb90dSTom Pothier /* set up buffers and ioctl data structure */ 569074bb90dSTom Pothier outsz = FM_IOC_MAXBUFSZ; 570074bb90dSTom Pothier obuf = topo_mod_alloc(mod, outsz); 571074bb90dSTom Pothier if (obuf == NULL) { 572074bb90dSTom Pothier perror("umem_alloc"); 573074bb90dSTom Pothier return (X86PI_NONE); 574074bb90dSTom Pothier } 575074bb90dSTom Pothier 576074bb90dSTom Pothier fid.fid_version = 1; 577074bb90dSTom Pothier fid.fid_insz = insz; 578074bb90dSTom Pothier fid.fid_inbuf = ibuf; 579074bb90dSTom Pothier fid.fid_outsz = outsz; 580074bb90dSTom Pothier fid.fid_outbuf = obuf; 581074bb90dSTom Pothier 582074bb90dSTom Pothier /* send the ioctl to /dev/fm to retrieve legacy variable */ 583074bb90dSTom Pothier rv = ioctl(fd, FM_IOC_GENTOPO_LEGACY, &fid); 584074bb90dSTom Pothier if (rv < 0) { 585074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: ioctl to /dev/fm failed", f); 586074bb90dSTom Pothier perror("fm_ioctl"); 587074bb90dSTom Pothier (void) close(fd); 588074bb90dSTom Pothier return (X86PI_NONE); 589074bb90dSTom Pothier } 590074bb90dSTom Pothier (void) close(fd); 591074bb90dSTom Pothier 592074bb90dSTom Pothier (void) nvlist_unpack(fid.fid_outbuf, fid.fid_outsz, &nvl, 0); 593074bb90dSTom Pothier (void) nvlist_lookup_int32(nvl, FM_GENTOPO_LEGACY, &legacy); 594074bb90dSTom Pothier 595074bb90dSTom Pothier nvlist_free(nvl); 596074bb90dSTom Pothier topo_mod_free(mod, obuf, outsz); 597074bb90dSTom Pothier 598074bb90dSTom Pothier if (legacy == 1) { 599074bb90dSTom Pothier /* legacy kernel variable set; will do the same */ 600074bb90dSTom Pothier return (X86PI_NONE); 601074bb90dSTom Pothier } 602074bb90dSTom Pothier 603074bb90dSTom Pothier /* legacy kernel variable not set; generic topo enum */ 604074bb90dSTom Pothier return (X86PI_FULL); 605074bb90dSTom Pothier } 606074bb90dSTom Pothier 607074bb90dSTom Pothier const char * 608074bb90dSTom Pothier x86pi_cleanup_smbios_str(topo_mod_t *mod, const char *begin, int str_type) 609074bb90dSTom Pothier { 610074bb90dSTom Pothier char buf[MAXNAMELEN]; 611074bb90dSTom Pothier const char *end, *cp; 612074bb90dSTom Pothier char *pp; 613074bb90dSTom Pothier char c; 614074bb90dSTom Pothier int i; 615074bb90dSTom Pothier 616074bb90dSTom Pothier end = begin + strlen(begin); 617074bb90dSTom Pothier 618074bb90dSTom Pothier while (begin < end && isspace(*begin)) 619074bb90dSTom Pothier begin++; 620074bb90dSTom Pothier while (begin < end && isspace(*(end - 1))) 621074bb90dSTom Pothier end--; 622074bb90dSTom Pothier 623074bb90dSTom Pothier if (begin >= end) 624074bb90dSTom Pothier return (NULL); 625074bb90dSTom Pothier 626074bb90dSTom Pothier cp = begin; 627074bb90dSTom Pothier for (i = 0; i < MAXNAMELEN - 1; i++) { 628074bb90dSTom Pothier if (cp >= end) 629074bb90dSTom Pothier break; 630074bb90dSTom Pothier c = *cp; 631074bb90dSTom Pothier if (str_type == LABEL) { 632074bb90dSTom Pothier if (!isprint(c)) 633074bb90dSTom Pothier buf[i] = '-'; 634074bb90dSTom Pothier else 635074bb90dSTom Pothier buf[i] = c; 636074bb90dSTom Pothier } else { 637074bb90dSTom Pothier if (c == ':' || c == '=' || c == '/' || 638074bb90dSTom Pothier isspace(c) || !isprint(c)) 639074bb90dSTom Pothier buf[i] = '-'; 640074bb90dSTom Pothier else 641074bb90dSTom Pothier buf[i] = c; 642074bb90dSTom Pothier } 643074bb90dSTom Pothier cp++; 644074bb90dSTom Pothier } 645074bb90dSTom Pothier buf[i] = 0; 646074bb90dSTom Pothier 647074bb90dSTom Pothier pp = topo_mod_strdup(mod, buf); 648074bb90dSTom Pothier 649074bb90dSTom Pothier if (str_type == LABEL) 650074bb90dSTom Pothier topo_mod_strfree(mod, (char *)begin); 651074bb90dSTom Pothier 652074bb90dSTom Pothier return (pp); 653074bb90dSTom Pothier } 654