static void print_everstyle(tnode_t *node) { char buf[PATH_MAX], numbuf[64]; nvlist_t *fmri, **hcl; int i, err; uint_t n; if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE, &fmri, &err) < 0) { (void) fprintf(stderr, "%s: failed to get fmri for %s=%d: %s\n", g_pname, topo_node_name(node), topo_node_instance(node), topo_strerror(err)); return; } if (nvlist_lookup_nvlist_array(fmri, FM_FMRI_HC_LIST, &hcl, &n) != 0) { (void) fprintf(stderr, "%s: failed to find %s for %s=%d\n", g_pname, FM_FMRI_HC_LIST, topo_node_name(node), topo_node_instance(node)); nvlist_free(fmri); return; } buf[0] = '\0'; for (i = 0; i < n; i++) { char *name, *inst, *estr; ulong_t ul; if (nvlist_lookup_string(hcl[i], FM_FMRI_HC_NAME, &name) != 0 || nvlist_lookup_string(hcl[i], FM_FMRI_HC_ID, &inst) != 0) { (void) fprintf(stderr, "%s: failed to get " "name-instance for %s=%d\n", g_pname, topo_node_name(node), topo_node_instance(node)); nvlist_free(fmri); return; } errno = 0; ul = strtoul(inst, &estr, 10); if (errno != 0 || estr == inst) { (void) fprintf(stderr, "%s: instance %s does not " "convert to an unsigned integer\n", g_pname, inst); } (void) strlcat(buf, "/", sizeof (buf)); (void) strlcat(buf, name, sizeof (buf)); (void) snprintf(numbuf, sizeof (numbuf), "%u", ul); (void) strlcat(buf, numbuf, sizeof (buf)); } nvlist_free(fmri); (void) printf("%s\n", buf); }
/*ARGSUSED*/ static int label_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; nvlist_t *in, *out; char *label; int err; 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 Label. Otherwise, continue with label set. */ if ((strcmp(topo_node_name(tn), PCIEX_BUS) == 0) && (strcmp(topo_node_name(topo_node_parent(tn)), PCIEX_ROOT) == 0)) { if (use_predecessor_label(mp, tn, CPUBOARD) == 0) return (0); } if (topo_mod_nvalloc(mp, &in, NV_UNIQUE_NAME) != 0) return (topo_mod_seterrno(mp, EMOD_FMRI_NVL)); if (nvlist_add_uint64(in, TOPO_METH_LABEL_ARG_NVL, (uintptr_t)pd) != 0) { nvlist_free(in); return (topo_mod_seterrno(mp, EMOD_NOMEM)); } if (topo_method_invoke(tn, TOPO_METH_LABEL, TOPO_METH_LABEL_VERSION, in, &out, &err) != 0) { nvlist_free(in); return (topo_mod_seterrno(mp, err)); } nvlist_free(in); if (out != NULL && nvlist_lookup_string(out, TOPO_METH_LABEL_RET_STR, &label) == 0) { if (topo_prop_set_string(tn, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE, label, &err) != 0) { nvlist_free(out); return (topo_mod_seterrno(mp, err)); } nvlist_free(out); } return (0); }
int topo_method_register(topo_mod_t *mod, tnode_t *node, const topo_method_t *mp) { topo_imethod_t *imp; const topo_method_t *meth; /* * Initialize module methods */ for (meth = &mp[0]; meth->tm_name != NULL; meth++) { topo_node_lock(node); if (topo_method_lookup(node, meth->tm_name) != NULL) { topo_node_unlock(node); continue; } if (meth->tm_stability < TOPO_STABILITY_INTERNAL || meth->tm_stability > TOPO_STABILITY_MAX || meth->tm_func == NULL) return (set_methregister_error(mod, node, NULL, ETOPO_METHOD_INVAL)); imp = topo_mod_zalloc(mod, sizeof (topo_imethod_t)); if (imp == NULL) return (set_methregister_error(mod, node, imp, ETOPO_METHOD_NOMEM)); if ((imp->tim_name = topo_mod_strdup(mod, meth->tm_name)) == NULL) return (set_methregister_error(mod, node, imp, ETOPO_METHOD_NOMEM)); if ((imp->tim_desc = topo_mod_strdup(mod, meth->tm_desc)) == NULL) return (set_methregister_error(mod, node, imp, ETOPO_METHOD_NOMEM)); imp->tim_stability = meth->tm_stability; imp->tim_version = meth->tm_version; imp->tim_func = meth->tm_func; imp->tim_mod = mod; topo_list_append(&node->tn_methods, imp); topo_node_unlock(node); topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC, "registered module %s method " "%s for %s=%d\n", mod->tm_name, imp->tim_name, topo_node_name(node), topo_node_instance(node)); } return (0); }
tnode_t * find_predecessor(tnode_t *tn, char *mod_name) { tnode_t *pnode = topo_node_parent(tn); while (pnode && (strcmp(topo_node_name(pnode), mod_name) != 0)) { pnode = topo_node_parent(pnode); } return (pnode); }
static tnode_t * iob_tnode_create(tnode_t *parent, const char *name, topo_instance_t i, void *priv, topo_mod_t *mod) { topo_hdl_t *thp; nvlist_t *args, *fmri, *pfmri; tnode_t *ntn; int err; thp = topo_mod_handle(mod); if (topo_node_resource(parent, &pfmri, &err) < 0) { topo_mod_seterrno(mod, err); topo_mod_dprintf(mod, "Unable to retrieve parent resource.\n"); return (NULL); } if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) { (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL); nvlist_free(pfmri); return (NULL); } err = nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri); if (err != 0) { nvlist_free(pfmri); nvlist_free(args); (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL); return (NULL); } fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, i, args, &err); if (fmri == NULL) { topo_mod_dprintf(mod, "Unable to make nvlist for %s bind.\n", name); return (NULL); } ntn = topo_node_bind(mod, parent, name, i, fmri, priv); if (ntn == NULL) { topo_mod_dprintf(mod, "topo_node_bind (%s%d/%s%d) failed: %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); nvlist_free(fmri); return (NULL); } nvlist_free(fmri); if (topo_method_register(mod, ntn, Iob_methods) < 0) { topo_mod_dprintf(mod, "topo_method_register failed: %s\n", topo_strerror(topo_mod_errno(mod))); topo_node_unbind(ntn); return (NULL); } return (ntn); }
static int dl_fault_walk_outer(topo_hdl_t *thp, tnode_t *node, void *arg) { disk_lights_t *dl = arg; dl_fault_walk_inner_t fwi; tnode_t *pnode; int err, has_fault; nvlist_t *fmri = NULL; bzero(&fwi, sizeof (fwi)); /* * We are only looking for DISK nodes in the topology that have a parent * BAY. */ if (strcmp(DISK, topo_node_name(node)) != 0 || (pnode = topo_node_parent(node)) == NULL || strcmp(BAY, topo_node_name(pnode)) != 0) { return (TOPO_WALK_NEXT); } /* * Check to see if the Resource this FMRI describes is Faulty: */ if (topo_node_resource(node, &fmri, &err) != 0) return (TOPO_WALK_NEXT); has_fault = fmd_nvl_fmri_has_fault(dl->dl_fmd, fmri, FMD_HAS_FAULT_RESOURCE, NULL); nvlist_free(fmri); /* * Walk the children of this BAY and flush out our fault status if * we find an appropriate indicator node. */ fwi.fwi_name = "fail"; fwi.fwi_mode = has_fault ? TOPO_LED_STATE_ON : TOPO_LED_STATE_OFF; (void) topo_node_child_walk(thp, pnode, dl_fault_walk_inner, &fwi, &err); return (TOPO_WALK_NEXT); }
/*ARGSUSED*/ static int gather_topo_cfg(topo_hdl_t *thp, tnode_t *node, void *arg) { char *nodename = topo_node_name(node); if (strcmp(DISK, nodename) == 0) return (topo_add_disk(thp, node, (walk_diskmon_t *)arg) ? TOPO_WALK_ERR : TOPO_WALK_NEXT); else if (strcmp(BAY, nodename) == 0) return (topo_add_bay(thp, node, (walk_diskmon_t *)arg) ? TOPO_WALK_ERR : TOPO_WALK_NEXT); return (TOPO_WALK_NEXT); }
/*ARGSUSED*/ static int gather_topo_cfg(topo_hdl_t *thp, tnode_t *node, void *arg) { char *nodename = topo_node_name(node); if (strcmp(SATA_DISK, nodename) == 0) return (topo_add_disk(thp, node, (diskmon_t *)arg) ? TOPO_WALK_ERR : TOPO_WALK_NEXT); else if (strcmp(SATA_PORT, nodename) == 0) return (topo_add_sata_port(thp, node, (diskmon_t *)arg) ? TOPO_WALK_ERR : TOPO_WALK_NEXT); return (TOPO_WALK_NEXT); }
static tnode_t * hb_tnode_create(topo_mod_t *mod, tnode_t *parent, const char *name, topo_instance_t i, void *priv) { int err; nvlist_t *fmri; tnode_t *ntn; nvlist_t *auth = topo_mod_auth(mod, parent); fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL, auth, NULL, NULL, NULL); nvlist_free(auth); if (fmri == NULL) { topo_mod_dprintf(mod, "Unable to make nvlist for %s bind: %s.\n", name, topo_mod_errmsg(mod)); return (NULL); } ntn = topo_node_bind(mod, parent, name, i, fmri); if (ntn == NULL) { topo_mod_dprintf(mod, "topo_node_bind (%s%d/%s%d) failed: %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); nvlist_free(fmri); return (NULL); } nvlist_free(fmri); topo_node_setspecific(ntn, priv); if (topo_pgroup_create(ntn, &hb_auth_pgroup, &err) == 0) { (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, &err); (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT_SN, &err); (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, &err); (void) topo_prop_inherit(ntn, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER, &err); } if (topo_method_register(mod, ntn, Hb_methods) < 0) { topo_mod_dprintf(mod, "topo_method_register failed: %s\n", topo_strerror(topo_mod_errno(mod))); topo_node_unbind(ntn); return (NULL); } return (ntn); }
static int amd_htconfig(topo_mod_t *mod, tnode_t *cnode, nvlist_t *htnvl) { nvpair_t *nvp; int nerr = 0; if (strcmp(topo_node_name(cnode), CHIP_NODE_NAME) != 0) { whinge(mod, &nerr, "amd_htconfig: must pass a chip node!"); return (-1); } for (nvp = nvlist_next_nvpair(htnvl, NULL); nvp != NULL; nvp = nvlist_next_nvpair(htnvl, nvp)) { if (nvprop_add(mod, nvp, PGNAME(CHIP), cnode) != 0) nerr++; } return (nerr == 0 ? 0 : -1); }
static tnode_t * niu_tnode_create(topo_mod_t *mod, tnode_t *parent, const char *name, topo_instance_t i, void *priv) { int err; nvlist_t *fmri; tnode_t *ntn; nvlist_t *auth = topo_mod_auth(mod, parent); fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL, auth, NULL, NULL, NULL); nvlist_free(auth); if (fmri == NULL) { topo_mod_dprintf(mod, "Unable to make nvlist for %s bind: %s.\n", name, topo_mod_errmsg(mod)); return (NULL); } ntn = topo_node_bind(mod, parent, name, i, fmri); if (ntn == NULL) { topo_mod_dprintf(mod, "topo_node_bind (%s%d/%s%d) failed: %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); nvlist_free(fmri); return (NULL); } nvlist_free(fmri); topo_node_setspecific(ntn, priv); if (topo_pgroup_create(ntn, &io_pgroup, &err) == 0) { (void) devprop_set(ntn, priv, TOPO_PGROUP_IO, TOPO_IO_DEV, mod); (void) driverprop_set(ntn, priv, TOPO_PGROUP_IO, TOPO_IO_DRIVER, mod); (void) moduleprop_set(ntn, priv, TOPO_PGROUP_IO, TOPO_IO_MODULE, mod); } return (ntn); }
/*ARGSUSED*/ static int fac_walker(topo_hdl_t *thp, tnode_t *node, void *arg) { int err; nvlist_t *out; if (topo_method_supported(node, TOPO_METH_FAC_ENUM, 0)) { /* * If the facility enumeration method fails, note the failure, * but continue on with the walk. */ if (topo_method_invoke(node, TOPO_METH_FAC_ENUM, 0, NULL, &out, &err) != 0) { topo_dprintf(thp, TOPO_DBG_ERR, "facility enumeration method failed on node %s=%d " "(%s)\n", topo_node_name(node), topo_node_instance(node), topo_strerror(err)); } } return (TOPO_WALK_NEXT); }
/* * Look for down-stream switch "4" on riser card. First find this node's parent. * If it is a pciexfn node and it has dev=4 and node 6 levels further up * from it has a physlot then return true. */ int ba_is_4(topo_mod_t *mod, did_t *dp) { tnode_t *ptp; did_t *pdp; int i, d; ptp = did_gettnode(dp); if (strcmp(topo_node_name(ptp), PCIEX_FUNCTION) != 0) return (0); pdp = did_find(mod, topo_node_getspecific(ptp)); if (!pdp) return (0); did_BDF(pdp, NULL, &d, NULL); if (d != 4) return (0); for (i = 0; i < 6; i++) if ((ptp = topo_node_parent(ptp)) == NULL) return (0); pdp = did_find(mod, topo_node_getspecific(ptp)); return (pdp && did_physlot_exists(pdp)); }
/*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); }
int platform_pci_fru(topo_mod_t *mod, tnode_t *node, nvlist_t *in, nvlist_t **out) { int err = 0; uint64_t ptr; did_t *dp, *pdp; tnode_t *pnode; char *nm, *plat, *pp, **cp; char *label; int found_t1plat = 0; uchar_t *loc; int locsiz; topo_mod_dprintf(mod, "entering platform_pci_fru\n"); if (topo_prop_get_string(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, &plat, &err) < 0) { (void) topo_mod_seterrno(mod, err); return (-1); } /* Delete the "SUNW," */ pp = strchr(plat, ','); if (pp == NULL) pp = plat; else ++pp; /* Is this an UltraSPARC-T1 platform? */ cp = usT1_plats; while ((*cp != NULL) && (found_t1plat == 0)) { if (strcmp(pp, *cp) == 0) found_t1plat = 1; cp++; } topo_mod_strfree(mod, plat); /* * On UltraSPARC-T1 systems, use the legacy hc scheme on * the adapter slots to ensure ALOM on the SP can interpret * the FRU correctly. For everything else, follow the normal * code flow */ if (found_t1plat) { *out = NULL; nm = topo_node_name(node); if (strcmp(nm, PCI_DEVICE) != 0 && strcmp(nm, PCIEX_DEVICE) != 0 && strcmp(nm, PCIEX_BUS) != 0) return (0); if (nvlist_lookup_uint64(in, "nv1", &ptr) != 0) { topo_mod_dprintf(mod, "label method argument " "not found.\n"); return (-1); } dp = (did_t *)(uintptr_t)ptr; pnode = did_gettnode(dp); pdp = did_find(mod, topo_node_getspecific(pnode)); /* * Is there a slotname associated with the device? */ if ((label = pci_slot_label_lookup(mod, pnode, dp, pdp)) != NULL) { nvlist_t *rnvl; char buf[PATH_MAX]; (void) snprintf(buf, PATH_MAX, "hc:///component=%s", label); if (topo_mod_str2nvl(mod, buf, &rnvl) < 0) return (-1); *out = rnvl; } return (0); } else if (di_bytes_get(mod, topo_node_getspecific(node), PI_PROP_CHASSIS_LOCATION_NAME, &locsiz, &loc) == 0 && locsiz > 0) { /* * We have crossed a FRU boundary and need to find the parent * node with this location and set our FMRI to that value. */ return (platform_pci_fru_location(mod, node, loc, locsiz)); } else { return (pci_fru_compute(mod, node, in, out)); } }
/*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); }
/*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); }
/* * Create a generic topo node based on the hcfmri strcuture passed in. */ int x86pi_enum_generic(topo_mod_t *mod, x86pi_hcfmri_t *hcfmri, tnode_t *t_bindparent, tnode_t *t_fmriparent, tnode_t **t_node, int flag) { int rv; int err; nvlist_t *out; nvlist_t *fmri; nvlist_t *auth; topo_mod_dprintf(mod, "%s adding entry for type (%s)\n", _ENUM_NAME, hcfmri->hc_name); if (t_bindparent == NULL) { topo_mod_dprintf(mod, "%s called with NULL parent for type %s\n", _ENUM_NAME, hcfmri->hc_name); return (-1); } /* Create the FMRI for this node */ auth = topo_mod_auth(mod, t_bindparent); fmri = topo_mod_hcfmri(mod, t_fmriparent, FM_HC_SCHEME_VERSION, hcfmri->hc_name, hcfmri->instance, NULL, auth, hcfmri->part_number, hcfmri->version, hcfmri->serial_number); nvlist_free(auth); if (fmri == NULL) { topo_mod_dprintf(mod, "%s failed to create %s fmri : %s\n", _ENUM_NAME, hcfmri->hc_name, topo_strerror(topo_mod_errno(mod))); return (-1); } rv = topo_node_range_create(mod, t_bindparent, hcfmri->hc_name, 0, 4); if (rv != 0 && topo_mod_errno(mod) != EMOD_NODE_DUP) { topo_mod_dprintf(mod, "%s range create failed for node %s\n", _ENUM_NAME, hcfmri->hc_name); } /* Bind this node to the parent */ *t_node = x86pi_node_bind(mod, t_bindparent, hcfmri, fmri, flag); nvlist_free(fmri); if (*t_node == NULL) { topo_mod_dprintf(mod, "%s failed to bind %s node instance %d: %s\n", _ENUM_NAME, hcfmri->hc_name, hcfmri->instance, topo_strerror(topo_mod_errno(mod))); return (-1); } /* call IPMI facility provider to register fac methods */ if (topo_mod_load(mod, _FAC_PROV, TOPO_VERSION) == NULL) { topo_mod_dprintf(mod, "%s: Failed to load %s module: %s\n", _ENUM_NAME, _FAC_PROV, topo_mod_errmsg(mod)); return (-1); } rv = topo_mod_enumerate(mod, *t_node, _FAC_PROV, _FAC_PROV, 0, 0, NULL); if (rv != 0) { topo_mod_dprintf(mod, "%s: %s failed: %s\n", _ENUM_NAME, _FAC_PROV, topo_mod_errmsg(mod)); return (-1); } /* invoke fac_prov_ipmi_enum method */ if (topo_method_supported(*t_node, TOPO_METH_FAC_ENUM, 0)) { if (topo_method_invoke(*t_node, TOPO_METH_FAC_ENUM, 0, NULL, &out, &err) != 0) { /* log the error and drive on */ topo_mod_dprintf(mod, "%s: TOPO_METH_FAC_ENUM failed\n", _ENUM_NAME); } else { fac_done = 1; } } topo_mod_dprintf(mod, "%s added (%s) node\n", _ENUM_NAME, topo_node_name(*t_node)); return (0); }
static int disk_add_temp_sensor(topo_mod_t *mod, tnode_t *pnode, const char *devid) { tnode_t *fnode; topo_pgroup_info_t pgi; nvlist_t *arg_nvl = NULL; int err; if ((fnode = topo_node_facbind(mod, pnode, "temp", TOPO_FAC_TYPE_SENSOR)) == NULL) { topo_mod_dprintf(mod, "failed to bind facility node"); /* errno set */ return (-1); } /* * Set props: * - facility/sensor-class * - facility/sensor-type * - facility/units */ pgi.tpi_name = TOPO_PGROUP_FACILITY; pgi.tpi_namestab = TOPO_STABILITY_PRIVATE; pgi.tpi_datastab = TOPO_STABILITY_PRIVATE; pgi.tpi_version = 1; if (topo_pgroup_create(fnode, &pgi, &err) != 0) { if (err != ETOPO_PROP_DEFD) { topo_mod_dprintf(mod, "pgroups create failure (%s)\n", topo_strerror(err)); /* errno set */ goto err; } } if (topo_prop_set_string(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_CLASS, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_CLASS_THRESHOLD, &err) != 0 || topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_TYPE_TEMP, &err) != 0 || topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_UNITS_DEGREES_C, &err) != 0) { topo_mod_dprintf(mod, "Failed to set props on facnode (%s)", topo_strerror(err)); /* errno set */ goto err; } /* * Register a property method for facility/reading */ if (topo_method_register(mod, fnode, disk_fac_methods) < 0) { topo_mod_dprintf(mod, "failed to register facility methods"); goto err; } if (topo_mod_nvalloc(mod, &arg_nvl, NV_UNIQUE_NAME) < 0 || nvlist_add_string(arg_nvl, TOPO_IO_DEVID, devid) != 0) { topo_mod_dprintf(mod, "Failed build arg nvlist\n"); (void) topo_mod_seterrno(mod, EMOD_NOMEM); goto err; } if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY, TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, "disk_temp_reading", arg_nvl, &err) != 0) { topo_mod_dprintf(mod, "Failed to register %s propmeth " "on fac node %s (%s)\n", TOPO_SENSOR_READING, topo_node_name(fnode), topo_strerror(err)); /* errno set */ goto err; } nvlist_free(arg_nvl); return (0); err: topo_node_unbind(fnode); nvlist_free(arg_nvl); return (-1); }
/* * For each visited cpu node, call the callback function with its ASRU. */ static int cpu_walker(topo_mod_t *mod, tnode_t *node, void *pdata) { struct cpu_walk_data *swdp = pdata; nvlist_t *asru; int err, rc; /* * Terminate the walk if we reach start-node's sibling */ if (node != swdp->parent && topo_node_parent(node) == topo_node_parent(swdp->parent)) return (TOPO_WALK_TERMINATE); if (strcmp(topo_node_name(node), CPU) != 0 && strcmp(topo_node_name(node), STRAND) != 0) return (TOPO_WALK_NEXT); if (topo_node_asru(node, &asru, NULL, &err) != 0) { swdp->fail++; return (TOPO_WALK_NEXT); } rc = swdp->func(swdp->lhp, asru); /* * The "offline" and "online" counter are only useful for the "status" * callback. */ if (rc == P_OFFLINE || rc == P_FAULTED) { swdp->offline++; err = 0; } else if (rc == P_ONLINE) { swdp->online++; err = 0; } else { swdp->fail++; err = errno; } /* dump out status info if debug is turned on. */ if (getenv("TOPOCHIPDBG") != NULL || getenv("TOPOSUN4VPIDBG") != NULL) { const char *op; char *fmristr = NULL; if (swdp->func == ldom_fmri_retire) op = "retire"; else if (swdp->func == ldom_fmri_unretire) op = "unretire"; else if (swdp->func == ldom_fmri_status) op = "check status"; else op = "unknown op"; (void) topo_mod_nvl2str(mod, asru, &fmristr); topo_mod_dprintf(mod, "%s cpu (%s): rc = %d, err = %s\n", op, fmristr == NULL ? "unknown fmri" : fmristr, rc, strerror(err)); if (fmristr != NULL) topo_mod_strfree(mod, fmristr); } nvlist_free(asru); return (TOPO_WALK_NEXT); }
/*ARGSUSED*/ int parent_is_rc(topo_mod_t *mod, did_t *dp) { return (strcmp(topo_node_name(did_gettnode(dp)), PCIEX_ROOT) == 0); }
/*ARGSUSED*/ static int walk_node(topo_hdl_t *thp, tnode_t *node, void *arg) { int err; nvlist_t *nvl; nvlist_t *rsrc, *out; char *s; if (opt_e && strcmp(opt_s, FM_FMRI_SCHEME_HC) == 0) { print_everstyle(node); return (TOPO_WALK_NEXT); } if (topo_node_resource(node, &rsrc, &err) < 0) { (void) fprintf(stderr, "%s: failed to get resource: " "%s", g_pname, topo_strerror(err)); return (TOPO_WALK_NEXT); } if (topo_fmri_nvl2str(thp, rsrc, &s, &err) < 0) { (void) fprintf(stderr, "%s: failed to convert " "resource to FMRI string: %s", g_pname, topo_strerror(err)); nvlist_free(rsrc); return (TOPO_WALK_NEXT); } if (g_fmri != NULL && fnmatch(g_fmri, s, 0) != 0) { nvlist_free(rsrc); topo_hdl_strfree(thp, s); return (TOPO_WALK_NEXT); } print_node(thp, node, rsrc, s); topo_hdl_strfree(thp, s); nvlist_free(rsrc); if (opt_m != NULL) { if (topo_method_invoke(node, opt_m, 0, NULL, &out, &err) == 0) { nvlist_print(stdout, out); nvlist_free(out); } else if (err != ETOPO_METHOD_NOTSUP) (void) fprintf(stderr, "%s: method failed unexpectedly " "on %s=%d (%s)\n", g_pname, topo_node_name(node), topo_node_instance(node), topo_strerror(err)); } if (opt_V || opt_all) { if ((nvl = topo_prop_getprops(node, &err)) == NULL) { (void) fprintf(stderr, "%s: failed to get " "properties for %s=%d: %s\n", g_pname, topo_node_name(node), topo_node_instance(node), topo_strerror(err)); } else { print_all_props(thp, node, nvl, ALL); nvlist_free(nvl); } } else if (pcnt > 0) print_props(thp, node); (void) printf("\n"); return (TOPO_WALK_NEXT); }
/* create the disk topo node */ static int disk_tnode_create(topo_mod_t *mod, tnode_t *parent, dev_di_node_t *dnode, const char *name, topo_instance_t i, tnode_t **rval) { int len; nvlist_t *fmri; tnode_t *dtn; char *part = NULL; nvlist_t *auth; char *mfg, *model, *firm, *serial; *rval = NULL; if (dnode != NULL) { mfg = topo_mod_clean_str(mod, dnode->ddn_mfg); model = topo_mod_clean_str(mod, dnode->ddn_model); firm = topo_mod_clean_str(mod, dnode->ddn_firm); serial = topo_mod_clean_str(mod, dnode->ddn_serial); } else { mfg = model = firm = serial = NULL; } /* form 'part=' of fmri as "<mfg>-<model>" */ if (mfg != NULL && model != NULL) { len = strlen(mfg) + 1 + strlen(model) + 1; if ((part = topo_mod_alloc(mod, len)) != NULL) (void) snprintf(part, len, "%s-%s", mfg, model); } auth = topo_mod_auth(mod, parent); fmri = topo_mod_hcfmri(mod, parent, FM_HC_SCHEME_VERSION, name, i, NULL, auth, part ? part : model, firm, serial); nvlist_free(auth); topo_mod_strfree(mod, part); topo_mod_strfree(mod, mfg); topo_mod_strfree(mod, model); topo_mod_strfree(mod, firm); topo_mod_strfree(mod, serial); if (fmri == NULL) { topo_mod_dprintf(mod, "disk_tnode_create: " "hcfmri (%s%d/%s%d) error %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); return (-1); } if ((dtn = topo_node_bind(mod, parent, name, i, fmri)) == NULL) { if (topo_mod_errno(mod) == EMOD_NODE_BOUND) { /* * if disk 0 is already there then we're done */ nvlist_free(fmri); return (0); } topo_mod_dprintf(mod, "disk_tnode_create: " "bind (%s%d/%s%d) error %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); nvlist_free(fmri); return (-1); } nvlist_free(fmri); /* add the properties of the disk */ if (disk_set_props(mod, parent, dtn, dnode) != 0) { topo_mod_dprintf(mod, "disk_tnode_create: " "disk_set_props (%s%d/%s%d) error %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); topo_node_unbind(dtn); return (-1); } if (dnode->ddn_devid != NULL && disk_add_temp_sensor(mod, dtn, dnode->ddn_devid) != 0) { topo_mod_dprintf(mod, "disk_tnode_create: failed to create " "temperature sensor node on bay=%d/disk=0", topo_node_instance(parent)); } *rval = dtn; return (0); }
static tnode_t * mb_tnode_create(topo_mod_t *mod, tnode_t *parent, const char *name, topo_instance_t i, void *priv) { nvlist_t *fmri; tnode_t *ntn; char *serial = NULL, *part = NULL; char *psn = NULL, *csn = NULL, *pstr = NULL; nvlist_t *auth = topo_mod_auth(mod, parent); /* * Get Product Serial Number, Chassis ID, MB Serial Number and * Part Number from PRI. */ (void) mb_get_pri_info(mod, &serial, &part, &csn, &psn); if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &pstr) != 0 && csn != NULL) { if (nvlist_add_string(auth, FM_FMRI_AUTH_CHASSIS, csn) != 0) { topo_mod_dprintf(mod, "failed to add chassis to auth"); nvlist_free(auth); return (NULL); } } if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT_SN, &pstr) != 0 && psn != NULL) { if (nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT_SN, psn) != 0) { topo_mod_dprintf(mod, "failed to add product-sn to auth"); nvlist_free(auth); return (NULL); } } fmri = topo_mod_hcfmri(mod, NULL, FM_HC_SCHEME_VERSION, name, i, NULL, auth, part, NULL, serial); topo_mod_strfree(mod, serial); topo_mod_strfree(mod, part); topo_mod_strfree(mod, csn); topo_mod_strfree(mod, psn); if (fmri == NULL) { topo_mod_dprintf(mod, "Unable to make nvlist for %s bind: %s.\n", name, topo_mod_errmsg(mod)); nvlist_free(auth); return (NULL); } ntn = topo_node_bind(mod, parent, name, i, fmri); if (ntn == NULL) { topo_mod_dprintf(mod, "topo_node_bind (%s%d/%s%d) failed: %s\n", topo_node_name(parent), topo_node_instance(parent), name, i, topo_strerror(topo_mod_errno(mod))); nvlist_free(auth); nvlist_free(fmri); return (NULL); } mb_prop_set(ntn, auth); nvlist_free(auth); nvlist_free(fmri); topo_node_setspecific(ntn, priv); return (ntn); }
/* 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); }
/*ARGSUSED*/ int topo_method_sensor_failure(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { const char *name = topo_node_name(node); topo_faclist_t faclist, *fp; int err; nvlist_t *nvl, *props, *propval, *tmp; int ret = -1; uint32_t type, state, units; nvpair_t *elem; double reading; char *propname; boolean_t has_reading; struct sensor_errinfo seinfo; if (strcmp(name, PSU) != 0 && strcmp(name, FAN) != 0) return (topo_mod_seterrno(mod, ETOPO_METHOD_NOTSUP)); if (topo_node_facility(mod->tm_hdl, node, TOPO_FAC_TYPE_SENSOR, TOPO_FAC_TYPE_ANY, &faclist, &err) != 0) return (topo_mod_seterrno(mod, ETOPO_METHOD_NOTSUP)); if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0) goto error; for (fp = topo_list_next(&faclist.tf_list); fp != NULL; fp = topo_list_next(fp)) { if (topo_prop_getpgrp(fp->tf_node, TOPO_PGROUP_FACILITY, &props, &err) != 0) { nvlist_free(nvl); goto error; } type = state = units = 0; reading = 0; has_reading = B_FALSE; elem = NULL; while ((elem = nvlist_next_nvpair(props, elem)) != NULL) { if (strcmp(nvpair_name(elem), TOPO_PROP_VAL) != 0 || nvpair_type(elem) != DATA_TYPE_NVLIST) continue; (void) nvpair_value_nvlist(elem, &propval); if (nvlist_lookup_string(propval, TOPO_PROP_VAL_NAME, &propname) != 0) continue; if (strcmp(propname, TOPO_FACILITY_TYPE) == 0) { (void) nvlist_lookup_uint32(propval, TOPO_PROP_VAL_VAL, &type); } else if (strcmp(propname, TOPO_SENSOR_STATE) == 0) { (void) nvlist_lookup_uint32(propval, TOPO_PROP_VAL_VAL, &state); } else if (strcmp(propname, TOPO_SENSOR_UNITS) == 0) { (void) nvlist_lookup_uint32(propval, TOPO_PROP_VAL_VAL, &units); } else if (strcmp(propname, TOPO_SENSOR_READING) == 0) { has_reading = B_TRUE; (void) nvlist_lookup_double(propval, TOPO_PROP_VAL_VAL, &reading); } } if (topo_sensor_failed(type, state, &seinfo)) { tmp = NULL; if (topo_mod_nvalloc(mod, &tmp, NV_UNIQUE_NAME) != 0 || nvlist_add_uint32(tmp, TOPO_FACILITY_TYPE, type) != 0 || nvlist_add_uint32(tmp, TOPO_SENSOR_STATE, state) != 0 || nvlist_add_uint32(tmp, TOPO_SENSOR_UNITS, units) != 0 || nvlist_add_boolean_value(tmp, "nonrecov", seinfo.se_nonrecov) != 0 || nvlist_add_boolean_value(tmp, "predictive", seinfo.se_predictive) != 0 || nvlist_add_uint32(tmp, "source", seinfo.se_src) != 0 || (has_reading && nvlist_add_double(tmp, TOPO_SENSOR_READING, reading) != 0) || nvlist_add_nvlist(nvl, topo_node_name(fp->tf_node), tmp) != 0) { nvlist_free(props); nvlist_free(tmp); nvlist_free(nvl); ret = topo_mod_seterrno(mod, ETOPO_METHOD_NOMEM); goto error; } nvlist_free(tmp); } nvlist_free(props); } *out = nvl; ret = 0; error: while ((fp = topo_list_next(&faclist.tf_list)) != NULL) { topo_list_delete(&faclist.tf_list, fp); topo_mod_free(mod, fp, sizeof (topo_faclist_t)); } return (ret); }