Example #1
0
static void
dev_di_node_free(topo_mod_t *mod, dev_di_node_t *dnode)
{
	int i;

	/* free the stuff we point to */
	if (dnode->ddn_devid)
		topo_mod_strfree(mod, dnode->ddn_devid);
	for (i = 0; i < dnode->ddn_ppath_count; i++) {
		/* topo_mod_strfree does NULL checking. */
		topo_mod_strfree(mod, dnode->ddn_ppath[i]);
		topo_mod_strfree(mod, dnode->ddn_target_port[i]);
		topo_mod_strfree(mod, dnode->ddn_attached_port[i]);
		topo_mod_strfree(mod, dnode->ddn_bridge_port[i]);
	}
	topo_mod_free(mod, dnode->ddn_ppath,
	    dnode->ddn_ppath_count * sizeof (char *));
	topo_mod_free(mod, dnode->ddn_target_port,
	    dnode->ddn_ppath_count * sizeof (char *));
	topo_mod_free(mod, dnode->ddn_attached_port,
	    dnode->ddn_ppath_count * sizeof (char *));
	topo_mod_free(mod, dnode->ddn_bridge_port,
	    dnode->ddn_ppath_count * sizeof (char *));
	topo_mod_strfree(mod, dnode->ddn_dpath);
	topo_mod_strfree(mod, dnode->ddn_lpath);

	topo_mod_strfree(mod, dnode->ddn_mfg);
	topo_mod_strfree(mod, dnode->ddn_model);
	topo_mod_strfree(mod, dnode->ddn_serial);
	topo_mod_strfree(mod, dnode->ddn_firm);
	topo_mod_strfree(mod, dnode->ddn_cap);

	/* free self */
	topo_mod_free(mod, dnode, sizeof (dev_di_node_t));
}
Example #2
0
void
topo_tree_destroy(ttree_t *tp)
{
    topo_mod_t *mod;

    if (tp == NULL)
        return;

    mod = tp->tt_mod;
    if (tp->tt_walk != NULL)
        topo_mod_free(mod, tp->tt_walk, sizeof (topo_walk_t));

    if (tp->tt_root != NULL) {
        assert(tp->tt_root->tn_refs == 1);
        topo_node_rele(tp->tt_root);
    }
    /*
     * Deallocate this last, because a pointer alias for tt_scheme
     * (stored in the root node's name field) may be used in
     * topo_node_rele().
     */
    if (tp->tt_scheme != NULL)
        topo_mod_strfree(mod, tp->tt_scheme);

    topo_mod_free(mod, tp, sizeof (ttree_t));
}
Example #3
0
/*
 * dev_for_hostbridge() -- For hostbridges we truncate the devfs path
 * after the first element in the bus address.
 */
static char *
dev_for_hostbridge(topo_mod_t *mp, char *path)
{
	char *lastslash;
	char *newpath;
	char *comma;
	int plen;

	plen = strlen(path) + 1;

	/*
	 * We only care about the last component of the dev path. If
	 * we don't find a slash, something is weird.
	 */
	lastslash = strrchr(path, '/');
	assert(lastslash != NULL);

	/*
	 * Find the comma in the last component component@x,y, and
	 * truncate the comma and any following number.
	 */
	comma = strchr(lastslash, ',');
	assert(comma != NULL);

	*comma = '\0';
	if ((newpath = topo_mod_strdup(mp, path)) == NULL) {
		topo_mod_free(mp, path, plen);
		return (NULL);
	}

	*comma = ',';
	topo_mod_free(mp, path, plen);
	return (newpath);
}
Example #4
0
void
cpu_mdesc_fini(topo_mod_t *mod, md_info_t *chip)
{
	int i;
	md_proc_t *procp;
	md_fru_t *frup;

	if (chip->cpus != NULL)
		topo_mod_free(mod, chip->cpus,
		    chip->ncpus * sizeof (md_cpumap_t));

	if (chip->procs != NULL) {
		procp = chip->procs;
		for (i = 0; i < chip->nprocs; i++) {
			if ((frup = procp->fru) != NULL) {
				topo_mod_strfree(mod, frup->nac);
				topo_mod_strfree(mod, frup->serial);
				topo_mod_strfree(mod, frup->part);
				topo_mod_strfree(mod, frup->dash);
				topo_mod_free(mod, frup, sizeof (md_fru_t));
			}
			procp++;
		}
		topo_mod_free(mod, chip->procs,
		    chip->nprocs * sizeof (md_proc_t));
	}
}
Example #5
0
void
tf_pad_free(topo_mod_t *mp, tf_pad_t *p)
{
	int n;
	if (p == NULL)
		return;
	if (p->tpad_pgs != NULL) {
		for (n = 0; n < p->tpad_pgcnt; n++)
			nvlist_free(p->tpad_pgs[n]);
		topo_mod_free(mp,
		    p->tpad_pgs, p->tpad_pgcnt * sizeof (nvlist_t *));
	}
	tf_rdata_free(mp, p->tpad_child);
	tf_rdata_free(mp, p->tpad_sibs);
	topo_mod_free(mp, p, sizeof (tf_pad_t));
}
Example #6
0
void
topo_method_unregister(topo_mod_t *mod, tnode_t *node, const char *name)
{
	topo_imethod_t *mp;

	topo_node_lock(node);
	for (mp = topo_list_next(&node->tn_methods); mp != NULL;
	    mp = topo_list_next(mp)) {
		if (strcmp(name, mp->tim_name) == 0)
			break;
	}

	if (mp == NULL) {
		topo_node_unlock(node);
		return;
	}

	topo_list_delete(&node->tn_methods, mp);
	topo_node_unlock(node);

	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));
}
Example #7
0
/*ARGSUSED*/
static int
maybe_di_chars_copy(tnode_t *tn, did_t *pd,
    const char *dpnm, const char *tpgrp, const char *tpnm)
{
	topo_mod_t *mp;
	uchar_t *typbuf;
	char *tmpbuf;
	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);

	if ((tmpbuf = topo_mod_alloc(mp, sz + 1)) == NULL)
		return (topo_mod_seterrno(mp, EMOD_NOMEM));

	bcopy(typbuf, tmpbuf, sz);
	tmpbuf[sz] = 0;
	e = topo_prop_set_string(tn,
	    tpgrp, tpnm, TOPO_PROP_IMMUTABLE, tmpbuf, &err);
	topo_mod_free(mp, tmpbuf, sz + 1);
	if (e != 0)
		return (topo_mod_seterrno(mp, err));
	return (0);
}
Example #8
0
void
tf_idata_free(topo_mod_t *mp, tf_idata_t *p)
{
	if (p == NULL)
		return;
	tf_idata_free(mp, p->ti_next);
	tf_pad_free(mp, p->ti_pad);
	topo_mod_free(mp, p, sizeof (tf_idata_t));
}
Example #9
0
static nvlist_t *
amd_lookup_by_mcid(topo_mod_t *mod, topo_instance_t id)
{
	mc_snapshot_info_t mcs;
	void *buf = NULL;
	uint8_t ver;

	nvlist_t *nvl = NULL;
	char path[64];
	int fd, err;

	(void) snprintf(path, sizeof (path), "/dev/mc/mc%d", id);
	fd = open(path, O_RDONLY);

	if (fd == -1) {
		/*
		 * Some v20z and v40z systems may have had the 3rd-party
		 * NWSnps packagae installed which installs a /dev/mc
		 * link.  So try again via /devices.
		 */
		(void) snprintf(path, sizeof (path),
		    "/devices/pci@0,0/pci1022,1102@%x,2:mc-amd",
		    MC_AMD_DEV_OFFSET + id);
		fd = open(path, O_RDONLY);
	}

	if (fd == -1)
		return (NULL);	/* do not whinge */

	if (ioctl(fd, MC_IOC_SNAPSHOT_INFO, &mcs) == -1 ||
	    (buf = topo_mod_alloc(mod, mcs.mcs_size)) == NULL ||
	    ioctl(fd, MC_IOC_SNAPSHOT, buf) == -1) {

		whinge(mod, NULL, "mc failed to snapshot %s: %s\n",
		    path, strerror(errno));

		free(buf);
		(void) close(fd);
		return (NULL);
	}

	(void) close(fd);
	err = nvlist_unpack(buf, mcs.mcs_size, &nvl, 0);
	topo_mod_free(mod, buf, mcs.mcs_size);

	if (nvlist_lookup_uint8(nvl, MC_NVLIST_VERSTR, &ver) != 0) {
		whinge(mod, NULL, "mc nvlist is not versioned\n");
		nvlist_free(nvl);
		return (NULL);
	} else if (ver != MC_NVLIST_VERS1) {
		whinge(mod, NULL, "mc nvlist version mismatch\n");
		nvlist_free(nvl);
		return (NULL);
	}

	return (err ? NULL : nvl);
}
Example #10
0
void
tf_edata_free(topo_mod_t *mp, tf_edata_t *p)
{
	if (p == NULL)
		return;
	if (p->te_name != NULL)
		xmlFree(p->te_name);
	topo_mod_free(mp, p, sizeof (tf_edata_t));
}
Example #11
0
void
tf_info_free(topo_mod_t *mp, tf_info_t *p)
{
	if (p->tf_xdoc != NULL)
		xmlFreeDoc(p->tf_xdoc);
	if (p->tf_scheme != NULL)
		topo_mod_strfree(mp, p->tf_scheme);
	tf_rdata_free(mp, p->tf_rd);
	topo_mod_free(mp, p, sizeof (tf_info_t));
}
Example #12
0
void
topo_node_range_destroy(tnode_t *pnode, const char *name)
{
	int i;
	topo_nodehash_t *nhp;
	topo_mod_t *mod;

	topo_node_lock(pnode);
	for (nhp = topo_list_next(&pnode->tn_children); nhp != NULL;
	    nhp = topo_list_next(nhp)) {
		if (strcmp(nhp->th_name, name) == 0) {
			break;
		}
	}

	if (nhp == NULL) {
		topo_node_unlock(pnode);
		return;
	}

	topo_list_delete(&pnode->tn_children, nhp);
	topo_node_unlock(pnode);

	/*
	 * Should be an empty node range
	 */
	for (i = 0; i < nhp->th_arrlen; i++) {
		topo_node_unbind(nhp->th_nodearr[i]);
	}

	mod = nhp->th_enum;
	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));
	topo_mod_rele(mod);

}
Example #13
0
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));
}
Example #14
0
void
tf_rdata_free(topo_mod_t *mp, tf_rdata_t *p)
{
	if (p == NULL)
		return;
	tf_rdata_free(mp, p->rd_next);
	if (p->rd_name != NULL)
		topo_mod_strfree(mp, p->rd_name);
	tf_edata_free(mp, p->rd_einfo);
	tf_idata_free(mp, p->rd_instances);
	tf_pad_free(mp, p->rd_pad);
	topo_mod_free(mp, p, sizeof (tf_rdata_t));
}
Example #15
0
void
topo_method_unregister_all(topo_mod_t *mod, tnode_t *node)
{
	topo_imethod_t *mp;

	topo_node_lock(node);
	while ((mp = topo_list_next(&node->tn_methods)) != 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);
}
Example #16
0
static topo_mod_t *
hb_enumr_load(topo_mod_t *mp, tnode_t *parent)
{
	topo_mod_t *rp = NULL;
	char *plat, *mach;
	char *hbpath;
	char *rootdir;
	int err;

	plat = mach = NULL;

	if (topo_prop_get_string(parent,
	    TOPO_PGROUP_SYSTEM, TOPO_PROP_PLATFORM, &plat, &err) < 0) {
		(void) topo_mod_seterrno(mp, err);
		return (NULL);
	}
	if (topo_prop_get_string(parent,
	    TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, &mach, &err) < 0) {
		(void) topo_mod_seterrno(mp, err);
		return (NULL);
	}
	hbpath = topo_mod_alloc(mp, PATH_MAX);
	rootdir = topo_mod_rootdir(mp);
	(void) snprintf(hbpath,
	    PATH_MAX, PATH_TO_HB_ENUM, rootdir ? rootdir : "", plat);

	if ((rp = topo_mod_load(mp, hbpath)) == NULL) {
		topo_mod_dprintf(mp,
		    "%s enumerator could not load %s.\n", IOBOARD, hbpath);
		(void) snprintf(hbpath,
		    PATH_MAX, PATH_TO_HB_ENUM, rootdir ? rootdir : "", mach);
		if ((rp = topo_mod_load(mp, hbpath)) == NULL) {
			topo_mod_dprintf(mp,
			    "%s enumerator could not load %s.\n",
			    IOBOARD, hbpath);
		}
	}
	topo_mod_strfree(mp, plat);
	topo_mod_strfree(mp, mach);
	topo_mod_free(mp, hbpath, PATH_MAX);
	return (rp);
}
Example #17
0
static int
rtld_fini(topo_mod_t *mod)
{
	topo_rtld_t *rp = mod->tm_data;

	assert(mod != NULL);

	if (mod->tm_flags & TOPO_MOD_REG) {
		rp->rtld_fini(mod);
		if (mod->tm_flags & TOPO_MOD_REG) {
			topo_mod_unregister(mod);
		}
	}

	if (getenv("TOPONODLCLOSE") == NULL)
		(void) dlclose(rp->rtld_dlp);
	topo_mod_free(mod, rp, sizeof (topo_rtld_t));

	return (0);
}
Example #18
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));
}
Example #19
0
static topo_mod_t *
module_load(topo_mod_t *mp, tnode_t *parent, const char *name)
{
	topo_mod_t *rp = NULL;
	char *plat, *mach;
	char *path;
	char *rootdir;
	int err;

	plat = mach = NULL;

	if (topo_prop_get_string(parent,
	    TOPO_PGROUP_SYSTEM, TOPO_PROP_PLATFORM, &plat, &err) < 0) {
		(void) topo_mod_seterrno(mp, err);
		return (NULL);
	}
	if (topo_prop_get_string(parent,
	    TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, &mach, &err) < 0) {
		(void) topo_mod_seterrno(mp, err);
		return (NULL);
	}
	path = topo_mod_alloc(mp, PATH_MAX);
	rootdir = topo_mod_rootdir(mp);
	(void) snprintf(path, PATH_MAX,
	    PATH_TEMPLATE, rootdir ? rootdir : "", plat, name);

	if ((rp = topo_mod_load(mp, path)) == NULL) {
		topo_mod_dprintf(mp, "Unable to load %s.\n", path);
		(void) snprintf(path, PATH_MAX,
		    PATH_TEMPLATE, rootdir ? rootdir : "", mach, name);
		if ((rp = topo_mod_load(mp, path)) == NULL)
			topo_mod_dprintf(mp, "Unable to load %s.\n", path);
	}
	topo_mod_strfree(mp, plat);
	topo_mod_strfree(mp, mach);
	topo_mod_free(mp, path, PATH_MAX);
	return (rp);
}
Example #20
0
static void
topo_node_destroy(tnode_t *node)
{
	int i;
	tnode_t *pnode = node->tn_parent;
	topo_nodehash_t *nhp;
	topo_mod_t *hmod, *mod = node->tn_enum;

	if (node == NULL)
		return;

	assert(node->tn_refs == 0);

	topo_dprintf(TOPO_DBG_TREE, "destroying node %s=%d\n", node->tn_name,
	    node->tn_instance);
	/*
	 * If not a root node, remove this node from the parent's node hash
	 */

	if (!(node->tn_state & TOPO_NODE_ROOT)) {
		topo_node_lock(pnode);

		nhp = node->tn_phash;
		for (i = 0; i < nhp->th_arrlen; i++) {
			if (node == nhp->th_nodearr[i]) {
				nhp->th_nodearr[i] = NULL;

				/*
				 * Release hold on parent
				 */
				--pnode->tn_refs;
				if (pnode->tn_refs == 0)
					topo_node_destroy(pnode);
			}
		}
		topo_node_unlock(pnode);
	}

	topo_node_unlock(node);

	/*
	 * Allow enumerator to clean-up private data and then release
	 * ref count
	 */
	if (mod->tm_info->tmi_release != NULL)
		mod->tm_info->tmi_release(mod, node);

	topo_method_unregister_all(mod, node);

	/*
	 * Destroy all node hash lists
	 */
	while ((nhp = topo_list_next(&node->tn_children)) != NULL) {
		for (i = 0; i < nhp->th_arrlen; i++) {
			assert(nhp->th_nodearr[i] == NULL);
		}
		hmod = nhp->th_enum;
		topo_mod_strfree(hmod, nhp->th_name);
		topo_mod_free(hmod, nhp->th_nodearr,
		    nhp->th_arrlen * sizeof (tnode_t *));
		topo_list_delete(&node->tn_children, nhp);
		topo_mod_free(hmod, nhp, sizeof (topo_nodehash_t));
		topo_mod_rele(hmod);
	}

	/*
	 * Destroy all property data structures, free the node and release
	 * the module that created it
	 */
	topo_pgroup_destroy_all(node);
	topo_mod_free(mod, node, sizeof (tnode_t));
	topo_mod_rele(mod);
}
Example #21
0
static void
mb_topo_free(void *data, size_t size)
{
	assert(mb_mod_hdl != NULL);
	topo_mod_free(mb_mod_hdl, data, size);
}
Example #22
0
/* ARGSUSED */
int
x86pi_check_comp(topo_mod_t *mod)
{
	int rv;
	int fd;
	int32_t legacy;
	nvlist_t *nvl = NULL;
	fm_ioc_data_t fid;
	char *ibuf = NULL, *obuf = NULL;
	size_t insz = 0, outsz = 0;
	char *f = "x86pi_check_comp";
	smbios_hdl_t *shp;

	shp = topo_mod_smbios(mod);
	if (shp == NULL)
		return (X86PI_NONE);

	/* open /dev/fm */
	fd = open("/dev/fm", O_RDONLY);
	if (fd < 0) {
		topo_mod_dprintf(mod, "%s: failed to open /dev/fm.\n", f);
		return (X86PI_NONE);
	}

	/* set up buffers and ioctl data structure */
	outsz = FM_IOC_MAXBUFSZ;
	obuf = topo_mod_alloc(mod, outsz);
	if (obuf == NULL) {
		perror("umem_alloc");
		return (X86PI_NONE);
	}

	fid.fid_version = 1;
	fid.fid_insz = insz;
	fid.fid_inbuf = ibuf;
	fid.fid_outsz = outsz;
	fid.fid_outbuf = obuf;

	/* send the ioctl to /dev/fm to retrieve legacy variable */
	rv = ioctl(fd, FM_IOC_GENTOPO_LEGACY, &fid);
	if (rv < 0) {
		topo_mod_dprintf(mod, "%s: ioctl to /dev/fm failed", f);
		perror("fm_ioctl");
		(void) close(fd);
		return (X86PI_NONE);
	}
	(void) close(fd);

	(void) nvlist_unpack(fid.fid_outbuf, fid.fid_outsz, &nvl, 0);
	(void) nvlist_lookup_int32(nvl, FM_GENTOPO_LEGACY, &legacy);

	nvlist_free(nvl);
	topo_mod_free(mod, obuf, outsz);

	if (legacy == 1) {
		/* legacy kernel variable set; will do the same */
		return (X86PI_NONE);
	}

	/* legacy kernel variable not set; generic topo enum */
	return (X86PI_FULL);
}
Example #23
0
static int
dev_di_node_add(di_node_t node, char *devid, disk_cbdata_t *cbp)
{
	topo_mod_t	*mod = cbp->dcb_mod;
	dev_di_node_t	*dnode;
	di_path_t	pnode;
	char		*path;
	int		mlen;
	char		*minorpath;
	char		*extn = ":a";
	char		*s;
	int64_t		*nblocksp;
	uint64_t	nblocks;
	int		*dblksizep;
	uint_t		dblksize;
	char		lentry[MAXPATHLEN];
	int		pathcount;
	int		*inq_dtype, itype;
	int		i;

	if (devid) {
		/*
		 * Check for list duplicate using devid search.
		 * Note if there is no devid, then we can end up with duplicates
		 * in the list, but this doesn't do any harm.
		 */
		for (dnode = topo_list_next(cbp->dcb_list);
		    dnode != NULL; dnode = topo_list_next(dnode)) {
			if (dnode->ddn_devid &&
			    devid_str_compare(dnode->ddn_devid, devid) == 0) {
				topo_mod_dprintf(mod, "dev_di_node_add: "
				    "already there %s\n", devid);
				return (0);
			}
		}
	}

	if ((dnode = topo_mod_zalloc(mod, sizeof (dev_di_node_t))) == NULL)
		return (-1);

	if (devid) {
		/* Establish the devid. */
		dnode->ddn_devid = topo_mod_strdup(mod, devid);
		if (dnode->ddn_devid == NULL)
			goto error;
	}

	/* Establish the devinfo dpath */
	if ((path = di_devfs_path(node)) == NULL) {
		(void) topo_mod_seterrno(mod, errno);
		goto error;
	}

	dnode->ddn_dpath = topo_mod_strdup(mod, path);
	di_devfs_path_free(path);
	if (dnode->ddn_dpath == NULL)
		goto error;

	/*
	 * Establish the physical ppath and target ports. If the device is
	 * non-mpxio then dpath and ppath are the same, and the target port is a
	 * property of the device node.
	 *
	 * If dpath is a client node under scsi_vhci, then iterate over all
	 * paths and get their physical paths and target port properrties.
	 * di_path_client_next_path call below will
	 * return non-NULL, and ppath is set to the physical path to the first
	 * pathinfo node.
	 *
	 * NOTE: It is possible to get a generic.vs.non-generic path
	 * for di_devfs_path.vs.di_path_devfs_path like:
	 *    xml: /pci@7b,0/pci1022,7458@11/pci1000,3060@2/sd@2,0
	 *  pnode: /pci@7b,0/pci1022,7458@11/pci1000,3060@2/disk@2,0
	 * To resolve this issue disk_declare_path() needs to use the
	 * special di_devfs_path_match() interface.
	 */
	pathcount = 0;
	pnode = NULL;
	while ((pnode = di_path_client_next_path(node, pnode)) != NULL) {
		pathcount++;
	}

	if (pathcount == 0) {
		if ((dnode->ddn_ppath =
		    topo_mod_zalloc(mod, sizeof (char *))) == NULL)
			goto error;

		dnode->ddn_ppath_count = 1;
		if ((dnode->ddn_ppath[0] = topo_mod_strdup(mod,
		    dnode->ddn_dpath)) == NULL)
			goto error;

		if ((dnode->ddn_target_port = topo_mod_zalloc(mod,
		    sizeof (char *))) == NULL)
			goto error;

		if ((dnode->ddn_attached_port = topo_mod_zalloc(mod,
		    sizeof (char *))) == NULL)
			goto error;

		if ((dnode->ddn_bridge_port = topo_mod_zalloc(mod,
		    sizeof (char *))) == NULL)
			goto error;

		/* There should be only one target port for a devinfo node. */
		if ((di_prop_lookup_strings(DDI_DEV_T_ANY, node,
		    SCSI_ADDR_PROP_TARGET_PORT, &s)) == 1) {
			if ((dnode->ddn_target_port[0] =
			    topo_mod_strdup(mod,
			    scsi_wwnstr_skip_ua_prefix(s))) ==
			    NULL)
				goto error;
		}

		if ((di_prop_lookup_strings(DDI_DEV_T_ANY, node,
		    SCSI_ADDR_PROP_ATTACHED_PORT, &s)) == 1) {
			/* There should be one attached port if any. */
			if ((dnode->ddn_attached_port[0] =
			    topo_mod_strdup(mod,
			    scsi_wwnstr_skip_ua_prefix(s))) ==
			    NULL)
				goto error;
		}

		if ((di_prop_lookup_strings(DDI_DEV_T_ANY, node,
		    SCSI_ADDR_PROP_BRIDGE_PORT, &s)) == 1) {
			/* There should be one bridge port if any. */
			if ((dnode->ddn_bridge_port[0] =
			    topo_mod_strdup(mod,
			    scsi_wwnstr_skip_ua_prefix(s))) ==
			    NULL)
				goto error;
		}

	} else {
		/* processing a scsi_vhci device. */
		if ((dnode->ddn_ppath = topo_mod_zalloc(mod,
		    pathcount * sizeof (char *))) == NULL)
			goto error;

		dnode->ddn_ppath_count = pathcount;

		if ((dnode->ddn_target_port = topo_mod_zalloc(mod,
		    pathcount * sizeof (char *))) == NULL)
			goto error;

		if ((dnode->ddn_attached_port = topo_mod_zalloc(mod,
		    pathcount * sizeof (char *))) == NULL)
			goto error;

		if ((dnode->ddn_bridge_port = topo_mod_zalloc(mod,
		    pathcount * sizeof (char *))) == NULL)
			goto error;

		pnode = NULL;
		pathcount = 0;
		while ((pnode = di_path_client_next_path(node,
		    pnode)) != NULL) {
			if ((path = di_path_devfs_path(pnode)) == NULL) {
				(void) topo_mod_seterrno(mod, errno);
				goto error;
			}

			dnode->ddn_ppath[pathcount] =
			    topo_mod_strdup(mod, path);
			di_devfs_path_free(path);
			if (dnode->ddn_ppath[pathcount] == NULL)
				goto error;

			if ((di_path_prop_lookup_strings(pnode,
			    SCSI_ADDR_PROP_TARGET_PORT, &s)) == 1) {
				if ((dnode->ddn_target_port[pathcount] =
				    topo_mod_strdup(mod,
				    scsi_wwnstr_skip_ua_prefix(s))) ==
				    NULL)
					goto error;
			}

			if ((di_path_prop_lookup_strings(pnode,
			    SCSI_ADDR_PROP_ATTACHED_PORT, &s)) == 1) {
				if ((dnode->ddn_attached_port[pathcount] =
				    topo_mod_strdup(mod,
				    scsi_wwnstr_skip_ua_prefix(s))) ==
				    NULL)
					goto error;
			}

			if ((di_path_prop_lookup_strings(pnode,
			    SCSI_ADDR_PROP_BRIDGE_PORT, &s)) == 1) {
				if ((dnode->ddn_bridge_port[pathcount] =
				    topo_mod_strdup(mod,
				    scsi_wwnstr_skip_ua_prefix(s))) ==
				    NULL)
					goto error;
			}

			pathcount++;
		}
	}

	/*
	 * Find the public /dev name for a disk by adding a minor name and using
	 * di_devlink interface for reverse translation (use devinfo path).
	 */
	if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "inquiry-device-type",
	    &inq_dtype) > 0) {
		dnode->ddn_dtype = *inq_dtype;
		itype = (*inq_dtype) & DTYPE_MASK;
		if (itype == DTYPE_DIRECT) {
			mlen = strlen(dnode->ddn_dpath) + strlen(extn) + 1;
			if ((minorpath = topo_mod_alloc(mod, mlen)) == NULL)
				goto error;
			(void) snprintf(minorpath, mlen, "%s%s",
			    dnode->ddn_dpath, extn);
			cbp->dcb_dnode = dnode;
			(void) di_devlink_walk(cbp->dcb_devhdl, "^dsk/",
			    minorpath, DI_PRIMARY_LINK, cbp,
			    disk_devlink_callback);
			topo_mod_free(mod, minorpath, mlen);
			if (dnode->ddn_lpath == NULL) {
				topo_mod_dprintf(mod, "dev_di_node_add: "
				    "failed to determine logical path");
			}
		}
	} else {
		dnode->ddn_dtype = DTYPE_UNKNOWN;
	}

	/* cache various bits of optional information about the device. */
	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
	    INQUIRY_VENDOR_ID, &s) > 0) {
		if ((dnode->ddn_mfg = disk_trim_whitespace(mod, s)) == NULL)
			goto error;
	}
	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
	    INQUIRY_PRODUCT_ID, &s) > 0) {
		if ((dnode->ddn_model = disk_trim_whitespace(mod, s)) == NULL)
			goto error;
	}
	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
	    INQUIRY_REVISION_ID, &s) > 0) {
		if ((dnode->ddn_firm = disk_trim_whitespace(mod, s)) == NULL)
			goto error;
	}
	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node,
	    INQUIRY_SERIAL_NO, &s) > 0) {
		if ((dnode->ddn_serial = disk_trim_whitespace(mod, s)) == NULL)
			goto error;
	}
	if (di_prop_lookup_int64(DDI_DEV_T_ANY, node,
	    "device-nblocks", &nblocksp) > 0) {
		nblocks = (uint64_t)*nblocksp;
		/*
		 * To save kernel memory, the driver may not define
		 * "device-dblksize" when its value is default DEV_BSIZE.
		 */
		if (di_prop_lookup_ints(DDI_DEV_T_ANY, node,
		    "device-dblksize", &dblksizep) > 0)
			dblksize = (uint_t)*dblksizep;
		else
			dblksize = DEV_BSIZE;		/* default value */
		(void) snprintf(lentry, sizeof (lentry),
		    "%" PRIu64, nblocks * dblksize);
		if ((dnode->ddn_cap = topo_mod_strdup(mod, lentry)) == NULL)
			goto error;
	}

	topo_mod_dprintf(mod, "dev_di_node_add: "
	    "adding %s\n", devid ? dnode->ddn_devid : "NULL devid");
	topo_mod_dprintf(mod, "                  "
	    "       %s\n", dnode->ddn_dpath);
	for (i = 0; i < dnode->ddn_ppath_count; i++) {
		topo_mod_dprintf(mod, "                  "
		    "       %s\n", dnode->ddn_ppath[i]);
	}
	topo_list_append(cbp->dcb_list, dnode);
	return (0);

error:
	dev_di_node_free(mod, dnode);
	return (-1);
}
Example #24
0
static void
topo_snap_destroy(topo_hdl_t *thp)
{
	int i;
	ttree_t *tp;
	topo_walk_t *twp;
	tnode_t *root;
	topo_nodehash_t *nhp;
	topo_mod_t *mod;

	for (tp = topo_list_next(&thp->th_trees); tp != NULL;
	    tp = topo_list_next(tp)) {

		root = tp->tt_root;
		twp = tp->tt_walk;
		/*
		 * Clean-up tree nodes from the bottom-up
		 */
		if ((twp->tw_node = topo_child_first(root)) != NULL) {
			twp->tw_cb = topo_walk_destroy;
			topo_node_hold(root);
			topo_node_hold(twp->tw_node); /* released at walk end */
			(void) topo_walk_bottomup(twp, TOPO_WALK_CHILD);
			topo_node_rele(root);
		}

		/*
		 * Tidy-up the root node
		 */
		while ((nhp = topo_list_next(&root->tn_children)) != NULL) {
			for (i = 0; i < nhp->th_arrlen; i++) {
				assert(nhp->th_nodearr[i] == NULL);
			}
			mod = nhp->th_enum;
			topo_mod_strfree(mod, nhp->th_name);
			topo_mod_free(mod, nhp->th_nodearr,
			    nhp->th_arrlen * sizeof (tnode_t *));
			topo_list_delete(&root->tn_children, nhp);
			topo_mod_free(mod, nhp, sizeof (topo_nodehash_t));
			topo_mod_rele(mod);
		}

	}

	/*
	 * Clean-up our cached devinfo and prom tree handles.
	 */
	if (thp->th_di != DI_NODE_NIL) {
		di_fini(thp->th_di);
		thp->th_di = DI_NODE_NIL;
	}
	if (thp->th_pi != DI_PROM_HANDLE_NIL) {
		di_prom_fini(thp->th_pi);
		thp->th_pi = DI_PROM_HANDLE_NIL;
	}


	if (thp->th_uuid != NULL) {
		topo_hdl_free(thp, thp->th_uuid, TOPO_UUID_SIZE);
		thp->th_uuid = NULL;
	}
}
Example #25
0
/*
 * Query the current disk status. If successful, the disk status is returned
 * as an nvlist consisting of at least the following members:
 *
 *	protocol	string		Supported protocol (currently "scsi")
 *
 *	status		nvlist		Arbitrary protocol-specific information
 *					about the current state of the disk.
 *
 *	faults		nvlist		A list of supported faults. Each
 *					element of this list is a boolean value.
 *					An element's existence indicates that
 *					the drive supports detecting this fault,
 *					and the value indicates the current
 *					state of the fault.
 *
 *	<fault-name>	nvlist		For each fault named in 'faults', a
 *					nvlist describing protocol-specific
 *					attributes of the fault.
 *
 * This method relies on the libdiskstatus library to query this information.
 */
static int
disk_status(topo_mod_t *mod, tnode_t *nodep, topo_version_t vers,
    nvlist_t *in_nvl, nvlist_t **out_nvl)
{
	disk_status_t	*dsp;
	char		*devpath, *fullpath;
	size_t		pathlen;
	nvlist_t	*status;
	int		err;

	*out_nvl = NULL;

	if (vers != TOPO_METH_DISK_STATUS_VERSION)
		return (topo_mod_seterrno(mod, EMOD_VER_NEW));

	/*
	 * If the caller specifies the "path" parameter, then this indicates
	 * that we should use this instead of deriving it from the topo node
	 * itself.
	 */
	if (nvlist_lookup_string(in_nvl, "path", &fullpath) == 0) {
		devpath = NULL;
	} else {
		/*
		 * Get the /devices path and attempt to open the disk status
		 * handle.
		 */
		if (topo_prop_get_string(nodep, TOPO_PGROUP_IO,
		    TOPO_IO_DEV_PATH, &devpath, &err) != 0)
			return (topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP));

		/*
		 * Note that sizeof(string) includes the terminating NULL byte
		 */
		pathlen = strlen(devpath) + sizeof ("/devices") +
		    sizeof (PHYS_EXTN) - 1;

		if ((fullpath = topo_mod_alloc(mod, pathlen)) == NULL)
			return (topo_mod_seterrno(mod, EMOD_NOMEM));

		(void) snprintf(fullpath, pathlen, "/devices%s%s", devpath,
		    PHYS_EXTN);

		topo_mod_strfree(mod, devpath);
	}

	if ((dsp = disk_status_open(fullpath, &err)) == NULL) {
		if (devpath)
			topo_mod_free(mod, fullpath, pathlen);
		return (topo_mod_seterrno(mod, err == EDS_NOMEM ?
		    EMOD_NOMEM : EMOD_METHOD_NOTSUP));
	}

	if (devpath)
		topo_mod_free(mod, fullpath, pathlen);

	if ((status = disk_status_get(dsp)) == NULL) {
		err = (disk_status_errno(dsp) == EDS_NOMEM ?
		    EMOD_NOMEM : EMOD_METHOD_NOTSUP);
		disk_status_close(dsp);
		return (topo_mod_seterrno(mod, err));
	}

	*out_nvl = status;
	disk_status_close(dsp);
	return (0);
}
Example #26
0
static int
cpu_n1_mdesc_init(topo_mod_t *mod, md_t *mdp, md_info_t *chip)
{
	mde_cookie_t *listp;
	md_cpumap_t *mcmp;
	int i, num_nodes, idx;
	uint64_t x;

	num_nodes = md_node_count(mdp);
	listp = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * num_nodes);

	chip->ncpus = md_scan_dag(mdp,
	    MDE_INVAL_ELEM_COOKIE,
	    md_find_name(mdp, "cpu"),
	    md_find_name(mdp, "fwd"),
	    listp);
	topo_mod_dprintf(mod, "Found %d cpus\n", chip->ncpus);

	chip->cpus = topo_mod_zalloc(mod, chip->ncpus * sizeof (md_cpumap_t));
	chip->nprocs = chip->ncpus;
	chip->procs = topo_mod_zalloc(mod, chip->nprocs * sizeof (md_proc_t));

	for (idx = 0, mcmp = chip->cpus; idx < chip->ncpus; idx++, mcmp++) {

		if (md_get_prop_val(mdp, listp[idx], MD_STR_ID, &x) < 0)
			x = (uint64_t)-1; /* invalid value */
		mcmp->cpumap_id = x;

		if (md_get_prop_val(mdp, listp[idx], MD_STR_PID, &x) < 0)
			x = mcmp->cpumap_id;
		mcmp->cpumap_pid = x;

		mcmp->cpumap_serialno = 0;
		mcmp->cpumap_chipidx = -1;
		if (md_get_prop_val(mdp, listp[idx], MD_STR_CPU_SERIAL,
		    &mcmp->cpumap_serialno) < 0) {
			continue;
		}
		if (mcmp->cpumap_serialno == 0) {
			continue;
		}

		/*
		 * This PRI/MD has no indentity info. of the FRU and no
		 * physical proc id.
		 * Find if there is already an existing processor entry
		 * Assign procid based on the order found during reading
		 */
		for (i = 0; i < chip->nprocs &&
		    chip->procs[i].serialno != 0; i++) {
			if (mcmp->cpumap_serialno == chip->procs[i].serialno) {
				break;
			}
		}
		if (i < chip->nprocs) {
			mcmp->cpumap_chipidx = i;
			if (chip->procs[i].serialno == 0) {
				chip->procs[i].id = i;
				chip->procs[i].serialno = mcmp->cpumap_serialno;
				topo_mod_dprintf(mod,
				    "chip[%d] serial is %llx\n",
				    i, chip->procs[i].serialno);
			}
		}

	}

	topo_mod_free(mod, listp, sizeof (mde_cookie_t) * num_nodes);

	return (0);
}
Example #27
0
/*
 * Request the SAS address of the disk (if any) attached to this mpt_sas
 * instance at (Enclosure Number, Slot Number).  The function returns
 * -1 on error and sets errno to ENOENT _only_ if the /devices node
 * (*devctl) does not exist.
 */
static int
get_sas_address(topo_mod_t *mod, char *devctl, uint32_t enclosure,
    uint32_t slot, char **sas_address)
{
	int ret = -1, en = ENXIO;
	int fd, i;
	mptsas_get_disk_info_t gdi;
	mptsas_disk_info_t *di;
	size_t disz;

	bzero(&gdi, sizeof (gdi));

	if ((fd = open(devctl, O_RDWR)) == -1) {
		en = errno;
		topo_mod_dprintf(mod, "could not open '%s' for ioctl: %s\n",
		    devctl, strerror(errno));
		errno = en;
		return (-1);
	}

	if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {
		if (errno != ENOENT)
			en = errno;
		topo_mod_dprintf(mod, "ioctl 1 on '%s' failed: %s\n", devctl,
		    strerror(errno));
		goto out;
	}

	gdi.DiskInfoArraySize = disz = sizeof (mptsas_disk_info_t) *
	    gdi.DiskCount;
	gdi.PtrDiskInfoArray = di = topo_mod_alloc(mod, disz);
	if (di == NULL) {
		topo_mod_dprintf(mod, "memory allocation failed\n");
		en = ENOMEM;
		goto out;
	}

	if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) {
		if (errno != ENOENT)
			en = errno;
		topo_mod_dprintf(mod, "ioctl 2 on '%s' failed: %s\n", devctl,
		    strerror(errno));
		topo_mod_free(mod, di, disz);
		goto out;
	}

	for (i = 0; i < gdi.DiskCount; i++) {
		if (di[i].Enclosure == enclosure && di[i].Slot == slot) {
			char sas[17]; /* 16 hex digits and NUL */
			(void) snprintf(sas, 17, "%llx", di[i].SasAddress);
			topo_mod_dprintf(mod, "found mpt_sas disk (%d/%d) "
			    "with adddress %s\n", enclosure, slot, sas);
			*sas_address = topo_mod_strdup(mod, sas);
			en = ret = 0;
			break;
		}
	}

	topo_mod_free(mod, di, disz);
out:
	(void) close(fd);
	errno = en;
	return (ret);
}
Example #28
0
static int
cpu_n2_mdesc_init(topo_mod_t *mod, md_t *mdp, md_info_t *chip)
{
	mde_cookie_t *list1p, *list2p;
	md_cpumap_t *mcmp;
	md_proc_t *procp;
	md_fru_t *frup;
	int i, j, cnt;
	int procid_flag = 0;
	int nnode, ncomp, nproc, ncpu;
	char *str = NULL;
	uint64_t x, sn;
	char *strserial, *end;

	nnode = md_node_count(mdp);
	list1p = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * nnode);

	/* Count the number of processors and strands */
	ncomp = md_scan_dag(mdp,
	    MDE_INVAL_ELEM_COOKIE,
	    md_find_name(mdp, MD_STR_COMPONENT),
	    md_find_name(mdp, "fwd"),
	    list1p);
	if (ncomp <= 0) {
		topo_mod_dprintf(mod, "Component nodes not found\n");
		topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode);
		return (-1);
	}
	for (i = 0, nproc = 0, ncpu = 0; i < ncomp; i++) {
		if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) == 0 &&
		    str != NULL && strcmp(str, MD_STR_PROCESSOR) == 0) {
			nproc++;
			/* check if the physical id exists */
			if (md_get_prop_val(mdp, list1p[i], MD_STR_ID, &x)
			    == 0) {
				procid_flag = 1;
			}
		}
		if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) == 0 &&
		    str && strcmp(str, MD_STR_STRAND) == 0) {
			ncpu++;
		}
	}
	topo_mod_dprintf(mod, "Found %d procs and %d strands\n", nproc, ncpu);
	if (nproc == 0 || ncpu == 0) {
		topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode);
		return (-1);
	}

	/* Alloc processors and strand entries */
	list2p = topo_mod_zalloc(mod, sizeof (mde_cookie_t) * 2 * ncpu);
	chip->nprocs = nproc;
	chip->procs = topo_mod_zalloc(mod, nproc * sizeof (md_proc_t));
	chip->ncpus = ncpu;
	chip->cpus = topo_mod_zalloc(mod, ncpu * sizeof (md_cpumap_t));

	/* Visit each processor node */
	procp = chip->procs;
	mcmp = chip->cpus;
	for (i = 0, nproc = 0, ncpu = 0; i < ncomp; i++) {
		if (md_get_prop_str(mdp, list1p[i], MD_STR_TYPE, &str) < 0 ||
		    str == NULL || strcmp(str, MD_STR_PROCESSOR))
			continue;
		if (md_get_prop_val(mdp, list1p[i], MD_STR_SERIAL, &sn) < 0) {
			if (md_get_prop_str(mdp, list1p[i], MD_STR_SERIAL,
			    &strserial) < 0) {
				topo_mod_dprintf(mod,
				    "Failed to get the serial number of"
				    "proc[%d]\n", nproc);
				continue;
			} else {
				sn = (uint64_t)strtoull(strserial, &end, 16);
				if (strserial == end) {
					topo_mod_dprintf(mod,
					    "Failed to convert the serial "
					    "string to serial int of "
					    "proc[%d]\n", nproc);
					continue;
				}
			}
		}
		procp->serialno = sn;

		/* Assign physical proc id */
		procp->id = -1;
		if (procid_flag) {
			if (md_get_prop_val(mdp, list1p[i], MD_STR_ID, &x)
			    == 0) {
				procp->id = x;
			}
		} else {
			procp->id = nproc;
		}
		topo_mod_dprintf(mod, "proc %d: sn=%llx, id=%d\n", nproc,
		    procp->serialno, procp->id);

		/* Get all the strands below this proc */
		cnt = md_scan_dag(mdp,
		    list1p[i],
		    md_find_name(mdp, MD_STR_COMPONENT),
		    md_find_name(mdp, "fwd"),
		    list2p);
		topo_mod_dprintf(mod, "proc[%llx]: Found %d fwd components\n",
		    sn, cnt);
		if (cnt <= 0) {
			nproc++;
			procp++;
			continue;
		}
		for (j = 0; j < cnt; j++) {
			/* Consider only the strand nodes */
			if (md_get_prop_str(mdp, list2p[j], MD_STR_TYPE, &str)
			    < 0 || str == NULL || strcmp(str, MD_STR_STRAND))
				continue;

			if (md_get_prop_val(mdp, list2p[j], MD_STR_ID, &x) < 0)
				x = (uint64_t)-1; /* invalid value */
			mcmp->cpumap_id = x;

			if (md_get_prop_val(mdp, list2p[j], MD_STR_PID, &x) < 0)
				x = mcmp->cpumap_id;
			mcmp->cpumap_pid = x;

			mcmp->cpumap_serialno = sn;
			mcmp->cpumap_chipidx = nproc;
			ncpu++;
			mcmp++;
		}

		/*
		 * To get the fru of this proc, follow the back arc up to
		 * find the first node whose fru field is set
		 */
		cnt = md_scan_dag(mdp,
		    list1p[i],
		    md_find_name(mdp, MD_STR_COMPONENT),
		    md_find_name(mdp, "back"),
		    list2p);
		topo_mod_dprintf(mod, "proc[%d]: Found %d back components\n",
		    nproc, cnt);
		if (cnt <= 0) {
			nproc++;
			procp++;
			continue;
		}
		for (j = 0; j < cnt; j++) {
			/* test the fru field which must be positive number */
			if ((md_get_prop_val(mdp, list2p[j], MD_STR_FRU, &x)
			    == 0) && x > 0)
				break;
		}
		if (j < cnt) {
			/* Found the FRU node, get the fru identity */
			topo_mod_dprintf(mod, "proc[%d] sn=%llx has a fru %d\n",
			    nproc, procp->serialno, j);
			frup = topo_mod_zalloc(mod, sizeof (md_fru_t));
			procp->fru = frup;
			if (!md_get_prop_str(mdp, list2p[j], MD_STR_NAC, &str))
				frup->nac = topo_mod_strdup(mod, str);
			else
				frup->nac = topo_mod_strdup(mod, MD_FRU_DEF);
			if (!md_get_prop_str(mdp, list2p[j], MD_STR_PART, &str))
				frup->part = topo_mod_strdup(mod, str);
			if (!md_get_prop_str(mdp, list2p[j], MD_STR_SERIAL,
			    &str))
				frup->serial = topo_mod_strdup(mod, str);
			if (!md_get_prop_str(mdp, list2p[j], MD_STR_DASH, &str))
				frup->dash = topo_mod_strdup(mod, str);
		} else {
			topo_mod_dprintf(mod, "proc[%d] sn=%llx has no fru\n",
			    i, procp->serialno);
		}

		nproc++;
		procp++;
	} /* for i */

	topo_mod_free(mod, list1p, sizeof (mde_cookie_t) * nnode);
	topo_mod_free(mod, list2p, sizeof (mde_cookie_t) * 2*chip->ncpus);

	return (0);
}
Example #29
0
static void
xaui_topo_free(void *data, size_t size)
{
	assert(xaui_mod_hdl != NULL);
	topo_mod_free(xaui_mod_hdl, data, size);
}
Example #30
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);
}