/*ARGSUSED*/ static int DEVprop_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; char *dnpath; char *path, *fpath; int d, f; int err, e; mp = did_mod(pd); if ((dnpath = di_devfs_path(did_dinode(pd))) == NULL) { topo_mod_dprintf(mp, "NULL di_devfs_path.\n"); return (topo_mod_seterrno(mp, ETOPO_PROP_NOENT)); } if ((path = topo_mod_strdup(mp, dnpath)) == NULL) { di_devfs_path_free(dnpath); return (-1); } di_devfs_path_free(dnpath); /* The DEV path is modified for hostbridges */ if (strcmp(topo_node_name(tn), HOSTBRIDGE) == 0) { fpath = dev_for_hostbridge(did_mod(pd), path); } else { did_BDF(pd, NULL, &d, &f); fpath = dev_path_fix(mp, path, d, f); } if (fpath == NULL) return (-1); e = topo_prop_set_string(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, fpath, &err); topo_mod_strfree(mp, fpath); if (e != 0) return (topo_mod_seterrno(mp, err)); return (0); }
/*ARGSUSED*/ static int iob_enum(topo_mod_t *mp, tnode_t *pn, const char *name, topo_instance_t imin, topo_instance_t imax, void *notused) { topo_mod_t *hbmod; int rv; did_hash_t *didhash; di_prom_handle_t promtree; if (strcmp(name, IOBOARD) != 0) { topo_mod_dprintf(mp, "Currently only know how to enumerate %s components.\n", IOBOARD); return (0); } if ((promtree = di_prom_init()) == DI_PROM_HANDLE_NIL) { topo_mod_dprintf(mp, "Ioboard enumerator: di_prom_handle_init failed.\n"); return (-1); } /* * Load the hostbridge enumerator, we'll soon need it! */ if ((hbmod = hb_enumr_load(mp, pn)) == NULL) { di_prom_fini(promtree); return (-1); } if ((didhash = did_hash_init(mp)) == NULL) { topo_mod_dprintf(mp, "Hash initialization for ioboard enumerator failed.\n"); di_prom_fini(promtree); topo_mod_unload(hbmod); return (-1); } rv = platform_iob_enum(pn, imin, imax, didhash, promtree, mp); did_hash_fini(didhash); di_prom_fini(promtree); topo_mod_unload(hbmod); if (rv < 0) return (topo_mod_seterrno(mp, EMOD_PARTIAL_ENUM)); else return (0); }
/*ARGSUSED*/ static int DRIVERprop_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { char *dnm; int err; if ((dnm = di_driver_name(did_dinode(pd))) == NULL) return (0); if (topo_prop_set_string(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, dnm, &err) < 0) return (topo_mod_seterrno(did_mod(pd), err)); return (0); }
/* ARGSUSED */ int cpu_unusable(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { struct cpu_walk_data swd; uint32_t rc; if (version > TOPO_METH_UNUSABLE_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (walk_cpus(mod, &swd, node, ldom_fmri_status) == -1) return (-1); rc = (swd.offline > 0 && swd.fail + swd.online == 0) ? 1 : 0; return (set_retnvl(mod, out, TOPO_METH_UNUSABLE_RET, rc)); }
/* ARGSUSED */ int cpu_unretire(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { struct cpu_walk_data swd; uint32_t rc; if (version > TOPO_METH_UNRETIRE_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (walk_cpus(mod, &swd, node, ldom_fmri_unretire) == -1) return (-1); rc = swd.fail > 0 ? FMD_AGENT_RETIRE_FAIL : FMD_AGENT_RETIRE_DONE; return (set_retnvl(mod, out, TOPO_METH_UNRETIRE_RET, rc)); }
/*ARGSUSED*/ static int BDF_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { int bdf; char str[23]; /* '0x' + sizeof (UINT64_MAX) + '\0' */ int e; if ((bdf = did_bdf(pd)) <= 0) return (0); (void) snprintf(str, 23, "0x%x", bdf); if (topo_prop_set_string(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, str, &e) < 0) return (topo_mod_seterrno(did_mod(pd), e)); return (0); }
/* * Calculate a generic FRU for the given node. If the node is not a FRU, * then inherit the FRU data from the nodes parent. */ int x86pi_set_frufmri(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_parent, tnode_t *t_node, int flag) { int result; int err; nvlist_t *auth = NULL; nvlist_t *frufmri = NULL; if (t_node == NULL || mod == NULL) { return (-1); } /* * Determine if this node is a FRU */ if (!(flag & X86PI_ENUM_FRU)) { /* This node is not a FRU. Inherit from parent and return */ (void) topo_node_fru_set(t_node, NULL, 0, &result); return (0); } /* * This node is a FRU. Create an FMRI. */ auth = topo_mod_auth(mod, t_parent); frufmri = topo_mod_hcfmri(mod, t_parent, FM_HC_SCHEME_VERSION, hcfmri->hc_name, hcfmri->instance, NULL, auth, hcfmri->part_number, hcfmri->version, hcfmri->serial_number); if (frufmri == NULL) { topo_mod_dprintf(mod, "failed to create FRU: %s\n", topo_strerror(topo_mod_errno(mod))); } nvlist_free(auth); /* Set the FRU, whether NULL or not */ result = topo_node_fru_set(t_node, frufmri, 0, &err); if (result != 0) { (void) topo_mod_seterrno(mod, err); } nvlist_free(frufmri); return (result); }
int sw_init(topo_mod_t *mod, topo_version_t version) { if (getenv("TOPOSWDEBUG")) topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing sw builtin\n"); if (version != SW_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (topo_mod_register(mod, &sw_info, TOPO_VERSION) != 0) { topo_mod_dprintf(mod, "failed to register sw_info: " "%s\n", topo_mod_errmsg(mod)); return (-1); } return (0); }
static tnode_t * node_bind_seterror(topo_mod_t *mod, tnode_t *pnode, tnode_t *node, int err) { topo_node_unlock(pnode); (void) topo_mod_seterrno(mod, err); if (node == NULL) return (NULL); topo_dprintf(TOPO_DBG_ERR, "unable to bind %s=%d: " "%s\n", (node->tn_name != NULL ? node->tn_name : "unknown"), node->tn_instance, topo_strerror(err)); topo_node_lock(node); /* expected to be locked */ topo_node_destroy(node); return (NULL); }
static int node_create_seterror(topo_mod_t *mod, tnode_t *pnode, topo_nodehash_t *nhp, int err) { topo_node_unlock(pnode); topo_dprintf(TOPO_DBG_ERR, "unable to insert child:" "%s\n", topo_strerror(err)); if (nhp != NULL) { if (nhp->th_name != NULL) topo_mod_strfree(mod, nhp->th_name); if (nhp->th_nodearr != NULL) { topo_mod_free(mod, nhp->th_nodearr, nhp->th_arrlen * sizeof (tnode_t *)); } topo_mod_free(mod, nhp, sizeof (topo_nodehash_t)); } return (topo_mod_seterrno(mod, err)); }
static int dimm_page_unusable(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { uint32_t rc = 0; nvlist_t *asru; int err; if (version > TOPO_METH_UNUSABLE_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (pi_lhp != NULL && is_page_fmri(in) && topo_node_asru(node, &asru, in, &err) == 0) { err = ldom_fmri_status(pi_lhp, asru); if (err == 0 || err == EINVAL) rc = 1; nvlist_free(asru); } return (set_retnvl(mod, out, TOPO_METH_UNUSABLE_RET, rc)); }
static int AADDR_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; uchar_t *typbuf; int sz = -1; int err, e; if (di_bytes_get(did_mod(pd), did_dinode(pd), dpnm, &sz, &typbuf) < 0) return (0); mp = did_mod(pd); e = topo_prop_set_uint32_array(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, /*LINTED*/ (uint32_t *)typbuf, sz/4, &err); if (e != 0) return (topo_mod_seterrno(mp, err)); return (0); }
int platform_pci_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in, nvlist_t **out) { int result; int err; int locsiz = 0; uchar_t *loc = NULL; char *nac = NULL; topo_mod_dprintf(mod, "entering platform_pci_label\n"); *out = NULL; result = di_bytes_get(mod, topo_node_getspecific(node), PI_PROP_CHASSIS_LOCATION_NAME, &locsiz, &loc); if (result == -1 || locsiz < 0) { topo_mod_dprintf(mod, "platform_pci_label: %s not found (%s)\n", PI_PROP_CHASSIS_LOCATION_NAME, strerror(errno)); /* Invoke the generic label generator for this node */ return (pci_label_cmn(mod, node, in, out)); } /* * We have crossed a FRU boundary. Use the value in the * chassis-location-name property as the node label. */ nac = alloca(locsiz+1); (void) memset(nac, 0, locsiz+1); (void) memcpy(nac, loc, locsiz); result = topo_node_label_set(node, nac, &err); if (result < 0) { if (err != ETOPO_PROP_NOENT) { return (topo_mod_seterrno(mod, err)); } } return (0); }
static int set_methregister_error(topo_mod_t *mod, tnode_t *node, topo_imethod_t *mp, int err) { if (mp != NULL) { topo_list_delete(&node->tn_methods, mp); if (mp->tim_name != NULL) topo_mod_strfree(mod, mp->tim_name); if (mp->tim_desc != NULL) topo_mod_strfree(mod, mp->tim_desc); topo_mod_free(mod, mp, sizeof (topo_imethod_t)); } topo_node_unlock(node); topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, "method registration failed for %s: %s\n", mod->tm_name, topo_strerror(err)); return (topo_mod_seterrno(mod, err)); }
static int dimm_page_unretire(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { uint32_t rc = FMD_AGENT_RETIRE_FAIL; nvlist_t *asru; int err; if (version > TOPO_METH_UNRETIRE_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (pi_lhp != NULL && is_page_fmri(in) && topo_node_asru(node, &asru, in, &err) == 0) { err = ldom_fmri_unretire(pi_lhp, asru); if (err == 0 || err == EIO) rc = FMD_AGENT_RETIRE_DONE; nvlist_free(asru); } return (set_retnvl(mod, out, TOPO_METH_UNRETIRE_RET, rc)); }
/*ARGSUSED*/ static int EXCAP_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { int excap = did_excap(pd); int err; int e = 0; switch (excap & PCIE_PCIECAP_DEV_TYPE_MASK) { case PCIE_PCIECAP_DEV_TYPE_ROOT: e = topo_prop_set_string(tn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_ROOT, &err); break; case PCIE_PCIECAP_DEV_TYPE_UP: e = topo_prop_set_string(tn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_SWUP, &err); break; case PCIE_PCIECAP_DEV_TYPE_DOWN: e = topo_prop_set_string(tn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_SWDWN, &err); break; case PCIE_PCIECAP_DEV_TYPE_PCI2PCIE: e = topo_prop_set_string(tn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_BUS, &err); break; case PCIE_PCIECAP_DEV_TYPE_PCIE2PCI: e = topo_prop_set_string(tn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCI_BUS, &err); break; case PCIE_PCIECAP_DEV_TYPE_PCIE_DEV: e = topo_prop_set_string(tn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_DEVICE, &err); break; } if (e != 0) return (topo_mod_seterrno(did_mod(pd), err)); return (0); }
static int niufn_instantiate(tnode_t *parent, const char *name, di_node_t pnode, topo_mod_t *mod) { di_node_t sib; tnode_t *ntn; topo_instance_t inst; if (strcmp(name, NIUFN) != 0) { topo_mod_dprintf(mod, "Currently only know how to enumerate %s components.\n", NIUFN); return (0); } sib = di_child_node(pnode); while (sib != DI_NODE_NIL) { if (niufn_instance_get(mod, sib, &inst) != 0) { topo_mod_dprintf(mod, "Enumeration of %s " "instance failed.\n", NIUFN); sib = di_sibling_node(sib); continue; } if ((ntn = niufn_declare(parent, NIUFN, inst, sib, mod)) == NULL) { topo_mod_dprintf(mod, "Enumeration of %s=%d " "failed: %s\n", NIUFN, inst, topo_strerror(topo_mod_errno(mod))); return (-1); } if (topo_mod_enumerate(mod, ntn, XAUI, XAUI, inst, inst, sib) != 0) { return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); } sib = di_sibling_node(sib); } return (0); }
static int platform_pci_fru_location(topo_mod_t *mod, tnode_t *node, uchar_t *loc, int locsiz) { int err; tnode_t *parent; tnode_t *top; topo_walk_t *wp; _pci_fru_t walkdata; topo_mod_dprintf(mod, "entering platform_pci_fru_location\n"); /* Find the root node */ top = node; while ((parent = topo_node_parent(top)) != NULL) { top = parent; } walkdata.node = node; walkdata.locsiz = locsiz; walkdata.location = alloca(locsiz+1); (void) memset(walkdata.location, 0, locsiz+1); (void) memcpy(walkdata.location, loc, locsiz); /* Create a walker starting at the root node */ wp = topo_mod_walk_init(mod, top, platform_pci_fru_cb, &walkdata, &err); if (wp == NULL) { return (topo_mod_seterrno(mod, err)); } /* * Walk the tree breadth first to hopefully avoid visiting too many * nodes while searching for the node with the appropriate FMRI. */ (void) topo_walk_step(wp, TOPO_WALK_SIBLING); topo_walk_fini(wp); return (0); }
/*ARGSUSED*/ static int moduleprop_set(tnode_t *tn, di_node_t dn, const char *tpgrp, const char *tpnm, topo_mod_t *mod) { nvlist_t *module; char *dnm; int err; if ((dnm = di_driver_name(dn)) == NULL) return (0); if ((module = topo_mod_modfmri(mod, FM_MOD_SCHEME_VERSION, dnm)) == NULL) return (0); /* driver maybe detached, return success */ if (topo_prop_set_fmri(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, module, &err) < 0) { nvlist_free(module); return (topo_mod_seterrno(mod, err)); } nvlist_free(module); return (0); }
int _topo_init(topo_mod_t *modhdl, topo_version_t version) { /* * Turn on module debugging output */ if (getenv("TOPOHBDBG") != NULL) topo_mod_setdebug(modhdl); topo_mod_dprintf(modhdl, "initializing hostbridge enumerator\n"); if (version != HB_ENUMR_VERS) return (topo_mod_seterrno(modhdl, EMOD_VER_NEW)); if (topo_mod_register(modhdl, &Hb_info, TOPO_VERSION) < 0) { topo_mod_dprintf(modhdl, "hostbridge registration failed: %s\n", topo_mod_errmsg(modhdl)); return (-1); /* mod errno already set */ } topo_mod_dprintf(modhdl, "Hostbridge enumr initd\n"); return (0); }
static nvlist_t * mem_fmri_create(topo_mod_t *mod, char *serial, char *label) { int err; nvlist_t *fmri; if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0) return (NULL); err = nvlist_add_uint8(fmri, FM_VERSION, FM_MEM_SCHEME_VERSION); err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_MEM); if (serial != NULL) err |= nvlist_add_string_array(fmri, FM_FMRI_MEM_SERIAL_ID, &serial, 1); if (label != NULL) err |= nvlist_add_string(fmri, FM_FMRI_MEM_UNUM, label); if (err != 0) { nvlist_free(fmri); (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL); return (NULL); } return (fmri); }
/* ARGSUSED */ int cpu_service_state(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { struct cpu_walk_data swd; uint32_t rc; if (version > TOPO_METH_SERVICE_STATE_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (walk_cpus(mod, &swd, node, ldom_fmri_status) == -1) return (-1); if (swd.fail > 0) rc = FMD_SERVICE_STATE_UNKNOWN; else if (swd.offline > 0) rc = swd.online > 0 ? FMD_SERVICE_STATE_DEGRADED : FMD_SERVICE_STATE_UNUSABLE; else rc = FMD_SERVICE_STATE_OK; return (set_retnvl(mod, out, TOPO_METH_SERVICE_STATE_RET, rc)); }
/*ARGSUSED*/ static int create_chips(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min, topo_instance_t max, void *arg, nvlist_t *auth, int mc_offchip) { fmd_agent_hdl_t *hdl; nvlist_t **cpus; int nerr = 0; uint_t i, ncpu; if (strcmp(name, CHIP_NODE_NAME) != 0) return (0); if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL) return (-1); if (fmd_agent_physcpu_info(hdl, &cpus, &ncpu) != 0) { whinge(mod, NULL, "create_chip: fmd_agent_physcpu_info " "failed: %s\n", fmd_agent_errmsg(hdl)); fmd_agent_close(hdl); return (-1); } fmd_agent_close(hdl); for (i = 0; i < ncpu; i++) { nerr -= create_chip(mod, pnode, min, max, cpus[i], auth, mc_offchip); nvlist_free(cpus[i]); } umem_free(cpus, sizeof (nvlist_t *) * ncpu); if (nerr == 0) { return (0); } else { (void) topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM); return (-1); } }
static int dimm_page_service_state(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { uint32_t rc = FMD_SERVICE_STATE_OK; nvlist_t *asru; int err; if (version > TOPO_METH_SERVICE_STATE_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (pi_lhp != NULL && is_page_fmri(in) && topo_node_asru(node, &asru, in, &err) == 0) { err = ldom_fmri_status(pi_lhp, asru); if (err == 0 || err == EINVAL) rc = FMD_SERVICE_STATE_UNUSABLE; else if (err == EAGAIN) rc = FMD_SERVICE_STATE_ISOLATE_PENDING; nvlist_free(asru); } return (set_retnvl(mod, out, TOPO_METH_SERVICE_STATE_RET, rc)); }
/* * Called by libtopo when the topo module is loaded. */ void _topo_init(topo_mod_t *mod, topo_version_t version) { int result; char isa[MAXNAMELEN]; if (getenv("TOPOSUN4VPIDBG") != NULL) { /* Debugging is requested for this module */ topo_mod_setdebug(mod); } topo_mod_dprintf(mod, "sun4vpi module initializing.\n"); if (version != TOPO_VERSION) { (void) topo_mod_seterrno(mod, EMOD_VER_NEW); topo_mod_dprintf(mod, "incompatible topo version %d\n", version); return; } /* Verify that this is a SUN4V architecture machine */ (void) sysinfo(SI_MACHINE, isa, MAXNAMELEN); if (strncmp(isa, "sun4v", MAXNAMELEN) != 0) { topo_mod_dprintf(mod, "not sun4v architecture: %s\n", isa); return; } result = topo_mod_register(mod, &pi_modinfo, TOPO_VERSION); if (result < 0) { topo_mod_dprintf(mod, "registration failed: %s\n", topo_mod_errmsg(mod)); /* module errno already set */ return; } topo_mod_dprintf(mod, "module ready.\n"); }
/*ARGSUSED*/ static int ASRU_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; nvlist_t *fmri; char *dnpath, *path, *fpath, *nm; int d, e, f; /* * If this topology node represents a function of device, * set the ASRU to a dev scheme FMRI based on the value of * di_devfs_path(). If that path is NULL, set the ASRU to * be the resource describing this topology node. If this * isn't a function, inherit any ASRU from the parent. */ mp = did_mod(pd); nm = topo_node_name(tn); if ((strcmp(nm, PCI_BUS) == 0 && did_gettnode(pd) && strcmp(topo_node_name(did_gettnode(pd)), HOSTBRIDGE) == 0) || strcmp(nm, PCI_FUNCTION) == 0 || strcmp(nm, PCIEX_FUNCTION) == 0 || strcmp(nm, PCIEX_ROOT) == 0) { if ((dnpath = di_devfs_path(did_dinode(pd))) != NULL) { /* * Dup the path, dev_path_fix() may replace it and * dev_path_fix() wouldn't know to use * di_devfs_path_free() */ if ((path = topo_mod_strdup(mp, dnpath)) == NULL) { di_devfs_path_free(dnpath); return (topo_mod_seterrno(mp, EMOD_NOMEM)); } di_devfs_path_free(dnpath); did_BDF(pd, NULL, &d, &f); if ((fpath = dev_path_fix(mp, path, d, f)) == NULL) return (topo_mod_seterrno(mp, EMOD_NOMEM)); fmri = topo_mod_devfmri(mp, FM_DEV_SCHEME_VERSION, fpath, NULL); if (fmri == NULL) { topo_mod_dprintf(mp, "dev:///%s fmri creation failed.\n", fpath); topo_mod_strfree(mp, fpath); return (-1); } topo_mod_strfree(mp, fpath); } else { topo_mod_dprintf(mp, "NULL di_devfs_path.\n"); if (topo_prop_get_fmri(tn, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE, &fmri, &e) < 0) return (topo_mod_seterrno(mp, e)); } if (topo_node_asru_set(tn, fmri, 0, &e) < 0) { nvlist_free(fmri); return (topo_mod_seterrno(mp, e)); } nvlist_free(fmri); return (0); } (void) topo_node_asru_set(tn, NULL, 0, &e); return (0); }
/* * Calculate the system information for a node. Inherit the data if * possible, but always create an appropriate property group. */ int x86pi_set_system(topo_mod_t *mod, tnode_t *t_node) { int result; int err; struct utsname uts; char isa[MAXNAMELEN]; if (mod == NULL || t_node == NULL) { return (-1); } result = topo_pgroup_create(t_node, &sys_pgroup, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { /* * We failed to create the property group and it was not * already defined. Set the err code and return failure. */ (void) topo_mod_seterrno(mod, err); return (-1); } result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { isa[0] = '\0'; result = sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)); if (result == -1) { /* Preserve the error and continue */ topo_mod_dprintf(mod, "x86pi_set_system: failed to " "read SI_ARCHITECTURE: %d\n", errno); } if (strnlen(isa, MAXNAMELEN) > 0) { result = topo_prop_set_string(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, TOPO_PROP_IMMUTABLE, isa, &err); if (result != 0) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "x86pi_set_auth: failed to " "set property %s (%d) : %s\n", TOPO_PROP_ISA, err, topo_strerror(err)); } } } result = topo_prop_inherit(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, &err); if (result != 0 && err != ETOPO_PROP_DEFD) { result = uname(&uts); if (result == -1) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, errno); topo_mod_dprintf(mod, "x86pi_set_system: failed to " "read uname: %d\n", errno); } if (strnlen(uts.machine, sizeof (uts.machine)) > 0) { result = topo_prop_set_string(t_node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, TOPO_PROP_IMMUTABLE, uts.machine, &err); if (result != 0) { /* Preserve the error and continue */ (void) topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "x86pi_set_auth: failed to " "set property %s (%d) : %s\n", TOPO_PROP_MACHINE, err, topo_strerror(err)); } } } return (0); }
/* Topo Methods */ static int mem_asru_compute(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { nvlist_t *asru, *pargs, *args, *hcsp; int err; char *serial = NULL, *label = NULL; uint64_t pa, offset; if (version > TOPO_METH_ASRU_COMPUTE_VERSION) return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (strcmp(topo_node_name(node), DIMM) != 0) return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); pargs = NULL; if (nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) (void) nvlist_lookup_string(pargs, FM_FMRI_HC_SERIAL_ID, &serial); if (serial == NULL && nvlist_lookup_nvlist(in, TOPO_PROP_ARGS, &args) == 0) (void) nvlist_lookup_string(args, FM_FMRI_HC_SERIAL_ID, &serial); (void) topo_node_label(node, &label, &err); asru = mem_fmri_create(mod, serial, label); if (label != NULL) topo_mod_strfree(mod, label); if (asru == NULL) return (topo_mod_seterrno(mod, EMOD_NOMEM)); err = 0; /* * For a memory page, 'in' includes an hc-specific member which * specifies physaddr and/or offset. Set them in asru as well. */ if (pargs && nvlist_lookup_nvlist(pargs, FM_FMRI_HC_SPECIFIC, &hcsp) == 0) { if (nvlist_lookup_uint64(hcsp, FM_FMRI_HC_SPECIFIC_PHYSADDR, &pa) == 0) err += nvlist_add_uint64(asru, FM_FMRI_MEM_PHYSADDR, pa); if (nvlist_lookup_uint64(hcsp, FM_FMRI_HC_SPECIFIC_OFFSET, &offset) == 0) err += nvlist_add_uint64(asru, FM_FMRI_MEM_OFFSET, offset); } if (err != 0 || topo_mod_nvalloc(mod, out, NV_UNIQUE_NAME) < 0) { nvlist_free(asru); return (topo_mod_seterrno(mod, EMOD_NOMEM)); } err = nvlist_add_string(*out, TOPO_PROP_VAL_NAME, TOPO_PROP_ASRU); err |= nvlist_add_uint32(*out, TOPO_PROP_VAL_TYPE, TOPO_TYPE_FMRI); err |= nvlist_add_nvlist(*out, TOPO_PROP_VAL_VAL, asru); nvlist_free(asru); if (err != 0) { nvlist_free(*out); *out = NULL; return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); } return (0); }
static int mptsas_led_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers, nvlist_t *in, nvlist_t **nvout) { int err, ret = 0; tnode_t *pnode = topo_node_parent(node); uint32_t type, ledmode = 0; nvlist_t *pargs, *nvl; char *driver = NULL, *devctl = NULL; uint32_t enclosure, slot; uint8_t mptsas_led; boolean_t set; if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION) return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW)); if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING, TOPO_BINDING_DRIVER, &driver, &err) != 0 || strcmp("mpt_sas", driver) != 0) { topo_mod_dprintf(mod, "%s: Facility driver was not mpt_sas", __func__); ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL); goto out; } if (topo_prop_get_uint32(node, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE, &type, &err) != 0) { topo_mod_dprintf(mod, "%s: Failed to lookup %s property " "(%s)", __func__, TOPO_FACILITY_TYPE, topo_strerror(err)); return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); } switch (type) { case (TOPO_LED_TYPE_SERVICE): mptsas_led = MPTSAS_LEDCTL_LED_FAIL; break; case (TOPO_LED_TYPE_LOCATE): mptsas_led = MPTSAS_LEDCTL_LED_IDENT; break; case (TOPO_LED_TYPE_OK2RM): mptsas_led = MPTSAS_LEDCTL_LED_OK2RM; break; default: topo_mod_dprintf(mod, "%s: Invalid LED type: 0x%x\n", __func__, type); return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); } if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING, TOPO_BINDING_DEVCTL, &devctl, &err) != 0 || topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING, TOPO_BINDING_ENCLOSURE, &enclosure, &err) != 0 || topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING, TOPO_BINDING_SLOT, &slot, &err) != 0) { topo_mod_dprintf(mod, "%s: Facility was missing mpt_sas binding" " properties\n", __func__); ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL); goto out; } if ((nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) && nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) { /* * Set the LED mode */ set = B_TRUE; if ((ret = nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL, &ledmode)) != 0) { topo_mod_dprintf(mod, "%s: Failed to lookup %s nvpair " "(%s)\n", __func__, TOPO_PROP_VAL_VAL, strerror(ret)); ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL); goto out; } topo_mod_dprintf(mod, "%s: Setting LED mode to %s\n", __func__, ledmode ? "ON" : "OFF"); } else { /* * Get the LED mode */ set = B_FALSE; topo_mod_dprintf(mod, "%s: Getting LED mode\n", __func__); } if (do_led_control(mod, devctl, enclosure, slot, mptsas_led, &ledmode, set) != 0) { topo_mod_dprintf(mod, "%s: do_led_control failed", __func__); ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); goto out; } if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 || nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 || nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 || nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) { topo_mod_dprintf(mod, "%s: Failed to allocate 'out' nvlist\n", __func__); nvlist_free(nvl); ret = topo_mod_seterrno(mod, EMOD_NOMEM); goto out; } *nvout = nvl; out: if (driver != NULL) topo_mod_strfree(mod, driver); if (devctl != NULL) topo_mod_strfree(mod, devctl); return (ret); }
/*ARGSUSED*/ static int FRU_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; char *nm; int e = 0, err = 0; nm = topo_node_name(tn); mp = did_mod(pd); /* * If this is a PCIEX_BUS and its parent is a PCIEX_ROOT, * check for a CPUBOARD predecessor. If found, inherit its * parent's FRU. Otherwise, continue with FRU set. */ if ((strcmp(nm, PCIEX_BUS) == 0) && (strcmp(topo_node_name(topo_node_parent(tn)), PCIEX_ROOT) == 0)) { if (use_predecessor_fru(tn, CPUBOARD) == 0) return (0); } /* * If this topology node represents something other than an * ioboard or a device that implements a slot, inherit the * parent's FRU value. If there is no label, inherit our * parent's FRU value. Otherwise, munge up an fmri based on * the label. */ if (strcmp(nm, IOBOARD) != 0 && strcmp(nm, PCI_DEVICE) != 0 && strcmp(nm, PCIEX_DEVICE) != 0 && strcmp(nm, PCIEX_BUS) != 0) { (void) topo_node_fru_set(tn, NULL, 0, &e); return (0); } /* * If ioboard, set fru fmri to hc fmri */ if (strcmp(nm, IOBOARD) == 0) { e = FRU_fmri_set(mp, tn); return (e); } else if (strcmp(nm, PCI_DEVICE) == 0 || strcmp(nm, PCIEX_DEVICE) == 0 || strcmp(nm, PCIEX_BUS) == 0) { nvlist_t *in, *out; mp = did_mod(pd); if (topo_mod_nvalloc(mp, &in, NV_UNIQUE_NAME) != 0) return (topo_mod_seterrno(mp, EMOD_FMRI_NVL)); if (nvlist_add_uint64(in, "nv1", (uintptr_t)pd) != 0) { nvlist_free(in); return (topo_mod_seterrno(mp, EMOD_NOMEM)); } if (topo_method_invoke(tn, TOPO_METH_FRU_COMPUTE, TOPO_METH_FRU_COMPUTE_VERSION, in, &out, &err) != 0) { nvlist_free(in); return (topo_mod_seterrno(mp, err)); } nvlist_free(in); (void) topo_node_fru_set(tn, out, 0, &err); if (out != NULL) nvlist_free(out); } else (void) topo_node_fru_set(tn, NULL, 0, &err); return (0); }