diff options
Diffstat (limited to 'usr/src/lib')
117 files changed, 5186 insertions, 3774 deletions
diff --git a/usr/src/lib/fm/topo/Makefile b/usr/src/lib/fm/topo/Makefile index 6d0f9d2e68..bf793c50a4 100644 --- a/usr/src/lib/fm/topo/Makefile +++ b/usr/src/lib/fm/topo/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -25,6 +24,6 @@ # #ident "%Z%%M% %I% %E% SMI" -SUBDIRS = libtopo modules files +SUBDIRS = libtopo modules maps include ../Makefile.subdirs diff --git a/usr/src/lib/fm/topo/Makefile.rootdirs b/usr/src/lib/fm/topo/Makefile.rootdirs index 6cb20f44ba..d8929d301a 100644 --- a/usr/src/lib/fm/topo/Makefile.rootdirs +++ b/usr/src/lib/fm/topo/Makefile.rootdirs @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -35,7 +34,7 @@ $(ROOT)/usr/lib/fm: $(ROOT)/usr/lib/fm/topo: $(ROOT)/usr/lib/fm $(INS.dir) -$(ROOT)/usr/lib/fm/topo/%: $(ROOT)/usr/lib/fm/topo +$(ROOT)/usr/lib/fm/topo/$(MODCLASS): $(ROOT)/usr/lib/fm/topo $(INS.dir) # @@ -50,13 +49,3 @@ $(ROOT)/usr/platform/%/lib/fm/topo: $(ROOT)/usr/platform/%/lib/fm $(ROOT)/usr/platform/%/lib/fm/topo/$(MODCLASS): $(ROOT)/usr/platform/%/lib/fm/topo $(INS.dir) - -# -# Define the transitive set of rules to create platform.xml install directories -# within the proto area. This is used by all Makefile.xml files -# -$(ROOT)/usr/platform/%/lib/fm: - $(INS.dir) - -$(ROOT)/usr/platform/%/lib/fm/topo: $(ROOT)/usr/platform/%/lib/fm - $(INS.dir) diff --git a/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile b/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile deleted file mode 100644 index 8ca6b9208b..0000000000 --- a/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" - -PLATFORMS = SUNW,Sun-Blade-T6300 -CLASS = platform -DTDFILE = -TOPOFILE = hc-topology.xml -SRCDIR = ../SUNW,Sun-Blade-T6300 - -include ../Makefile.file diff --git a/usr/src/lib/fm/topo/files/i86pc/Makefile b/usr/src/lib/fm/topo/files/i86pc/Makefile deleted file mode 100644 index fe24fb86ac..0000000000 --- a/usr/src/lib/fm/topo/files/i86pc/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" - -ARCH = i86pc -CLASS = arch -DTDFILE = topology.dtd.1 -TOPOFILE = hc-topology.xml -SRCDIR = ../i86pc - -include ../Makefile.file diff --git a/usr/src/lib/fm/topo/libtopo/Makefile b/usr/src/lib/fm/topo/libtopo/Makefile index 02d911d5cb..62a1e04906 100644 --- a/usr/src/lib/fm/topo/libtopo/Makefile +++ b/usr/src/lib/fm/topo/libtopo/Makefile @@ -28,7 +28,7 @@ include ../../../Makefile.lib include ../../Makefile.lib -FMHDRS = libtopo.h topo_mod.h +FMHDRS = libtopo.h topo_mod.h topo_hc.h HDRDIR = common SUBDIRS = $(MACH) diff --git a/usr/src/lib/fm/topo/libtopo/Makefile.com b/usr/src/lib/fm/topo/libtopo/Makefile.com index 5b43c663de..b4c89f2556 100644 --- a/usr/src/lib/fm/topo/libtopo/Makefile.com +++ b/usr/src/lib/fm/topo/libtopo/Makefile.com @@ -37,6 +37,7 @@ BUILTINSRCS = \ pkg.c LIBSRCS = \ + topo_2xml.c \ topo_alloc.c \ topo_builtin.c \ topo_error.c \ @@ -78,7 +79,8 @@ CFLAGS64 += $(CCVERBOSE) $(C_BIGPICFLAGS) LINTFLAGS = -msux LINTFLAGS64 = -msux -Xarch=$(MACH64:sparcv9=v9) -$(DYNLIB) := LDLIBS += -lnvpair -lelf -lumem -lxml2 -lkstat -luuid -lc +$(DYNLIB) := LDLIBS += \ + -lnvpair -lelf -lumem -lxml2 -lkstat -luuid -ldevinfo -lsmbios -lc $(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) $(LINTLIB) := LINTFLAGS = -nsvx @@ -100,8 +102,9 @@ pics/%.o: ../$(MACH)/%.c $(POST_PROCESS_O) ../common/topo_error.c: ../common/mkerror.sh ../common/topo_error.h - sh ../common/mkerror.sh internal < ../common/topo_error.h > $@ - sh ../common/mkerror.sh external < ../common/topo_mod.h >> $@ + sh ../common/mkerror.sh liberrors < ../common/topo_error.h > $@ + sh ../common/mkerror.sh properrors < ../common/libtopo.h >> $@ + sh ../common/mkerror.sh moderrors < ../common/topo_mod.h >> $@ include ../../../../Makefile.targ include ../../../Makefile.targ diff --git a/usr/src/lib/fm/topo/libtopo/common/cpu.c b/usr/src/lib/fm/topo/libtopo/common/cpu.c index 0e8d5e9f3a..db5a1e2011 100644 --- a/usr/src/lib/fm/topo/libtopo/common/cpu.c +++ b/usr/src/lib/fm/topo/libtopo/common/cpu.c @@ -27,80 +27,65 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <errno.h> -#include <kstat.h> #include <limits.h> #include <strings.h> #include <unistd.h> #include <fm/topo_mod.h> #include <sys/fm/protocol.h> -#include <topo_error.h> - -typedef struct cpu_node { - kstat_ctl_t *cn_kc; - kstat_t **cn_cpustats; - uint_t cn_ncpustats; -} cpu_node_t; +#include <topo_method.h> +#include <cpu.h> static int cpu_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); static void cpu_release(topo_mod_t *, tnode_t *); static int cpu_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); static int cpu_str2nvl(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); -static int cpu_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int cpu_unusable(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int cpu_contains(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int cpu_expand(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); static int cpu_fmri_asru(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); static nvlist_t *fmri_create(topo_mod_t *, uint32_t, uint8_t, char *); -#define CPU_VERSION TOPO_VERSION - static const topo_method_t cpu_methods[] = { { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, TOPO_STABILITY_INTERNAL, cpu_nvl2str }, { TOPO_METH_STR2NVL, TOPO_METH_STR2NVL_DESC, TOPO_METH_STR2NVL_VERSION, TOPO_STABILITY_INTERNAL, cpu_str2nvl }, - { TOPO_METH_PRESENT, TOPO_METH_PRESENT_DESC, TOPO_METH_PRESENT_VERSION, - TOPO_STABILITY_INTERNAL, cpu_present }, - { TOPO_METH_CONTAINS, TOPO_METH_CONTAINS_DESC, - TOPO_METH_CONTAINS_VERSION, TOPO_STABILITY_INTERNAL, cpu_contains }, - { TOPO_METH_UNUSABLE, TOPO_METH_UNUSABLE_DESC, - TOPO_METH_UNUSABLE_VERSION, TOPO_STABILITY_INTERNAL, cpu_unusable }, - { TOPO_METH_EXPAND, TOPO_METH_EXPAND_DESC, - TOPO_METH_EXPAND_VERSION, TOPO_STABILITY_INTERNAL, cpu_expand }, { TOPO_METH_ASRU_COMPUTE, TOPO_METH_ASRU_COMPUTE_DESC, TOPO_METH_ASRU_COMPUTE_VERSION, TOPO_STABILITY_INTERNAL, cpu_fmri_asru }, + { TOPO_METH_FMRI, TOPO_METH_FMRI_DESC, TOPO_METH_FMRI_VERSION, + TOPO_STABILITY_INTERNAL, cpu_fmri_asru }, { NULL } }; +static const topo_modops_t cpu_ops = + { cpu_enum, cpu_release }; + static const topo_modinfo_t cpu_info = - { "cpu", CPU_VERSION, cpu_enum, cpu_release }; + { "cpu", FM_FMRI_SCHEME_CPU, CPU_VERSION, &cpu_ops }; -void -cpu_init(topo_mod_t *mod) +int +cpu_init(topo_mod_t *mod, topo_version_t version) { cpu_node_t *cpuip; - topo_mod_setdebug(mod, TOPO_DBG_ALL); + if (getenv("TOPOCPUDEBUG")) + topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing cpu builtin\n"); + if (version != CPU_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + if ((cpuip = topo_mod_zalloc(mod, sizeof (cpu_node_t))) == NULL) - return; + return (topo_mod_seterrno(mod, EMOD_NOMEM)); if ((cpuip->cn_kc = kstat_open()) == NULL) { topo_mod_dprintf(mod, "kstat_open failed: %s\n", strerror(errno)); topo_mod_free(mod, cpuip, sizeof (cpu_node_t)); - return; + return (-1); } cpuip->cn_ncpustats = sysconf(_SC_CPUID_MAX); @@ -108,18 +93,22 @@ cpu_init(topo_mod_t *mod) cpuip->cn_ncpustats + 1) * sizeof (kstat_t *))) == NULL) { (void) kstat_close(cpuip->cn_kc); topo_mod_free(mod, cpuip, sizeof (cpu_node_t)); - return; + return (-1); } - if (topo_mod_register(mod, &cpu_info, (void *)cpuip) != 0) { + if (topo_mod_register(mod, &cpu_info, TOPO_VERSION) != 0) { topo_mod_dprintf(mod, "failed to register cpu_info: " "%s\n", topo_mod_errmsg(mod)); topo_mod_free(mod, cpuip->cn_cpustats, (cpuip->cn_ncpustats + 1) * sizeof (kstat_t *)); (void) kstat_close(cpuip->cn_kc); topo_mod_free(mod, cpuip, sizeof (cpu_node_t)); - return; + return (-1); } + + topo_mod_setspecific(mod, (void *)cpuip); + + return (0); } void @@ -127,7 +116,7 @@ cpu_fini(topo_mod_t *mod) { cpu_node_t *cpuip; - cpuip = topo_mod_private(mod); + cpuip = topo_mod_getspecific(mod); if (cpuip->cn_cpustats != NULL) topo_mod_free(mod, cpuip->cn_cpustats, @@ -183,7 +172,7 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, if ((fmri = fmri_create(mod, cpu_id, 0, s)) == NULL) continue; - (void) topo_node_bind(mod, rnode, name, cpu_id, fmri, NULL); + (void) topo_node_bind(mod, rnode, name, cpu_id, fmri); nvlist_free(fmri); } @@ -194,7 +183,7 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, /*ARGSUSED*/ static int cpu_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t min, topo_instance_t max, void *arg) + topo_instance_t min, topo_instance_t max, void *arg, void *notused2) { cpu_node_t *cpuip = (cpu_node_t *)arg; @@ -349,38 +338,6 @@ cpu_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, return (0); } -/*ARGSUSED*/ -static int -cpu_present(topo_mod_t *mod, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP)); -} - -/*ARGSUSED*/ -static int -cpu_contains(topo_mod_t *mod, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP)); -} - -/*ARGSUSED*/ -static int -cpu_unusable(topo_mod_t *mod, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP)); -} - -/*ARGSUSED*/ -static int -cpu_expand(topo_mod_t *mod, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mod, EMOD_METHOD_NOTSUP)); -} - static nvlist_t * fmri_create(topo_mod_t *mod, uint32_t cpu_id, uint8_t cpumask, char *s) { diff --git a/usr/src/lib/fm/topo/libtopo/common/cpu.h b/usr/src/lib/fm/topo/libtopo/common/cpu.h new file mode 100644 index 0000000000..d184b52fe5 --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/cpu.h @@ -0,0 +1,53 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _CPU_H +#define _CPU_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <kstat.h> + +#define CPU_VERSION 1 + +typedef struct cpu_node { + kstat_ctl_t *cn_kc; + kstat_t **cn_cpustats; + uint_t cn_ncpustats; +} cpu_node_t; + +extern int cpu_init(topo_mod_t *, topo_version_t); /* see cpu.c */ +extern void cpu_fini(topo_mod_t *); /* see cpu.c */ + +#ifdef __cplusplus +} +#endif + +#endif /* _CPU_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/dev.c b/usr/src/lib/fm/topo/libtopo/common/dev.c index c79bc6af34..18defd40d3 100644 --- a/usr/src/lib/fm/topo/libtopo/common/dev.c +++ b/usr/src/lib/fm/topo/libtopo/common/dev.c @@ -36,11 +36,12 @@ #include <fm/topo_mod.h> #include <sys/fm/protocol.h> +#include <topo_method.h> #include <topo_subr.h> -#include <topo_error.h> +#include <dev.h> static int dev_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); static void dev_release(topo_mod_t *, tnode_t *); static int dev_fmri_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); @@ -49,8 +50,6 @@ static int dev_fmri_str2nvl(topo_mod_t *, tnode_t *, topo_version_t, static int dev_fmri_create_meth(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); -#define DEV_VERSION TOPO_VERSION - static const topo_method_t dev_methods[] = { { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, TOPO_STABILITY_INTERNAL, dev_fmri_nvl2str }, @@ -61,20 +60,28 @@ static const topo_method_t dev_methods[] = { { NULL } }; +static const topo_modops_t dev_ops = + { dev_enum, dev_release }; static const topo_modinfo_t dev_info = - { "dev", DEV_VERSION, dev_enum, dev_release }; + { "dev", FM_FMRI_SCHEME_DEV, DEV_VERSION, &dev_ops }; -void -dev_init(topo_mod_t *mod) +int +dev_init(topo_mod_t *mod, topo_version_t version) { - topo_mod_setdebug(mod, TOPO_DBG_ALL); + if (getenv("TOPOHCDEBUG")) + topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing dev builtin\n"); - if (topo_mod_register(mod, &dev_info, NULL) != 0) { + if (version != DEV_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_mod_register(mod, &dev_info, TOPO_VERSION) != 0) { topo_mod_dprintf(mod, "failed to register dev_info: " "%s\n", topo_mod_errmsg(mod)); - return; + return (-1); } + + return (0); } void @@ -86,7 +93,7 @@ dev_fini(topo_mod_t *mod) /*ARGSUSED*/ static int dev_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t min, topo_instance_t max, void *arg) + topo_instance_t min, topo_instance_t max, void *notused1, void *notused2) { (void) topo_method_register(mod, pnode, dev_methods); return (0); diff --git a/usr/src/lib/fm/topo/libtopo/common/dev.h b/usr/src/lib/fm/topo/libtopo/common/dev.h new file mode 100644 index 0000000000..219d3e2737 --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/dev.h @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _DEV_H +#define _DEV_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEV_VERSION 1 + +extern int dev_init(topo_mod_t *, topo_version_t); /* see dev.c */ +extern void dev_fini(topo_mod_t *); /* see dev.c */ + +#ifdef __cplusplus +} +#endif + +#endif /* _DEV_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/hc.c b/usr/src/lib/fm/topo/libtopo/common/hc.c index b94e02699e..9719af0684 100644 --- a/usr/src/lib/fm/topo/libtopo/common/hc.c +++ b/usr/src/lib/fm/topo/libtopo/common/hc.c @@ -35,26 +35,21 @@ #include <alloca.h> #include <limits.h> #include <fm/topo_mod.h> +#include <fm/topo_hc.h> #include <sys/param.h> #include <sys/systeminfo.h> #include <sys/fm/protocol.h> -#include <topo_parse.h> -#include <topo_subr.h> - -#include <hc_canon.h> +#include <sys/stat.h> +#include <sys/systeminfo.h> +#include <sys/utsname.h> -#define HC "hc" -#define HC_VERSION TOPO_VERSION +#include <topo_method.h> +#include <topo_subr.h> +#include <hc.h> static int hc_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); static void hc_release(topo_mod_t *, tnode_t *); -static int hc_contains(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int hc_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int hc_unusable(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); static int hc_fmri_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); static int hc_fmri_str2nvl(topo_mod_t *, tnode_t *, topo_version_t, @@ -69,12 +64,6 @@ static nvlist_t *hc_fmri_create(topo_mod_t *, nvlist_t *, int, const char *, const char *); const topo_method_t hc_methods[] = { - { "hc_contains", "Hardware Component Contains", HC_VERSION, - TOPO_STABILITY_INTERNAL, hc_contains }, - { "hc_present", "Hardware Component Present", HC_VERSION, - TOPO_STABILITY_INTERNAL, hc_present }, - { "hc_unusable", "Hardware Component Unusable", HC_VERSION, - TOPO_STABILITY_INTERNAL, hc_unusable }, { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, TOPO_STABILITY_INTERNAL, hc_fmri_nvl2str }, { TOPO_METH_STR2NVL, TOPO_METH_STR2NVL_DESC, TOPO_METH_STR2NVL_VERSION, @@ -86,67 +75,187 @@ const topo_method_t hc_methods[] = { { NULL } }; -const topo_modinfo_t hc_info = - { HC, HC_VERSION, hc_enum, hc_release }; +static const topo_modops_t hc_ops = + { hc_enum, hc_release }; +static const topo_modinfo_t hc_info = + { HC, FM_FMRI_SCHEME_HC, HC_VERSION, &hc_ops }; + +static const hcc_t hc_canon[] = { + { CMP, TOPO_STABILITY_PRIVATE }, + { CENTERPLANE, TOPO_STABILITY_PRIVATE }, + { CHASSIS, TOPO_STABILITY_PRIVATE }, + { CHIP, TOPO_STABILITY_PRIVATE }, + { CHIP_SELECT, TOPO_STABILITY_PRIVATE }, + { CPU, TOPO_STABILITY_PRIVATE }, + { DIMM, TOPO_STABILITY_PRIVATE }, + { DISK, TOPO_STABILITY_PRIVATE }, + { DRAMCHANNEL, TOPO_STABILITY_PRIVATE }, + { HOSTBRIDGE, TOPO_STABILITY_PRIVATE }, + { INTERCONNECT, TOPO_STABILITY_PRIVATE }, + { IOBOARD, TOPO_STABILITY_PRIVATE }, + { MEMORYCONTROL, TOPO_STABILITY_PRIVATE }, + { MOTHERBOARD, TOPO_STABILITY_PRIVATE }, + { PCI_BUS, TOPO_STABILITY_PRIVATE }, + { PCI_DEVICE, TOPO_STABILITY_PRIVATE }, + { PCI_FUNCTION, TOPO_STABILITY_PRIVATE }, + { PCIEX_BUS, TOPO_STABILITY_PRIVATE }, + { PCIEX_DEVICE, TOPO_STABILITY_PRIVATE }, + { PCIEX_FUNCTION, TOPO_STABILITY_PRIVATE }, + { PCIEX_ROOT, TOPO_STABILITY_PRIVATE }, + { PCIEX_SWUP, TOPO_STABILITY_PRIVATE }, + { PCIEX_SWDWN, TOPO_STABILITY_PRIVATE }, + { RANK, TOPO_STABILITY_PRIVATE }, + { SATA_PORT, TOPO_STABILITY_PRIVATE }, + { SYSTEMBOARD, TOPO_STABILITY_PRIVATE } +}; + +static int hc_ncanon = sizeof (hc_canon) / sizeof (hcc_t); -void -hc_init(topo_mod_t *mp) +int +hc_init(topo_mod_t *mod, topo_version_t version) { /* * Turn on module debugging output */ - topo_mod_setdebug(mp, TOPO_DBG_ALL); - topo_mod_dprintf(mp, "initializing hc builtin\n"); + if (getenv("TOPOHCDEBUG")) + topo_mod_setdebug(mod); + + topo_mod_dprintf(mod, "initializing hc builtin\n"); - if (topo_mod_register(mp, &hc_info, NULL) != 0) { - topo_mod_dprintf(mp, "failed to register hc: " - "%s\n", topo_mod_errmsg(mp)); + if (version != HC_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_mod_register(mod, &hc_info, TOPO_VERSION) != 0) { + topo_mod_dprintf(mod, "failed to register hc: " + "%s\n", topo_mod_errmsg(mod)); + return (-1); /* mod errno already set */ } + + return (0); } void -hc_fini(topo_mod_t *mp) +hc_fini(topo_mod_t *mod) { - topo_mod_unregister(mp); + topo_mod_unregister(mod); +} + + +static const topo_pgroup_info_t sys_pgroup = { + TOPO_PGROUP_SYSTEM, + TOPO_STABILITY_PRIVATE, + TOPO_STABILITY_PRIVATE, + 1 +}; + +static const topo_pgroup_info_t auth_pgroup = { + FM_FMRI_AUTHORITY, + TOPO_STABILITY_PRIVATE, + TOPO_STABILITY_PRIVATE, + 1 +}; + +static void +hc_prop_set(tnode_t *node, nvlist_t *auth) +{ + int err; + char isa[MAXNAMELEN]; + struct utsname uts; + char *prod, *csn, *server; + + if (topo_pgroup_create(node, &auth_pgroup, &err) != 0) { + if (err != ETOPO_PROP_DEFD) + return; + } + + /* + * Inherit if we can, it saves memory + */ + if (topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, + &err) != 0) { + if (nvlist_lookup_string(auth, FM_FMRI_AUTH_PRODUCT, &prod) + == 0) + (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_PRODUCT, TOPO_PROP_IMMUTABLE, prod, + &err); + } + if (topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_CHASSIS, + &err) != 0) { + if (nvlist_lookup_string(auth, FM_FMRI_AUTH_CHASSIS, &csn) == 0) + (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_CHASSIS, TOPO_PROP_IMMUTABLE, csn, + &err); + } + if (topo_prop_inherit(node, FM_FMRI_AUTHORITY, FM_FMRI_AUTH_SERVER, + &err) != 0) { + if (nvlist_lookup_string(auth, FM_FMRI_AUTH_SERVER, &server) + == 0) + (void) topo_prop_set_string(node, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_SERVER, TOPO_PROP_IMMUTABLE, server, + &err); + } + + if (topo_pgroup_create(node, &sys_pgroup, &err) != 0) + return; + + isa[0] = '\0'; + (void) sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)); + (void) uname(&uts); + (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_ISA, + TOPO_PROP_IMMUTABLE, isa, &err); + (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, TOPO_PROP_MACHINE, + TOPO_PROP_IMMUTABLE, uts.machine, &err); } /*ARGSUSED*/ int -hc_enum(topo_mod_t *mp, tnode_t *pnode, const char *name, topo_instance_t min, - topo_instance_t max, void *notused) +hc_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min, + topo_instance_t max, void *notused1, void *arg) { nvlist_t *pfmri = NULL; nvlist_t *nvl; + nvlist_t *auth; + tnode_t *node; int err; /* * Register root node methods */ if (strcmp(name, HC) == 0) { - (void) topo_method_register(mp, pnode, hc_methods); + (void) topo_method_register(mod, pnode, hc_methods); return (0); } if (min != max) { - topo_mod_dprintf(mp, + topo_mod_dprintf(mod, "Request to enumerate %s component with an " "ambiguous instance number, min (%d) != max (%d).\n", HC, min, max); - return (topo_mod_seterrno(mp, EINVAL)); + return (topo_mod_seterrno(mod, EINVAL)); } (void) topo_node_resource(pnode, &pfmri, &err); - nvl = hc_fmri_create(mp, pfmri, FM_HC_SCHEME_VERSION, name, min, - NULL, NULL, NULL, NULL); + if (arg == NULL) + auth = topo_mod_auth(mod, pnode); + nvl = hc_fmri_create(mod, pfmri, FM_HC_SCHEME_VERSION, name, min, + auth, NULL, NULL, NULL); nvlist_free(pfmri); /* callee ignores NULLs */ - if (nvl == NULL) + if (nvl == NULL) { + nvlist_free(auth); return (-1); + } - if (topo_node_bind(mp, pnode, name, min, nvl, NULL) == NULL) { - topo_mod_dprintf(mp, "topo_node_bind failed: %s\n", - topo_strerror(topo_mod_errno(mp))); + if ((node = topo_node_bind(mod, pnode, name, min, nvl)) == NULL) { + topo_mod_dprintf(mod, "topo_node_bind failed: %s\n", + topo_strerror(topo_mod_errno(mod))); + nvlist_free(auth); nvlist_free(nvl); return (-1); } + + if (arg == NULL) + hc_prop_set(node, auth); nvlist_free(nvl); + nvlist_free(auth); + return (0); } @@ -159,31 +268,7 @@ hc_release(topo_mod_t *mp, tnode_t *node) /*ARGSUSED*/ static int -hc_contains(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mp, EMOD_METHOD_NOTSUP)); -} - -/*ARGSUSED*/ -static int -hc_present(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mp, EMOD_METHOD_NOTSUP)); -} - -/*ARGSUSED*/ -static int -hc_unusable(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (topo_mod_seterrno(mp, EMOD_METHOD_NOTSUP)); -} - -/*ARGSUSED*/ -static int -hc_compare(topo_mod_t *mp, tnode_t *node, topo_version_t version, +hc_compare(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { uint8_t v1, v2; @@ -193,21 +278,21 @@ hc_compare(topo_mod_t *mp, tnode_t *node, topo_version_t version, uint_t nhcp1, nhcp2; if (version > TOPO_METH_COMPARE_VERSION) - return (topo_mod_seterrno(mp, EMOD_VER_NEW)); + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); if (nvlist_lookup_nvlist(in, "nv1", &nv1) != 0 || nvlist_lookup_nvlist(in, "nv2", &nv2) != 0) - return (topo_mod_seterrno(mp, EMOD_METHOD_INVAL)); + return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); if (nvlist_lookup_uint8(nv1, FM_VERSION, &v1) != 0 || nvlist_lookup_uint8(nv2, FM_VERSION, &v2) != 0 || v1 > FM_HC_SCHEME_VERSION || v2 > FM_HC_SCHEME_VERSION) - return (topo_mod_seterrno(mp, EMOD_FMRI_VERSION)); + return (topo_mod_seterrno(mod, EMOD_FMRI_VERSION)); err = nvlist_lookup_nvlist_array(nv1, FM_FMRI_HC_LIST, &hcp1, &nhcp1); err |= nvlist_lookup_nvlist_array(nv2, FM_FMRI_HC_LIST, &hcp2, &nhcp2); if (err != 0) - return (topo_mod_seterrno(mp, EMOD_FMRI_NVL)); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); if (nhcp1 != nhcp2) return (0); @@ -223,7 +308,7 @@ hc_compare(topo_mod_t *mp, tnode_t *node, topo_version_t version, (void) nvlist_lookup_string(hcp1[i], FM_FMRI_HC_ID, &id1); (void) nvlist_lookup_string(hcp2[i], FM_FMRI_HC_ID, &id2); if (nm1 == NULL || nm2 == NULL || id1 == NULL || id2 == NULL) - return (topo_mod_seterrno(mp, EMOD_FMRI_NVL)); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); if (strcmp(nm1, nm2) == 0 && strcmp(id1, id2) == 0) continue; @@ -303,28 +388,19 @@ fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) /* authority, if any */ if (aprod != NULL) topo_fmristr_build(&size, - buf, buflen, aprod, FM_FMRI_AUTH_PRODUCT "=", - --more_auth > 0 ? "," : NULL); + buf, buflen, aprod, ":" FM_FMRI_AUTH_PRODUCT "=", NULL); if (achas != NULL) topo_fmristr_build(&size, - buf, buflen, achas, FM_FMRI_AUTH_CHASSIS "=", - --more_auth > 0 ? "," : NULL); + buf, buflen, achas, ":" FM_FMRI_AUTH_CHASSIS "=", NULL); if (adom != NULL) topo_fmristr_build(&size, - buf, buflen, adom, FM_FMRI_AUTH_DOMAIN "=", - --more_auth > 0 ? "," : NULL); + buf, buflen, adom, ":" FM_FMRI_AUTH_DOMAIN "=", NULL); if (asrvr != NULL) topo_fmristr_build(&size, - buf, buflen, asrvr, FM_FMRI_AUTH_SERVER "=", - --more_auth > 0 ? "," : NULL); + buf, buflen, asrvr, ":" FM_FMRI_AUTH_SERVER "=", NULL); if (ahost != NULL) topo_fmristr_build(&size, - buf, buflen, ahost, FM_FMRI_AUTH_HOST "=", - NULL); - - /* separating slash */ - if (serial != NULL || part != NULL || rev != NULL) - topo_fmristr_build(&size, buf, buflen, "/", NULL, NULL); + buf, buflen, ahost, ":" FM_FMRI_AUTH_HOST "=", NULL); /* hardware-id part */ topo_fmristr_build(&size, @@ -430,9 +506,10 @@ hc_base_fmri_create(topo_mod_t *mod, const nvlist_t *auth, const char *part, } static nvlist_t ** -make_hc_pairs(topo_mod_t *mod, char *fromstr, int *num) +make_hc_pairs(topo_mod_t *mod, char *fmri, int *num) { nvlist_t **pa; + char *hc, *fromstr; char *starti, *startn, *endi, *endi2; char *ne, *ns; char *cname; @@ -442,12 +519,18 @@ make_hc_pairs(topo_mod_t *mod, char *fromstr, int *num) int npairs = 0; int i, e; + if ((hc = topo_mod_strdup(mod, fmri + 5)) == NULL) + return (NULL); + /* * Count equal signs and slashes to determine how many * hc-pairs will be present in the final FMRI. There should * be at least as many slashes as equal signs. There can be * more, though if the string after an = includes them. */ + if ((fromstr = strchr(hc, '/')) == NULL) + return (NULL); + find = fromstr; while ((ne = strchr(find, '=')) != NULL) { find = ne + 1; @@ -463,8 +546,10 @@ make_hc_pairs(topo_mod_t *mod, char *fromstr, int *num) /* * Do we appear to have a well-formed string version of the FMRI? */ - if (nslashes < npairs || npairs == 0) + if (nslashes < npairs || npairs == 0) { + topo_mod_strfree(mod, hc); return (NULL); + } *num = npairs; @@ -528,12 +613,101 @@ make_hc_pairs(topo_mod_t *mod, char *fromstr, int *num) if (pa[i--] != NULL) nvlist_free(pa[i + 1]); topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *)); + topo_mod_strfree(mod, hc); return (NULL); } + topo_mod_strfree(mod, hc); + return (pa); } +void +make_hc_auth(topo_mod_t *mod, char *fmri, char **serial, char **part, +char **rev, nvlist_t **auth) +{ + char *starti, *startn, *endi, *copy; + char *aname, *aid, *fs; + nvlist_t *na = NULL; + size_t len; + + if ((copy = topo_mod_strdup(mod, fmri + 5)) == NULL) + return; + + len = strlen(copy); + + /* + * Make sure there are a valid authority members + */ + startn = strchr(copy, ':'); + fs = strchr(copy, '/'); + + if (startn == NULL || fs == NULL) { + topo_mod_strfree(mod, copy); + return; + } + + /* + * The first colon we encounter must occur before the + * first slash + */ + if (startn > fs) + return; + + do { + if (++startn >= copy + len) + break; + + if ((starti = strchr(startn, '=')) == NULL) + break; + + *starti = '\0'; + if (++starti > copy + len) + break; + + if ((aname = topo_mod_strdup(mod, startn)) == NULL) + break; + + startn = endi = strchr(starti, ':'); + if (endi == NULL) + if ((endi = strchr(starti, '/')) == NULL) + break; + + *endi = '\0'; + if ((aid = topo_mod_strdup(mod, starti)) == NULL) { + topo_mod_strfree(mod, aname); + break; + } + + /* + * Return possible serial, part and revision + */ + if (strcmp(aname, FM_FMRI_HC_SERIAL_ID) == 0) { + *serial = aid; + } else if (strcmp(aname, FM_FMRI_HC_PART) == 0) { + *part = aid; + } else if (strcmp(aname, FM_FMRI_HC_REVISION) == 0) { + *rev = aid; + } else { + if (na == NULL) { + if (topo_mod_nvalloc(mod, &na, + NV_UNIQUE_NAME) == 0) { + nvlist_add_string(na, aname, aid); + } + } else { + (void) nvlist_add_string(na, aname, aid); + } + } + topo_mod_strfree(mod, aname); + topo_mod_strfree(mod, aid); + + } while (startn != NULL); + + *auth = na; + + topo_mod_free(mod, copy, len + 1); +} + /*ARGSUSED*/ static int hc_fmri_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, @@ -541,7 +715,9 @@ hc_fmri_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, { nvlist_t **pa = NULL; nvlist_t *nf = NULL; - char *str, *copy; + nvlist_t *auth = NULL; + char *str; + char *serial = NULL, *part = NULL, *rev = NULL; int npairs; int i, e; @@ -552,17 +728,14 @@ hc_fmri_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); /* We're expecting a string version of an hc scheme FMRI */ - if (strncmp(str, "hc:///", 6) != 0) + if (strncmp(str, "hc://", 5) != 0) return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM)); - copy = topo_mod_strdup(mod, str + 5); - if ((pa = make_hc_pairs(mod, copy, &npairs)) == NULL) { - topo_mod_strfree(mod, copy); + if ((pa = make_hc_pairs(mod, str, &npairs)) == NULL) return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM)); - } - topo_mod_strfree(mod, copy); - if ((nf = hc_base_fmri_create(mod, NULL, NULL, NULL, NULL)) == NULL) + make_hc_auth(mod, str, &serial, &part, &rev, &auth); + if ((nf = hc_base_fmri_create(mod, auth, part, rev, serial)) == NULL) goto hcfmbail; if ((e = nvlist_add_uint32(nf, FM_FMRI_HC_LIST_SZ, npairs)) == 0) e = nvlist_add_nvlist_array(nf, FM_FMRI_HC_LIST, pa, npairs); @@ -573,6 +746,14 @@ hc_fmri_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, for (i = 0; i < npairs; i++) nvlist_free(pa[i]); topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *)); + if (serial != NULL) + topo_mod_strfree(mod, serial); + if (part != NULL) + topo_mod_strfree(mod, part); + if (rev != NULL) + topo_mod_strfree(mod, rev); + nvlist_free(auth); + *out = nf; return (0); @@ -583,6 +764,13 @@ hcfmbail: for (i = 0; i < npairs; i++) nvlist_free(pa[i]); topo_mod_free(mod, pa, npairs * sizeof (nvlist_t *)); + if (serial != NULL) + topo_mod_strfree(mod, serial); + if (part != NULL) + topo_mod_strfree(mod, part); + if (rev != NULL) + topo_mod_strfree(mod, rev); + nvlist_free(auth); return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM)); } @@ -629,20 +817,27 @@ hc_create_seterror(topo_mod_t *mod, nvlist_t **hcl, int n, nvlist_t *fmri, } static int -hc_name_canonical(const char *name) +hc_name_canonical(topo_mod_t *mod, const char *name) { int i; + + if (getenv("NOHCCHECK") != NULL) + return (1); + /* * Only enumerate elements with correct canonical names */ - for (i = 0; i < Hc_ncanon; i++) { - if (strcmp(name, Hc_canon[i]) == 0) + for (i = 0; i < hc_ncanon; i++) { + if (strcmp(name, hc_canon[i].hcc_name) == 0) break; } - if (i >= Hc_ncanon) + if (i >= hc_ncanon) { + topo_mod_dprintf(mod, "non-canonical name %s\n", + name); return (0); - else + } else { return (1); + } } static nvlist_t * @@ -667,7 +862,7 @@ hc_fmri_create(topo_mod_t *mod, nvlist_t *pfmri, int version, const char *name, /* * Check that the requested name is in our canonical list */ - if (hc_name_canonical(name) == 0) + if (hc_name_canonical(mod, name) == 0) return (hc_create_seterror(mod, hcl, pelems, fmri, EMOD_NONCANON)); /* @@ -717,7 +912,7 @@ hc_fmri_create(topo_mod_t *mod, nvlist_t *pfmri, int version, const char *name, /*ARGSUSED*/ static int -hc_fmri_create_meth(topo_mod_t *mp, tnode_t *node, topo_version_t version, +hc_fmri_create_meth(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { int ret; @@ -727,13 +922,13 @@ hc_fmri_create_meth(topo_mod_t *mp, tnode_t *node, topo_version_t version, char *name, *serial, *rev, *part; if (version > TOPO_METH_FMRI_VERSION) - return (topo_mod_seterrno(mp, EMOD_VER_NEW)); + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); /* First the must-have fields */ if (nvlist_lookup_string(in, TOPO_METH_FMRI_ARG_NAME, &name) != 0) - return (topo_mod_seterrno(mp, EMOD_METHOD_INVAL)); + return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); if (nvlist_lookup_uint32(in, TOPO_METH_FMRI_ARG_INST, &inst) != 0) - return (topo_mod_seterrno(mp, EMOD_METHOD_INVAL)); + return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); /* * args is optional @@ -744,7 +939,7 @@ hc_fmri_create_meth(topo_mod_t *mp, tnode_t *node, topo_version_t version, if ((ret = nvlist_lookup_nvlist(in, TOPO_METH_FMRI_ARG_NVL, &args)) != 0) { if (ret != ENOENT) - return (topo_mod_seterrno(mp, EMOD_METHOD_INVAL)); + return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL)); } else { /* And then optional arguments */ @@ -759,8 +954,8 @@ hc_fmri_create_meth(topo_mod_t *mp, tnode_t *node, topo_version_t version, &serial); } - *out = hc_fmri_create(mp, - pfmri, version, name, inst, auth, part, rev, serial); + *out = hc_fmri_create(mod, pfmri, version, name, inst, auth, part, + rev, serial); if (*out == NULL) return (-1); return (0); diff --git a/usr/src/lib/fm/topo/libtopo/common/hc_canon.h b/usr/src/lib/fm/topo/libtopo/common/hc.h index 3edb066d32..1159821172 100644 --- a/usr/src/lib/fm/topo/libtopo/common/hc_canon.h +++ b/usr/src/lib/fm/topo/libtopo/common/hc.h @@ -24,8 +24,8 @@ * Use is subject to license terms. */ -#ifndef _HC_CANON_H -#define _HC_CANON_H +#ifndef _HC_H +#define _HC_H #pragma ident "%Z%%M% %I% %E% SMI" @@ -33,42 +33,24 @@ extern "C" { #endif +#define HC_VERSION 1 +#define HC "hc" + /* * Array declaring all known canonical HC scheme component names. * Hopefully this file will one day be generated from the event registry * automagically. */ -static const char *Hc_canon[] = { - "CMP", - "centerplane", - "chip", - "chip-select", - "cpu", - "dimm", - "rank", - "disk", - "hostbridge", - "interconnect", - "chassis", - "ioboard", - "memory-controller", - "dram-channel", - "motherboard", - "pcibus", - "pcidev", - "pciexbus", - "pciexdev", - "pciexfn", - "pciexrc", - "pcifn", - "sata-port", - "systemboard" -}; +typedef struct hcc { + const char *hcc_name; + topo_stability_t hcc_stability; +} hcc_t; -static int Hc_ncanon = sizeof (Hc_canon) / sizeof (const char *); +extern int hc_init(topo_mod_t *, topo_version_t); /* see hc.c */ +extern void hc_fini(topo_mod_t *); /* see hc.c */ #ifdef __cplusplus } #endif -#endif /* _HC_CANON_H */ +#endif /* _HC_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/libtopo.h b/usr/src/lib/fm/topo/libtopo/common/libtopo.h index 892f2ca91a..1ac15ded4c 100644 --- a/usr/src/lib/fm/topo/libtopo/common/libtopo.h +++ b/usr/src/lib/fm/topo/libtopo/common/libtopo.h @@ -30,6 +30,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <sys/nvpair.h> +#include <stdio.h> #ifdef __cplusplus extern "C" { @@ -51,18 +52,18 @@ typedef uint32_t topo_version_t; */ typedef enum topo_stability { - TOPO_STABILITY_INTERNAL = 0, /* private to libtopo */ + TOPO_STABILITY_UNKNOWN = 0, /* private to libtopo */ + TOPO_STABILITY_INTERNAL, /* private to libtopo */ TOPO_STABILITY_PRIVATE, /* private to Sun */ TOPO_STABILITY_OBSOLETE, /* scheduled for removal */ TOPO_STABILITY_EXTERNAL, /* not controlled by Sun */ TOPO_STABILITY_UNSTABLE, /* new or rapidly changing */ TOPO_STABILITY_EVOLVING, /* less rapidly changing */ TOPO_STABILITY_STABLE, /* mature interface from Sun */ - TOPO_STABILITY_STANDARD, /* industry standard */ - TOPO_STABILITY_MAX /* end */ + TOPO_STABILITY_STANDARD /* industry standard */ } topo_stability_t; -#define TOPO_STABILITY_MAX TOPO_STABILITY_STANDARD /* max valid stability */ +#define TOPO_STABILITY_MAX TOPO_STABILITY_STANDARD /* max valid stab */ typedef enum { TOPO_TYPE_INVALID = 0, @@ -74,15 +75,36 @@ typedef enum { TOPO_TYPE_STRING, /* const char* */ TOPO_TYPE_TIME, /* uint64_t */ TOPO_TYPE_SIZE, /* uint64_t */ - TOPO_TYPE_FMRI /* nvlist_t */ + TOPO_TYPE_FMRI, /* nvlist_t */ + TOPO_TYPE_INT32_ARRAY, /* array of int32_t */ + TOPO_TYPE_UINT32_ARRAY, /* array of uint32_t */ + TOPO_TYPE_INT64_ARRAY, /* array of int64_t */ + TOPO_TYPE_UINT64_ARRAY, /* array of uint64_t */ + TOPO_TYPE_STRING_ARRAY, /* array of const char* */ + TOPO_TYPE_FMRI_ARRAY /* array of nvlist_t */ } topo_type_t; -typedef int (*topo_walk_cb_t)(topo_hdl_t *, tnode_t *, void *); +typedef struct topo_pgroup_info { + const char *tpi_name; /* property group name */ + topo_stability_t tpi_namestab; /* stability of group name */ + topo_stability_t tpi_datastab; /* stability of all property values */ + topo_version_t tpi_version; /* version of pgroup definition */ +} topo_pgroup_info_t; + +extern topo_stability_t topo_name2stability(const char *); +extern const char *topo_stability2name(topo_stability_t); extern topo_hdl_t *topo_open(int, const char *, int *); extern void topo_close(topo_hdl_t *); extern char *topo_snap_hold(topo_hdl_t *, const char *, int *); extern void topo_snap_release(topo_hdl_t *); +extern int topo_xml_print(topo_hdl_t *, FILE *, const char *scheme, int *); + +/* + * Snapshot walker support + */ +typedef int (*topo_walk_cb_t)(topo_hdl_t *, tnode_t *, void *); + extern topo_walk_t *topo_walk_init(topo_hdl_t *, const char *, topo_walk_cb_t, void *, int *); extern int topo_walk_step(topo_walk_t *, int); @@ -95,6 +117,9 @@ extern void topo_walk_fini(topo_walk_t *); #define TOPO_WALK_CHILD 0x0001 #define TOPO_WALK_SIBLING 0x0002 +/* + * FMRI helper routines + */ extern int topo_fmri_present(topo_hdl_t *, nvlist_t *, int *); extern int topo_fmri_contains(topo_hdl_t *, nvlist_t *, nvlist_t *, int *); extern int topo_fmri_unusable(topo_hdl_t *, nvlist_t *, int *); @@ -120,14 +145,12 @@ extern int topo_node_asru(tnode_t *, nvlist_t **, nvlist_t *, int *); extern int topo_node_fru(tnode_t *, nvlist_t **, nvlist_t *, int *); extern int topo_node_resource(tnode_t *, nvlist_t **, int *); extern int topo_node_label(tnode_t *, char **, int *); -extern int topo_node_asru_set(tnode_t *node, nvlist_t *, int, int *); -extern int topo_node_fru_set(tnode_t *node, nvlist_t *, int, int *); -extern int topo_node_label_set(tnode_t *node, char *, int *); extern int topo_method_invoke(tnode_t *node, const char *, topo_version_t, nvlist_t *, nvlist_t **, int *); -extern int topo_pgroup_create(tnode_t *, const char *, topo_stability_t, int *); +extern int topo_pgroup_create(tnode_t *, const topo_pgroup_info_t *, int *); extern void topo_pgroup_destroy(tnode_t *, const char *); +extern topo_pgroup_info_t *topo_pgroup_info(tnode_t *, const char *, int *); extern int topo_prop_get_int32(tnode_t *, const char *, const char *, int32_t *, int *); extern int topo_prop_get_uint32(tnode_t *, const char *, const char *, @@ -140,6 +163,18 @@ extern int topo_prop_get_string(tnode_t *, const char *, const char *, char **, int *); extern int topo_prop_get_fmri(tnode_t *, const char *, const char *, nvlist_t **, int *); +extern int topo_prop_get_int32_array(tnode_t *, const char *, const char *, + int32_t **, uint_t *, int *); +extern int topo_prop_get_uint32_array(tnode_t *, const char *, const char *, + uint32_t **, uint_t *, int *); +extern int topo_prop_get_int64_array(tnode_t *, const char *, const char *, + int64_t **, uint_t *, int *); +extern int topo_prop_get_uint64_array(tnode_t *, const char *, const char *, + uint64_t **, uint_t *, int *); +extern int topo_prop_get_string_array(tnode_t *, const char *, const char *, + char ***, uint_t *, int *); +extern int topo_prop_get_fmri_array(tnode_t *, const char *, const char *, + nvlist_t ***, uint_t *, int *); extern int topo_prop_set_int32(tnode_t *, const char *, const char *, int, int32_t, int *); extern int topo_prop_set_uint32(tnode_t *, const char *, const char *, int, @@ -152,15 +187,23 @@ extern int topo_prop_set_string(tnode_t *, const char *, const char *, int, const char *, int *); extern int topo_prop_set_fmri(tnode_t *, const char *, const char *, int, const nvlist_t *, int *); -extern int topo_prop_stability(tnode_t *, const char *, topo_stability_t *); -extern nvlist_t *topo_prop_get_all(topo_hdl_t *, tnode_t *); +extern int topo_prop_set_int32_array(tnode_t *, const char *, const char *, int, + int32_t *, uint_t, int *); +extern int topo_prop_set_uint32_array(tnode_t *, const char *, const char *, + int, uint32_t *, uint_t, int *); +extern int topo_prop_set_int64_array(tnode_t *, const char *, const char *, + int, int64_t *, uint_t, int *); +extern int topo_prop_set_uint64_array(tnode_t *, const char *, const char *, + int, uint64_t *, uint_t, int *); +extern int topo_prop_set_string_array(tnode_t *, const char *, const char *, + int, const char **, uint_t, int *); +extern int topo_prop_set_fmri_array(tnode_t *, const char *, const char *, + int, const nvlist_t **, uint_t, int *); +extern nvlist_t *topo_prop_getprops(tnode_t *, int *err); extern int topo_prop_inherit(tnode_t *, const char *, const char *, int *); -#define TOPO_PROP_SET_ONCE 0 -#define TOPO_PROP_SET_MULTIPLE 1 - -#define TOPO_ASRU_COMPUTE 0x0001 /* Compute ASRU dynamically */ -#define TOPO_FRU_COMPUTE 0x0002 /* Compute FRU dynamically */ +#define TOPO_PROP_IMMUTABLE 0 +#define TOPO_PROP_MUTABLE 1 /* Protocol property group and property names */ #define TOPO_PGROUP_PROTOCOL "protocol" /* Required property group */ @@ -172,30 +215,44 @@ extern int topo_prop_inherit(tnode_t *, const char *, const char *, int *); #define TOPO_PROP_LABEL "label" /* property LABEL */ /* - * Legacy TOPO property group: this group supports legacy platform.topo - * property names - */ -#define TOPO_PGROUP_LEGACY "legacy" /* Legacy property group */ -#define TOPO_PROP_PLATASRU "PLAT-ASRU" -#define TOPO_PROP_PLATFRU "PLAT-FRU" - -/* * System property group */ #define TOPO_PGROUP_SYSTEM "system" -#define TOPO_PROP_PLATFORM "platform" #define TOPO_PROP_ISA "isa" #define TOPO_PROP_MACHINE "machine" -/* Property node NVL names */ +/* Property node NVL names used in topo_prop_getprops */ #define TOPO_PROP_GROUP "property-group" #define TOPO_PROP_GROUP_NAME "property-group-name" +#define TOPO_PROP_GROUP_DSTAB "property-group-data-stability" +#define TOPO_PROP_GROUP_NSTAB "property-group-name-stability" +#define TOPO_PROP_GROUP_VERSION "property-group-version" #define TOPO_PROP_VAL "property" #define TOPO_PROP_VAL_NAME "property-name" #define TOPO_PROP_VAL_VAL "property-value" +#define TOPO_PROP_VAL_TYPE "property-type" + +/* + * This enum definition is used to define a set of error tags associated with + * the libtopo various error conditions occuring during the adminstration of + * properties. The shell script mkerror.sh is + * used to parse this file and create a corresponding topo_error.c source file. + * If you do something other than add a new error tag here, you may need to + * update the mkerror shell script as it is based upon simple regexps. + */ +typedef enum topo_prop_errno { + ETOPO_PROP_UNKNOWN = 3000, /* unknown topo prop error */ + ETOPO_PROP_NOENT, /* undefined property or property group */ + ETOPO_PROP_DEFD, /* static property already defined */ + ETOPO_PROP_NOMEM, /* memory limit exceeded during property allocation */ + ETOPO_PROP_TYPE, /* invalid property type */ + ETOPO_PROP_NOINHERIT, /* can not inherit property */ + ETOPO_PROP_NVL, /* malformed property nvlist */ + ETOPO_PROP_END /* end of prop errno list (to ease auto-merge) */ +} topo_prop_errno_t; extern const char *topo_strerror(int); -extern void topo_debug_set(topo_hdl_t *, int, char *); +extern void topo_debug_set(topo_hdl_t *, const char *, const char *); extern void *topo_hdl_alloc(topo_hdl_t *, size_t); extern void *topo_hdl_zalloc(topo_hdl_t *, size_t); extern void topo_hdl_free(topo_hdl_t *, void *, size_t); @@ -204,13 +261,6 @@ extern int topo_hdl_nvdup(topo_hdl_t *, nvlist_t *, nvlist_t **); extern char *topo_hdl_strdup(topo_hdl_t *, const char *); extern void topo_hdl_strfree(topo_hdl_t *, char *); -#define TOPO_DBG_ERR 0x0001 /* enable error handling debug messages */ -#define TOPO_DBG_MOD 0x0002 /* enable module subsystem debug messages */ -#define TOPO_DBG_LOG 0x0004 /* enable log subsystem debug messages */ -#define TOPO_DBG_WALK 0x0008 /* enable walker subsystem debug messages */ -#define TOPO_DBG_TREE 0x0010 /* enable tree subsystem debug messages */ -#define TOPO_DBG_ALL 0xffff /* enable all debug modes */ - #ifdef __cplusplus } #endif diff --git a/usr/src/lib/fm/topo/libtopo/common/mapfile-vers b/usr/src/lib/fm/topo/libtopo/common/mapfile-vers index 84378f8c76..5d7cfc7b44 100644 --- a/usr/src/lib/fm/topo/libtopo/common/mapfile-vers +++ b/usr/src/lib/fm/topo/libtopo/common/mapfile-vers @@ -54,21 +54,32 @@ SUNWprivate { topo_method_unregister; topo_method_unregister_all; topo_mod_alloc; + topo_mod_auth; topo_mod_clrdebug; + topo_mod_cpufmri; + topo_mod_devfmri; + topo_mod_devinfo; topo_mod_dprintf; topo_mod_enumerate; + topo_mod_enummap; topo_mod_errmsg; topo_mod_errno; topo_mod_free; - topo_mod_handle; + topo_mod_getspecific; + topo_mod_hcfmri; topo_mod_load; + topo_mod_memfmri; + topo_mod_modfmri; topo_mod_nvalloc; topo_mod_nvdup; - topo_mod_private; + topo_mod_nvl2str; + topo_mod_pkgfmri; + topo_mod_prominfo; topo_mod_register; - topo_mod_rootdir; topo_mod_setdebug; topo_mod_seterrno; + topo_mod_setspecific; + topo_mod_str2nvl; topo_mod_strdup; topo_mod_strfree; topo_mod_unload; @@ -79,25 +90,32 @@ SUNWprivate { topo_node_bind; topo_node_fru; topo_node_fru_set; + topo_node_getspecific; topo_node_instance; topo_node_label; topo_node_label_set; topo_node_name; - topo_node_private; topo_node_range_create; topo_node_range_destroy; topo_node_resource; + topo_node_setspecific; topo_node_unbind; topo_open; topo_pgroup_create; topo_pgroup_destroy; - topo_prop_get_all; topo_prop_get_fmri; topo_prop_get_int32; topo_prop_get_int64; topo_prop_get_string; topo_prop_get_uint32; topo_prop_get_uint64; + topo_prop_get_int32_array; + topo_prop_get_uint32_array; + topo_prop_get_int64_array; + topo_prop_get_uint64_array; + topo_prop_get_string_array; + topo_prop_get_fmri_array; + topo_prop_getprops; topo_prop_inherit; topo_prop_set_fmri; topo_prop_set_int32; @@ -105,13 +123,21 @@ SUNWprivate { topo_prop_set_string; topo_prop_set_uint32; topo_prop_set_uint64; - topo_prop_stability; + topo_prop_set_int32_array; + topo_prop_set_uint32_array; + topo_prop_set_int64_array; + topo_prop_set_uint64_array; + topo_prop_set_string_array; + topo_prop_set_fmri_array; + topo_name2stability; + topo_stability2name; topo_snap_hold; topo_snap_release; topo_strerror; topo_walk_fini; topo_walk_init; topo_walk_step; + topo_xml_print; local: *; }; diff --git a/usr/src/lib/fm/topo/libtopo/common/mem.c b/usr/src/lib/fm/topo/libtopo/common/mem.c index 6d89042372..7da4a4f3fa 100644 --- a/usr/src/lib/fm/topo/libtopo/common/mem.c +++ b/usr/src/lib/fm/topo/libtopo/common/mem.c @@ -34,57 +34,47 @@ #include <fm/topo_mod.h> #include <sys/fm/protocol.h> -#include <topo_error.h> +#include <topo_method.h> +#include <mem.h> static int mem_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); static void mem_release(topo_mod_t *, tnode_t *); static int mem_nvl2str(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); -static int mem_str2nvl(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int mem_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int mem_contains(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int mem_unusable(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int mem_expand(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); - -#define MEM_VERSION TOPO_VERSION +static int mem_fmri_create(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); static const topo_method_t mem_methods[] = { { TOPO_METH_NVL2STR, TOPO_METH_NVL2STR_DESC, TOPO_METH_NVL2STR_VERSION, TOPO_STABILITY_INTERNAL, mem_nvl2str }, - { TOPO_METH_STR2NVL, TOPO_METH_STR2NVL_DESC, TOPO_METH_STR2NVL_VERSION, - TOPO_STABILITY_INTERNAL, mem_str2nvl }, - { TOPO_METH_PRESENT, TOPO_METH_PRESENT_DESC, TOPO_METH_PRESENT_VERSION, - TOPO_STABILITY_INTERNAL, mem_present }, - { TOPO_METH_CONTAINS, TOPO_METH_CONTAINS_DESC, - TOPO_METH_CONTAINS_VERSION, TOPO_STABILITY_INTERNAL, mem_contains }, - { TOPO_METH_UNUSABLE, TOPO_METH_UNUSABLE_DESC, - TOPO_METH_UNUSABLE_VERSION, TOPO_STABILITY_INTERNAL, mem_unusable }, - { TOPO_METH_EXPAND, TOPO_METH_UNUSABLE_DESC, - TOPO_METH_EXPAND_VERSION, TOPO_STABILITY_INTERNAL, mem_expand }, + { TOPO_METH_FMRI, TOPO_METH_FMRI_DESC, TOPO_METH_FMRI_VERSION, + TOPO_STABILITY_INTERNAL, mem_fmri_create }, { NULL } }; +static const topo_modops_t mem_ops = + { mem_enum, mem_release }; static const topo_modinfo_t mem_info = - { "mem", MEM_VERSION, mem_enum, mem_release }; + { "mem", FM_FMRI_SCHEME_MEM, MEM_VERSION, &mem_ops }; -void -mem_init(topo_mod_t *mod) +int +mem_init(topo_mod_t *mod, topo_version_t version) { - topo_mod_setdebug(mod, TOPO_DBG_ALL); + topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing mem builtin\n"); - if (topo_mod_register(mod, &mem_info, NULL) != 0) { + if (version != MEM_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_mod_register(mod, &mem_info, TOPO_VERSION) != 0) { topo_mod_dprintf(mod, "failed to register mem_info: " "%s\n", topo_mod_errmsg(mod)); - return; + return (-1); /* mod errno already set */ } + + return (0); } void @@ -96,7 +86,7 @@ mem_fini(topo_mod_t *mod) /*ARGSUSED*/ static int mem_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t min, topo_instance_t max, void *arg) + topo_instance_t min, topo_instance_t max, void *notused1, void *notused2) { (void) topo_method_register(mod, pnode, mem_methods); @@ -143,10 +133,14 @@ mem_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version, format = FM_FMRI_SCHEME_MEM ":///" "%1$s"; /* - * If we have a well-formed unum we step over the hc:/// prefix + * If we have a well-formed unum we step over the hc:// and + * authority prefix */ - if (strncmp(unum, "hc:///", 6) == 0) - unum += 6; + if (strncmp(unum, "hc://", 5) == 0) { + unum += 5; + unum = strchr(unum, '/'); + ++unum; + } len = snprintf(NULL, 0, format, unum, val) + 1; buf = topo_mod_zalloc(mod, len); @@ -169,42 +163,65 @@ mem_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version, return (0); } -/*ARGSUSED*/ -static int -mem_str2nvl(topo_mod_t *mod, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) +static nvlist_t * +mem_fmri(topo_mod_t *mod, uint64_t pa, uint64_t offset, char *unum, int flags) { - return (-1); -} + int err; + nvlist_t *asru; -/*ARGSUSED*/ -static int -mem_present(topo_mod_t *mod, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (-1); -} + if (topo_mod_nvalloc(mod, &asru, NV_UNIQUE_NAME) != 0) + return (NULL); -/*ARGSUSED*/ -static int -mem_contains(topo_mod_t *mod, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (-1); -} + /* + * If we have a well-formed unum we step over the hc:/// and + * authority prefix + */ + if (strncmp(unum, "hc://", 5) == 0) { + char *tstr; -/*ARGSUSED*/ -static int -mem_unusable(topo_mod_t *mod, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (-1); + tstr = strchr(unum, '/'); + unum = ++tstr; + } + + err = nvlist_add_uint8(asru, FM_VERSION, FM_MEM_SCHEME_VERSION); + err |= nvlist_add_string(asru, FM_FMRI_SCHEME, FM_FMRI_SCHEME_MEM); + err |= nvlist_add_string(asru, FM_FMRI_MEM_UNUM, unum); + if (flags & TOPO_MEMFMRI_PA) + err |= nvlist_add_uint64(asru, FM_FMRI_MEM_PHYSADDR, pa); + if (flags & TOPO_MEMFMRI_OFFSET) + err |= nvlist_add_uint64(asru, FM_FMRI_MEM_OFFSET, offset); + + if (err != 0) { + nvlist_free(asru); + return (NULL); + } + + return (asru); } /*ARGSUSED*/ static int -mem_expand(topo_mod_t *mod, tnode_t *node, topo_version_t version, +mem_fmri_create(topo_mod_t *mod, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { - return (-1); + uint64_t pa = 0, offset = 0; + int flags = 0; + nvlist_t *asru; + char *unum; + + if (nvlist_lookup_uint64(in, FM_FMRI_MEM_PHYSADDR, &pa) == 0) + flags |= TOPO_MEMFMRI_PA; + if (nvlist_lookup_uint64(in, FM_FMRI_MEM_OFFSET, &offset) == 0) + flags |= TOPO_MEMFMRI_OFFSET; + if (nvlist_lookup_string(in, FM_FMRI_MEM_UNUM, &unum) != 0) + return (topo_mod_seterrno(mod, EMOD_FMRI_MALFORM)); + + asru = mem_fmri(mod, pa, offset, unum, flags); + + if (asru == NULL) + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + + *out = asru; + + return (0); } diff --git a/usr/src/lib/fm/topo/libtopo/common/mem.h b/usr/src/lib/fm/topo/libtopo/common/mem.h new file mode 100644 index 0000000000..fd05266741 --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/mem.h @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _MEM_H +#define _MEM_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MEM_VERSION 1 + +extern int mem_init(topo_mod_t *, topo_version_t); /* see mem.c */ +extern void mem_fini(topo_mod_t *); /* see mem.c */ + +#ifdef __cplusplus +} +#endif + +#endif /* _MEM_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/mkerror.sh b/usr/src/lib/fm/topo/libtopo/common/mkerror.sh index 8ce9a05a31..583cb7f5f0 100644 --- a/usr/src/lib/fm/topo/libtopo/common/mkerror.sh +++ b/usr/src/lib/fm/topo/libtopo/common/mkerror.sh @@ -3,9 +3,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -24,7 +23,7 @@ # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" +#ident "@(#)mkerror.sh 1.1 06/02/11 SMI" #pragma ident "%Z%%M% %I% %E% SMI" @@ -32,7 +31,7 @@ input="`cat`" [ -z "$input" ] && exit 1 -if [ $1 = "internal" ] ; then +if [ $1 = "liberrors" ] ; then echo "\ /*\n\ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.\n\ @@ -79,9 +78,27 @@ topo_hdl_errmsg(topo_hdl_t *thp) return (topo_strerror(thp->th_errno)); }" +elif [ $1 = "properrors" ] ; then + +echo "\ +\n\ +static const char *const _topo_properrstrs[] = {" + +pattern='^[ ]*ETOPO_PROP_[A-Z0-9_]*.*\* \(.*\) \*.*' +replace=' "\1",' + +echo "$input" | sed -n "s/$pattern/$replace/p" || exit 1 + +echo "\ +};\n\ +\n\ +static const int _topo_nproperrstrs =\n\ + sizeof (_topo_properrstrs) / sizeof (_topo_properrstrs[0]);" + else echo "\ +\n\ static const char *const _topo_moderrstrs[] = {" pattern='^[ ]*EMOD_[A-Z0-9_]*.*\* \(.*\) \*.*' @@ -91,7 +108,6 @@ echo "$input" | sed -n "s/$pattern/$replace/p" || exit 1 echo "\ };\n\ -\n\ static const int _topo_nmoderrstrs =\n\ sizeof (_topo_moderrstrs) / sizeof (_topo_moderrstrs[0]);\n\ \n\ @@ -122,8 +138,12 @@ topo_strerror(int err) if (err >= ETOPO_UNKNOWN && (err - ETOPO_UNKNOWN) < _topo_nerrstrs) s = _topo_errstrs[err - ETOPO_UNKNOWN]; - else if (err >= EMOD_UNKNOWN && (err - EMOD_UNKNOWN) < _topo_nmoderrstrs) + else if (err >= EMOD_UNKNOWN && (err - EMOD_UNKNOWN) < + _topo_nmoderrstrs) s = _topo_moderrstrs[err - EMOD_UNKNOWN]; + else if (err >= ETOPO_PROP_UNKNOWN && (err - ETOPO_PROP_UNKNOWN) < + _topo_nproperrstrs) + s = _topo_properrstrs[err - ETOPO_PROP_UNKNOWN]; else s = _topo_errstrs[0]; diff --git a/usr/src/lib/fm/topo/libtopo/common/mod.c b/usr/src/lib/fm/topo/libtopo/common/mod.c index 042aae03e7..1ab75aea2c 100644 --- a/usr/src/lib/fm/topo/libtopo/common/mod.c +++ b/usr/src/lib/fm/topo/libtopo/common/mod.c @@ -41,36 +41,43 @@ #include <libelf.h> #include <gelf.h> -#include <topo_error.h> +#include <topo_method.h> +#include <mod.h> static int mod_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); static void mod_release(topo_mod_t *, tnode_t *); static int mod_fmri_create_meth(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); -#define MOD_VERSION TOPO_VERSION - static const topo_method_t mod_methods[] = { { TOPO_METH_FMRI, TOPO_METH_FMRI_DESC, TOPO_METH_FMRI_VERSION, TOPO_STABILITY_INTERNAL, mod_fmri_create_meth }, { NULL } }; +static const topo_modops_t mod_modops = + { mod_enum, mod_release }; static const topo_modinfo_t mod_info = - { "mod", MOD_VERSION, mod_enum, mod_release }; + { "mod", FM_FMRI_SCHEME_MOD, MOD_VERSION, &mod_modops }; -void -mod_init(topo_mod_t *mod) +int +mod_init(topo_mod_t *mod, topo_version_t version) { - topo_mod_setdebug(mod, TOPO_DBG_ALL); + if (getenv("TOPOMODDEBUG")) + topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing mod builtin\n"); - if (topo_mod_register(mod, &mod_info, NULL) != 0) { + if (version != MOD_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_mod_register(mod, &mod_info, TOPO_VERSION) != 0) { topo_mod_dprintf(mod, "failed to register mod_info: " "%s\n", topo_mod_errmsg(mod)); - return; + return (-1); /* mod errno already set */ } + + return (0); } void @@ -82,7 +89,7 @@ mod_fini(topo_mod_t *mod) /*ARGSUSED*/ static int mod_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t min, topo_instance_t max, void *arg) + topo_instance_t min, topo_instance_t max, void *notused1, void *notused2) { (void) topo_method_register(mod, pnode, mod_methods); return (0); @@ -191,16 +198,12 @@ mod_nvl_data(topo_mod_t *mp, nvlist_t *out, const char *path) static nvlist_t * mod_fmri_create(topo_mod_t *mp, const char *driver) { - topo_hdl_t *thp; - nvlist_t *arg = NULL; nvlist_t *out = NULL; nvlist_t *pkg = NULL; char objpath[PATH_MAX]; char *path = NULL; - int err; - if (topo_mod_nvalloc(mp, &arg, NV_UNIQUE_NAME) != 0 || - topo_mod_nvalloc(mp, &out, NV_UNIQUE_NAME) != 0) { + if (topo_mod_nvalloc(mp, &out, NV_UNIQUE_NAME) != 0) { (void) topo_mod_seterrno(mp, EMOD_FMRI_NVL); goto mfc_bail; } @@ -209,23 +212,14 @@ mod_fmri_create(topo_mod_t *mp, const char *driver) if ((path = mod_binary_path_get(mp, objpath)) == NULL) goto mfc_bail; - if (nvlist_add_string(arg, "path", path) != 0) { - (void) topo_mod_seterrno(mp, EMOD_FMRI_NVL); - goto mfc_bail; - } if (mod_nvl_data(mp, out, objpath) < 0) goto mfc_bail; - thp = topo_mod_handle(mp); - pkg = topo_fmri_create(thp, - FM_FMRI_SCHEME_PKG, FM_FMRI_SCHEME_PKG, 0, arg, &err); + pkg = topo_mod_pkgfmri(mp, FM_PKG_SCHEME_VERSION, path); if (pkg == NULL) { - (void) topo_mod_seterrno(mp, err); goto mfc_bail; } - nvlist_free(arg); - arg = NULL; if (nvlist_add_nvlist(out, FM_FMRI_MOD_PKG, pkg) != 0) { (void) topo_mod_seterrno(mp, EMOD_FMRI_NVL); @@ -238,7 +232,6 @@ mod_fmri_create(topo_mod_t *mp, const char *driver) mfc_bail: nvlist_free(pkg); nvlist_free(out); - nvlist_free(arg); return (NULL); } diff --git a/usr/src/lib/fm/topo/libtopo/common/mod.h b/usr/src/lib/fm/topo/libtopo/common/mod.h new file mode 100644 index 0000000000..a4efa7db7e --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/mod.h @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _MOD_H +#define _MOD_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MOD_VERSION 1 + +extern int mod_init(topo_mod_t *, topo_version_t); /* see mod.c */ +extern void mod_fini(topo_mod_t *); /* see mod.c */ + +#ifdef __cplusplus +} +#endif + +#endif /* _MOD_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/pkg.c b/usr/src/lib/fm/topo/libtopo/common/pkg.c index 867b2f6deb..81aa321cae 100644 --- a/usr/src/lib/fm/topo/libtopo/common/pkg.c +++ b/usr/src/lib/fm/topo/libtopo/common/pkg.c @@ -44,38 +44,45 @@ #include <libelf.h> #include <gelf.h> -#include <topo_error.h> +#include <topo_method.h> +#include <pkg.h> #define BUFLEN (2 * PATH_MAX) static int pkg_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); static void pkg_release(topo_mod_t *, tnode_t *); static int pkg_fmri_create_meth(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); -#define PKG_VERSION TOPO_VERSION - static const topo_method_t pkg_methods[] = { { TOPO_METH_FMRI, TOPO_METH_FMRI_DESC, TOPO_METH_FMRI_VERSION, TOPO_STABILITY_INTERNAL, pkg_fmri_create_meth }, { NULL } }; +static const topo_modops_t pkg_ops = + { pkg_enum, pkg_release }; static const topo_modinfo_t pkg_info = - { "pkg", PKG_VERSION, pkg_enum, pkg_release }; + { "pkg", FM_FMRI_SCHEME_PKG, PKG_VERSION, &pkg_ops }; -void -pkg_init(topo_mod_t *mod) +int +pkg_init(topo_mod_t *mod, topo_version_t version) { - topo_mod_setdebug(mod, TOPO_DBG_ALL); + if (getenv("TOPOPKGDEBUG")) + topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing mod builtin\n"); - if (topo_mod_register(mod, &pkg_info, NULL) != 0) { + if (version != PKG_VERSION) + return (topo_mod_seterrno(mod, EMOD_VER_NEW)); + + if (topo_mod_register(mod, &pkg_info, TOPO_VERSION) != 0) { topo_mod_dprintf(mod, "failed to register pkg_info: " "%s\n", topo_mod_errmsg(mod)); - return; + return (-1); } + + return (0); } void @@ -87,7 +94,7 @@ pkg_fini(topo_mod_t *mod) /*ARGSUSED*/ static int pkg_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t min, topo_instance_t max, void *arg) + topo_instance_t min, topo_instance_t max, void *notused1, void *notused2) { (void) topo_method_register(mod, pnode, pkg_methods); return (0); diff --git a/usr/src/lib/fm/topo/libtopo/common/pkg.h b/usr/src/lib/fm/topo/libtopo/common/pkg.h new file mode 100644 index 0000000000..1640e6271d --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/pkg.h @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _PKG_H +#define _PKG_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PKG_VERSION 1 + +extern int pkg_init(topo_mod_t *, topo_version_t); /* see pkg.c */ +extern void pkg_fini(topo_mod_t *); /* see pkg.c */ + +#ifdef __cplusplus +} +#endif + +#endif /* _PKG_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_2xml.c b/usr/src/lib/fm/topo/libtopo/common/topo_2xml.c new file mode 100644 index 0000000000..94a221e3b7 --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/topo_2xml.c @@ -0,0 +1,294 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <strings.h> +#include <time.h> +#include <sys/types.h> +#include <sys/fm/protocol.h> +#include <sys/utsname.h> + +#include <topo_parse.h> +#include <topo_prop.h> +#include <topo_tree.h> + +#define INT32BUFSZ sizeof (UINT32_MAX) + 1 +#define INT64BUFSZ sizeof (UINT64_MAX) + 1 +#define XML_VERSION "1.0" + +static int txml_print_range(topo_hdl_t *, FILE *, tnode_t *, int); + +void +print_header(FILE *fp) +{ + char buf[32]; + time_t tod = time(NULL); + struct utsname uts; + + (void) fprintf(fp, "<?xml version=\"%s\"?>\n", XML_VERSION); + (void) fprintf(fp, "<!DOCTYPE topology SYSTEM \"%s\">\n", + TOPO_DTD_PATH); + + (void) uname(&uts); + (void) strftime(buf, sizeof (buf), "%b %d %T", localtime(&tod)); + (void) fprintf(fp, "<!--\n"); + (void) fprintf(fp, " This topology map file was generated on " + "%-15s for %s\n", buf, uts.nodename); + (void) fprintf(fp, "<-->\n\n"); +} + +void +begin_element(FILE *fp, const char *ename, ...) +{ + char *name, *value; + va_list ap; + + (void) fprintf(fp, "<%s ", ename); + va_start(ap, ename); + name = va_arg(ap, char *); + while (name != NULL) { + value = va_arg(ap, char *); + (void) fprintf(fp, "%s='%s' ", name, value); + name = va_arg(ap, char *); + } + (void) fprintf(fp, ">\n"); +} + +void +begin_end_element(FILE *fp, const char *ename, ...) +{ + char *name, *value; + va_list ap; + + (void) fprintf(fp, "<%s ", ename); + va_start(ap, ename); + name = va_arg(ap, char *); + while (name != NULL) { + value = va_arg(ap, char *); + (void) fprintf(fp, "%s='%s' ", name, value); + name = va_arg(ap, char *); + } + (void) fprintf(fp, "/>\n"); +} + +void +end_element(FILE *fp, const char *ename) +{ + (void) fprintf(fp, "</%s>\n", ename); +} + +static void +txml_print_prop(topo_hdl_t *thp, FILE *fp, topo_propval_t *pv) +{ + int err; + char *fmri = NULL; + char vbuf[INT64BUFSZ], tbuf[10], *pval; + nvpair_t *nvp; + + if ((nvp = nvlist_next_nvpair(pv->tp_val, NULL)) == NULL) + return; + + switch (pv->tp_type) { + case TOPO_TYPE_INT32: { + int32_t val; + (void) nvpair_value_int32(nvp, &val); + (void) snprintf(vbuf, INT64BUFSZ, "%d", val); + (void) snprintf(tbuf, 10, "%s", Int32); + pval = vbuf; + break; + } + case TOPO_TYPE_UINT32: { + uint32_t val; + (void) nvpair_value_uint32(nvp, &val); + (void) snprintf(vbuf, INT64BUFSZ, "0x%x", val); + (void) snprintf(tbuf, 10, "%s", UInt32); + pval = vbuf; + break; + } + case TOPO_TYPE_INT64: { + int64_t val; + (void) nvpair_value_int64(nvp, &val); + (void) snprintf(vbuf, INT64BUFSZ, "%lld", + (longlong_t)val); + (void) snprintf(tbuf, 10, "%s", Int64); + pval = vbuf; + break; + } + case TOPO_TYPE_UINT64: { + uint64_t val; + (void) nvpair_value_uint64(nvp, &val); + (void) snprintf(vbuf, INT64BUFSZ, "0x%llx", + (u_longlong_t)val); + (void) snprintf(tbuf, 10, "%s", UInt64); + pval = vbuf; + break; + } + case TOPO_TYPE_STRING: { + (void) nvpair_value_string(nvp, &pval); + (void) snprintf(tbuf, 10, "%s", String); + break; + } + case TOPO_TYPE_FMRI: { + nvlist_t *val; + + (void) nvpair_value_nvlist(nvp, &val); + if (topo_fmri_nvl2str(thp, val, &fmri, &err) == 0) + pval = fmri; + else + return; + + (void) snprintf(tbuf, 10, "%s", FMRI); + break; + } + } + + begin_end_element(fp, Propval, Name, pv->tp_name, Type, tbuf, + Value, pval, NULL); + + if (fmri != NULL) + topo_hdl_strfree(thp, fmri); + +} + +static void +txml_print_pgroup(topo_hdl_t *thp, FILE *fp, topo_pgroup_t *pg) +{ + topo_ipgroup_info_t *pip = pg->tpg_info; + topo_proplist_t *plp; + const char *namestab, *datastab; + char version[INT32BUFSZ]; + + namestab = topo_stability2name(pip->tpi_namestab); + datastab = topo_stability2name(pip->tpi_datastab); + (void) snprintf(version, INT32BUFSZ, "%d", pip->tpi_version); + begin_element(fp, Propgrp, Name, pip->tpi_name, Namestab, + namestab, Datastab, datastab, Version, version, NULL); + topo_hdl_strfree(thp, (char *)namestab); + topo_hdl_strfree(thp, (char *)datastab); + for (plp = topo_list_next(&pg->tpg_pvals); plp != NULL; + plp = topo_list_next(plp)) { + txml_print_prop(thp, fp, plp->tp_pval); + } + end_element(fp, Propgrp); +} + +static void +txml_print_dependents(topo_hdl_t *thp, FILE *fp, tnode_t *node) +{ + if (topo_list_next(&node->tn_children) == NULL) + return; + + if (txml_print_range(thp, fp, node, 1) == 1) + end_element(fp, Dependents); +} + +static void +txml_print_node(topo_hdl_t *thp, FILE *fp, tnode_t *node) +{ + char inst[INT32BUFSZ]; + topo_pgroup_t *pg; + + (void) snprintf(inst, INT32BUFSZ, "%d", node->tn_instance); + begin_element(fp, Node, Instance, inst, Static, True, NULL); + for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; + pg = topo_list_next(pg)) { + txml_print_pgroup(thp, fp, pg); + } + txml_print_dependents(thp, fp, node); + end_element(fp, Node); + +} + +static int +txml_print_range(topo_hdl_t *thp, FILE *fp, tnode_t *node, int dependent) +{ + int i, create = 0, ret = 0; + topo_nodehash_t *nhp; + char min[INT32BUFSZ], max[INT32BUFSZ]; + + for (nhp = topo_list_next(&node->tn_children); nhp != NULL; + nhp = topo_list_next(nhp)) { + (void) snprintf(min, INT32BUFSZ, "%d", nhp->th_range.tr_min); + (void) snprintf(max, INT32BUFSZ, "%d", nhp->th_range.tr_max); + + /* + * Some enumerators create empty ranges: make sure there + * are real nodes before creating this range + */ + for (i = 0; i < nhp->th_arrlen; ++i) { + if (nhp->th_nodearr[i] != NULL) + ++create; + } + if (!create) + continue; + + if (dependent) { + begin_element(fp, Dependents, Grouping, Children, NULL); + dependent = 0; + ret = 1; + } + begin_element(fp, Range, Name, nhp->th_name, Min, min, Max, + max, NULL); + for (i = 0; i < nhp->th_arrlen; ++i) { + if (nhp->th_nodearr[i] != NULL) + txml_print_node(thp, fp, nhp->th_nodearr[i]); + } + end_element(fp, Range); + } + + return (ret); +} + +static void +txml_print_topology(topo_hdl_t *thp, FILE *fp, char *scheme, tnode_t *node) +{ + begin_element(fp, Topology, Name, thp->th_product, Scheme, scheme, + NULL); + (void) txml_print_range(thp, fp, node, 0); + end_element(fp, Topology); + +} + +int +topo_xml_print(topo_hdl_t *thp, FILE *fp, const char *scheme, int *err) +{ + ttree_t *tp; + + print_header(fp); + for (tp = topo_list_next(&thp->th_trees); tp != NULL; + tp = topo_list_next(tp)) { + if (strcmp(scheme, tp->tt_scheme) == 0) { + txml_print_topology(thp, fp, tp->tt_scheme, + tp->tt_root); + return (0); + } + } + + *err = EINVAL; + return (-1); +} diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_builtin.c b/usr/src/lib/fm/topo/libtopo/common/topo_builtin.c index 0e91e1e7b5..3de77a8be6 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_builtin.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_builtin.c @@ -33,18 +33,25 @@ #include <topo_error.h> #include <topo_subr.h> +#include <cpu.h> +#include <hc.h> +#include <dev.h> +#include <mem.h> +#include <mod.h> +#include <pkg.h> + static const struct topo_builtin _topo_builtins[] = { - { "cpu", cpu_init, cpu_fini }, - { "dev", dev_init, dev_fini }, - { "mem", mem_init, mem_fini }, - { "pkg", pkg_init, pkg_fini }, - { "mod", mod_init, mod_fini }, - { "hc", hc_init, hc_fini }, + { "cpu", CPU_VERSION, cpu_init, cpu_fini }, + { "dev", DEV_VERSION, dev_init, dev_fini }, + { "mem", MEM_VERSION, mem_init, mem_fini }, + { "pkg", PKG_VERSION, pkg_init, pkg_fini }, + { "mod", MOD_VERSION, mod_init, mod_fini }, + { "hc", HC_VERSION, hc_init, hc_fini }, /* hc must go last */ { NULL, NULL, NULL } }; static int -bltin_init(topo_mod_t *mp) +bltin_init(topo_mod_t *mp, topo_version_t version) { const topo_builtin_t *bp; @@ -55,12 +62,13 @@ bltin_init(topo_mod_t *mp) mp->tm_data = (void *)bp; - (*bp->bltin_init)(mp); - - if (mp->tm_info == NULL) { - topo_dprintf(TOPO_DBG_ERR, - "unable initialize builtin module: %s\n", bp->bltin_name); - return (topo_mod_seterrno(mp, ETOPO_MOD_INIT)); + if ((*bp->bltin_init)(mp, version) != 0 || mp->tm_info == NULL) { + if (mp->tm_errno == 0) + (void) topo_mod_seterrno(mp, ETOPO_MOD_INIT); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "unable initialize builtin module: %s: %s\n", + bp->bltin_name, topo_mod_errmsg(mp)); + return (-1); } return (0); @@ -79,7 +87,7 @@ bltin_fini(topo_mod_t *mp) return (0); } -const topo_modops_t topo_bltin_ops = { +const topo_imodops_t topo_bltin_ops = { bltin_init, bltin_fini, }; @@ -101,16 +109,18 @@ topo_builtin_create(topo_hdl_t *thp, const char *rootdir) /* * Load scheme-specific module */ - if ((mod = topo_modhash_load(thp, bp->bltin_name, - &topo_bltin_ops)) == NULL) { - topo_dprintf(TOPO_DBG_ERR, "unable to create scheme " + if ((mod = topo_modhash_load(thp, bp->bltin_name, NULL, + &topo_bltin_ops, bp->bltin_version)) == NULL) { + topo_dprintf(thp, TOPO_DBG_ERR, + "unable to create scheme " "tree for %s:%s\n", bp->bltin_name, topo_hdl_errmsg(thp)); return (-1); } if ((tp = topo_tree_create(thp, mod, bp->bltin_name)) == NULL) { - topo_dprintf(TOPO_DBG_ERR, "unable to create scheme " + topo_dprintf(thp, TOPO_DBG_ERR, + "unable to create scheme " "tree for %s:%s\n", bp->bltin_name, topo_hdl_errmsg(thp)); return (-1); @@ -124,7 +134,7 @@ topo_builtin_create(topo_hdl_t *thp, const char *rootdir) */ rnode = tp->tt_root; if (topo_mod_enumerate(mod, rnode, mod->tm_name, rnode->tn_name, - rnode->tn_instance, rnode->tn_instance) < 0) { + rnode->tn_instance, rnode->tn_instance, NULL) < 0) { /* * If we see a failure, note it in the handle and * drive on diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_builtin.h b/usr/src/lib/fm/topo/libtopo/common/topo_builtin.h index 4db2d37451..8d34f643d0 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_builtin.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_builtin.h @@ -47,25 +47,13 @@ extern "C" { typedef struct topo_builtin { const char *bltin_name; - void (*bltin_init)(topo_mod_t *); + topo_version_t bltin_version; + int (*bltin_init)(topo_mod_t *, topo_version_t version); void (*bltin_fini)(topo_mod_t *); } topo_builtin_t; extern int topo_builtin_create(topo_hdl_t *, const char *); -extern void hc_init(topo_mod_t *); /* see hc.c */ -extern void hc_fini(topo_mod_t *); /* see hc.c */ -extern void cpu_init(topo_mod_t *); /* see cpu.c */ -extern void cpu_fini(topo_mod_t *); /* see cpu.c */ -extern void dev_init(topo_mod_t *); /* see dev.c */ -extern void dev_fini(topo_mod_t *); /* see dev.c */ -extern void mem_init(topo_mod_t *); /* see mem.c */ -extern void mem_fini(topo_mod_t *); /* see mem.c */ -extern void mod_init(topo_mod_t *); /* see mod.c */ -extern void mod_fini(topo_mod_t *); /* see mod.c */ -extern void pkg_init(topo_mod_t *); /* see pkg.c */ -extern void pkg_fini(topo_mod_t *); /* see pkg.c */ - #ifdef __cplusplus } #endif diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_error.h b/usr/src/lib/fm/topo/libtopo/common/topo_error.h index fd3bb7bd66..6b513694b1 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_error.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_error.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -38,7 +37,7 @@ extern "C" { /* * This enum definition is used to define a set of error tags associated with - * the fmd daemon's various error conditions. The shell script mkerror.sh is + * the libtopo internal error conditions. The shell script mkerror.sh is * used to parse this file and create a corresponding topo_error.c source file. * If you do something other than add a new error tag here, you may need to * update the mkerror shell script as it is based upon simple regexps. @@ -47,7 +46,7 @@ typedef enum topo_errno { ETOPO_UNKNOWN = 1000, /* unknown libtopo error */ ETOPO_NOMEM, /* memory limit exceeded */ ETOPO_MODULE, /* module detected or caused an error */ - ETOPO_HDL_VER, /* handle opened with invalid ABI version */ + ETOPO_HDL_ABIVER, /* handle opened with invalid ABI version */ ETOPO_HDL_SNAP, /* snapshot already taken */ ETOPO_HDL_INVAL, /* invalid argument specified */ ETOPO_HDL_UUID, /* uuid already set */ @@ -55,12 +54,15 @@ typedef enum topo_errno { ETOPO_MOD_FINI, /* failed to uninitialize module */ ETOPO_MOD_LOADED, /* specified module is already loaded */ ETOPO_MOD_NOMOD, /* specified module is not loaded */ - ETOPO_MOD_NONVL, /* specified module is not loaded */ + ETOPO_MOD_ABIVER, /* module registered with invalid ABI version */ ETOPO_MOD_INVAL, /* module invalid argument */ ETOPO_MOD_DUP, /* module duplicate node entry */ ETOPO_MOD_NOREG, /* module failed to register */ ETOPO_MOD_NOENT, /* module path invalid */ + ETOPO_MOD_XRD, /* unable to read topology map file */ + ETOPO_MOD_XENUM, /* unable to enumerate from a topology map file */ ETOPO_MOD_NOSUP, /* enumerator not supported in this module */ + ETOPO_MOD_VER, /* module version mismatch while loading */ ETOPO_RTLD_OPEN, /* rtld failed to open shared library plug-in */ ETOPO_RTLD_INIT, /* shared library plug-in does not define _topo_init */ ETOPO_RTLD_NOMEM, /* memory limit exceeded when opening shared library */ @@ -76,11 +78,8 @@ typedef enum topo_errno { ETOPO_VER_OLD, /* plugin compiled using an obsolete topo ABI */ ETOPO_VER_NEW, /* plugin is compiled using a newer topo ABI */ ETOPO_ENUM_PARTIAL, /* partial enumeration completed for client */ - ETOPO_PROP_NOENT, /* undefined property or property group */ - ETOPO_PROP_DEFD, /* static property already defined */ - ETOPO_PROP_NOMEM, /* memory limit exceeded during property allocation */ - ETOPO_PROP_TYPE, /* invalid property type */ - ETOPO_PROP_NOINHERIT, /* can not inherit property */ + ETOPO_ENUM_NOMAP, /* no topology map file for enumeration */ + ETOPO_ENUM_FATAL, /* fatal enumeration error */ ETOPO_FMRI_NVL, /* nvlist allocation failure for FMRI */ ETOPO_FMRI_VERSION, /* invalid FMRI scheme version */ ETOPO_FMRI_MALFORM, /* malformed FMRI */ diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_file.c b/usr/src/lib/fm/topo/libtopo/common/topo_file.c index b46938eb63..64f5e5f463 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_file.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_file.c @@ -28,6 +28,7 @@ #include <limits.h> #include <string.h> +#include <unistd.h> #include <sys/param.h> #include <topo_error.h> #include <topo_tree.h> @@ -38,132 +39,70 @@ * topo_file.c * * This file hides the details of any file manipulation to - * establish topology for a given scheme. It has two outward - * facing interfaces topo_file_load() and topo_file_unload(). + * establish topology for a given enumerator. */ -#define TOPO_DEFAULT_FILE "%s-topology.xml" -#define PLATFORM_TOPO_PATH "%susr/platform/%s/lib/fm/topo/%s" -#define COMMON_TOPO_PATH "%susr/lib/fm/topo/%s" +#define TOPO_DEFAULT_FILE "maps/%s-%s-topology.xml" +#define TOPO_COMMON_FILE "maps/%s-topology.xml" -static int -xml_read(topo_hdl_t *hp, ttree_t *tp) +static void +topo_file_unload(topo_file_t *tfp) { - topo_file_t *tfp; - char *pplat, *pmach; - int err, e; - char _topo_file[MAXNAMELEN * 2]; - char _topo_path[PATH_MAX]; - - - tfp = (topo_file_t *)tp->tt_file; - - (void) snprintf(_topo_file, - 2 * MAXNAMELEN, TOPO_DEFAULT_FILE, tp->tt_scheme); - - /* - * Look for a platform-specific topology file first - */ - e = topo_prop_get_string(tp->tt_root, TOPO_PGROUP_SYSTEM, - TOPO_PROP_PLATFORM, &pplat, &err); - if (e < 0) - return (topo_hdl_seterrno(hp, err)); - (void) snprintf(_topo_path, PATH_MAX, PLATFORM_TOPO_PATH, - hp->th_rootdir, pplat, _topo_file); - - tfp->tf_fileinfo = - topo_xml_read(tfp->tf_mod, _topo_path, tp->tt_scheme); - if (tfp->tf_fileinfo != NULL) { - topo_hdl_strfree(hp, pplat); - return (0); - } - topo_dprintf(TOPO_DBG_MOD, "failed to load topology file %s: %s\n", - _topo_path, topo_strerror(topo_hdl_errno(hp))); - - /* - * No luck with the platform-specific file, how about a - * machine-specific one? - */ - e = topo_prop_get_string(tp->tt_root, TOPO_PGROUP_SYSTEM, - TOPO_PROP_MACHINE, &pmach, &err); - if (e < 0) { - topo_hdl_strfree(hp, pplat); - return (topo_hdl_seterrno(hp, err)); - } - /* - * Don't waste time trying to open the same file twice in the - * cases where the platform name is identical to the machine - * name - */ - if (strcmp(pplat, pmach) != 0) { - (void) snprintf(_topo_path, PATH_MAX, PLATFORM_TOPO_PATH, - hp->th_rootdir, pmach, _topo_file); - tfp->tf_fileinfo = - topo_xml_read(tfp->tf_mod, _topo_path, tp->tt_scheme); - } - if (tfp->tf_fileinfo != NULL) { - topo_hdl_strfree(hp, pplat); - topo_hdl_strfree(hp, pmach); - return (0); - } else { - topo_dprintf(TOPO_DBG_MOD, - "failed to load topology file %s: %s\n", - _topo_path, topo_strerror(topo_hdl_errno(hp))); - } - topo_hdl_strfree(hp, pplat); - topo_hdl_strfree(hp, pmach); - (void) snprintf(_topo_path, PATH_MAX, COMMON_TOPO_PATH, - hp->th_rootdir, _topo_file); - tfp->tf_fileinfo = - topo_xml_read(tfp->tf_mod, _topo_path, tp->tt_scheme); - if (tfp->tf_fileinfo == NULL) { - topo_dprintf(TOPO_DBG_MOD, - "failed to load topology file %s: %s\n", - _topo_path, topo_strerror(topo_hdl_errno(hp))); - return (topo_hdl_seterrno(hp, ETOPO_FILE_NOENT)); - } - return (0); + if (tfp == NULL) + return; + + if (tfp->tf_filenm != NULL) + topo_mod_strfree(tfp->tf_mod, tfp->tf_filenm); + + if (tfp->tf_tmap != NULL) + tf_info_free(tfp->tf_mod, tfp->tf_tmap); + + topo_mod_free(tfp->tf_mod, tfp, sizeof (topo_file_t)); } int -topo_file_load(topo_hdl_t *thp, topo_mod_t *mod, ttree_t *tp) +topo_file_load(topo_mod_t *mod, tnode_t *node, const char *name, + const char *scheme) { topo_file_t *tfp; + char fp[MAXNAMELEN]; - if ((tfp = topo_hdl_zalloc(thp, sizeof (topo_file_t))) == NULL) - return (topo_hdl_seterrno(thp, ETOPO_NOMEM)); - - tp->tt_file = tfp; + if ((tfp = topo_mod_zalloc(mod, sizeof (topo_file_t))) == NULL) + return (topo_mod_seterrno(mod, ETOPO_NOMEM)); tfp->tf_mod = mod; - if (xml_read(thp, tp) < 0) { - topo_file_unload(thp, tp); - return (-1); - } + if (name != NULL) + (void) snprintf(fp, MAXNAMELEN, TOPO_DEFAULT_FILE, name, + scheme); + else + (void) snprintf(fp, MAXNAMELEN, TOPO_COMMON_FILE, scheme); - if (topo_xml_enum(tfp->tf_mod, tfp->tf_fileinfo, tp->tt_root) < 0) { - topo_dprintf(TOPO_DBG_ERR, - "Failed to enumerate topology: %s\n", - topo_strerror(topo_hdl_errno(thp))); - topo_file_unload(thp, tp); - return (-1); + if ((tfp->tf_filenm = topo_search_path(mod, mod->tm_rootdir, fp)) + == NULL) { + topo_file_unload(tfp); + return (topo_mod_seterrno(mod, ETOPO_MOD_NOENT)); } - return (0); -} -void -topo_file_unload(topo_hdl_t *thp, ttree_t *tp) -{ - topo_file_t *tfp = tp->tt_file; + if ((tfp->tf_tmap = topo_xml_read(mod, tfp->tf_filenm, scheme)) + == NULL) { + topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, + "failed to load topology file %s: " + "%s\n", tfp->tf_filenm, topo_strerror(ETOPO_MOD_XRD)); + topo_file_unload(tfp); + return (topo_mod_seterrno(mod, ETOPO_MOD_XRD)); + } - if (tfp == NULL) - return; + if (topo_xml_enum(mod, tfp->tf_tmap, node) < 0) { + topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, + "Failed to enumerate topology: %s\n", + topo_strerror(ETOPO_MOD_XENUM)); + topo_file_unload(tfp); + return (topo_mod_seterrno(mod, ETOPO_MOD_XENUM)); + } - if (tfp->tf_fileinfo != NULL) - tf_info_free(tfp->tf_mod, tfp->tf_fileinfo); + topo_file_unload(tfp); - topo_hdl_free(thp, tfp, sizeof (topo_file_t)); - tp->tt_file = NULL; + return (0); } diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_file.h b/usr/src/lib/fm/topo/libtopo/common/topo_file.h index ce2f3a258a..642b9fa499 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_file.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_file.h @@ -35,23 +35,14 @@ extern "C" { #endif -/* - * We support loading topology from a file. The topo_tree routines - * don't need to know anymore than to call topo_file_load() to try to - * load the topology initially, and topo_file_unload() to clean up. - */ typedef struct topo_file { - /* - * Currently we directly parse xml into topology nodes. The - * tf_info_t is created and used by the xml parsing routines. - */ - tf_info_t *tf_fileinfo; - /* - * Module on whose behalf the enumeration-from-file is occuring. - */ - topo_mod_t *tf_mod; + tf_info_t *tf_tmap; /* topology map file info */ + char *tf_filenm; /* topology file name */ + topo_mod_t *tf_mod; /* scheme-specific builtin mod */ } topo_file_t; +extern int topo_file_load(topo_mod_t *, tnode_t *, const char *, const char *); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c b/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c index 56a3de7bb8..50bfd0db2a 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_fmri.c @@ -32,6 +32,7 @@ #include <sys/fm/protocol.h> #include <topo_alloc.h> #include <topo_error.h> +#include <topo_method.h> #include <topo_subr.h> #include <topo_string.h> @@ -42,7 +43,7 @@ set_error(topo_hdl_t *thp, int err, int *errp, char *method, nvlist_t *nvlp) if (nvlp != NULL) nvlist_free(nvlp); - topo_dprintf(TOPO_DBG_ERR, "%s failed: %s\n", method, + topo_dprintf(thp, TOPO_DBG_ERR, "%s failed: %s\n", method, topo_strerror(err)); *errp = err; @@ -56,7 +57,7 @@ set_nverror(topo_hdl_t *thp, int err, int *errp, char *method, nvlist_t *nvlp) if (nvlp != NULL) nvlist_free(nvlp); - topo_dprintf(TOPO_DBG_ERR, "%s failed: %s\n", method, + topo_dprintf(thp, TOPO_DBG_ERR, "%s failed: %s\n", method, topo_strerror(err)); *errp = err; @@ -99,18 +100,18 @@ int topo_fmri_str2nvl(topo_hdl_t *thp, const char *fmristr, nvlist_t **fmri, int *err) { - char *f, scheme[PATH_MAX]; + char *f, buf[PATH_MAX]; nvlist_t *out = NULL, *in = NULL; tnode_t *rnode; - (void) strlcpy(scheme, fmristr, sizeof (scheme)); - if ((f = strrchr(scheme, ':')) == NULL) + (void) strlcpy(buf, fmristr, sizeof (buf)); + if ((f = strchr(buf, ':')) == NULL) return (set_error(thp, ETOPO_FMRI_MALFORM, err, TOPO_METH_STR2NVL, in)); *f = '\0'; /* strip trailing FMRI path */ - if ((rnode = topo_hdl_root(thp, scheme)) == NULL) + if ((rnode = topo_hdl_root(thp, buf)) == NULL) return (set_error(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_STR2NVL, in)); @@ -137,14 +138,41 @@ topo_fmri_str2nvl(topo_hdl_t *thp, const char *fmristr, nvlist_t **fmri, return (0); } +/* ARGSUSED */ +static int +is_present(topo_hdl_t *thp, tnode_t *node, void *data) +{ + int err; + uint32_t present = 0; + nvlist_t *out = NULL; + nvlist_t *fmri = (nvlist_t *)data; + + if (topo_method_invoke(node, TOPO_METH_PRESENT, + TOPO_METH_PRESENT_VERSION, fmri, &out, &err) < 0) { + if (out != NULL) + nvlist_free(out); + return (present); + } + + (void) nvlist_lookup_uint32(out, TOPO_METH_PRESENT_RET, &present); + + nvlist_free(out); + + return (present); +} + int topo_fmri_present(topo_hdl_t *thp, nvlist_t *fmri, int *err) { - int rc; + int ret = 0; + uint32_t present = 0; char *scheme; nvlist_t *out = NULL; tnode_t *rnode; + if (topo_fmri_invoke(thp, fmri, is_present, fmri, &ret) == 0) + return (ret); + if (nvlist_lookup_string(fmri, FM_FMRI_SCHEME, &scheme) != 0) return (set_error(thp, ETOPO_FMRI_MALFORM, err, TOPO_METH_PRESENT, out)); @@ -153,11 +181,16 @@ topo_fmri_present(topo_hdl_t *thp, nvlist_t *fmri, int *err) return (set_error(thp, ETOPO_METHOD_NOTSUP, err, TOPO_METH_PRESENT, out)); - if ((rc = topo_method_invoke(rnode, TOPO_METH_PRESENT, - TOPO_METH_PRESENT_VERSION, fmri, &out, err)) < 0) - return (set_error(thp, *err, err, TOPO_METH_PRESENT, out)); + if (topo_method_invoke(rnode, TOPO_METH_PRESENT, + TOPO_METH_PRESENT_VERSION, fmri, &out, err) < 0) { + (void) set_error(thp, *err, err, TOPO_METH_PRESENT, out); + return (present); + } - return (rc); + (void) nvlist_lookup_uint32(out, TOPO_METH_PRESENT_RET, &present); + nvlist_free(out); + + return (present); } int @@ -272,33 +305,17 @@ get_prop(topo_hdl_t *thp, tnode_t *node, void *pdata) int topo_fmri_asru(topo_hdl_t *thp, nvlist_t *nvl, nvlist_t **asru, int *err) { - char *uuid = NULL; struct rsrc r; - if (thp->th_uuid == NULL) { - if ((uuid = topo_snap_hold(thp, NULL, err)) == NULL) - return (set_error(thp, *err, err, "topo_fmri_asru", - NULL)); - } - r.rs_flag = 0; r.rs_err = 0; r.rs_priv = nvl; r.rs_fprop = asru; if (topo_fmri_invoke(thp, nvl, get_prop, &r, err) < 0) { - if (uuid != NULL) { - topo_hdl_strfree(thp, uuid); - topo_snap_release(thp); - } return (set_error(thp, *err, err, "topo_fmri_asru", NULL)); } - if (uuid != NULL) { - topo_hdl_strfree(thp, uuid); - topo_snap_release(thp); - } - return (0); } @@ -306,33 +323,17 @@ int topo_fmri_fru(topo_hdl_t *thp, nvlist_t *nvl, nvlist_t **fru, int *err) { - char *uuid = NULL; struct rsrc r; - if (thp->th_uuid == NULL) { - if ((uuid = topo_snap_hold(thp, NULL, err)) == NULL) - return (set_error(thp, *err, err, "topo_fmri_fru", - NULL)); - } - r.rs_flag = 1; r.rs_err = 0; r.rs_priv = nvl; r.rs_fprop = fru; if (topo_fmri_invoke(thp, nvl, get_prop, &r, err) < 0) { - if (uuid != NULL) { - topo_hdl_strfree(thp, uuid); - topo_snap_release(thp); - } return (set_error(thp, *err, err, "topo_fmri_fru", NULL)); } - if (uuid != NULL) { - topo_hdl_strfree(thp, uuid); - topo_snap_release(thp); - } - return (0); } @@ -380,7 +381,7 @@ topo_fmri_compare(topo_hdl_t *thp, nvlist_t *f1, nvlist_t *f2, int *err) struct topo_lookup { nvlist_t *tl_resource; topo_walk_cb_t tl_func; - int tl_err; + int tl_ret; void *tl_pdata; }; @@ -391,48 +392,51 @@ walk_lookup(topo_hdl_t *thp, tnode_t *node, void *pdata) struct topo_lookup *tlp = (struct topo_lookup *)pdata; nvlist_t *r1, *r2 = tlp->tl_resource; - if (topo_node_resource(node, &r1, &tlp->tl_err) != 0) + if (topo_node_resource(node, &r1, &tlp->tl_ret) != 0) return (TOPO_WALK_ERR); - rc = topo_fmri_compare(thp, r1, r2, &tlp->tl_err); + rc = topo_fmri_compare(thp, r1, r2, &tlp->tl_ret); nvlist_free(r1); if (rc == 0) return (TOPO_WALK_NEXT); else if (rc == -1) return (TOPO_WALK_ERR); - tlp->tl_err = tlp->tl_func(thp, node, tlp->tl_pdata); + tlp->tl_ret = tlp->tl_func(thp, node, tlp->tl_pdata); return (TOPO_WALK_TERMINATE); } int topo_fmri_invoke(topo_hdl_t *thp, nvlist_t *nvl, topo_walk_cb_t cb_f, - void *pdata, int *err) + void *pdata, int *ret) { + int err; topo_walk_t *wp; char *scheme; struct topo_lookup tl; - if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &scheme) != 0) - return (set_error(thp, ETOPO_METHOD_INVAL, err, + if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &scheme) != 0) + return (set_error(thp, ETOPO_METHOD_INVAL, ret, "topo_fmri_invoke", NULL)); tl.tl_resource = nvl; tl.tl_func = cb_f; tl.tl_pdata = pdata; - tl.tl_err = 0; - if ((wp = topo_walk_init(thp, scheme, walk_lookup, &tl, err)) == NULL) - return (set_error(thp, *err, err, "topo_fmri_invoke", NULL)); + tl.tl_ret = 0; + if ((wp = topo_walk_init(thp, scheme, walk_lookup, &tl, &err)) == NULL) + return (set_error(thp, err, ret, "topo_fmri_invoke", NULL)); - (void) topo_walk_step(wp, TOPO_WALK_CHILD); + err = topo_walk_step(wp, TOPO_WALK_CHILD); topo_walk_fini(wp); - if (tl.tl_err != 0) { - *err = tl.tl_err; + if (err == TOPO_WALK_ERR) { + *ret = err; return (-1); } + *ret = tl.tl_ret; + return (0); } diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_hc.h b/usr/src/lib/fm/topo/libtopo/common/topo_hc.h new file mode 100644 index 0000000000..0f7b0216e8 --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/topo_hc.h @@ -0,0 +1,87 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _TOPO_HC_H +#define _TOPO_HC_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Allowable hardware component names for hc FMRIs + */ +#define CMP "CMP" +#define CENTERPLANE "centerplane" +#define CHASSIS "chassis" +#define CHIP "chip" +#define CHIP_SELECT "chip-select" +#define CPU "cpu" +#define DIMM "dimm" +#define DISK "disk" +#define DRAMCHANNEL "dram-channel" +#define HOSTBRIDGE "hostbridge" +#define INTERCONNECT "interconnect" +#define IOBOARD "ioboard" +#define MEMORYCONTROL "memory-controller" +#define MOTHERBOARD "motherboard" +#define PCI_BUS "pcibus" +#define PCI_DEVICE "pcidev" +#define PCI_FUNCTION "pcifn" +#define PCIEX_BUS "pciexbus" +#define PCIEX_DEVICE "pciexdev" +#define PCIEX_FUNCTION "pciexfn" +#define PCIEX_ROOT "pciexrc" +#define PCIEX_SWUP "pciexswu" +#define PCIEX_SWDWN "pciexswd" +#define RANK "rank" +#define SATA_PORT "sata-port" +#define SYSTEMBOARD "systemboard" + +/* + * Allowable hc node property group and property names + */ +#define TOPO_PGROUP_IO "io" +#define TOPO_IO_DEVTYPE "devtype" +#define TOPO_IO_DRIVER "driver" +#define TOPO_IO_DEV "dev" +#define TOPO_IO_DEV_PATH "devfs-path" +#define TOPO_IO_AP_PATH "ap-path" + +#define TOPO_PGROUP_PCI "pci" +#define TOPO_PCI_VENDID "vendor-id" +#define TOPO_PCI_DEVID "device-id" +#define TOPO_PCI_EXCAP "extended-capabilities" +#define TOPO_PCI_BDF "BDF" +#define TOPO_PCI_CLASS "class-code" + +#ifdef __cplusplus +} +#endif + +#endif /* _TOPO_HC_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_method.c b/usr/src/lib/fm/topo/libtopo/common/topo_method.c index 6b64df14bd..c05f1a8876 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_method.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_method.c @@ -99,7 +99,8 @@ set_methregister_error(topo_mod_t *mod, tnode_t *node, topo_imethod_t *mp, topo_mod_free(mod, mp, sizeof (topo_imethod_t)); } - topo_dprintf(TOPO_DBG_ERR, "method registration failed for %s: %s\n", + 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)); @@ -150,7 +151,8 @@ topo_method_register(topo_mod_t *mod, tnode_t *node, const topo_method_t *mp) topo_list_append(&node->tn_methods, imp); topo_node_unlock(node); - topo_dprintf(TOPO_DBG_MOD, "registered module %s method " + 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)); diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_method.h b/usr/src/lib/fm/topo/libtopo/common/topo_method.h new file mode 100644 index 0000000000..df004ccec4 --- /dev/null +++ b/usr/src/lib/fm/topo/libtopo/common/topo_method.h @@ -0,0 +1,83 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _TOPO_METHOD_H +#define _TOPO_METHOD_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * FMRI methods + */ +#define TOPO_METH_ASRU_COMPUTE "topo_asru_compute" +#define TOPO_METH_FRU_COMPUTE "topo_fru_compute" +#define TOPO_METH_FMRI "topo_fmri" +#define TOPO_METH_NVL2STR "topo_nvl2str" +#define TOPO_METH_STR2NVL "topo_str2nvl" +#define TOPO_METH_CONTAINS "topo_contains" +#define TOPO_METH_UNUSABLE "topo_unusable" +#define TOPO_METH_EXPAND "topo_expand" +#define TOPO_METH_COMPARE "topo_compare" + +#define TOPO_METH_FMRI_VERSION 0 +#define TOPO_METH_FRU_COMPUTE_VERSION 0 +#define TOPO_METH_ASRU_COMPUTE_VERSION 0 +#define TOPO_METH_NVL2STR_VERSION 0 +#define TOPO_METH_STR2NVL_VERSION 0 +#define TOPO_METH_CONTAINS_VERSION 0 +#define TOPO_METH_UNUSABLE_VERSION 0 +#define TOPO_METH_EXPAND_VERSION 0 +#define TOPO_METH_COMPARE_VERSION 0 + +#define TOPO_METH_ASRU_COMPUTE_DESC "Dynamic ASRU constructor" +#define TOPO_METH_FRU_COMPUTE_DESC "Dynamic FRU constructor" +#define TOPO_METH_FMRI_DESC "Dynamic FMRI constructor" +#define TOPO_METH_NVL2STR_DESC "FMRI to string" +#define TOPO_METH_STR2NVL_DESC "string to FMRI" +#define TOPO_METH_CONTAINS_DESC "FMRI contains sub-FMRI" +#define TOPO_METH_UNUSABLE_DESC "FMRI is unusable" +#define TOPO_METH_EXPAND_DESC "expand FMRI" +#define TOPO_METH_COMPARE_DESC "compare two FMRIs" + +#define TOPO_METH_FMRI_ARG_NAME "child-name" +#define TOPO_METH_FMRI_ARG_INST "child-inst" +#define TOPO_METH_FMRI_ARG_NVL "args" +#define TOPO_METH_FMRI_ARG_PARENT "parent-fmri" +#define TOPO_METH_FMRI_ARG_AUTH "auth" +#define TOPO_METH_FMRI_ARG_PART "part" +#define TOPO_METH_FMRI_ARG_REV "rev" +#define TOPO_METH_FMRI_ARG_SER "serial" +#define TOPO_METH_FMRI_ARG_HCS "hc-specific" + +#ifdef __cplusplus +} +#endif + +#endif /* _TOPO_METHOD_H */ diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.c b/usr/src/lib/fm/topo/libtopo/common/topo_mod.c index 80a2088920..6daafcd511 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -70,51 +69,60 @@ #include <alloca.h> #include <unistd.h> #include <stdio.h> +#include <sys/param.h> +#include <sys/utsname.h> +#include <sys/smbios.h> +#include <sys/fm/protocol.h> -#include <topo_module.h> #include <topo_alloc.h> -#include <topo_string.h> #include <topo_error.h> +#include <topo_file.h> +#include <topo_module.h> +#include <topo_method.h> +#include <topo_string.h> #include <topo_subr.h> +#include <topo_tree.h> + +#define PLUGIN_PATH "plugins" +#define PLUGIN_PATH_LEN MAXNAMELEN + 5 topo_mod_t * -topo_mod_load(topo_mod_t *pmod, const char *path) +topo_mod_load(topo_mod_t *pmod, const char *name, + topo_version_t version) { - int err = 0; - char *p; + char *path; + char file[PLUGIN_PATH_LEN]; topo_mod_t *mod = NULL; topo_hdl_t *thp; thp = pmod->tm_hdl; /* - * Already loaded, bump the ref count + * Already loaded, topo_mod_lookup will bump the ref count */ - if ((mod = topo_mod_lookup(thp, path)) != NULL) { - topo_mod_hold(mod); + if ((mod = topo_mod_lookup(thp, name, 1)) != NULL) { + if (mod->tm_info->tmi_version != version) { + topo_mod_rele(mod); + (void) topo_mod_seterrno(pmod, ETOPO_MOD_VER); + return (NULL); + } return (mod); } - /* - * Check for a valid path - */ - if (access(path, F_OK) != 0) { - (void) topo_mod_seterrno(pmod, ETOPO_MOD_NOENT); - return (NULL); - } - - if ((p = strrchr(path, '.')) != NULL && strcmp(p, ".so") == 0) { - if ((mod = topo_modhash_load(thp, path, - &topo_rtld_ops)) == NULL) { /* returned with mod held */ - (void) topo_mod_seterrno(pmod, err ? err : - ETOPO_MOD_NOENT); + (void) snprintf(file, PLUGIN_PATH_LEN, "%s/%s.so", + PLUGIN_PATH, name); + path = topo_search_path(pmod, thp->th_rootdir, (const char *)file); + if (path == NULL || + (mod = topo_modhash_load(thp, name, path, &topo_rtld_ops, version)) + == NULL) { /* returned with mod held */ + topo_mod_strfree(pmod, path); + (void) topo_mod_seterrno(pmod, topo_hdl_errno(thp) ? + topo_hdl_errno(thp) : ETOPO_MOD_NOENT); return (NULL); - } - } else { - (void) topo_mod_seterrno(pmod, err ? err : ETOPO_MOD_NOENT); - return (NULL); } + topo_mod_strfree(pmod, path); + return (mod); } @@ -130,49 +138,48 @@ set_register_error(topo_mod_t *mod, int err) if (mod->tm_info != NULL) topo_mod_unregister(mod); - topo_dprintf(TOPO_DBG_ERR, "module registration failed for %s: %s\n", + topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, + "module registration failed for %s: %s\n", mod->tm_name, topo_strerror(err)); return (topo_mod_seterrno(mod, err)); } int -topo_mod_register(topo_mod_t *mod, const topo_modinfo_t *mip, void *priv) +topo_mod_register(topo_mod_t *mod, const topo_modinfo_t *mip, + topo_version_t version) { assert(!(mod->tm_flags & TOPO_MOD_FINI || mod->tm_flags & TOPO_MOD_REG)); - if (mod->tm_version > mip->tmi_version) - return (set_register_error(mod, ETOPO_VER_OLD)); - if (mod->tm_version < mip->tmi_version) - return (set_register_error(mod, ETOPO_VER_NEW)); + if (version != TOPO_VERSION) + return (set_register_error(mod, EMOD_VER_ABI)); - if ((mod->tm_info = topo_mod_alloc(mod, sizeof (topo_modinfo_t))) + if ((mod->tm_info = topo_mod_alloc(mod, sizeof (topo_imodinfo_t))) == NULL) - return (set_register_error(mod, ETOPO_NOMEM)); + return (set_register_error(mod, EMOD_NOMEM)); + if ((mod->tm_info->tmi_ops = topo_mod_alloc(mod, + sizeof (topo_modops_t))) == NULL) + return (set_register_error(mod, EMOD_NOMEM)); mod->tm_info->tmi_desc = topo_mod_strdup(mod, mip->tmi_desc); if (mod->tm_info->tmi_desc == NULL) - return (set_register_error(mod, ETOPO_NOMEM)); - - mod->tm_info->tmi_version = (topo_version_t)mip->tmi_version; - mod->tm_info->tmi_enum = mip->tmi_enum; - mod->tm_info->tmi_release = mip->tmi_release; + return (set_register_error(mod, EMOD_NOMEM)); - mod->tm_flags |= TOPO_MOD_REG; - mod->tm_priv = priv; + mod->tm_info->tmi_scheme = topo_mod_strdup(mod, mip->tmi_scheme); + if (mod->tm_info->tmi_scheme == NULL) + return (set_register_error(mod, EMOD_NOMEM)); - if (mod == NULL) { - topo_dprintf(TOPO_DBG_MOD, "registration succeeded for %s\n", - mod->tm_name); - return (0); - } + mod->tm_info->tmi_version = (topo_version_t)mip->tmi_version; + mod->tm_info->tmi_ops->tmo_enum = mip->tmi_ops->tmo_enum; + mod->tm_info->tmi_ops->tmo_release = mip->tmi_ops->tmo_release; + mod->tm_flags |= TOPO_MOD_REG; - topo_dprintf(TOPO_DBG_MOD, "registration succeeded for %s\n", - mod->tm_name); + topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC, + "registration succeeded for %s\n", mod->tm_name); return (0); } @@ -190,40 +197,47 @@ topo_mod_unregister(topo_mod_t *mod) if (mod->tm_info == NULL) return; + if (mod->tm_info->tmi_ops != NULL) + topo_mod_free(mod, mod->tm_info->tmi_ops, + sizeof (topo_modops_t)); if (mod->tm_info->tmi_desc != NULL) topo_mod_strfree(mod, mod->tm_info->tmi_desc); + if (mod->tm_info->tmi_scheme != NULL) + topo_mod_strfree(mod, mod->tm_info->tmi_scheme); - topo_mod_free(mod, mod->tm_info, sizeof (topo_modinfo_t)); + topo_mod_free(mod, mod->tm_info, sizeof (topo_imodinfo_t)); mod->tm_info = NULL; } int topo_mod_enumerate(topo_mod_t *mod, tnode_t *node, const char *enum_name, - const char *name, topo_instance_t min, topo_instance_t max) + const char *name, topo_instance_t min, topo_instance_t max, void *data) { int err = 0; topo_mod_t *enum_mod; assert(mod->tm_flags & TOPO_MOD_REG); - if ((enum_mod = topo_mod_lookup(mod->tm_hdl, enum_name)) == NULL) - return (topo_mod_seterrno(mod, ETOPO_MOD_NOENT)); + if ((enum_mod = topo_mod_lookup(mod->tm_hdl, enum_name, 0)) == NULL) + return (topo_mod_seterrno(mod, EMOD_MOD_NOENT)); topo_node_hold(node); - topo_dprintf(TOPO_DBG_MOD, "module %s enumerating node %s=%d\n", - (char *)mod->tm_name, (char *)node->tn_name, node->tn_instance); + topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC, "module %s enumerating " + "node %s=%d\n", (char *)mod->tm_name, (char *)node->tn_name, + node->tn_instance); topo_mod_enter(enum_mod); - err = enum_mod->tm_info->tmi_enum(enum_mod, node, name, min, max, - enum_mod->tm_priv); + err = enum_mod->tm_info->tmi_ops->tmo_enum(enum_mod, node, name, min, + max, enum_mod->tm_priv, data); topo_mod_exit(enum_mod); if (err != 0) { - (void) topo_mod_seterrno(mod, ETOPO_MODULE); + (void) topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM); - topo_dprintf(TOPO_DBG_ERR, "module %s failed enumeration for " + topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, + "module %s failed enumeration for " " node %s=%d\n", (char *)mod->tm_name, (char *)node->tn_name, node->tn_instance); @@ -236,28 +250,339 @@ topo_mod_enumerate(topo_mod_t *mod, tnode_t *node, const char *enum_name, return (0); } -char * -topo_mod_rootdir(topo_mod_t *mod) +int +topo_mod_enummap(topo_mod_t *mod, tnode_t *node, const char *name, + const char *scheme) +{ + return (topo_file_load(mod, node, (char *)name, (char *)scheme)); +} + +static nvlist_t * +set_fmri_err(topo_mod_t *mod, int err) +{ + (void) topo_mod_seterrno(mod, err); + return (NULL); +} + +nvlist_t * +topo_mod_hcfmri(topo_mod_t *mod, tnode_t *pnode, int version, const char *name, + topo_instance_t inst, nvlist_t *hc_specific, nvlist_t *auth, + const char *part, const char *rev, const char *serial) +{ + int err; + nvlist_t *pfmri = NULL, *fmri = NULL, *args = NULL; + nvlist_t *nfp = NULL; + + if (version != FM_HC_SCHEME_VERSION) + return (set_fmri_err(mod, EMOD_FMRI_VERSION)); + + /* + * Do we have any args to pass? + */ + if (pnode != NULL || auth != NULL || part != NULL || rev != NULL || + serial != NULL || hc_specific != NULL) { + if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + } + + if (pnode != NULL) { + if (topo_node_resource(pnode, &pfmri, &err) < 0) + return (set_fmri_err(mod, EMOD_NVL_INVAL)); + + if (nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, + pfmri) != 0) { + nvlist_free(pfmri); + nvlist_free(args); + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + } + nvlist_free(pfmri); + } + + /* + * Add optional payload + */ + if (auth != NULL) + (void) nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_AUTH, auth); + if (part != NULL) + (void) nvlist_add_string(args, TOPO_METH_FMRI_ARG_PART, part); + if (rev != NULL) + (void) nvlist_add_string(args, TOPO_METH_FMRI_ARG_REV, rev); + if (serial != NULL) + (void) nvlist_add_string(args, TOPO_METH_FMRI_ARG_SER, + serial); + if (hc_specific != NULL) + (void) nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_HCS, + hc_specific); + + if ((fmri = topo_fmri_create(mod->tm_hdl, FM_FMRI_SCHEME_HC, name, inst, + args, &err)) == NULL) { + nvlist_free(args); + return (set_fmri_err(mod, err)); + } + + nvlist_free(args); + + (void) topo_mod_nvdup(mod, fmri, &nfp); + nvlist_free(fmri); + + return (nfp); +} + +nvlist_t * +topo_mod_devfmri(topo_mod_t *mod, int version, const char *dev_path, + const char *devid) +{ + int err; + nvlist_t *fmri, *args; + nvlist_t *nfp = NULL; + + if (version != FM_DEV_SCHEME_VERSION) + return (set_fmri_err(mod, EMOD_FMRI_VERSION)); + + if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + + if (nvlist_add_string(args, FM_FMRI_DEV_PATH, dev_path) != 0) { + nvlist_free(args); + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + } + + (void) nvlist_add_string(args, FM_FMRI_DEV_ID, devid); + + if ((fmri = topo_fmri_create(mod->tm_hdl, FM_FMRI_SCHEME_DEV, + FM_FMRI_SCHEME_DEV, 0, args, &err)) == NULL) { + nvlist_free(args); + return (set_fmri_err(mod, err)); + } + + nvlist_free(args); + + (void) topo_mod_nvdup(mod, fmri, &nfp); + nvlist_free(fmri); + + return (nfp); +} + +nvlist_t * +topo_mod_cpufmri(topo_mod_t *mod, int version, uint32_t cpu_id, uint8_t cpumask, + const char *serial) +{ + int err; + nvlist_t *fmri = NULL, *args = NULL; + nvlist_t *nfp = NULL; + + if (version != FM_CPU_SCHEME_VERSION) + return (set_fmri_err(mod, EMOD_FMRI_VERSION)); + + if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + + if (nvlist_add_uint32(args, FM_FMRI_CPU_ID, cpu_id) != 0) { + nvlist_free(args); + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + } + + /* + * Add optional payload + */ + (void) nvlist_add_uint8(args, FM_FMRI_CPU_MASK, cpumask); + (void) nvlist_add_string(args, FM_FMRI_CPU_SERIAL_ID, serial); + + if ((fmri = topo_fmri_create(mod->tm_hdl, FM_FMRI_SCHEME_CPU, + FM_FMRI_SCHEME_CPU, 0, args, &err)) == NULL) { + nvlist_free(args); + return (set_fmri_err(mod, err)); + } + + nvlist_free(args); + + (void) topo_mod_nvdup(mod, fmri, &nfp); + nvlist_free(fmri); + + return (nfp); +} + +nvlist_t * +topo_mod_memfmri(topo_mod_t *mod, int version, uint64_t pa, uint64_t offset, + const char *unum, int flags) +{ + int err; + nvlist_t *args = NULL, *fmri = NULL; + nvlist_t *nfp = NULL; + + if (version != FM_MEM_SCHEME_VERSION) + return (set_fmri_err(mod, EMOD_FMRI_VERSION)); + + if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + + err = nvlist_add_string(args, FM_FMRI_MEM_UNUM, unum); + nvlist_free(args); + if (flags & TOPO_MEMFMRI_PA) + err |= nvlist_add_uint64(args, FM_FMRI_MEM_PHYSADDR, pa); + if (flags & TOPO_MEMFMRI_OFFSET) + err |= nvlist_add_uint64(args, FM_FMRI_MEM_OFFSET, offset); + + if (err != 0) { + nvlist_free(args); + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + } + + if ((fmri = topo_fmri_create(mod->tm_hdl, FM_FMRI_SCHEME_MEM, + FM_FMRI_SCHEME_MEM, 0, args, &err)) == NULL) { + nvlist_free(args); + return (set_fmri_err(mod, err)); + } + + nvlist_free(args); + + (void) topo_mod_nvdup(mod, fmri, &nfp); + nvlist_free(fmri); + + return (nfp); + +} + +nvlist_t * +topo_mod_pkgfmri(topo_mod_t *mod, int version, const char *path) +{ + int err; + nvlist_t *fmri = NULL, *args = NULL; + nvlist_t *nfp = NULL; + + if (version != FM_PKG_SCHEME_VERSION) + return (set_fmri_err(mod, EMOD_FMRI_VERSION)); + + if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + + if (nvlist_add_string(args, "path", path) != 0) { + nvlist_free(args); + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + } + + if ((fmri = topo_fmri_create(mod->tm_hdl, FM_FMRI_SCHEME_CPU, + FM_FMRI_SCHEME_CPU, 0, args, &err)) == NULL) { + nvlist_free(args); + return (set_fmri_err(mod, err)); + } + + nvlist_free(args); + + (void) topo_mod_nvdup(mod, fmri, &nfp); + nvlist_free(fmri); + + return (nfp); +} + +nvlist_t * +topo_mod_modfmri(topo_mod_t *mod, int version, const char *driver) { - return (mod->tm_rootdir); + int err; + nvlist_t *fmri = NULL, *args = NULL; + nvlist_t *nfp = NULL; + + if (version != FM_MOD_SCHEME_VERSION) + return (set_fmri_err(mod, EMOD_FMRI_VERSION)); + + if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + + if (nvlist_add_string(args, "DRIVER", driver) != 0) { + nvlist_free(args); + return (set_fmri_err(mod, EMOD_FMRI_NVL)); + } + + if ((fmri = topo_fmri_create(mod->tm_hdl, FM_FMRI_SCHEME_CPU, + FM_FMRI_SCHEME_CPU, 0, args, &err)) == NULL) { + nvlist_free(args); + return (set_fmri_err(mod, err)); + } + + nvlist_free(args); + + (void) topo_mod_nvdup(mod, fmri, &nfp); + nvlist_free(fmri); + + return (nfp); } -topo_hdl_t * -topo_mod_handle(topo_mod_t *mod) +int +topo_mod_str2nvl(topo_mod_t *mod, const char *fmristr, nvlist_t **fmri) { - return (mod->tm_hdl); + int err; + nvlist_t *np = NULL; + + if (topo_fmri_str2nvl(mod->tm_hdl, fmristr, &np, &err) < 0) + return (topo_mod_seterrno(mod, err)); + + if (topo_mod_nvdup(mod, np, fmri) < 0) { + nvlist_free(np); + return (topo_mod_seterrno(mod, EMOD_FMRI_NVL)); + } + + nvlist_free(np); + + return (0); +} + +int +topo_mod_nvl2str(topo_mod_t *mod, nvlist_t *fmri, char **fmristr) +{ + int err; + char *sp; + + if (topo_fmri_nvl2str(mod->tm_hdl, fmri, &sp, &err) < 0) + return (topo_mod_seterrno(mod, err)); + + if ((*fmristr = topo_mod_strdup(mod, sp)) == NULL) { + topo_hdl_strfree(mod->tm_hdl, sp); + return (topo_mod_seterrno(mod, EMOD_NOMEM)); + } + + topo_hdl_strfree(mod->tm_hdl, sp); + + return (0); } void * -topo_mod_private(topo_mod_t *mod) +topo_mod_getspecific(topo_mod_t *mod) { return (mod->tm_priv); } void -topo_mod_setdebug(topo_mod_t *mod, int mask) +topo_mod_setspecific(topo_mod_t *mod, void *data) +{ + mod->tm_priv = data; +} + +void +topo_mod_setdebug(topo_mod_t *mod) +{ + mod->tm_debug = 1; +} + +di_node_t +topo_mod_devinfo(topo_mod_t *mod) +{ + topo_hdl_t *thp = mod->tm_hdl; + + if (thp->th_di == DI_NODE_NIL) + thp->th_di = di_init("/", DINFOCPYALL); + + return (thp->th_di); +} + +di_prom_handle_t +topo_mod_prominfo(topo_mod_t *mod) { - mod->tm_debug |= mask; + topo_hdl_t *thp = mod->tm_hdl; + + if (thp->th_pi == DI_PROM_HANDLE_NIL) + thp->th_pi = di_prom_init(); + + return (thp->th_pi); } void @@ -270,12 +595,132 @@ topo_mod_clrdebug(topo_mod_t *mod) void topo_mod_dprintf(topo_mod_t *mod, const char *format, ...) { - if (mod->tm_debug & mod->tm_hdl->th_debug) { - va_list alist; + va_list alist; + + if (mod->tm_debug == 0) + return; + + va_start(alist, format); + topo_vdprintf(mod->tm_hdl, TOPO_DBG_MOD, (const char *)mod->tm_name, + format, alist); + va_end(alist); +} + +static char * +topo_mod_product(topo_mod_t *mod) +{ + return (topo_mod_strdup(mod, mod->tm_hdl->th_product)); +} + +static char * +topo_mod_server(topo_mod_t *mod) +{ + static struct utsname uts; - va_start(alist, format); - (void) fputs("libtopo DEBUG: ", stderr); - (void) vfprintf(stderr, format, alist); - va_end(alist); + (void) uname(&uts); + return (topo_mod_strdup(mod, uts.nodename)); +} + +static char * +topo_mod_csn(topo_mod_t *mod) +{ + char csn[MAXNAMELEN]; + di_prom_handle_t promh = DI_PROM_HANDLE_NIL; + di_node_t rooth = DI_NODE_NIL; + char *bufp, *str; + smbios_hdl_t *shp; + smbios_system_t s1; + smbios_info_t s2; + id_t id; + + if ((shp = smbios_open(NULL, SMB_VERSION, 0, NULL)) != NULL) { + if ((id = smbios_info_system(shp, &s1)) != SMB_ERR && + smbios_info_common(shp, id, &s2) != SMB_ERR) { + (void) strlcpy(csn, s2.smbi_serial, MAXNAMELEN); + } + smbios_close(shp); + + if (strcmp(csn, SMB_DEFAULT1) == 0 || + strcmp(csn, SMB_DEFAULT2) == 0) + return (NULL); + + /* + * Terminate CSN at the first white space + */ + if ((str = strchr(csn, ' ')) != NULL) + *str = '\0'; + + } else if ((rooth = topo_mod_devinfo(mod)) != DI_NODE_NIL && + (promh = topo_mod_prominfo(mod)) != DI_PROM_HANDLE_NIL) { + if (di_prom_prop_lookup_bytes(promh, rooth, "chassis-sn", + (unsigned char **)&bufp) != -1) { + (void) strlcpy(csn, bufp, MAXNAMELEN); + } else { + return (NULL); + } + } else { + return (NULL); } + + return (topo_mod_strdup(mod, csn)); +} + +nvlist_t * +topo_mod_auth(topo_mod_t *mod, tnode_t *pnode) +{ + int err; + char *prod = NULL; + char *csn = NULL; + char *server = NULL; + nvlist_t *auth; + + (void) topo_prop_get_string(pnode, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_PRODUCT, &prod, &err); + (void) topo_prop_get_string(pnode, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_CHASSIS, &csn, &err); + (void) topo_prop_get_string(pnode, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_SERVER, &server, &err); + + /* + * Let's do this the hard way + */ + if (prod == NULL) + prod = topo_mod_product(mod); + if (csn == NULL) + csn = topo_mod_csn(mod); + if (server == NULL) { + server = topo_mod_server(mod); + } + + /* + * No luck, return NULL + */ + if (!prod && !server && !csn) + return (NULL); + + if ((err = topo_mod_nvalloc(mod, &auth, NV_UNIQUE_NAME)) != 0) { + (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL); + return (NULL); + } + + if (prod != NULL) { + err |= nvlist_add_string(auth, FM_FMRI_AUTH_PRODUCT, prod); + topo_mod_strfree(mod, prod); + } + if (server != NULL) { + err |= nvlist_add_string(auth, FM_FMRI_AUTH_SERVER, server); + topo_mod_strfree(mod, server); + } + if (csn != NULL) { + err |= nvlist_add_string(auth, FM_FMRI_AUTH_CHASSIS, csn); + topo_mod_strfree(mod, csn); + } + + if (err != 0) { + nvlist_free(auth); + (void) topo_mod_seterrno(mod, EMOD_NVL_INVAL); + return (NULL); + } + + return (auth); } diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h index a0edeb0cb4..62d3f22b7b 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.h @@ -30,7 +30,9 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <fm/libtopo.h> +#include <fm/topo_hc.h> #include <libnvpair.h> +#include <libdevinfo.h> #ifdef __cplusplus extern "C" { @@ -44,7 +46,7 @@ typedef struct topo_mod topo_mod_t; typedef int topo_method_f(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); typedef int topo_enum_f(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); typedef void topo_release_f(topo_mod_t *, tnode_t *); typedef struct topo_method { @@ -55,78 +57,82 @@ typedef struct topo_method { topo_method_f *tm_func; /* Method function */ } topo_method_t; +typedef struct topo_modops { + topo_enum_f *tmo_enum; /* enumeration op */ + topo_release_f *tmo_release; /* resource release op */ +} topo_modops_t; + typedef struct topo_mod_info { - char *tmi_desc; /* Client module description */ - topo_version_t tmi_version; /* Client module version */ - topo_enum_f *tmi_enum; /* enumerator function */ - topo_release_f *tmi_release; /* de-enumerator function */ + const char *tmi_desc; /* module description */ + const char *tmi_scheme; /* enumeration scheme type */ + topo_version_t tmi_version; /* module version */ + const topo_modops_t *tmi_ops; /* module ops vector */ } topo_modinfo_t; -extern topo_mod_t *topo_mod_load(topo_mod_t *, const char *); +extern topo_mod_t *topo_mod_load(topo_mod_t *, const char *, topo_version_t); extern void topo_mod_unload(topo_mod_t *); -extern int topo_mod_register(topo_mod_t *, const topo_modinfo_t *, void *); +extern int topo_mod_register(topo_mod_t *, const topo_modinfo_t *, + topo_version_t); extern void topo_mod_unregister(topo_mod_t *); extern int topo_mod_enumerate(topo_mod_t *, tnode_t *, const char *, - const char *, topo_instance_t, topo_instance_t); + const char *, topo_instance_t, topo_instance_t, void *); +extern int topo_mod_enummap(topo_mod_t *mod, tnode_t *, const char *, + const char *); extern void topo_mod_release(topo_mod_t *, tnode_t *); -extern char *topo_mod_rootdir(topo_mod_t *); -extern void *topo_mod_private(topo_mod_t *); -extern topo_hdl_t *topo_mod_handle(topo_mod_t *); +extern void topo_mod_setspecific(topo_mod_t *, void *); +extern void *topo_mod_getspecific(topo_mod_t *); + +extern nvlist_t *topo_mod_cpufmri(topo_mod_t *, int, uint32_t, uint8_t, + const char *); +extern nvlist_t *topo_mod_devfmri(topo_mod_t *, int, const char *, + const char *); +extern nvlist_t *topo_mod_hcfmri(topo_mod_t *, tnode_t *, int, const char *, + topo_instance_t, nvlist_t *, nvlist_t *, const char *, const char *, + const char *); +extern nvlist_t *topo_mod_memfmri(topo_mod_t *, int, uint64_t, uint64_t, + const char *, int); +extern nvlist_t *topo_mod_modfmri(topo_mod_t *, int, const char *); +extern nvlist_t *topo_mod_pkgfmri(topo_mod_t *, int, const char *); +extern int topo_mod_nvl2str(topo_mod_t *, nvlist_t *, char **); +extern int topo_mod_str2nvl(topo_mod_t *, const char *, nvlist_t **); + +/* + * Flags for topo_mod_memfmri + */ +#define TOPO_MEMFMRI_PA 0x0001 /* Valid physical address */ +#define TOPO_MEMFMRI_OFFSET 0x0002 /* Valid offset */ extern int topo_method_register(topo_mod_t *, tnode_t *, const topo_method_t *); extern void topo_method_unregister(topo_mod_t *, tnode_t *, const char *); extern void topo_method_unregister_all(topo_mod_t *, tnode_t *); +extern di_node_t topo_mod_devinfo(topo_mod_t *); +extern di_prom_handle_t topo_mod_prominfo(topo_mod_t *); +extern nvlist_t *topo_mod_auth(topo_mod_t *, tnode_t *); + /* * FMRI methods */ -#define TOPO_METH_ASRU_COMPUTE "topo_asru_compute" -#define TOPO_METH_FRU_COMPUTE "topo_fru_compute" -#define TOPO_METH_FMRI "topo_fmri" #define TOPO_METH_LABEL "topo_label" -#define TOPO_METH_NVL2STR "topo_nvl2str" -#define TOPO_METH_STR2NVL "topo_str2nvl" +#define TOPO_METH_LABEL_DESC "Dynamic label discovery" +#define TOPO_METH_LABEL_VERSION0 0 +#define TOPO_METH_LABEL_VERSION TOPO_METH_LABEL_VERSION0 +#define TOPO_METH_LABEL_ARG_NVL "label-specific" +#define TOPO_METH_LABEL_RET_STR "label-string" + #define TOPO_METH_PRESENT "topo_present" -#define TOPO_METH_CONTAINS "topo_contains" -#define TOPO_METH_UNUSABLE "topo_unusable" -#define TOPO_METH_EXPAND "topo_expand" -#define TOPO_METH_COMPARE "topo_compare" - -#define TOPO_METH_FMRI_VERSION 0 -#define TOPO_METH_LABEL_VERSION 0 -#define TOPO_METH_FRU_COMPUTE_VERSION 0 -#define TOPO_METH_ASRU_COMPUTE_VERSION 0 -#define TOPO_METH_NVL2STR_VERSION 0 -#define TOPO_METH_STR2NVL_VERSION 0 -#define TOPO_METH_PRESENT_VERSION 0 -#define TOPO_METH_CONTAINS_VERSION 0 -#define TOPO_METH_UNUSABLE_VERSION 0 -#define TOPO_METH_EXPAND_VERSION 0 -#define TOPO_METH_COMPARE_VERSION 0 - -#define TOPO_METH_ASRU_COMPUTE_DESC "Dynamic ASRU constructor" -#define TOPO_METH_FRU_COMPUTE_DESC "Dynamic FRU constructor" -#define TOPO_METH_FMRI_DESC "Dynamic FMRI constructor" -#define TOPO_METH_LABEL_DESC "Dynamic label discovery" -#define TOPO_METH_NVL2STR_DESC "FMRI to string" -#define TOPO_METH_STR2NVL_DESC "string to FMRI" -#define TOPO_METH_PRESENT_DESC "FMRI is present" -#define TOPO_METH_CONTAINS_DESC "FMRI contains sub-FMRI" -#define TOPO_METH_UNUSABLE_DESC "FMRI is unusable" -#define TOPO_METH_EXPAND_DESC "expand FMRI" -#define TOPO_METH_COMPARE_DESC "compare two FMRIs" - -#define TOPO_METH_FMRI_ARG_NAME "child-name" -#define TOPO_METH_FMRI_ARG_INST "child-inst" -#define TOPO_METH_FMRI_ARG_NVL "args" -#define TOPO_METH_FMRI_ARG_PARENT "parent-fmri" -#define TOPO_METH_FMRI_ARG_AUTH "auth" -#define TOPO_METH_FMRI_ARG_PART "part" -#define TOPO_METH_FMRI_ARG_REV "rev" -#define TOPO_METH_FMRI_ARG_SER "serial" - -#define TOPO_METH_LABEL_ARG_NVL "label-private" -#define TOPO_METH_LABEL_RET_STR "label-string" +#define TOPO_METH_PRESENT_DESC "Dynamic label discovery" +#define TOPO_METH_PRESENT_VERSION0 0 +#define TOPO_METH_PRESENT_VERSION TOPO_METH_PRESENT_VERSION0 +#define TOPO_METH_PRESENT_RET "present-ret" + +#define TOPO_METH_ASRU_COMPUTE "topo_asru_compute" +#define TOPO_METH_ASRU_COMPUTE_VERSION 0 +#define TOPO_METH_ASRU_COMPUTE_DESC "Dynamic ASRU constructor" + +#define TOPO_METH_FRU_COMPUTE "topo_fru_compute" +#define TOPO_METH_FRU_COMPUTE_VERSION 0 +#define TOPO_METH_FRU_COMPUTE_DESC "Dynamic FRU constructor" extern void *topo_mod_alloc(topo_mod_t *, size_t); extern void *topo_mod_zalloc(topo_mod_t *, size_t); @@ -137,7 +143,7 @@ extern int topo_mod_nvalloc(topo_mod_t *, nvlist_t **, uint_t); extern int topo_mod_nvdup(topo_mod_t *, nvlist_t *, nvlist_t **); extern void topo_mod_clrdebug(topo_mod_t *); -extern void topo_mod_setdebug(topo_mod_t *, int); +extern void topo_mod_setdebug(topo_mod_t *); extern void topo_mod_dprintf(topo_mod_t *, const char *, ...); extern const char *topo_mod_errmsg(topo_mod_t *); extern int topo_mod_errno(topo_mod_t *); @@ -149,12 +155,20 @@ extern int topo_node_range_create(topo_mod_t *, tnode_t *, const char *, topo_instance_t, topo_instance_t); extern void topo_node_range_destroy(tnode_t *, const char *); extern tnode_t *topo_node_bind(topo_mod_t *, tnode_t *, const char *, - topo_instance_t, nvlist_t *, void *); + topo_instance_t, nvlist_t *); extern void topo_node_unbind(tnode_t *); +extern void topo_node_setspecific(tnode_t *, void *); +extern void *topo_node_getspecific(tnode_t *); +extern int topo_node_asru_set(tnode_t *node, nvlist_t *, int, int *); +extern int topo_node_fru_set(tnode_t *node, nvlist_t *, int, int *); +extern int topo_node_label_set(tnode_t *node, char *, int *); + +#define TOPO_ASRU_COMPUTE 0x0001 /* Compute ASRU dynamically */ +#define TOPO_FRU_COMPUTE 0x0002 /* Compute FRU dynamically */ /* * This enum definition is used to define a set of error tags associated with - * the fmd daemon's various error conditions. The shell script mkerror.sh is + * the module api error conditions. The shell script mkerror.sh is * used to parse this file and create a corresponding topo_error.c source file. * If you do something other than add a new error tag here, you may need to * update the mkerror shell script as it is based upon simple regexps. @@ -168,10 +182,13 @@ typedef enum topo_mod_errno { EMOD_FMRI_NVL, /* nvlist allocation failure for FMRI */ EMOD_FMRI_VERSION, /* invalid FMRI scheme version */ EMOD_FMRI_MALFORM, /* malformed FMRI */ - EMOD_VER_OLD, /* module compiled using an obsolete topo ABI */ - EMOD_VER_NEW, /* module is compiled using a newer topo ABI */ + EMOD_VER_ABI, /* registered with invalid ABI version */ + EMOD_VER_OLD, /* attempt to load obsolete module */ + EMOD_VER_NEW, /* attempt to load a newer module */ EMOD_NVL_INVAL, /* invalid nvlist */ EMOD_NONCANON, /* non-canonical component name requested */ + EMOD_MOD_NOENT, /* module lookup failed */ + EMOD_UKNOWN_ENUM, /* unknown enumeration error */ EMOD_END /* end of mod errno list (to ease auto-merge) */ } topo_mod_errno_t; diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_mod.map b/usr/src/lib/fm/topo/libtopo/common/topo_mod.map index d48b37c00d..d99b4a4a96 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_mod.map +++ b/usr/src/lib/fm/topo/libtopo/common/topo_mod.map @@ -5,9 +5,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -30,7 +29,8 @@ topo_node_bind = FUNCTION extern; topo_node_unbind = FUNCTION extern; topo_node_name = FUNCTION extern; - topo_node_private = FUNCTION extern; + topo_node_setspecific = FUNCTION extern; + topo_node_getspecific = FUNCTION extern; topo_node_instance = FUNCTION extern; topo_mod_alloc = FUNCTION extern; @@ -41,8 +41,6 @@ topo_mod_strfree = FUNCTION extern; topo_mod_strdup = FUNCTION extern; - topo_fmri_create = FUNCTION extern; - topo_mod_clrdebug = FUNCTION extern; topo_mod_setdebug = FUNCTION extern; topo_mod_dprintf = FUNCTION extern; @@ -54,10 +52,18 @@ topo_mod_register = FUNCTION extern; topo_mod_unregister = FUNCTION extern; topo_mod_enumerate = FUNCTION extern; + topo_mod_enummap = FUNCTION extern; topo_mod_release = FUNCTION extern; - topo_mod_rootdir = FUNCTION extern; - topo_mod_handle = FUNCTION extern; - topo_mod_private = FUNCTION extern; + topo_mod_getspecific = FUNCTION extern; + topo_mod_setspecific = FUNCTION extern; + topo_mod_hcfmri = FUNCTION extern; + topo_mod_devfmri = FUNCTION extern; + topo_mod_cpufmri = FUNCTION extern; + topo_mod_pkgfmri = FUNCTION extern; + topo_mod_modfmri = FUNCTION extern; + topo_mod_nvl2str = FUNCTION extern; + topo_mod_str2nvl = FUNCTION extern; + topo_mod_auth = FUNCTION extern; topo_method_register = FUNCTION extern; topo_method_unregister = FUNCTION extern; diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_module.c b/usr/src/lib/fm/topo/libtopo/common/topo_module.c index fc593173f8..424d983cf0 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_module.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_module.c @@ -50,8 +50,8 @@ topo_mod_release(topo_mod_t *mod, tnode_t *node) { topo_mod_enter(mod); - if (mod->tm_info->tmi_release != NULL) - mod->tm_info->tmi_release(mod, node); + if (mod->tm_info->tmi_ops->tmo_release != NULL) + mod->tm_info->tmi_ops->tmo_release(mod, node); topo_mod_exit(mod); } @@ -129,17 +129,20 @@ topo_mod_stop(topo_mod_t *mod) mod->tm_flags = TOPO_MOD_FINI; - topo_dprintf(TOPO_DBG_MOD, "module %s stopped\n", mod->tm_name); + topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC, + "module %s stopped\n", mod->tm_name); } static int -topo_mod_start(topo_mod_t *mod) +topo_mod_start(topo_mod_t *mod, topo_version_t version) { - topo_dprintf(TOPO_DBG_MOD, "starting module %s\n", mod->tm_name); + topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC, + "starting module %s\n", mod->tm_name); - if (mod->tm_mops->mop_init(mod) != 0) { - mod->tm_errno = errno ? errno : ETOPO_MOD_INIT; - topo_dprintf(TOPO_DBG_ERR, + if (mod->tm_mops->mop_init(mod, version) != 0) { + if (mod->tm_errno == 0) + mod->tm_errno = ETOPO_MOD_INIT; + topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, "module %s failed to initialize: %s\n", mod->tm_name, topo_strerror(mod->tm_errno)); return (-1); @@ -148,32 +151,26 @@ topo_mod_start(topo_mod_t *mod) mod->tm_flags |= TOPO_MOD_INIT; if (!(mod->tm_flags & TOPO_MOD_REG)) { - topo_dprintf(TOPO_DBG_ERR, + topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, "module %s failed to register\n", mod->tm_name); mod->tm_errno = ETOPO_MOD_NOREG; topo_mod_stop(mod); return (-1); } - topo_dprintf(TOPO_DBG_MOD, "module %s started\n", mod->tm_name); - return (0); } topo_mod_t * -topo_mod_lookup(topo_hdl_t *thp, const char *path) +topo_mod_lookup(topo_hdl_t *thp, const char *name, int bump) { - char *p; - char name[PATH_MAX]; topo_mod_t *mod; topo_modhash_t *mhp = thp->th_modhash; - (void) strlcpy(name, topo_strbasename(path), sizeof (name)); - if ((p = strrchr(name, '.')) != NULL && strcmp(p, ".so") == 0) - *p = '\0'; /* strip trailing .so from any module name */ - topo_modhash_lock(mhp); mod = topo_modhash_lookup(mhp, name); + if (mod != NULL && bump != 0) + topo_mod_hold(mod); topo_modhash_unlock(mhp); return (mod); @@ -203,7 +200,7 @@ topo_mod_destroy(topo_mod_t *mod) static topo_mod_t * set_create_error(topo_hdl_t *thp, topo_mod_t *mod, const char *path, int err) { - topo_dprintf(TOPO_DBG_ERR, "unable to load module %s: %s\n", + topo_dprintf(thp, TOPO_DBG_ERR, "unable to load module %s: %s\n", path, topo_strerror(err)); if (mod != NULL) @@ -216,7 +213,7 @@ set_create_error(topo_hdl_t *thp, topo_mod_t *mod, const char *path, int err) static topo_mod_t * topo_mod_create(topo_hdl_t *thp, const char *name, const char *path, - const topo_modops_t *ops) + const topo_imodops_t *ops, topo_version_t version) { topo_mod_t *mod; @@ -229,24 +226,23 @@ topo_mod_create(topo_hdl_t *thp, const char *name, const char *path, (void) pthread_mutex_init(&mod->tm_lock, NULL); mod->tm_name = topo_hdl_strdup(thp, name); - mod->tm_path = topo_hdl_strdup(thp, path); + if (path != NULL) + mod->tm_path = topo_hdl_strdup(thp, path); mod->tm_rootdir = topo_hdl_strdup(thp, thp->th_rootdir); - if (mod->tm_name == NULL || mod->tm_path == NULL || - mod->tm_rootdir == NULL) + if (mod->tm_name == NULL || mod->tm_rootdir == NULL) return (set_create_error(thp, mod, path, ETOPO_NOMEM)); - mod->tm_mops = (topo_modops_t *)ops; + mod->tm_mops = (topo_imodops_t *)ops; mod->tm_hdl = thp; mod->tm_alloc = thp->th_alloc; - mod->tm_version = TOPO_VERSION; /* * Module will be held upon a successful return from topo_mod_start() */ - if ((topo_mod_start(mod)) < 0) + if ((topo_mod_start(mod, version)) < 0) return (set_create_error(thp, mod, path, mod->tm_errno)); - topo_dprintf(TOPO_DBG_MOD, "loaded module %s\n", mod->tm_name); + topo_dprintf(thp, TOPO_DBG_MODSVC, "loaded module %s\n", mod->tm_name); return (mod); } @@ -305,20 +301,16 @@ topo_modhash_lookup(topo_modhash_t *mhp, const char *name) } topo_mod_t * -topo_modhash_load(topo_hdl_t *thp, const char *path, const topo_modops_t *ops) +topo_modhash_load(topo_hdl_t *thp, const char *name, const char *path, + const topo_imodops_t *ops, topo_version_t version) { - char name[PATH_MAX], *p; topo_modhash_t *mhp = thp->th_modhash; topo_mod_t *mod; uint_t h; topo_modhash_lock(mhp); - (void) strlcpy(name, topo_strbasename(path), sizeof (name)); - if ((p = strrchr(name, '.')) != NULL && strcmp(p, ".so") == 0) - *p = '\0'; /* strip trailing .so from any module name */ - - if ((mod = topo_mod_create(thp, name, path, ops)) == NULL) { + if ((mod = topo_mod_create(thp, name, path, ops, version)) == NULL) { topo_modhash_unlock(mhp); return (NULL); /* th_errno set */ } @@ -391,9 +383,12 @@ topo_modhash_unload_all(topo_hdl_t *thp) while (mp != NULL) { topo_mod_stop(mp); - assert(mp->tm_refs == 1); + /* + * At this point we are forcing all modules to + * stop, ignore any remaining module reference counts. + */ + mp->tm_refs = 0; - --mp->tm_refs; *pp = mp->tm_next; topo_mod_destroy(mp); mp = *pp; diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_module.h b/usr/src/lib/fm/topo/libtopo/common/topo_module.h index e482b524d1..45056a1933 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_module.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_module.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -38,10 +37,10 @@ extern "C" { #endif -typedef struct topo_modops { - int (*mop_init)(struct topo_mod *); +typedef struct topo_imodops { + int (*mop_init)(struct topo_mod *, topo_version_t version); int (*mop_fini)(struct topo_mod *); -} topo_modops_t; +} topo_imodops_t; #define TOPO_HASH_BUCKETS 3 @@ -52,6 +51,13 @@ struct topo_modhash { uint_t mh_nelems; /* number of modules in hash */ }; +typedef struct topo_imod_info { + char *tmi_desc; /* module description */ + char *tmi_scheme; /* enumeration scheme-type */ + topo_version_t tmi_version; /* module version */ + topo_modops_t *tmi_ops; /* module ops vector */ +} topo_imodinfo_t; + struct topo_mod { pthread_mutex_t tm_lock; /* Lock for tm_cv/owner/flags/refs */ pthread_cond_t tm_cv; /* Module condition variable */ @@ -63,14 +69,12 @@ struct topo_mod { char *tm_path; /* Full pathname of module file */ char *tm_rootdir; /* Relative root directory of module */ void *tm_priv; /* Module private data */ - topo_version_t tm_version; /* Module ABI version */ - topo_stability_t tm_stability; /* SMI stability level */ uint_t tm_refs; /* Module reference count */ uint_t tm_flags; /* Miscellaneous flags (see below) */ uint_t tm_debug; /* Debug printf mask */ void *tm_data; /* Private rtld/builtin data */ - topo_modops_t *tm_mops; /* Module class ops vector */ - topo_modinfo_t *tm_info; /* Module info registered with handle */ + topo_imodops_t *tm_mops; /* Module class ops vector */ + topo_imodinfo_t *tm_info; /* Module info registered with handle */ int tm_errno; /* Module error */ }; @@ -79,8 +83,7 @@ struct topo_mod { #define TOPO_MOD_REG 0x004 /* topo_modinfo_t registered */ #define TOPO_MOD_UNREG 0x008 /* Module unregistered */ -extern const topo_modops_t topo_bltin_ops; -extern const topo_modops_t topo_rtld_ops; +extern const topo_imodops_t topo_rtld_ops; extern void topo_mod_enter(topo_mod_t *); extern void topo_mod_exit(topo_mod_t *); @@ -90,13 +93,13 @@ extern void topo_mod_rele(topo_mod_t *); extern topo_modhash_t *topo_modhash_create(topo_hdl_t *); extern void topo_modhash_destroy(topo_hdl_t *); extern topo_mod_t *topo_modhash_lookup(topo_modhash_t *, const char *); -extern topo_mod_t *topo_modhash_load(topo_hdl_t *, const char *, - const topo_modops_t *); +extern topo_mod_t *topo_modhash_load(topo_hdl_t *, const char *, const char *, + const topo_imodops_t *, topo_version_t); extern void topo_modhash_unload(topo_mod_t *); extern void topo_modhash_unload_all(topo_hdl_t *); extern void topo_mod_release(topo_mod_t *, tnode_t *); -extern topo_mod_t *topo_mod_lookup(topo_hdl_t *, const char *); +extern topo_mod_t *topo_mod_lookup(topo_hdl_t *, const char *, int); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_node.c b/usr/src/lib/fm/topo/libtopo/common/topo_node.c index 2b9f8257a7..f8ef4432ca 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_node.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_node.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -77,10 +76,26 @@ #include <assert.h> #include <pthread.h> #include <strings.h> +#include <sys/fm/protocol.h> #include <topo_alloc.h> -#include <topo_tree.h> -#include <topo_subr.h> #include <topo_error.h> +#include <topo_method.h> +#include <topo_subr.h> +#include <topo_tree.h> + +static topo_pgroup_info_t protocol_pgroup = { + TOPO_PGROUP_PROTOCOL, + TOPO_STABILITY_PRIVATE, + TOPO_STABILITY_PRIVATE, + 1 +}; + +static const topo_pgroup_info_t auth_pgroup = { + FM_FMRI_AUTHORITY, + TOPO_STABILITY_PRIVATE, + TOPO_STABILITY_PRIVATE, + 1 +}; static void topo_node_destroy(tnode_t *node) @@ -95,8 +110,6 @@ topo_node_destroy(tnode_t *node) 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 */ @@ -126,8 +139,8 @@ topo_node_destroy(tnode_t *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); + if (mod->tm_info->tmi_ops->tmo_release != NULL) + mod->tm_info->tmi_ops->tmo_release(mod, node); topo_method_unregister_all(mod, node); @@ -203,8 +216,14 @@ topo_node_instance(tnode_t *node) return (node->tn_instance); } +void +topo_node_setspecific(tnode_t *node, void *data) +{ + node->tn_priv = data; +} + void * -topo_node_private(tnode_t *node) +topo_node_getspecific(tnode_t *node) { return (node->tn_priv); } @@ -215,7 +234,7 @@ node_create_seterror(topo_mod_t *mod, tnode_t *pnode, topo_nodehash_t *nhp, { topo_node_unlock(pnode); - topo_dprintf(TOPO_DBG_ERR, "unable to insert child:" + topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, "unable to insert child:" "%s\n", topo_strerror(err)); if (nhp != NULL) { @@ -276,8 +295,8 @@ topo_node_range_create(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_list_append(&pnode->tn_children, nhp); topo_node_unlock(pnode); - topo_dprintf(TOPO_DBG_MOD, "created node range %s[%d-%d]\n", name, - min, max); + topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC, + "created node range %s[%d-%d]\n", name, min, max); return (0); } @@ -370,7 +389,7 @@ node_bind_seterror(topo_mod_t *mod, tnode_t *pnode, tnode_t *node, int err) if (node == NULL) return (NULL); - topo_dprintf(TOPO_DBG_ERR, "unable to bind %s=%d: " + topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, "unable to bind %s=%d: " "%s\n", (node->tn_name != NULL ? node->tn_name : "unknown"), node->tn_instance, topo_strerror(err)); @@ -382,7 +401,7 @@ node_bind_seterror(topo_mod_t *mod, tnode_t *pnode, tnode_t *node, int err) tnode_t * topo_node_bind(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t inst, nvlist_t *fmri, void *priv) + topo_instance_t inst, nvlist_t *fmri) { int h, err; tnode_t *node; @@ -430,33 +449,30 @@ topo_node_bind(topo_mod_t *mod, tnode_t *pnode, const char *name, if (fmri == NULL) return (node_bind_seterror(mod, pnode, node, ETOPO_NODE_INVAL)); - if (topo_pgroup_create(node, TOPO_PGROUP_PROTOCOL, - TOPO_STABILITY_PRIVATE, &err) < 0) + if (topo_pgroup_create(node, &protocol_pgroup, &err) < 0) return (node_bind_seterror(mod, pnode, node, err)); if (topo_prop_set_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE, - TOPO_PROP_SET_ONCE, fmri, &err) < 0) + TOPO_PROP_IMMUTABLE, fmri, &err) < 0) return (node_bind_seterror(mod, pnode, node, err)); - topo_dprintf(TOPO_DBG_MOD, "node bound %s=%d\n", node->tn_name, - node->tn_instance); + topo_dprintf(mod->tm_hdl, TOPO_DBG_MODSVC, + "node bound %s=%d\n", node->tn_name, node->tn_instance); node->tn_state |= TOPO_NODE_BOUND; - node->tn_priv = priv; topo_node_hold(node); nhp->th_nodearr[h] = node; ++pnode->tn_refs; topo_node_unlock(pnode); - if (topo_pgroup_create(node, TOPO_PGROUP_SYSTEM, - TOPO_STABILITY_PRIVATE, &err) == 0) { - (void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM, - TOPO_PROP_PLATFORM, &err); - (void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM, - TOPO_PROP_ISA, &err); - (void) topo_prop_inherit(node, TOPO_PGROUP_SYSTEM, - TOPO_PROP_MACHINE, &err); + if (topo_pgroup_create(node, &auth_pgroup, &err) == 0) { + (void) topo_prop_inherit(node, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_PRODUCT, &err); + (void) topo_prop_inherit(node, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_CHASSIS, &err); + (void) topo_prop_inherit(node, FM_FMRI_AUTHORITY, + FM_FMRI_AUTH_SERVER, &err); } return (node); diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_parse.c b/usr/src/lib/fm/topo/libtopo/common/topo_parse.c index 847c9bad13..84658982d9 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_parse.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_parse.c @@ -31,24 +31,16 @@ #include <topo_alloc.h> #include <topo_error.h> #include <topo_parse.h> - -extern const char * const Name; -const char * const Min = "min"; -const char * const Max = "max"; - +#include <topo_subr.h> tf_info_t * -tf_info_new(topo_mod_t *mp, const char *fn, xmlDocPtr doc, xmlChar *scheme) +tf_info_new(topo_mod_t *mp, xmlDocPtr doc, xmlChar *scheme) { tf_info_t *r; if ((r = topo_mod_zalloc(mp, sizeof (tf_info_t))) == NULL) return (NULL); r->tf_flags = TF_LIVE; - if ((r->tf_fn = topo_mod_strdup(mp, fn)) == NULL) { - tf_info_free(mp, r); - return (NULL); - } if ((r->tf_scheme = topo_mod_strdup(mp, (char *)scheme)) == NULL) { tf_info_free(mp, r); return (NULL); @@ -62,8 +54,6 @@ tf_info_free(topo_mod_t *mp, tf_info_t *p) { if (p->tf_xdoc != NULL) xmlFreeDoc(p->tf_xdoc); - if (p->tf_fn != NULL) - topo_mod_strfree(mp, p->tf_fn); if (p->tf_scheme != NULL) topo_mod_strfree(mp, p->tf_scheme); tf_rdata_free(mp, p->tf_rd); @@ -77,7 +67,7 @@ tf_rdata_new(topo_mod_t *mp, tf_info_t *xinfo, xmlNodePtr n, tnode_t *troot) uint64_t ui; xmlChar *name = NULL; - topo_mod_dprintf(mp, "new rdata\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "new rdata\n"); if ((r = topo_mod_zalloc(mp, sizeof (tf_rdata_t))) == NULL) { (void) topo_mod_seterrno(mp, ETOPO_NOMEM); return (NULL); @@ -136,7 +126,7 @@ tf_idata_new(topo_mod_t *mp, topo_instance_t i, tnode_t *tn) { tf_idata_t *r; - topo_mod_dprintf(mp, "new idata %d\n", i); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "new idata %d\n", i); if ((r = topo_mod_zalloc(mp, sizeof (tf_idata_t))) == NULL) return (NULL); r->ti_tn = tn; @@ -155,11 +145,10 @@ tf_idata_free(topo_mod_t *mp, tf_idata_t *p) } int -tf_idata_insert(topo_mod_t *mp, tf_idata_t **head, tf_idata_t *ni) +tf_idata_insert(tf_idata_t **head, tf_idata_t *ni) { tf_idata_t *l, *p; - topo_mod_dprintf(mp, "idata insert %d\n", ni->ti_i); p = NULL; for (l = *head; l != NULL; l = l->ti_next) { if (ni->ti_i < l->ti_i) @@ -175,10 +164,9 @@ tf_idata_insert(topo_mod_t *mp, tf_idata_t **head, tf_idata_t *ni) } tf_idata_t * -tf_idata_lookup(topo_mod_t *mp, tf_idata_t *head, topo_instance_t i) +tf_idata_lookup(tf_idata_t *head, topo_instance_t i) { tf_idata_t *f; - topo_mod_dprintf(mp, "idata lookup %d\n", i); for (f = head; f != NULL; f = f->ti_next) if (i == f->ti_i) break; @@ -190,7 +178,8 @@ tf_pad_new(topo_mod_t *mp, int pcnt, int dcnt) { tf_pad_t *r; - topo_mod_dprintf(mp, "new pad p=%d, d=%d\n", pcnt, dcnt); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "new pad p=%d, d=%d\n", + pcnt, dcnt); if ((r = topo_mod_zalloc(mp, sizeof (tf_pad_t))) == NULL) return (NULL); r->tpad_pgcnt = pcnt; @@ -223,7 +212,5 @@ tf_edata_free(topo_mod_t *mp, tf_edata_t *p) return; if (p->te_name != NULL) xmlFree(p->te_name); - if (p->te_path != NULL) - xmlFree(p->te_path); topo_mod_free(mp, p, sizeof (tf_edata_t)); } diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_parse.h b/usr/src/lib/fm/topo/libtopo/common/topo_parse.h index b3516b0e06..4722c10779 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_parse.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_parse.h @@ -33,15 +33,13 @@ #include <libxml/parser.h> #include <libnvpair.h> #include <fm/libtopo.h> +#include <fm/topo_mod.h> #ifdef __cplusplus extern "C" { #endif -#define TOPO_DTD_PATH "topology.dtd.1" -#define TOPO_FILE "topology.xml" -#define TOPO_PLATFORM_PATH "%susr/platform/%s/lib/fm/topo/%s" -#define TOPO_COMMON_PATH "%susr/lib/fm/topo/%s" +#define TOPO_DTD_PATH "/usr/share/lib/xml/dtd/topology.dtd.1" /* * Plenty of room to hold string representation of an instance @@ -61,11 +59,8 @@ struct tf_info; */ typedef struct tf_edata { char *te_name; /* name of the enumerator, if any */ - char *te_path; /* path to the enumerator, if any */ topo_stability_t te_stab; /* stability of the enumerator, if any */ - int te_vers; /* version of the enumerator, if any */ - int te_amcnt; /* number of apply-methods */ - nvlist_t **te_ams; /* apply-methods */ + topo_version_t te_vers; /* version of the enumerator, if any */ } tf_edata_t; /* properties and dependents off of an instance or a range */ @@ -108,7 +103,6 @@ typedef struct tf_rdata { * affected, etc. */ typedef struct tf_info { - char *tf_fn; /* name of file read */ char *tf_scheme; /* scheme of topology in file */ /* UUID ? */ uint_t tf_flags; /* behavior modifiers (see values below) */ @@ -127,18 +121,69 @@ typedef struct tf_info { #define INV_PGRP_ALLPROPS "propgrp-props" #define INV_PGRP_NAME "propgrp-name" #define INV_PGRP_NPROP "propgrp-numprops" -#define INV_PGRP_STAB "propgrp-name-stability" +#define INV_PGRP_NMSTAB "propgrp-name-stability" +#define INV_PGRP_DSTAB "propgrp-data-stability" +#define INV_PGRP_VER "propgrp-version" #define INV_PNAME "prop-name" #define INV_PVAL "prop-val" #define INV_PVALTYPE "prop-valtype" -extern tf_idata_t *tf_idata_lookup(topo_mod_t *, tf_idata_t *, topo_instance_t); +/* + * Valid .xml element and attribute names + */ +#define Children "children" +#define Dependents "dependents" +#define FMRI "fmri" +#define Grouping "grouping" +#define Immutable "immutable" +#define Instance "instance" +#define Int32 "int32" +#define Int64 "int64" +#define Name "name" +#define Path "path" +#define Range "range" +#define Scheme "scheme" +#define Siblings "siblings" +#define Static "static" +#define String "string" +#define Topology "topology" +#define Type "type" +#define UInt32 "uint32" +#define UInt64 "uint64" +#define Value "value" +#define Verify "verify" +#define Version "version" +#define Min "min" +#define Max "max" + +#define Enum_meth "enum-method" +#define Propgrp "propgroup" +#define Propval "propval" + +#define Node "node" +#define Hc "hc" + +#define True "true" +#define False "false" + +#define Namestab "name-stability" +#define Datastab "data-stability" + +#define Evolving "Evolving" +#define External "External" +#define Internal "Internal" +#define Obsolete "Obsolete" +#define Private "Private" +#define Stable "Stable" +#define Standard "Standard" +#define Unstable "Unstable" + +extern tf_idata_t *tf_idata_lookup(tf_idata_t *, topo_instance_t); extern tf_rdata_t *tf_rdata_new(topo_mod_t *, tf_info_t *, xmlNodePtr, tnode_t *); extern tf_idata_t *tf_idata_new(topo_mod_t *, topo_instance_t, tnode_t *); extern tf_info_t *topo_xml_read(topo_mod_t *, const char *, const char *); -extern tf_info_t *tf_info_new(topo_mod_t *, - const char *, xmlDocPtr, xmlChar *); +extern tf_info_t *tf_info_new(topo_mod_t *, xmlDocPtr, xmlChar *); extern tf_pad_t *tf_pad_new(topo_mod_t *, int, int); extern void topo_xml_cleanup(topo_mod_t *, tf_info_t *); extern void tf_rdata_free(topo_mod_t *, tf_rdata_t *); @@ -148,9 +193,10 @@ extern void tf_info_free(topo_mod_t *, tf_info_t *); extern void tf_pad_free(topo_mod_t *, tf_pad_t *); extern int topo_xml_range_process(topo_mod_t *, xmlNodePtr, tf_rdata_t *); extern int topo_xml_enum(topo_mod_t *, tf_info_t *, tnode_t *); -extern int tf_idata_insert(topo_mod_t *, tf_idata_t **, tf_idata_t *); +extern int tf_idata_insert(tf_idata_t **, tf_idata_t *); extern int xmlattr_to_int(topo_mod_t *, xmlNodePtr, const char *, uint64_t *); -extern int xmlattr_to_stab(topo_mod_t *, xmlNodePtr, topo_stability_t *); +extern int xmlattr_to_stab(topo_mod_t *, xmlNodePtr, const char *, + topo_stability_t *); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_prop.c b/usr/src/lib/fm/topo/libtopo/common/topo_prop.c index d4c6259656..3548b8e916 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_prop.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_prop.c @@ -42,7 +42,7 @@ pgroup_get(tnode_t *node, const char *pgname) */ for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { - if (strcmp(pg->tpg_name, pgname) == 0) { + if (strcmp(pg->tpg_info->tpi_name, pgname) == 0) { return (pg); } } @@ -84,65 +84,187 @@ topo_prop_get(tnode_t *node, const char *pgname, const char *pname, int *err) } static int -prop_val_add(nvlist_t *nvl, topo_propval_t *pv) +prop_val_add(nvlist_t *nvl, topo_propval_t *pv, int *err) { + int ret = 0; + uint_t nelems; + + if (nvlist_add_int32(nvl, TOPO_PROP_VAL_TYPE, pv->tp_type) != 0) + return (-1); + switch (pv->tp_type) { case TOPO_TYPE_INT32: - return (nvlist_add_int32(nvl, TOPO_PROP_VAL_VAL, - pv->tp_u.tp_int32)); + { + int32_t val; + if ((ret = nvlist_lookup_int32(pv->tp_val, + TOPO_PROP_VAL_VAL, &val)) < 0) + break; + ret = nvlist_add_int32(nvl, TOPO_PROP_VAL_VAL, val); + } + break; case TOPO_TYPE_UINT32: - return (nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, - pv->tp_u.tp_uint32)); + { + uint32_t val; + if ((ret = nvlist_lookup_uint32(pv->tp_val, + TOPO_PROP_VAL_VAL, &val)) < 0) + break; + ret = nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, val); + } + break; case TOPO_TYPE_INT64: - return (nvlist_add_int64(nvl, TOPO_PROP_VAL_VAL, - pv->tp_u.tp_int64)); + { + int64_t val; + if ((ret = nvlist_lookup_int64(pv->tp_val, + TOPO_PROP_VAL_VAL, &val)) < 0) + break; + ret = nvlist_add_int64(nvl, TOPO_PROP_VAL_VAL, val); + } + break; case TOPO_TYPE_UINT64: - return (nvlist_add_uint64(nvl, TOPO_PROP_VAL_VAL, - pv->tp_u.tp_uint64)); + { + uint64_t val; + if ((ret = nvlist_lookup_uint64(pv->tp_val, + TOPO_PROP_VAL_VAL, &val)) < 0) + break; + ret = nvlist_add_uint64(nvl, TOPO_PROP_VAL_VAL, val); + } + break; case TOPO_TYPE_STRING: - return (nvlist_add_string(nvl, TOPO_PROP_VAL_VAL, - pv->tp_u.tp_string)); + { + char *val; + if ((ret = nvlist_lookup_string(pv->tp_val, + TOPO_PROP_VAL_VAL, &val)) < 0) + break; + ret = nvlist_add_string(nvl, TOPO_PROP_VAL_VAL, val); + } + break; case TOPO_TYPE_FMRI: - return (nvlist_add_nvlist(nvl, TOPO_PROP_VAL_VAL, - pv->tp_u.tp_fmri)); + { + nvlist_t *val; + if ((ret = nvlist_lookup_nvlist(pv->tp_val, + TOPO_PROP_VAL_VAL, &val)) < 0) + break; + ret = nvlist_add_nvlist(nvl, TOPO_PROP_VAL_VAL, val); + } + break; + case TOPO_TYPE_INT32_ARRAY: + { + int32_t *val; + if ((ret = nvlist_lookup_int32_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &val, &nelems)) < 0) + break; + ret = nvlist_add_int32_array(nvl, TOPO_PROP_VAL_VAL, + val, nelems); + } + break; + case TOPO_TYPE_UINT32_ARRAY: + { + uint32_t *val; + if ((ret = nvlist_lookup_uint32_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &val, &nelems)) < 0) + break; + ret = nvlist_add_uint32_array(nvl, TOPO_PROP_VAL_VAL, + val, nelems); + } + break; + case TOPO_TYPE_INT64_ARRAY: + { + int64_t *val; + if ((ret = nvlist_lookup_int64_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &val, &nelems)) < 0) + break; + ret = nvlist_add_int64_array(nvl, TOPO_PROP_VAL_VAL, + val, nelems); + } + break; + case TOPO_TYPE_UINT64_ARRAY: + { + uint64_t *val; + if ((ret = nvlist_lookup_uint64_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &val, &nelems)) < 0) + break; + ret = nvlist_add_uint64_array(nvl, TOPO_PROP_VAL_VAL, + val, nelems); + } + break; + case TOPO_TYPE_STRING_ARRAY: + { + char **val; + if ((ret = nvlist_lookup_string_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &val, &nelems)) < 0) + break; + ret = nvlist_add_string_array(nvl, TOPO_PROP_VAL_VAL, + val, nelems); + } + break; + case TOPO_TYPE_FMRI_ARRAY: + { + nvlist_t **val; + if ((ret = nvlist_lookup_nvlist_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &val, &nelems)) < 0) + break; + ret = nvlist_add_nvlist_array(nvl, TOPO_PROP_VAL_VAL, + val, nelems); + } + break; default: - return (ETOPO_PROP_TYPE); + ret = ETOPO_PROP_TYPE; } + + if (ret != 0) { + if (ret == ENOMEM) + *err = ETOPO_NOMEM; + else + *err = ETOPO_PROP_NVL; + return (-1); + } + + return (0); } nvlist_t * -get_all_seterror(topo_hdl_t *thp, nvlist_t *nvl, int err) +get_all_seterror(tnode_t *node, nvlist_t *nvl, int *errp, int err) { + topo_node_unlock(node); + if (nvl != NULL) nvlist_free(nvl); - (void) topo_hdl_seterrno(thp, err); + *errp = err; return (NULL); } nvlist_t * -topo_prop_get_all(topo_hdl_t *thp, tnode_t *node) +topo_prop_getprops(tnode_t *node, int *err) { - int err; + int ret; + topo_hdl_t *thp = node->tn_hdl; nvlist_t *nvl, *pgnvl, *pvnvl; topo_pgroup_t *pg; topo_propval_t *pv; topo_proplist_t *pvl; if (topo_hdl_nvalloc(thp, &nvl, 0) != 0) { - return (get_all_seterror(thp, NULL, ETOPO_NOMEM)); + return (get_all_seterror(node, NULL, err, ETOPO_NOMEM)); } + topo_node_lock(node); for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { - err = 0; if (topo_hdl_nvalloc(thp, &pgnvl, 0) != 0) - return (get_all_seterror(thp, nvl, ETOPO_NOMEM)); - - if ((err = nvlist_add_string(pgnvl, TOPO_PROP_GROUP_NAME, - pg->tpg_name)) != 0) - return (get_all_seterror(thp, nvl, err)); + return (get_all_seterror(node, nvl, err, ETOPO_NOMEM)); + + if (nvlist_add_string(pgnvl, TOPO_PROP_GROUP_NAME, + pg->tpg_info->tpi_name) != 0 || + nvlist_add_string(pgnvl, TOPO_PROP_GROUP_NSTAB, + topo_stability2name(pg->tpg_info->tpi_namestab)) != 0 || + nvlist_add_string(pgnvl, TOPO_PROP_GROUP_DSTAB, + topo_stability2name(pg->tpg_info->tpi_datastab)) != 0 || + nvlist_add_int32(pgnvl, TOPO_PROP_GROUP_VERSION, + pg->tpg_info->tpi_version) != 0) + return (get_all_seterror(node, nvl, err, + ETOPO_PROP_NVL)); for (pvl = topo_list_next(&pg->tpg_pvals); pvl != NULL; pvl = topo_list_next(pvl)) { @@ -151,38 +273,40 @@ topo_prop_get_all(topo_hdl_t *thp, tnode_t *node) if (topo_hdl_nvalloc(thp, &pvnvl, 0) != 0) { nvlist_free(pgnvl); - return (get_all_seterror(thp, nvl, + return (get_all_seterror(node, nvl, err, ETOPO_NOMEM)); } - if ((err = nvlist_add_string(pvnvl, TOPO_PROP_VAL_NAME, + if ((ret = nvlist_add_string(pvnvl, TOPO_PROP_VAL_NAME, pv->tp_name)) != 0) { nvlist_free(pgnvl); nvlist_free(pvnvl); - return (get_all_seterror(thp, nvl, err)); + return (get_all_seterror(node, nvl, err, ret)); } - if ((err = prop_val_add(pvnvl, pv)) != 0) { + if (prop_val_add(pvnvl, pv, err) < 0) { nvlist_free(pgnvl); nvlist_free(pvnvl); - return (get_all_seterror(thp, nvl, err)); + return (get_all_seterror(node, nvl, err, ret)); } - if ((err = nvlist_add_nvlist(pgnvl, TOPO_PROP_VAL, + if ((ret = nvlist_add_nvlist(pgnvl, TOPO_PROP_VAL, pvnvl)) != 0) { nvlist_free(pgnvl); nvlist_free(pvnvl); - return (get_all_seterror(thp, nvl, err)); + return (get_all_seterror(node, nvl, err, ret)); } nvlist_free(pvnvl); } - if ((err = nvlist_add_nvlist(nvl, TOPO_PROP_GROUP, pgnvl)) + if ((ret = nvlist_add_nvlist(nvl, TOPO_PROP_GROUP, pgnvl)) != 0) { nvlist_free(pgnvl); - return (get_all_seterror(thp, nvl, err)); + return (get_all_seterror(node, nvl, err, ret)); } nvlist_free(pgnvl); } + topo_node_unlock(node); + return (nvl); } @@ -194,10 +318,12 @@ get_seterror(tnode_t *node, int *errp, int err) return (-1); } -int -topo_prop_get_int32(tnode_t *node, const char *pgname, const char *pname, - int32_t *val, int *err) +static int +prop_getval(tnode_t *node, const char *pgname, const char *pname, void *val, + topo_type_t type, uint_t *nelems, int *err) { + int i, j, ret = 0; + topo_hdl_t *thp = node->tn_hdl; topo_propval_t *pv; topo_node_lock(node); @@ -205,139 +331,288 @@ topo_prop_get_int32(tnode_t *node, const char *pgname, const char *pname, == NULL) return (get_seterror(node, err, *err)); - if (pv->tp_type != TOPO_TYPE_INT32) + if (pv->tp_type != type) return (get_seterror(node, err, ETOPO_PROP_TYPE)); - *val = pv->tp_u.tp_int32; + switch (type) { + case TOPO_TYPE_INT32: + ret = nvlist_lookup_int32(pv->tp_val, TOPO_PROP_VAL_VAL, + (int32_t *)val); + break; + case TOPO_TYPE_UINT32: + ret = nvlist_lookup_uint32(pv->tp_val, + TOPO_PROP_VAL_VAL, (uint32_t *)val); + break; + case TOPO_TYPE_INT64: + ret = nvlist_lookup_int64(pv->tp_val, TOPO_PROP_VAL_VAL, + (int64_t *)val); + break; + case TOPO_TYPE_UINT64: + ret = nvlist_lookup_uint64(pv->tp_val, + TOPO_PROP_VAL_VAL, (uint64_t *)val); + break; + case TOPO_TYPE_STRING: { + char *str; - topo_node_unlock(node); + ret = nvlist_lookup_string(pv->tp_val, + TOPO_PROP_VAL_VAL, &str); + if (ret == 0) + *(char **)val = topo_hdl_strdup(thp, str); + break; + } + case TOPO_TYPE_FMRI: { + nvlist_t *nvl; + + ret = nvlist_lookup_nvlist(pv->tp_val, + TOPO_PROP_VAL_VAL, &nvl); + if (ret == 0) + ret = topo_hdl_nvdup(thp, nvl, + (nvlist_t **)val); + break; + } + case TOPO_TYPE_INT32_ARRAY: { + int32_t *a1, *a2; + + if ((ret = nvlist_lookup_int32_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) + break; + if ((a1 = topo_hdl_alloc(thp, sizeof (int32_t) * + *nelems)) == NULL) { + ret = ETOPO_NOMEM; + break; + } + for (i = 0; i < *nelems; ++i) + a1[i] = a2[i]; + *(int32_t **)val = a1; + break; + } + case TOPO_TYPE_UINT32_ARRAY: { + uint32_t *a1, *a2; + + if ((ret = nvlist_lookup_uint32_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) + break; + if ((a1 = topo_hdl_alloc(thp, sizeof (uint32_t) * + *nelems)) == NULL) { + ret = ETOPO_NOMEM; + break; + } + for (i = 0; i < *nelems; ++i) + a1[i] = a2[i]; + *(uint32_t **)val = a1; + break; + } + case TOPO_TYPE_INT64_ARRAY: { + int64_t *a1, *a2; + + if ((ret = nvlist_lookup_int64_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) + break; + if ((a1 = topo_hdl_alloc(thp, sizeof (int64_t) * + *nelems)) == NULL) { + ret = ETOPO_NOMEM; + break; + } + for (i = 0; i < *nelems; ++i) + a1[i] = a2[i]; + *(int64_t **)val = a1; + break; + } + case TOPO_TYPE_UINT64_ARRAY: { + uint64_t *a1, *a2; + + if ((ret = nvlist_lookup_uint64_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) + break; + if ((a1 = topo_hdl_alloc(thp, sizeof (uint64_t) * + *nelems)) == NULL) { + ret = ETOPO_NOMEM; + break; + } + for (i = 0; i < *nelems; ++i) + a1[i] = a2[i]; + *(uint64_t **)val = a1; + break; + } + case TOPO_TYPE_STRING_ARRAY: { + char **a1, **a2; + + if ((ret = nvlist_lookup_string_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) + break; + if ((a1 = topo_hdl_alloc(thp, sizeof (char *) * + *nelems)) == NULL) { + ret = ETOPO_NOMEM; + break; + } + for (i = 0; i < *nelems; ++i) { + if ((a1[i] = topo_hdl_strdup(thp, a2[i])) + == NULL) { + for (j = 0; j < i; ++j) + topo_hdl_free(thp, a1[j], + sizeof (char *)); + topo_hdl_free(thp, a1, + sizeof (char *) * *nelems); + break; + } + } + *(char ***)val = a1; + break; + } + case TOPO_TYPE_FMRI_ARRAY: { + nvlist_t **a1, **a2; + + if ((ret = nvlist_lookup_nvlist_array(pv->tp_val, + TOPO_PROP_VAL_VAL, &a2, nelems)) != 0) + break; + if ((a1 = topo_hdl_alloc(thp, sizeof (nvlist_t *) * + *nelems)) == NULL) { + ret = ETOPO_NOMEM; + break; + } + for (i = 0; i < *nelems; ++i) { + if (topo_hdl_nvdup(thp, a2[i], &a1[i]) < 0) { + for (j = 0; j < i; ++j) + nvlist_free(a1[j]); + topo_hdl_free(thp, a1, + sizeof (nvlist_t *) * *nelems); + break; + } + } + *(nvlist_t ***)val = a1; + break; + } + default: + ret = ETOPO_PROP_NOENT; + } + + if (ret != 0) + if (ret == ENOENT) + return (get_seterror(node, err, ETOPO_PROP_NOENT)); + else if (ret < ETOPO_UNKNOWN) + return (get_seterror(node, err, ETOPO_PROP_NVL)); + else + return (get_seterror(node, err, ret)); + topo_node_unlock(node); return (0); } int +topo_prop_get_int32(tnode_t *node, const char *pgname, const char *pname, + int32_t *val, int *err) +{ + return (prop_getval(node, pgname, pname, (void *)val, TOPO_TYPE_INT32, + NULL, err)); +} + +int topo_prop_get_uint32(tnode_t *node, const char *pgname, const char *pname, uint32_t *val, int *err) { - topo_propval_t *pv; - - topo_node_lock(node); - if ((pv = topo_prop_get(node, pgname, pname, err)) - == NULL) - return (get_seterror(node, err, *err)); - - if (pv->tp_type != TOPO_TYPE_UINT32) - return (get_seterror(node, err, ETOPO_PROP_TYPE)); - - *val = pv->tp_u.tp_uint32; - - topo_node_unlock(node); - - return (0); + return (prop_getval(node, pgname, pname, (void *)val, TOPO_TYPE_UINT32, + NULL, err)); } int topo_prop_get_int64(tnode_t *node, const char *pgname, const char *pname, int64_t *val, int *err) { - topo_propval_t *pv; - - topo_node_lock(node); - if ((pv = topo_prop_get(node, pgname, pname, err)) - == NULL) - return (get_seterror(node, err, *err)); - - if (pv->tp_type != TOPO_TYPE_INT64) - return (get_seterror(node, err, ETOPO_PROP_TYPE)); - - *val = pv->tp_u.tp_int64; - - topo_node_unlock(node); - - return (0); + return (prop_getval(node, pgname, pname, (void *)val, TOPO_TYPE_INT64, + NULL, err)); } int topo_prop_get_uint64(tnode_t *node, const char *pgname, const char *pname, uint64_t *val, int *err) { - topo_propval_t *pv; - - topo_node_lock(node); - if ((pv = topo_prop_get(node, pgname, pname, err)) - == NULL) - return (get_seterror(node, err, *err)); - - if (pv->tp_type != TOPO_TYPE_UINT64) - return (get_seterror(node, err, ETOPO_PROP_TYPE)); - - *val = pv->tp_u.tp_int64; - - topo_node_unlock(node); - - return (0); + return (prop_getval(node, pgname, pname, (void *)val, TOPO_TYPE_UINT64, + NULL, err)); } int topo_prop_get_string(tnode_t *node, const char *pgname, const char *pname, char **val, int *err) { - topo_propval_t *pv; - - topo_node_lock(node); - if ((pv = topo_prop_get(node, pgname, pname, err)) == NULL) - return (get_seterror(node, err, *err)); - - if (pv->tp_type != TOPO_TYPE_STRING) - return (get_seterror(node, err, ETOPO_PROP_TYPE)); - - if ((*val = topo_hdl_strdup(node->tn_hdl, pv->tp_u.tp_string)) - == NULL) - return (get_seterror(node, err, ETOPO_NOMEM)); - - topo_node_unlock(node); - - return (0); + return (prop_getval(node, pgname, pname, (void *)val, TOPO_TYPE_STRING, + NULL, err)); } int topo_prop_get_fmri(tnode_t *node, const char *pgname, const char *pname, nvlist_t **val, int *err) { - topo_propval_t *pv; - - topo_node_lock(node); - if ((pv = topo_prop_get(node, pgname, pname, err)) == NULL) - return (get_seterror(node, err, *err)); + return (prop_getval(node, pgname, pname, (void *)val, TOPO_TYPE_FMRI, + NULL, err)); +} - if (pv->tp_type != TOPO_TYPE_FMRI) - return (get_seterror(node, err, ETOPO_PROP_TYPE)); +int +topo_prop_get_int32_array(tnode_t *node, const char *pgname, const char *pname, + int32_t **val, uint_t *nelem, int *err) +{ + return (prop_getval(node, pgname, pname, (void *)val, + TOPO_TYPE_INT32_ARRAY, nelem, err)); +} - if (topo_hdl_nvdup(node->tn_hdl, pv->tp_u.tp_fmri, val) < 0) - return (get_seterror(node, err, ETOPO_NOMEM)); +int +topo_prop_get_uint32_array(tnode_t *node, const char *pgname, const char *pname, + uint32_t **val, uint_t *nelem, int *err) +{ + return (prop_getval(node, pgname, pname, (void *)val, + TOPO_TYPE_UINT32_ARRAY, nelem, err)); +} - topo_node_unlock(node); +int +topo_prop_get_int64_array(tnode_t *node, const char *pgname, const char *pname, + int64_t **val, uint_t *nelem, int *err) +{ + return (prop_getval(node, pgname, pname, (void *)val, + TOPO_TYPE_INT64_ARRAY, nelem, err)); +} - return (0); +int +topo_prop_get_uint64_array(tnode_t *node, const char *pgname, const char *pname, + uint64_t **val, uint_t *nelem, int *err) +{ + return (prop_getval(node, pgname, pname, (void *)val, + TOPO_TYPE_UINT64_ARRAY, nelem, err)); } -static void -topo_propval_strfree(topo_propval_t *pv) +int +topo_prop_get_string_array(tnode_t *node, const char *pgname, const char *pname, + char ***val, uint_t *nelem, int *err) { - topo_hdl_strfree(pv->tp_hdl, pv->tp_u.tp_string); + return (prop_getval(node, pgname, pname, (void *)val, + TOPO_TYPE_STRING_ARRAY, nelem, err)); } -static void -topo_propval_nvlfree(topo_propval_t *pv) +int +topo_prop_get_fmri_array(tnode_t *node, const char *pgname, const char *pname, + nvlist_t ***val, uint_t *nelem, int *err) { - nvlist_free(pv->tp_u.tp_fmri); + return (prop_getval(node, pgname, pname, (void *)val, + TOPO_TYPE_FMRI_ARRAY, nelem, err)); } static int -set_seterror(tnode_t *node, int *errp, int err) +set_seterror(tnode_t *node, topo_proplist_t *pvl, int *errp, int err) { - topo_node_unlock(node); + topo_hdl_t *thp = node->tn_hdl; + topo_propval_t *pv; + + if (pvl != NULL) { + pv = pvl->tp_pval; + if (pv != NULL) { + if (pv->tp_name != NULL) + topo_hdl_strfree(thp, pv->tp_name); + if (pv->tp_val != NULL) + nvlist_free(pv->tp_val); + topo_hdl_free(thp, pv, sizeof (topo_propval_t)); + } + topo_hdl_free(thp, pvl, sizeof (topo_proplist_t)); + } + topo_node_unlock(node); *errp = err; return (-1); @@ -345,8 +620,9 @@ set_seterror(tnode_t *node, int *errp, int err) static int topo_prop_set(tnode_t *node, const char *pgname, const char *pname, - topo_type_t type, int flag, void *val, int *err) + topo_type_t type, int flag, void *val, int nelems, int *err) { + int ret, new_prop = 0; topo_hdl_t *thp = node->tn_hdl; topo_pgroup_t *pg; topo_propval_t *pv; @@ -354,13 +630,18 @@ topo_prop_set(tnode_t *node, const char *pgname, const char *pname, topo_node_lock(node); if ((pg = pgroup_get(node, pgname)) == NULL) - return (set_seterror(node, err, ETOPO_PROP_NOENT)); + return (set_seterror(node, NULL, err, ETOPO_PROP_NOENT)); + /* + * Replace existing prop value with new one + */ if ((pv = propval_get(pg, pname)) != NULL) { if (pv->tp_type != type) - return (set_seterror(node, err, ETOPO_PROP_TYPE)); - else if (pv->tp_flag == TOPO_PROP_SET_ONCE) - return (set_seterror(node, err, ETOPO_PROP_DEFD)); + return (set_seterror(node, NULL, err, ETOPO_PROP_TYPE)); + else if (pv->tp_flag == TOPO_PROP_IMMUTABLE) + return (set_seterror(node, NULL, err, ETOPO_PROP_DEFD)); + nvlist_free(pv->tp_val); + pv->tp_val = NULL; } else { /* * Property values may be a shared resources among @@ -369,58 +650,90 @@ topo_prop_set(tnode_t *node, const char *pgname, const char *pname, */ if ((pvl = topo_hdl_zalloc(thp, sizeof (topo_proplist_t))) == NULL) - return (set_seterror(node, err, ETOPO_NOMEM)); + return (set_seterror(node, NULL, err, ETOPO_NOMEM)); if ((pv = topo_hdl_zalloc(thp, sizeof (topo_propval_t))) - == NULL) { - topo_hdl_free(thp, pvl, sizeof (topo_proplist_t)); - return (set_seterror(node, err, ETOPO_NOMEM)); - } + == NULL) + return (set_seterror(node, pvl, err, ETOPO_NOMEM)); + pvl->tp_pval = pv; + if ((pv->tp_name = topo_hdl_strdup(thp, pname)) - == NULL) { - topo_hdl_free(thp, pvl, sizeof (topo_proplist_t)); - topo_hdl_free(thp, pv, sizeof (topo_propval_t)); - return (set_seterror(node, err, ETOPO_NOMEM)); - } + == NULL) + return (set_seterror(node, pvl, err, ETOPO_NOMEM)); pv->tp_flag = flag; pv->tp_type = type; pv->tp_hdl = thp; topo_prop_hold(pv); - pvl->tp_pval = pv; - topo_list_append(&pg->tpg_pvals, pvl); - - + new_prop++; } + if (topo_hdl_nvalloc(thp, &pv->tp_val, NV_UNIQUE_NAME) < 0) + return (set_seterror(node, pvl, err, ETOPO_PROP_NVL)); + + ret = 0; switch (type) { case TOPO_TYPE_INT32: - pv->tp_u.tp_int32 = *(int32_t *)val; + ret = nvlist_add_int32(pv->tp_val, TOPO_PROP_VAL_VAL, + *(int32_t *)val); break; case TOPO_TYPE_UINT32: - pv->tp_u.tp_uint32 = *(uint32_t *)val; + ret = nvlist_add_uint32(pv->tp_val, TOPO_PROP_VAL_VAL, + *(uint32_t *)val); break; case TOPO_TYPE_INT64: - pv->tp_u.tp_int64 = *(int64_t *)val; + ret = nvlist_add_int64(pv->tp_val, TOPO_PROP_VAL_VAL, + *(int64_t *)val); break; case TOPO_TYPE_UINT64: - pv->tp_u.tp_uint64 = *(uint64_t *)val; + ret = nvlist_add_uint64(pv->tp_val, TOPO_PROP_VAL_VAL, + *(uint64_t *)val); break; case TOPO_TYPE_STRING: - pv->tp_u.tp_string = topo_hdl_strdup(thp, (char *)val); - if (pv->tp_u.tp_string == NULL) - return (set_seterror(node, err, ETOPO_NOMEM)); - pv->tp_free = topo_propval_strfree; + ret = nvlist_add_string(pv->tp_val, TOPO_PROP_VAL_VAL, + (char *)val); break; case TOPO_TYPE_FMRI: - if (topo_hdl_nvdup(thp, - (nvlist_t *)val, &pv->tp_u.tp_fmri) < 0) - return (set_seterror(node, err, ETOPO_NOMEM)); - pv->tp_free = topo_propval_nvlfree; + ret = nvlist_add_nvlist(pv->tp_val, TOPO_PROP_VAL_VAL, + (nvlist_t *)val); + break; + case TOPO_TYPE_INT32_ARRAY: + ret = nvlist_add_int32_array(pv->tp_val, + TOPO_PROP_VAL_VAL, (int32_t *)val, nelems); + break; + case TOPO_TYPE_UINT32_ARRAY: + ret = nvlist_add_uint32_array(pv->tp_val, + TOPO_PROP_VAL_VAL, (uint32_t *)val, nelems); + break; + case TOPO_TYPE_INT64_ARRAY: + ret = nvlist_add_int64_array(pv->tp_val, + TOPO_PROP_VAL_VAL, (int64_t *)val, nelems); + break; + case TOPO_TYPE_UINT64_ARRAY: + ret = nvlist_add_uint64_array(pv->tp_val, + TOPO_PROP_VAL_VAL, (uint64_t *)val, nelems); + break; + case TOPO_TYPE_STRING_ARRAY: + ret = nvlist_add_string_array(pv->tp_val, + TOPO_PROP_VAL_VAL, (char **)val, nelems); + break; + case TOPO_TYPE_FMRI_ARRAY: + ret = nvlist_add_nvlist_array(pv->tp_val, + TOPO_PROP_VAL_VAL, (nvlist_t **)val, nelems); break; default: - return (set_seterror(node, err, ETOPO_PROP_TYPE)); + return (set_seterror(node, pvl, err, ETOPO_PROP_TYPE)); } + if (ret != 0) { + if (ret == ENOMEM) + return (set_seterror(node, pvl, err, ETOPO_NOMEM)); + else + return (set_seterror(node, pvl, err, ETOPO_PROP_NVL)); + } + + if (new_prop > 0) + topo_list_append(&pg->tpg_pvals, pvl); + topo_node_unlock(node); return (0); @@ -431,7 +744,7 @@ topo_prop_set_int32(tnode_t *node, const char *pgname, const char *pname, int flag, int32_t val, int *err) { return (topo_prop_set(node, pgname, pname, TOPO_TYPE_INT32, flag, - &val, err)); + &val, 1, err)); } int @@ -439,7 +752,7 @@ topo_prop_set_uint32(tnode_t *node, const char *pgname, const char *pname, int flag, uint32_t val, int *err) { return (topo_prop_set(node, pgname, pname, TOPO_TYPE_UINT32, flag, - &val, err)); + &val, 1, err)); } int @@ -447,7 +760,7 @@ topo_prop_set_int64(tnode_t *node, const char *pgname, const char *pname, int flag, int64_t val, int *err) { return (topo_prop_set(node, pgname, pname, TOPO_TYPE_INT64, flag, - &val, err)); + &val, 1, err)); } int @@ -455,7 +768,7 @@ topo_prop_set_uint64(tnode_t *node, const char *pgname, const char *pname, int flag, uint64_t val, int *err) { return (topo_prop_set(node, pgname, pname, TOPO_TYPE_UINT64, flag, - &val, err)); + &val, 1, err)); } int @@ -463,7 +776,7 @@ topo_prop_set_string(tnode_t *node, const char *pgname, const char *pname, int flag, const char *val, int *err) { return (topo_prop_set(node, pgname, pname, TOPO_TYPE_STRING, flag, - (void *)val, err)); + (void *)val, 1, err)); } int @@ -471,7 +784,55 @@ topo_prop_set_fmri(tnode_t *node, const char *pgname, const char *pname, int flag, const nvlist_t *fmri, int *err) { return (topo_prop_set(node, pgname, pname, TOPO_TYPE_FMRI, flag, - (void *)fmri, err)); + (void *)fmri, 1, err)); +} + +int +topo_prop_set_int32_array(tnode_t *node, const char *pgname, const char *pname, + int flag, int32_t *val, uint_t nelems, int *err) +{ + return (topo_prop_set(node, pgname, pname, TOPO_TYPE_INT32_ARRAY, flag, + val, nelems, err)); +} + +int +topo_prop_set_uint32_array(tnode_t *node, const char *pgname, const char *pname, + int flag, uint32_t *val, uint_t nelems, int *err) +{ + return (topo_prop_set(node, pgname, pname, TOPO_TYPE_UINT32_ARRAY, flag, + val, nelems, err)); +} + +int +topo_prop_set_int64_array(tnode_t *node, const char *pgname, const char *pname, + int flag, int64_t *val, uint_t nelems, int *err) +{ + return (topo_prop_set(node, pgname, pname, TOPO_TYPE_INT64_ARRAY, flag, + val, nelems, err)); +} + +int +topo_prop_set_uint64_array(tnode_t *node, const char *pgname, const char *pname, + int flag, uint64_t *val, uint_t nelems, int *err) +{ + return (topo_prop_set(node, pgname, pname, TOPO_TYPE_UINT64_ARRAY, flag, + val, nelems, err)); +} + +int +topo_prop_set_string_array(tnode_t *node, const char *pgname, const char *pname, + int flag, const char **val, uint_t nelems, int *err) +{ + return (topo_prop_set(node, pgname, pname, TOPO_TYPE_STRING_ARRAY, flag, + (void *)val, nelems, err)); +} + +int +topo_prop_set_fmri_array(tnode_t *node, const char *pgname, const char *pname, + int flag, const nvlist_t **fmri, uint_t nelems, int *err) +{ + return (topo_prop_set(node, pgname, pname, TOPO_TYPE_FMRI_ARRAY, flag, + (void *)fmri, nelems, err)); } static int @@ -508,7 +869,7 @@ topo_prop_inherit(tnode_t *node, const char *pgname, const char *name, int *err) /* * Can this propval be inherited? */ - if (pv->tp_flag != TOPO_PROP_SET_ONCE) + if (pv->tp_flag != TOPO_PROP_IMMUTABLE) return (inherit_seterror(node, err, ETOPO_PROP_NOINHERIT)); /* @@ -532,56 +893,108 @@ topo_prop_inherit(tnode_t *node, const char *pgname, const char *name, int *err) return (0); } -int -topo_prop_stability(tnode_t *node, const char *pgname, topo_stability_t *stab) +topo_pgroup_info_t * +topo_pgroup_info(tnode_t *node, const char *pgname, int *err) { + topo_hdl_t *thp = node->tn_hdl; topo_pgroup_t *pg; + topo_ipgroup_info_t *pip; + topo_pgroup_info_t *info; + topo_node_lock(node); for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { - if (strcmp(pgname, pg->tpg_name) == 0) { - *stab = pg->tpg_stability; - return (0); + if (strcmp(pgname, pg->tpg_info->tpi_name) == 0) { + if ((info = topo_hdl_alloc(thp, + sizeof (topo_pgroup_info_t))) == NULL) + return (NULL); + + pip = pg->tpg_info; + if ((info->tpi_name = + topo_hdl_strdup(thp, pip->tpi_name)) == NULL) { + *err = ETOPO_PROP_NOMEM; + topo_hdl_free(thp, info, + sizeof (topo_pgroup_info_t)); + topo_node_unlock(node); + return (NULL); + } + info->tpi_namestab = pip->tpi_namestab; + info->tpi_datastab = pip->tpi_datastab; + info->tpi_version = pip->tpi_version; + topo_node_unlock(node); + return (info); } } + *err = ETOPO_PROP_NOENT; + topo_node_unlock(node); + return (NULL); +} + +static int +pgroup_seterr(tnode_t *node, topo_pgroup_t *pg, topo_ipgroup_info_t *pip, + int *err) +{ + topo_hdl_t *thp = node->tn_hdl; + + if (pip != NULL) { + if (pip->tpi_name != NULL) + topo_hdl_strfree(thp, (char *)pip->tpi_name); + topo_hdl_free(thp, pip, sizeof (topo_ipgroup_info_t)); + } + + topo_hdl_free(thp, pg, sizeof (topo_pgroup_t)); + *err = ETOPO_NOMEM; + + topo_node_unlock(node); + return (-1); } int -topo_pgroup_create(tnode_t *node, const char *pname, topo_stability_t stab, - int *err) +topo_pgroup_create(tnode_t *node, const topo_pgroup_info_t *pinfo, int *err) { topo_pgroup_t *pg; + topo_ipgroup_info_t *pip; + topo_hdl_t *thp = node->tn_hdl; *err = 0; + topo_node_lock(node); /* * Check for an existing pgroup */ for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { - if (strcmp(pg->tpg_name, pname) == 0) { + if (strcmp(pg->tpg_info->tpi_name, pinfo->tpi_name) == 0) { *err = ETOPO_PROP_DEFD; + topo_node_unlock(node); return (-1); } } - if ((pg = topo_hdl_zalloc(node->tn_hdl, - sizeof (topo_pgroup_t))) == NULL) { + if ((pg = topo_hdl_zalloc(thp, sizeof (topo_pgroup_t))) == NULL) { *err = ETOPO_NOMEM; + topo_node_unlock(node); return (-1); } - if ((pg->tpg_name = topo_hdl_strdup(node->tn_hdl, pname)) == NULL) { - topo_hdl_free(node->tn_hdl, pg, sizeof (topo_pgroup_t)); - *err = ETOPO_NOMEM; - return (-1); - } + if ((pip = topo_hdl_zalloc(thp, sizeof (topo_ipgroup_info_t))) + == NULL) + return (pgroup_seterr(node, pg, pip, err)); - pg->tpg_stability = stab; + if ((pip->tpi_name = topo_hdl_strdup(thp, pinfo->tpi_name)) + == NULL) + return (pgroup_seterr(node, pg, pip, err)); + + pip->tpi_namestab = pinfo->tpi_namestab; + pip->tpi_datastab = pinfo->tpi_datastab; + pip->tpi_version = pinfo->tpi_version; + + pg->tpg_info = pip; topo_list_append(&node->tn_pgroups, pg); + topo_node_unlock(node); return (0); } @@ -592,11 +1005,12 @@ topo_pgroup_destroy(tnode_t *node, const char *pname) topo_hdl_t *thp = node->tn_hdl; topo_pgroup_t *pg; topo_proplist_t *pvl; + topo_ipgroup_info_t *pip; topo_node_lock(node); for (pg = topo_list_next(&node->tn_pgroups); pg != NULL; pg = topo_list_next(pg)) { - if (strcmp(pg->tpg_name, pname) == 0) { + if (strcmp(pg->tpg_info->tpi_name, pname) == 0) { break; } } @@ -613,12 +1027,16 @@ topo_pgroup_destroy(tnode_t *node, const char *pname) } topo_list_delete(&node->tn_pgroups, pg); + topo_node_unlock(node); - if (pg->tpg_name != NULL) - topo_hdl_strfree(thp, pg->tpg_name); - topo_hdl_free(thp, pg, sizeof (topo_pgroup_t)); + pip = pg->tpg_info; + if (pip != NULL) { + if (pip->tpi_name != NULL) + topo_hdl_strfree(thp, (char *)pip->tpi_name); + topo_hdl_free(thp, pip, sizeof (topo_ipgroup_info_t)); + } - topo_node_unlock(node); + topo_hdl_free(thp, pg, sizeof (topo_pgroup_t)); } void @@ -627,6 +1045,7 @@ topo_pgroup_destroy_all(tnode_t *node) topo_hdl_t *thp = node->tn_hdl; topo_pgroup_t *pg; topo_proplist_t *pvl; + topo_ipgroup_info_t *pip; topo_node_lock(node); while ((pg = topo_list_next(&node->tn_pgroups)) != NULL) { @@ -638,8 +1057,13 @@ topo_pgroup_destroy_all(tnode_t *node) topo_list_delete(&node->tn_pgroups, pg); - if (pg->tpg_name != NULL) - topo_hdl_strfree(thp, pg->tpg_name); + pip = pg->tpg_info; + if (pip != NULL) { + if (pip->tpi_name != NULL) + topo_hdl_strfree(thp, (char *)pip->tpi_name); + topo_hdl_free(thp, pip, sizeof (topo_pgroup_info_t)); + } + topo_hdl_free(thp, pg, sizeof (topo_pgroup_t)); } topo_node_unlock(node); @@ -652,8 +1076,8 @@ topo_propval_destroy(topo_propval_t *pv) if (pv->tp_name != NULL) topo_hdl_strfree(thp, pv->tp_name); - if (pv->tp_free != NULL) - pv->tp_free(pv); + if (pv->tp_val != NULL) + nvlist_free(pv->tp_val); topo_hdl_free(thp, pv, sizeof (topo_propval_t)); } diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_prop.h b/usr/src/lib/fm/topo/libtopo/common/topo_prop.h index 25dcf33702..a121259291 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_prop.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_prop.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -37,28 +36,27 @@ extern "C" { #endif +typedef struct topo_ipgroup_info { + char *tpi_name; /* property group name */ + topo_stability_t tpi_namestab; /* stability of group name */ + topo_stability_t tpi_datastab; /* stability of all property values */ + topo_version_t tpi_version; /* version of pgroup definition */ +} topo_ipgroup_info_t; + typedef struct topo_pgroup { topo_list_t tpg_list; /* next/prev pointers */ - char *tpg_name; /* Group name */ - topo_stability_t tpg_stability; /* SMI Stability level */ - topo_list_t tpg_pvals; /* Property values */ + topo_ipgroup_info_t *tpg_info; /* name, version, stability */ + topo_list_t tpg_pvals; /* property values */ } topo_pgroup_t; typedef struct topo_propval { - char *tp_name; /* Prop name */ - topo_type_t tp_type; /* Prop type */ - int tp_flag; /* Dynamic property */ + char *tp_name; /* prop name */ + topo_type_t tp_type; /* prop type */ + int tp_flag; /* dynamic property */ int tp_refs; /* ref count for this prop val */ topo_hdl_t *tp_hdl; /* handle pointer for allocations */ - void (*tp_free)(struct topo_propval *); /* Prop value destructor */ - union { - int32_t tp_int32; - int32_t tp_uint32; - int64_t tp_int64; - int64_t tp_uint64; - char *tp_string; - nvlist_t *tp_fmri; - } tp_u; + void (*tp_free)(struct topo_propval *); /* prop value destructor */ + nvlist_t *tp_val; } topo_propval_t; typedef struct topo_proplist { @@ -66,7 +64,6 @@ typedef struct topo_proplist { topo_propval_t *tp_pval; /* actual value */ } topo_proplist_t; -extern int topo_prop_inherit(tnode_t *, const char *, const char *, int *); extern void topo_prop_hold(topo_propval_t *); extern void topo_prop_rele(topo_propval_t *); extern void topo_pgroup_destroy_all(tnode_t *); diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_protocol.c b/usr/src/lib/fm/topo/libtopo/common/topo_protocol.c index 85ced6fa43..938193c0fc 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_protocol.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_protocol.c @@ -32,6 +32,7 @@ #include <topo_alloc.h> #include <topo_error.h> +#include <topo_method.h> #include <topo_protocol.h> #include <topo_subr.h> @@ -157,7 +158,7 @@ topo_node_asru_set(tnode_t *node, nvlist_t *asru, int flag, int *err) node->tn_fflags |= TOPO_ASRU_COMPUTE; if (topo_prop_set_fmri(node, TOPO_PGROUP_PROTOCOL, - TOPO_PROP_ASRU, TOPO_PROP_SET_ONCE, asru, err) < 0) + TOPO_PROP_ASRU, TOPO_PROP_IMMUTABLE, asru, err) < 0) return (-1); } @@ -184,7 +185,7 @@ topo_node_fru_set(tnode_t *node, nvlist_t *fru, int flag, int *err) node->tn_fflags |= TOPO_FRU_COMPUTE; if (topo_prop_set_fmri(node, TOPO_PGROUP_PROTOCOL, - TOPO_PROP_FRU, TOPO_PROP_SET_ONCE, fru, err) < 0) + TOPO_PROP_FRU, TOPO_PROP_IMMUTABLE, fru, err) < 0) return (-1); } @@ -194,6 +195,7 @@ topo_node_fru_set(tnode_t *node, nvlist_t *fru, int flag, int *err) int topo_node_label_set(tnode_t *node, char *label, int *err) { + /* * Inherit FRU property from our parent if * not specified */ @@ -204,7 +206,7 @@ topo_node_label_set(tnode_t *node, char *label, int *err) } } else { if (topo_prop_set_string(node, TOPO_PGROUP_PROTOCOL, - TOPO_PROP_LABEL, TOPO_PROP_SET_ONCE, label, err) < 0) + TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE, label, err) < 0) return (-1); } diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_rtld.c b/usr/src/lib/fm/topo/libtopo/common/topo_rtld.c index 1472fe9bea..44ee6eaa72 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_rtld.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_rtld.c @@ -38,8 +38,8 @@ typedef struct topo_rtld { void *rtld_dlp; /* libdl(3DL) handle for shared library */ - int (*rtld_init)(topo_mod_t *); /* shared library's _topo_init() */ - void (*rtld_fini)(topo_mod_t *); /* shared library's _topo_fini() */ + int (*rtld_init)(topo_mod_t *, topo_version_t); /* .so _topo_init() */ + void (*rtld_fini)(topo_mod_t *); /* .so _topo_fini() */ } topo_rtld_t; static int @@ -64,14 +64,14 @@ rtld_fini(topo_mod_t *mod) } static int -rtld_init(topo_mod_t *mod) +rtld_init(topo_mod_t *mod, topo_version_t version) { int err; topo_rtld_t *rp; void *dlp; if ((dlp = dlopen(mod->tm_path, RTLD_LOCAL | RTLD_NOW)) == NULL) { - topo_dprintf(TOPO_DBG_ERR, + topo_dprintf(mod->tm_hdl, TOPO_DBG_ERR, "dlopen() failed: %s\n", dlerror()); return (topo_mod_seterrno(mod, ETOPO_RTLD_OPEN)); } @@ -93,7 +93,7 @@ rtld_init(topo_mod_t *mod) /* * Call _topo_init() in the module. */ - err = rp->rtld_init(mod); + err = rp->rtld_init(mod, version); if (err < 0 || !(mod->tm_flags & TOPO_MOD_REG)) { (void) rtld_fini(mod); @@ -103,7 +103,7 @@ rtld_init(topo_mod_t *mod) return (0); } -const topo_modops_t topo_rtld_ops = { +const topo_imodops_t topo_rtld_ops = { rtld_init, rtld_fini, }; diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_snap.c b/usr/src/lib/fm/topo/libtopo/common/topo_snap.c index 5c68f5624f..345d2c9c7c 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_snap.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_snap.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -69,12 +68,18 @@ * and release nodes that may be still held. */ +#include <alloca.h> +#include <ctype.h> #include <pthread.h> #include <limits.h> #include <assert.h> #include <fcntl.h> +#include <smbios.h> +#include <sys/param.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/systeminfo.h> +#include <sys/utsname.h> #include <uuid/uuid.h> #include <fm/libtopo.h> @@ -98,18 +103,57 @@ set_open_errno(topo_hdl_t *thp, int *errp, int err) return (NULL); } +static char * +smbios_fix(topo_hdl_t *thp, char *begin) +{ + char buf[MAXNAMELEN]; + size_t count; + char *str, *end, *pp; + + end = begin + strlen(begin); + + while (begin < end && isspace(*begin)) + begin++; + while (begin < end && isspace(*(end - 1))) + end--; + + if (begin >= end) + return (NULL); + + count = end - begin; + count += 1; + + if (count > sizeof (buf)) + return (NULL); + + (void) snprintf(buf, count, "%s", begin); + while ((str = strchr(buf, ' ')) != NULL) + *str = '-'; + + pp = topo_hdl_strdup(thp, buf); + return (pp); +} + topo_hdl_t * topo_open(int version, const char *rootdir, int *errp) { topo_hdl_t *thp = NULL; topo_alloc_t *tap; + + char platform[MAXNAMELEN]; + char isa[MAXNAMELEN]; + struct utsname uts; struct stat st; - if (version < TOPO_VERSION) - return (set_open_errno(thp, errp, ETOPO_HDL_VER)); + smbios_hdl_t *shp; + smbios_system_t s1; + smbios_info_t s2; + id_t id; + + char *dbflags, *dbout; - if (version > TOPO_VERSION) - return (set_open_errno(thp, errp, ETOPO_HDL_VER)); + if (version != TOPO_VERSION) + return (set_open_errno(thp, errp, ETOPO_HDL_ABIVER)); if (rootdir != NULL && stat(rootdir, &st) < 0) return (set_open_errno(thp, errp, ETOPO_HDL_INVAL)); @@ -117,8 +161,12 @@ topo_open(int version, const char *rootdir, int *errp) if ((thp = topo_zalloc(sizeof (topo_hdl_t), 0)) == NULL) return (set_open_errno(thp, errp, ETOPO_NOMEM)); - if ((tap = topo_zalloc(sizeof (topo_alloc_t), 0)) == NULL) + (void) pthread_mutex_init(&thp->th_lock, NULL); + + if ((tap = topo_zalloc(sizeof (topo_alloc_t), 0)) == NULL) { + topo_close(thp); return (set_open_errno(thp, errp, ETOPO_NOMEM)); + } /* * Install default allocators @@ -135,22 +183,68 @@ topo_open(int version, const char *rootdir, int *errp) if ((thp->th_modhash = topo_modhash_create(thp)) == NULL) return (set_open_errno(thp, errp, ETOPO_NOMEM)); + /* + * Set-up system information and search paths for modules + * and topology map files + */ if (rootdir == NULL) { rootdir = topo_hdl_strdup(thp, "/"); thp->th_rootdir = (char *)rootdir; } else { - if (strlen(rootdir) > PATH_MAX) + int len; + char *rpath; + + len = strlen(rootdir); + if (len >= PATH_MAX) return (set_open_errno(thp, errp, EINVAL)); - thp->th_rootdir = topo_hdl_strdup(thp, rootdir); + if (rootdir[len] != '/') { + rpath = alloca(len + 1); + (void) snprintf(rpath, len + 1, "%s/", rootdir); + } else { + rpath = (char *)rootdir; + } + thp->th_rootdir = topo_hdl_strdup(thp, rpath); } - if (thp->th_rootdir == NULL) + platform[0] = '\0'; + isa[0] = '\0'; + (void) sysinfo(SI_PLATFORM, platform, sizeof (platform)); + (void) sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)); + (void) uname(&uts); + thp->th_platform = topo_hdl_strdup(thp, platform); + thp->th_isa = topo_hdl_strdup(thp, isa); + thp->th_machine = topo_hdl_strdup(thp, uts.machine); + if ((shp = smbios_open(NULL, SMB_VERSION, 0, NULL)) != NULL) { + if ((id = smbios_info_system(shp, &s1)) != SMB_ERR && + smbios_info_common(shp, id, &s2) != SMB_ERR) { + + if (strcmp(s2.smbi_product, SMB_DEFAULT1) != 0 && + strcmp(s2.smbi_product, SMB_DEFAULT2) != 0) { + thp->th_product = smbios_fix(thp, + (char *)s2.smbi_product); + } + } + smbios_close(shp); + } else { + thp->th_product = topo_hdl_strdup(thp, thp->th_platform); + } + + if (thp->th_rootdir == NULL) { + topo_close(thp); return (set_open_errno(thp, errp, ETOPO_NOMEM)); + } + + dbflags = getenv("TOPO_DEBUG"); + dbout = getenv("TOPO_DEBUG_OUT"); + if (dbflags != NULL) + topo_debug_set(thp, dbflags, dbout); if (topo_builtin_create(thp, thp->th_rootdir) != 0) { - topo_dprintf(TOPO_DBG_ERR, "failed to load builtin modules: " - "%s\n", topo_hdl_errmsg(thp)); + topo_dprintf(thp, TOPO_DBG_ERR, + "failed to load builtin modules: %s\n", + topo_hdl_errmsg(thp)); + topo_close(thp); return (NULL); } @@ -163,6 +257,14 @@ topo_close(topo_hdl_t *thp) ttree_t *tp; topo_hdl_lock(thp); + if (thp->th_platform != NULL) + topo_hdl_strfree(thp, thp->th_platform); + if (thp->th_isa != NULL) + topo_hdl_strfree(thp, thp->th_isa); + if (thp->th_machine != NULL) + topo_hdl_strfree(thp, thp->th_machine); + if (thp->th_product != NULL) + topo_hdl_strfree(thp, thp->th_product); if (thp->th_rootdir != NULL) topo_hdl_strfree(thp, thp->th_rootdir); @@ -176,7 +278,7 @@ topo_close(topo_hdl_t *thp) */ while ((tp = topo_list_next(&thp->th_trees)) != NULL) { topo_list_delete(&thp->th_trees, tp); - topo_tree_destroy(thp, tp); + topo_tree_destroy(tp); } /* @@ -209,7 +311,7 @@ topo_snap_create(topo_hdl_t *thp, int *errp) if ((thp->th_uuid = topo_hdl_zalloc(thp, TOPO_UUID_SIZE)) == NULL) { *errp = ETOPO_NOMEM; - topo_dprintf(TOPO_DBG_ERR, "unable to allocate uuid: %s\n", + topo_dprintf(thp, TOPO_DBG_ERR, "unable to allocate uuid: %s\n", topo_strerror(*errp)); topo_hdl_unlock(thp); return (NULL); @@ -219,9 +321,9 @@ topo_snap_create(topo_hdl_t *thp, int *errp) uuid_unparse(uuid, thp->th_uuid); if (topo_tree_enum_all(thp) < 0) { - topo_dprintf(TOPO_DBG_ERR, "enumeration failure: %s\n", + topo_dprintf(thp, TOPO_DBG_ERR, "enumeration failure: %s\n", topo_hdl_errmsg(thp)); - if (topo_hdl_errno(thp) != ETOPO_ENUM_PARTIAL) { + if (topo_hdl_errno(thp) == ETOPO_ENUM_FATAL) { *errp = thp->th_errno; topo_hdl_unlock(thp); return (NULL); @@ -231,6 +333,9 @@ topo_snap_create(topo_hdl_t *thp, int *errp) if ((ustr = topo_hdl_strdup(thp, thp->th_uuid)) == NULL) *errp = ETOPO_NOMEM; + thp->th_di = DI_NODE_NIL; + thp->th_pi = DI_PROM_HANDLE_NIL; + topo_hdl_unlock(thp); return (ustr); @@ -316,14 +421,12 @@ topo_snap_destroy(topo_hdl_t *thp) topo_mod_rele(mod); } - /* - * Release the file handle - */ - if (tp->tt_file != NULL) - topo_file_unload(thp, tp); - } + if (thp->th_uuid != NULL) { + topo_hdl_free(thp, thp->th_uuid, TOPO_UUID_SIZE); + thp->th_uuid = NULL; + } } void @@ -333,11 +436,7 @@ topo_snap_release(topo_hdl_t *thp) return; topo_hdl_lock(thp); - if (thp->th_uuid != NULL) { - topo_hdl_free(thp, thp->th_uuid, TOPO_UUID_SIZE); - topo_snap_destroy(thp); - thp->th_uuid = NULL; - } + topo_snap_destroy(thp); topo_hdl_unlock(thp); } @@ -405,7 +504,8 @@ step_child(tnode_t *cnp, topo_walk_t *wp, int bottomup) if (nnp == NULL) return (TOPO_WALK_TERMINATE); - topo_dprintf(TOPO_DBG_WALK, "walk through child node %s=%d\n", + topo_dprintf(wp->tw_thp, TOPO_DBG_WALK, + "walk through child node %s=%d\n", nnp->tn_name, nnp->tn_instance); topo_node_hold(nnp); /* released on return from walk_step */ @@ -429,7 +529,8 @@ step_sibling(tnode_t *cnp, topo_walk_t *wp, int bottomup) if (nnp == NULL) return (TOPO_WALK_TERMINATE); - topo_dprintf(TOPO_DBG_WALK, "walk through sibling node %s=%d\n", + topo_dprintf(wp->tw_thp, TOPO_DBG_WALK, + "walk through sibling node %s=%d\n", nnp->tn_name, nnp->tn_instance); topo_node_hold(nnp); /* released on return from walk_step */ @@ -457,12 +558,14 @@ topo_walk_step(topo_walk_t *wp, int flag) * End of the line */ if (cnp == NULL) { - topo_dprintf(TOPO_DBG_WALK, "walk_step terminated\n"); + topo_dprintf(wp->tw_thp, TOPO_DBG_WALK, + "walk_step terminated\n"); topo_node_rele(cnp); return (TOPO_WALK_TERMINATE); } - topo_dprintf(TOPO_DBG_WALK, "%s walk_step through node %s=%d\n", + topo_dprintf(wp->tw_thp, TOPO_DBG_WALK, + "%s walk_step through node %s=%d\n", (flag == TOPO_WALK_CHILD ? "TOPO_WALK_CHILD" : "TOPO_WALK_SIBLING"), cnp->tn_name, cnp->tn_instance); @@ -522,12 +625,14 @@ topo_walk_bottomup(topo_walk_t *wp, int flag) * End of the line */ if (cnp == NULL) { - topo_dprintf(TOPO_DBG_WALK, "walk_bottomup terminated\n"); + topo_dprintf(wp->tw_thp, TOPO_DBG_WALK, + "walk_bottomup terminated\n"); topo_node_rele(cnp); return (TOPO_WALK_TERMINATE); } - topo_dprintf(TOPO_DBG_WALK, "%s walk_bottomup through node %s=%d\n", + topo_dprintf(wp->tw_thp, TOPO_DBG_WALK, + "%s walk_bottomup through node %s=%d\n", (flag == TOPO_WALK_CHILD ? "TOPO_WALK_CHILD" : "TOPO_WALK_SIBLING"), cnp->tn_name, cnp->tn_instance); diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_subr.c b/usr/src/lib/fm/topo/libtopo/common/topo_subr.c index bd2ca8bdfe..50f69156c4 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_subr.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_subr.c @@ -27,8 +27,11 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <alloca.h> +#include <ctype.h> +#include <limits.h> #include <syslog.h> #include <strings.h> +#include <unistd.h> #include <topo_error.h> #include <topo_subr.h> @@ -36,9 +39,6 @@ struct _rwlock; struct _lwp_mutex; -int _topo_debug = 0; /* debug messages enabled (off) */ -int _topo_dbout = 0; /* debug messages output mode */ - int topo_rw_read_held(pthread_rwlock_t *lock) { @@ -73,50 +73,133 @@ topo_hdl_unlock(topo_hdl_t *thp) } const char * -topo_stability_name(topo_stability_t s) +topo_stability2name(topo_stability_t s) { switch (s) { - case TOPO_STABILITY_INTERNAL: return ("Internal"); - case TOPO_STABILITY_PRIVATE: return ("Private"); - case TOPO_STABILITY_OBSOLETE: return ("Obsolete"); - case TOPO_STABILITY_EXTERNAL: return ("External"); - case TOPO_STABILITY_UNSTABLE: return ("Unstable"); - case TOPO_STABILITY_EVOLVING: return ("Evolving"); - case TOPO_STABILITY_STABLE: return ("Stable"); - case TOPO_STABILITY_STANDARD: return ("Standard"); - default: return (NULL); + case TOPO_STABILITY_INTERNAL: return (TOPO_STABSTR_INTERNAL); + case TOPO_STABILITY_PRIVATE: return (TOPO_STABSTR_PRIVATE); + case TOPO_STABILITY_OBSOLETE: return (TOPO_STABSTR_OBSOLETE); + case TOPO_STABILITY_EXTERNAL: return (TOPO_STABSTR_EXTERNAL); + case TOPO_STABILITY_UNSTABLE: return (TOPO_STABSTR_UNSTABLE); + case TOPO_STABILITY_EVOLVING: return (TOPO_STABSTR_EVOLVING); + case TOPO_STABILITY_STABLE: return (TOPO_STABSTR_STABLE); + case TOPO_STABILITY_STANDARD: return (TOPO_STABSTR_STANDARD); + default: return (TOPO_STABSTR_UNKNOWN); } } +topo_stability_t +topo_name2stability(const char *name) +{ + if (strcmp(name, TOPO_STABSTR_INTERNAL) == 0) + return (TOPO_STABILITY_INTERNAL); + else if (strcmp(name, TOPO_STABSTR_PRIVATE) == 0) + return (TOPO_STABILITY_PRIVATE); + else if (strcmp(name, TOPO_STABSTR_OBSOLETE) == 0) + return (TOPO_STABILITY_OBSOLETE); + else if (strcmp(name, TOPO_STABSTR_EXTERNAL) == 0) + return (TOPO_STABILITY_EXTERNAL); + else if (strcmp(name, TOPO_STABSTR_UNSTABLE) == 0) + return (TOPO_STABILITY_UNSTABLE); + else if (strcmp(name, TOPO_STABSTR_EVOLVING) == 0) + return (TOPO_STABILITY_EVOLVING); + else if (strcmp(name, TOPO_STABSTR_STABLE) == 0) + return (TOPO_STABILITY_STABLE); + else if (strcmp(name, TOPO_STABSTR_STANDARD) == 0) + return (TOPO_STABILITY_STANDARD); + + return (TOPO_STABILITY_UNKNOWN); +} + static const topo_debug_mode_t _topo_dbout_modes[] = { { "stderr", "send debug messages to stderr", TOPO_DBOUT_STDERR }, { "syslog", "send debug messages to syslog", TOPO_DBOUT_SYSLOG }, { NULL, NULL, 0 } }; +static const topo_debug_mode_t _topo_dbflag_modes[] = { + { "error", "error handling debug messages enabled", TOPO_DBG_ERR }, + { "module", "module debug messages enabled", TOPO_DBG_MOD }, + { "modulesvc", "module services debug messages enabled", + TOPO_DBG_MODSVC }, + { "walk", "walker subsystem debug messages enabled", TOPO_DBG_WALK }, + { "xml", "xml file parsing messages enabled", TOPO_DBG_XML }, + { "all", "all debug modes enabled", TOPO_DBG_ALL}, + { NULL, NULL, 0 } +}; + void -topo_debug_set(topo_hdl_t *thp, int mask, char *dout) +env_process_value(topo_hdl_t *thp, const char *begin, const char *end) { - int i; - - for (i = 0; i < 2; ++i) { - if (strcmp(_topo_dbout_modes[i].tdm_name, dout) == 0) { - thp->th_dbout = _topo_dbout = - _topo_dbout_modes[i].tdm_mode; - thp->th_debug = _topo_debug = mask; - topo_dprintf(mask, _topo_dbout_modes[i].tdm_desc); - } + char buf[MAXNAMELEN]; + size_t count; + topo_debug_mode_t *dbp; + + while (begin < end && isspace(*begin)) + begin++; + + while (begin < end && isspace(*(end - 1))) + end--; + + if (begin >= end) + return; + + count = end - begin; + count += 1; + + if (count > sizeof (buf)) + return; + + (void) snprintf(buf, count, "%s", begin); + + for (dbp = (topo_debug_mode_t *)_topo_dbflag_modes; + dbp->tdm_name != NULL; ++dbp) { + if (strcmp(buf, dbp->tdm_name) == 0) + thp->th_debug |= dbp->tdm_mode; + } +} + +void +topo_debug_set(topo_hdl_t *thp, const char *dbmode, const char *dout) +{ + char *end, *value, *next; + topo_debug_mode_t *dbp; + + topo_hdl_lock(thp); + value = (char *)dbmode; + + for (end = (char *)dbmode; *end != '\0'; value = next) { + end = strchr(value, ','); + if (end != NULL) + next = end + 1; /* skip the comma */ + else + next = end = value + strlen(value); + + env_process_value(thp, value, end); + } + + if (dout == NULL) { + topo_hdl_unlock(thp); + return; } + + for (dbp = (topo_debug_mode_t *)_topo_dbout_modes; + dbp->tdm_name != NULL; ++dbp) { + if (strcmp(dout, dbp->tdm_name) == 0) + thp->th_dbout = dbp->tdm_mode; + } + topo_hdl_unlock(thp); } void -topo_vdprintf(int mask, const char *format, va_list ap) +topo_vdprintf(topo_hdl_t *thp, int mask, const char *mod, const char *format, + va_list ap) { char *msg; size_t len; char c; - if (!(_topo_debug & mask)) + if (!(thp->th_debug & mask)) return; len = vsnprintf(&c, 1, format, ap); @@ -126,24 +209,31 @@ topo_vdprintf(int mask, const char *format, va_list ap) if (msg[len - 1] != '\n') (void) strcpy(&msg[len], "\n"); - if (_topo_dbout == TOPO_DBOUT_STDERR) - (void) fprintf(stderr, "libtopo DEBUG: %s", msg); - - if (_topo_dbout == TOPO_DBOUT_SYSLOG) - syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg); + if (thp->th_dbout == TOPO_DBOUT_SYSLOG) { + if (mod == NULL) { + syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s", msg); + } else { + syslog(LOG_DEBUG | LOG_USER, "libtopo DEBUG: %s: %s", + mod, msg); + } + } else { + if (mod == NULL) { + (void) fprintf(stderr, "libtopo DEBUG: %s", msg); + } else { + (void) fprintf(stderr, "libtopo DEBUG: %s: %s", mod, + msg); + } + } } -/*PRINTFLIKE2*/ +/*PRINTFLIKE3*/ void -topo_dprintf(int mask, const char *format, ...) +topo_dprintf(topo_hdl_t *thp, int mask, const char *format, ...) { va_list ap; - if (!(_topo_debug & mask)) - return; - va_start(ap, format); - topo_vdprintf(mask, format, ap); + topo_vdprintf(thp, mask, NULL, format, ap); va_end(ap); } @@ -191,3 +281,35 @@ topo_fmristr_build(ssize_t *sz, char *buf, size_t buflen, char *str, else *sz += snprintf(buf, left, "%s%s%s", prepend, str, append); } + +#define TOPO_PLATFORM_PATH "%s/usr/platform/%s/lib/fm/topo/%s" +#define TOPO_COMMON_PATH "%s/usr/lib/fm/topo/%s" + +char * +topo_search_path(topo_mod_t *mod, const char *rootdir, const char *file) +{ + char *pp, sp[PATH_MAX]; + topo_hdl_t *thp = mod->tm_hdl; + + /* + * Search for file name in order of platform, machine and common + * topo directories + */ + (void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH, rootdir, + thp->th_platform, file); + if (access(sp, F_OK) != 0) { + (void) snprintf(sp, PATH_MAX, TOPO_PLATFORM_PATH, + thp->th_rootdir, thp->th_machine, file); + if (access(sp, F_OK) != 0) { + (void) snprintf(sp, PATH_MAX, TOPO_COMMON_PATH, + thp->th_rootdir, file); + if (access(sp, F_OK) != 0) { + return (NULL); + } + } + } + + pp = topo_mod_strdup(mod, sp); + + return (pp); +} diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_subr.h b/usr/src/lib/fm/topo/libtopo/common/topo_subr.h index 99a7a00162..2e78f7d712 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_subr.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_subr.h @@ -48,6 +48,24 @@ typedef struct topo_debug_mode { #define TOPO_DBOUT_STDERR 0 /* Debug messages to stderr */ #define TOPO_DBOUT_SYSLOG 1 /* Debug messages to syslog */ +#define TOPO_DBG_ERR 0x0001 /* enable error handling debug messages */ +#define TOPO_DBG_MOD 0x0002 /* enable module debug messages */ +#define TOPO_DBG_MODSVC 0x0004 /* enable module services debug messages */ +#define TOPO_DBG_WALK 0x0008 /* enable walker debug messages */ +#define TOPO_DBG_XML 0x0010 /* enable xml parsing debug messages */ +#define TOPO_DBG_ALL 0xffff /* enable all debug modes */ + +#define TOPO_STABSTR_INTERNAL "Internal" /* private to libtopo */ +#define TOPO_STABSTR_PRIVATE "Private" /* private to Sun */ +#define TOPO_STABSTR_OBSOLETE "Obsolete" /* scheduled for removal */ +#define TOPO_STABSTR_EXTERNAL "External" /* not controlled by Sun */ +#define TOPO_STABSTR_UNSTABLE "Unstable" /* new or rapidly changing */ +#define TOPO_STABSTR_EVOLVING "Evolving" /* less rapidly changing */ +#define TOPO_STABSTR_STABLE "Stable" /* mature interface from Sun */ +#define TOPO_STABSTR_STANDARD "Standard" /* industry standard */ +#define TOPO_STABSTR_UNKNOWN "Unknown" /* stability unknown */ + + extern int topo_rw_read_held(pthread_rwlock_t *); extern int topo_rw_write_held(pthread_rwlock_t *); extern int topo_mutex_held(pthread_mutex_t *); @@ -60,10 +78,12 @@ extern char *topo_version_num2str(topo_version_t, char *, size_t); extern int topo_version_str2num(const char *, topo_version_t); extern int topo_version_defined(topo_version_t); -extern void topo_dprintf(int, const char *, ...); -extern void topo_vdprintf(int, const char *, va_list); +extern void topo_dprintf(topo_hdl_t *, int, const char *, ...); +extern void topo_vdprintf(topo_hdl_t *, int, const char *, const char *, + va_list); extern tnode_t *topo_hdl_root(topo_hdl_t *, const char *); +extern char *topo_search_path(topo_mod_t *, const char *, const char *); extern void topo_fmristr_build(ssize_t *, char *, size_t, char *, char *, char *); diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_tree.c b/usr/src/lib/fm/topo/libtopo/common/topo_tree.c index 45c68a9485..1a59aebb46 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_tree.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_tree.c @@ -62,6 +62,7 @@ #include <topo_alloc.h> #include <topo_error.h> +#include <topo_file.h> #include <topo_module.h> #include <topo_string.h> #include <topo_subr.h> @@ -71,7 +72,7 @@ static ttree_t * set_create_error(topo_hdl_t *thp, ttree_t *tp, int err) { if (tp != NULL) - topo_tree_destroy(thp, tp); + topo_tree_destroy(tp); if (err != 0) (void) topo_hdl_seterrno(thp, err); @@ -79,46 +80,24 @@ set_create_error(topo_hdl_t *thp, ttree_t *tp, int err) return (NULL); } -static void -set_system_props(tnode_t *node) -{ - int err; - char platform[MAXNAMELEN]; - char isa[MAXNAMELEN]; - struct utsname uts; - - platform[0] = '\0'; - isa[0] = '\0'; - (void) sysinfo(SI_PLATFORM, platform, sizeof (platform)); - (void) sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)); - (void) uname(&uts); - - (void) topo_pgroup_create(node, TOPO_PGROUP_SYSTEM, - TOPO_STABILITY_PRIVATE, &err); - (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, - TOPO_PROP_PLATFORM, TOPO_PROP_SET_ONCE, platform, &err); - (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, - TOPO_PROP_ISA, TOPO_PROP_SET_ONCE, isa, &err); - (void) topo_prop_set_string(node, TOPO_PGROUP_SYSTEM, - TOPO_PROP_MACHINE, TOPO_PROP_SET_ONCE, uts.machine, &err); -} - ttree_t * topo_tree_create(topo_hdl_t *thp, topo_mod_t *mod, const char *scheme) { ttree_t *tp; tnode_t *rp; - if ((tp = topo_hdl_zalloc(thp, sizeof (ttree_t))) == NULL) + if ((tp = topo_mod_zalloc(mod, sizeof (ttree_t))) == NULL) return (set_create_error(thp, NULL, ETOPO_NOMEM)); - if ((tp->tt_scheme = topo_hdl_strdup(thp, scheme)) == NULL) + tp->tt_mod = mod; + + if ((tp->tt_scheme = topo_mod_strdup(mod, scheme)) == NULL) return (set_create_error(thp, tp, ETOPO_NOMEM)); /* * Initialize a private walker for internal use */ - if ((tp->tt_walk = topo_hdl_zalloc(thp, sizeof (topo_walk_t))) == NULL) + if ((tp->tt_walk = topo_mod_zalloc(mod, sizeof (topo_walk_t))) == NULL) return (set_create_error(thp, tp, ETOPO_NOMEM)); /* @@ -133,7 +112,6 @@ topo_tree_create(topo_hdl_t *thp, topo_mod_t *mod, const char *scheme) rp->tn_enum = mod; rp->tn_hdl = thp; - set_system_props(rp); topo_node_hold(rp); tp->tt_walk->tw_root = rp; @@ -147,16 +125,16 @@ topo_tree_create(topo_hdl_t *thp, topo_mod_t *mod, const char *scheme) } void -topo_tree_destroy(topo_hdl_t *thp, ttree_t *tp) +topo_tree_destroy(ttree_t *tp) { + topo_mod_t *mod; + if (tp == NULL) return; + mod = tp->tt_mod; if (tp->tt_walk != NULL) - topo_hdl_free(thp, tp->tt_walk, sizeof (topo_walk_t)); - - if (tp->tt_file != NULL) - topo_file_unload(thp, tp); + topo_mod_free(mod, tp->tt_walk, sizeof (topo_walk_t)); if (tp->tt_root != NULL) { assert(tp->tt_root->tn_refs == 1); @@ -168,28 +146,71 @@ topo_tree_destroy(topo_hdl_t *thp, ttree_t *tp) * topo_node_rele(). */ if (tp->tt_scheme != NULL) - topo_hdl_strfree(thp, tp->tt_scheme); + topo_mod_strfree(mod, tp->tt_scheme); - topo_hdl_free(thp, tp, sizeof (ttree_t)); + topo_mod_free(mod, tp, sizeof (ttree_t)); } static int topo_tree_enum(topo_hdl_t *thp, ttree_t *tp) { - tnode_t *rnode; + char *pp; + + /* + * Attempt to enumerate the tree from a topology map in the + * following order: + * <product-name>-<scheme>-topology + * <platform-name>-<scheme>-topology (uname -i) + * <machine-name>-<scheme>-topology (uname -m) + * <scheme>-topology + * + * Trim any SUNW, from the product or platform name + * before loading file + */ + if (thp->th_product == NULL || + (pp = strchr(thp->th_product, ',')) == NULL) + pp = thp->th_product; + else + pp++; + if (topo_file_load(tp->tt_root->tn_enum, tp->tt_root, + pp, tp->tt_scheme) < 0) { + if ((pp = strchr(thp->th_platform, ',')) == NULL) + pp = thp->th_platform; + else + pp++; + + if (topo_file_load(tp->tt_root->tn_enum, tp->tt_root, + pp, tp->tt_scheme) < 0) { + if (topo_file_load(tp->tt_root->tn_enum, tp->tt_root, + thp->th_machine, tp->tt_scheme) < 0) { + + if (topo_file_load(tp->tt_root->tn_enum, + tp->tt_root, NULL, tp->tt_scheme) < 0) { + topo_dprintf(thp, TOPO_DBG_ERR, "no " + "topology map found for the %s " + "FMRI set\n", tp->tt_scheme); + return (topo_hdl_seterrno(thp, + ETOPO_ENUM_NOMAP)); + } + } + } + } - rnode = tp->tt_root; /* - * Attempt to populate the tree from a topology file + * It would be nice to leave the devinfo and prominfo trees + * active but the interfaces consume copious amounts of memory + * while searching for property information */ - if (topo_file_load(thp, rnode->tn_enum, tp) < 0) { - /* - * If this tree does not have a matching static topology file, - * continue on. - */ - if (topo_hdl_errno(thp) != ETOPO_FILE_NOENT) - return (topo_hdl_seterrno(thp, ETOPO_ENUM_PARTIAL)); + 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; + } + + return (0); } diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_tree.h b/usr/src/lib/fm/topo/libtopo/common/topo_tree.h index 3409c1f377..1983efccfb 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_tree.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_tree.h @@ -91,9 +91,9 @@ struct topo_node { typedef struct topo_tree { topo_list_t tt_list; /* next/prev pointers */ - char *tt_scheme; /* Scheme name */ - void *tt_file; /* Topology file info */ - struct topo_node *tt_root; /* Root node */ + char *tt_scheme; /* scheme name */ + topo_mod_t *tt_mod; /* builtin enumerator mod */ + struct topo_node *tt_root; /* root node */ topo_walk_t *tt_walk; /* private walker */ } ttree_t; @@ -118,6 +118,12 @@ struct topo_hdl { pthread_mutex_t th_lock; /* lock protecting hdl */ char *th_uuid; /* uuid of snapshot */ char *th_rootdir; /* Root directory of plugin paths */ + char *th_platform; /* platform name */ + char *th_isa; /* isa name */ + char *th_machine; /* machine name */ + char *th_product; /* product name */ + di_node_t th_di; /* handle to root of devinfo tree */ + di_prom_handle_t th_pi; /* handle to root of prom tree */ topo_modhash_t *th_modhash; /* Module hash */ topo_list_t th_trees; /* Scheme-specific topo tree list */ topo_alloc_t *th_alloc; /* allocators */ @@ -127,14 +133,13 @@ struct topo_hdl { }; #define TOPO_UUID_SIZE 37 /* libuuid limit + 1 */ +#define SMB_DEFAULT1 "To Be Filled By O.E.M." +#define SMB_DEFAULT2 "Not Available At This Time" extern ttree_t *topo_tree_create(topo_hdl_t *, topo_mod_t *, const char *); -extern void topo_tree_destroy(topo_hdl_t *, ttree_t *); +extern void topo_tree_destroy(ttree_t *); extern int topo_tree_enum_all(topo_hdl_t *); -extern int topo_file_load(topo_hdl_t *, topo_mod_t *, ttree_t *); -extern void topo_file_unload(topo_hdl_t *, ttree_t *); - extern void topo_node_lock(tnode_t *); extern void topo_node_unlock(tnode_t *); extern void topo_node_hold(tnode_t *); diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_xml.c b/usr/src/lib/fm/topo/libtopo/common/topo_xml.c index fbcf10b690..caf2f63b09 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_xml.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_xml.c @@ -45,66 +45,12 @@ #include <topo_parse.h> #include <topo_error.h> -const char * const Children = "children"; -const char * const Dependents = "dependents"; -const char * const FMRI = "fmri"; -const char * const Grouping = "grouping"; -const char * const Immutable = "immutable"; -const char * const Instance = "instance"; -const char * const Int32 = "int32"; -const char * const Int64 = "int64"; -const char * const Name = "name"; -const char * const Path = "path"; -const char * const Range = "range"; -const char * const Scheme = "scheme"; -const char * const Siblings = "siblings"; -const char * const String = "string"; -const char * const Topology = "topology"; -const char * const Type = "type"; -const char * const UInt32 = "uint32"; -const char * const UInt64 = "uint64"; -const char * const Value = "value"; -const char * const Verify = "verify"; -const char * const Version = "version"; - -const char * const Enum_meth = "enum-method"; -const char * const Propgrp = "propgroup"; -const char * const Propval = "propval"; - -const char * const Node = "node"; -const char * const Hc = "hc"; - -const char * const True = "true"; -const char * const False = "false"; - -const char * const Namestab = "name-stability"; -const char * const Datastab = "data-stability"; - -const char * const Evolving = "Evolving"; -const char * const External = "External"; -const char * const Internal = "Internal"; -const char * const Obsolete = "Obsolete"; -const char * const Private = "Private"; -const char * const Stable = "Stable"; -const char * const Standard = "Standard"; -const char * const Unstable = "Unstable"; - static tf_rdata_t *topo_xml_walk(topo_mod_t *, tf_info_t *, xmlNodePtr, tnode_t *); -static void -txml_dump(int g, xmlNodePtr p) -{ - if (p && p->name) { - topo_dprintf(TOPO_DBG_MOD, "%d %s\n", g, p->name); - - for (p = p->xmlChildrenNode; p != NULL; p = p->next) - txml_dump(g + 1, p); - } -} - int -xmlattr_to_stab(topo_mod_t *mp, xmlNodePtr n, topo_stability_t *rs) +xmlattr_to_stab(topo_mod_t *mp, xmlNodePtr n, const char *stabname, + topo_stability_t *rs) { xmlChar *str; int rv = 0; @@ -114,8 +60,12 @@ xmlattr_to_stab(topo_mod_t *mp, xmlNodePtr n, topo_stability_t *rs) *rs = TOPO_STABILITY_PRIVATE; return (0); } - if ((str = xmlGetProp(n, (xmlChar *)Value)) == NULL) + if ((str = xmlGetProp(n, (xmlChar *)stabname)) == NULL) { + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, + "attribute to stability:\n"); return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); + } + if (xmlStrcmp(str, (xmlChar *)Internal) == 0) { *rs = TOPO_STABILITY_INTERNAL; } else if (xmlStrcmp(str, (xmlChar *)Private) == 0) { @@ -147,7 +97,7 @@ xmlattr_to_int(topo_mod_t *mp, xmlChar *str; xmlChar *estr; - topo_mod_dprintf(mp, "attribute to int\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "attribute to int\n"); if ((str = xmlGetProp(n, (xmlChar *)propname)) == NULL) return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); *value = strtoull((char *)str, (char **)&estr, 10); @@ -164,14 +114,12 @@ static int xmlattr_to_fmri(topo_mod_t *mp, xmlNodePtr xn, const char *propname, nvlist_t **rnvl) { - int err; xmlChar *str; - topo_mod_dprintf(mp, "attribute to int\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "attribute to int\n"); if ((str = xmlGetProp(xn, (xmlChar *)propname)) == NULL) return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); - if (topo_fmri_str2nvl(topo_mod_handle(mp), (const char *)str, rnvl, - &err) < 0) + if (topo_mod_str2nvl(mp, (const char *)str, rnvl) < 0) return (-1); xmlFree(str); return (0); @@ -183,7 +131,7 @@ xmlattr_to_type(topo_mod_t *mp, xmlNodePtr xn) topo_type_t rv; xmlChar *str; if ((str = xmlGetProp(xn, (xmlChar *)Type)) == NULL) { - topo_mod_dprintf(mp, "Property missing type"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "Property missing type"); (void) topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR); return (TOPO_TYPE_INVALID); } @@ -201,7 +149,8 @@ xmlattr_to_type(topo_mod_t *mp, xmlNodePtr xn) rv = TOPO_TYPE_STRING; } else { xmlFree(str); - topo_mod_dprintf(mp, "Unrecognized type attribute.\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "Unrecognized type attribute.\n"); (void) topo_mod_seterrno(mp, ETOPO_PRSR_BADTYPE); return (TOPO_TYPE_INVALID); } @@ -220,14 +169,16 @@ xmlprop_xlate(topo_mod_t *mp, xmlNodePtr xn, nvlist_t *nvl) if ((str = xmlGetProp(xn, (xmlChar *)Immutable)) != NULL) { if (xmlStrcmp(str, (xmlChar *)False) == 0) - e = nvlist_add_boolean_value(nvl, INV_IMMUTE, B_FALSE); + (void) nvlist_add_boolean_value(nvl, INV_IMMUTE, + B_FALSE); else - e = nvlist_add_boolean_value(nvl, INV_IMMUTE, B_TRUE); + (void) nvlist_add_boolean_value(nvl, INV_IMMUTE, + B_TRUE); xmlFree(str); - if (e != 0) - return (-1); + } else { + (void) nvlist_add_boolean_value(nvl, INV_IMMUTE, B_TRUE); } - /* FMXXX stability of the property value */ + if ((ptype = xmlattr_to_type(mp, xn)) == TOPO_TYPE_INVALID) return (-1); e = nvlist_add_int32(nvl, INV_PVALTYPE, ptype); @@ -267,11 +218,13 @@ xmlprop_xlate(topo_mod_t *mp, xmlNodePtr xn, nvlist_t *nvl) xmlFree(str); break; default: - topo_mod_dprintf(mp, "Unrecognized type attribute.\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "Unrecognized type attribute.\n"); return (topo_mod_seterrno(mp, ETOPO_PRSR_BADTYPE)); } if (e != 0) { - topo_mod_dprintf(mp, "Nvlist construction failed.\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "Nvlist construction failed.\n"); return (topo_mod_seterrno(mp, ETOPO_NOMEM)); } return (0); @@ -285,9 +238,10 @@ dependent_create(topo_mod_t *mp, xmlChar *grptype; int sibs = 0; - topo_mod_dprintf(mp, "dependent create\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "dependent create\n"); if ((grptype = xmlGetProp(dxn, (xmlChar *)Grouping)) == NULL) { - topo_mod_dprintf(mp, "Dependents missing grouping attribute"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "Dependents missing grouping attribute"); return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); } @@ -298,7 +252,7 @@ dependent_create(topo_mod_t *mp, } else if (xmlStrcmp(grptype, (xmlChar *)Children) == 0) { rp = pad->tpad_child; } else { - topo_mod_dprintf(mp, + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "Dependents have bogus grouping attribute"); xmlFree(grptype); return (topo_mod_seterrno(mp, ETOPO_PRSR_BADGRP)); @@ -310,7 +264,7 @@ dependent_create(topo_mod_t *mp, rp = rp->rd_next; } if ((np = topo_xml_walk(mp, xinfo, dxn, ptn)) == NULL) { - topo_mod_dprintf(mp, + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "error within dependent .xml topology: " "%s\n", topo_strerror(topo_mod_errno(mp))); return (-1); @@ -330,7 +284,7 @@ dependents_create(topo_mod_t *mp, { xmlNodePtr cn; - topo_mod_dprintf(mp, "dependents create\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "dependents create\n"); for (cn = pxn->xmlChildrenNode; cn != NULL; cn = cn->next) { if (xmlStrcmp(cn->name, (xmlChar *)Dependents) == 0) { if (dependent_create(mp, xinfo, pad, cn, ptn) < 0) @@ -353,7 +307,7 @@ prop_create(topo_mod_t *mp, char *str; int err, e; - topo_mod_dprintf(mp, "prop create\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "prop create\n"); switch (ptype) { case TOPO_TYPE_INT32: e = nvlist_lookup_int32(pfmri, INV_PVAL, &i32); @@ -377,7 +331,8 @@ prop_create(topo_mod_t *mp, e = ETOPO_PRSR_BADTYPE; } if (e != 0) { - topo_mod_dprintf(mp, "prop value lookup failed.\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "prop value lookup failed.\n"); return (topo_mod_seterrno(mp, e)); } switch (ptype) { @@ -400,8 +355,15 @@ prop_create(topo_mod_t *mp, e = topo_prop_set_string(ptn, gnm, pnm, flag, str, &err); break; } - if (e != 0) { - topo_mod_dprintf(mp, "prop set failed.\n"); + if (e != 0 && err != ETOPO_PROP_DEFD) { + + /* + * Some properties may have already been set + * in topo_node_bind() or topo_prop_inherit if we are + * enumerating from a static .xml file + */ + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "prop set " + "failed %s/%s:%s\n", gnm, pnm, topo_strerror(err)); return (topo_mod_seterrno(mp, err)); } return (0); @@ -419,28 +381,28 @@ props_create(topo_mod_t *mp, int pn; int e; - topo_mod_dprintf(mp, "props create\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "props create\n"); for (pn = 0; pn < nprops; pn++) { e = nvlist_lookup_string(props[pn], INV_PNAME, &pnm); if (e != 0) { - topo_mod_dprintf(mp, + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "props create lookup (%s) failure: %s", INV_PNAME, topo_strerror(e)); return (topo_mod_seterrno(mp, ETOPO_PRSR_NVPROP)); } e = nvlist_lookup_boolean_value(props[pn], INV_IMMUTE, &pim); if (e != 0) { - topo_mod_dprintf(mp, + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "props create lookup (%s) failure: %s", INV_IMMUTE, topo_strerror(e)); return (topo_mod_seterrno(mp, ETOPO_PRSR_NVPROP)); } flag = (pim == B_TRUE) ? - TOPO_PROP_SET_ONCE : TOPO_PROP_SET_MULTIPLE; + TOPO_PROP_IMMUTABLE : TOPO_PROP_MUTABLE; e = nvlist_lookup_int32(props[pn], INV_PVALTYPE, &i32); if (e != 0) { - topo_mod_dprintf(mp, + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "props create lookup (%s) failure: %s", INV_PVALTYPE, topo_strerror(e)); return (topo_mod_seterrno(mp, ETOPO_PRSR_NVPROP)); @@ -455,34 +417,66 @@ props_create(topo_mod_t *mp, static int pgroups_create(topo_mod_t *mp, tf_pad_t *pad, tnode_t *ptn) { - topo_stability_t gs; + topo_pgroup_info_t pgi; nvlist_t **props; char *gnm; + char *nmstab, *dstab; uint32_t rnprops, nprops; - uint32_t ui32; + uint32_t gv; int pg; int e; - topo_mod_dprintf(mp, "pgroups create\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "pgroups create\n"); for (pg = 0; pg < pad->tpad_pgcnt; pg++) { e = nvlist_lookup_string(pad->tpad_pgs[pg], INV_PGRP_NAME, &gnm); if (e != 0) { - topo_mod_dprintf(mp, "pad lookup (%s) failed.\n", + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "pad lookup (%s) failed.\n", INV_PGRP_NAME); return (topo_mod_seterrno(mp, ETOPO_PRSR_NVPROP)); } + e = nvlist_lookup_string(pad->tpad_pgs[pg], + INV_PGRP_NMSTAB, &nmstab); + if (e != 0) { + if (e != ENOENT) { + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "pad lookup (%s) " + "failed.\n", INV_PGRP_NMSTAB); + return (topo_mod_seterrno(mp, + ETOPO_PRSR_NVPROP)); + } else { + nmstab = TOPO_STABSTR_PRIVATE; + } + } + e = nvlist_lookup_string(pad->tpad_pgs[pg], + INV_PGRP_DSTAB, &dstab); + if (e != 0) { + if (e != ENOENT) { + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "pad lookup (%s) failed.\n", + INV_PGRP_DSTAB); + return (topo_mod_seterrno(mp, + ETOPO_PRSR_NVPROP)); + } else { + dstab = TOPO_STABSTR_PRIVATE; + } + } e = nvlist_lookup_uint32(pad->tpad_pgs[pg], - INV_PGRP_STAB, &ui32); + INV_PGRP_VER, &gv); if (e != 0) { - topo_mod_dprintf(mp, "pad lookup (%s) failed.\n", - INV_PGRP_STAB); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "pad lookup (%s) failed.\n", + INV_PGRP_VER); return (topo_mod_seterrno(mp, ETOPO_PRSR_NVPROP)); } - gs = (topo_stability_t)ui32; - if (topo_pgroup_create(ptn, gnm, gs, &e) != 0) { + pgi.tpi_name = gnm; + pgi.tpi_namestab = topo_name2stability(nmstab); + pgi.tpi_datastab = topo_name2stability(dstab); + pgi.tpi_version = gv; + if (topo_pgroup_create(ptn, &pgi, &e) != 0) { if (e != ETOPO_PROP_DEFD) { - topo_mod_dprintf(mp, + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "pgroups create failure: %s\n", topo_strerror(e)); return (-1); @@ -493,8 +487,8 @@ pgroups_create(topo_mod_t *mp, tf_pad_t *pad, tnode_t *ptn) e |= nvlist_lookup_nvlist_array(pad->tpad_pgs[pg], INV_PGRP_ALLPROPS, &props, &nprops); if (rnprops != nprops) { - topo_mod_dprintf(mp, - "warning: recorded number of props %d does not " + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "recorded number of props %d does not " "match number of props recorded %d.\n", rnprops, nprops); } @@ -510,9 +504,10 @@ pval_record(topo_mod_t *mp, xmlNodePtr xn) nvlist_t *pnvl = NULL; xmlChar *pname; - topo_mod_dprintf(mp, "pval record\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "pval record\n"); if ((pname = xmlGetProp(xn, (xmlChar *)Name)) == NULL) { - topo_mod_dprintf(mp, "propval lacks a name\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, + "propval lacks a name\n"); (void) topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR); return (NULL); } @@ -538,8 +533,8 @@ pval_record(topo_mod_t *mp, xmlNodePtr xn) static int pgroup_record(topo_mod_t *mp, xmlNodePtr pxn, tf_pad_t *rpad, int pi) { - topo_stability_t nmstab; - xmlNodePtr sn = NULL; + topo_stability_t nmstab, dstab; + uint64_t ver; xmlNodePtr cn; xmlChar *name; nvlist_t **apl = NULL; @@ -548,29 +543,43 @@ pgroup_record(topo_mod_t *mp, xmlNodePtr pxn, tf_pad_t *rpad, int pi) int ai = 0; int e; - topo_mod_dprintf(mp, "pgroup record\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "pgroup record\n"); if ((name = xmlGetProp(pxn, (xmlChar *)Name)) == NULL) { - topo_mod_dprintf(mp, "propgroup lacks a name\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "propgroup lacks a name\n"); return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); } - topo_mod_dprintf(mp, "pgroup %s\n", (char *)name); + if (xmlattr_to_int(mp, pxn, Version, &ver) < 0) { + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "propgroup lacks a version\n"); + return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); + } + if (xmlattr_to_stab(mp, pxn, Namestab, &nmstab) < 0) { + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "propgroup lacks name-stability\n"); + return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); + } + if (xmlattr_to_stab(mp, pxn, Datastab, &dstab) < 0) { + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "propgroup lacks data-stability\n"); + return (topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR)); + } + + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "pgroup %s\n", (char *)name); for (cn = pxn->xmlChildrenNode; cn != NULL; cn = cn->next) { if (xmlStrcmp(cn->name, (xmlChar *)Propval) == 0) pcnt++; - else if (xmlStrcmp(cn->name, (xmlChar *)Namestab) == 0) - sn = cn; - } - if (xmlattr_to_stab(mp, sn, &nmstab) < 0) { - xmlFree(name); - return (-1); } + if (topo_mod_nvalloc(mp, &pgnvl, NV_UNIQUE_NAME) < 0) { xmlFree(name); return (-1); } e = nvlist_add_string(pgnvl, INV_PGRP_NAME, (char *)name); - e |= nvlist_add_uint32(pgnvl, INV_PGRP_STAB, nmstab); + e |= nvlist_add_uint32(pgnvl, INV_PGRP_NMSTAB, nmstab); + e |= nvlist_add_uint32(pgnvl, INV_PGRP_DSTAB, dstab); + e |= nvlist_add_uint32(pgnvl, INV_PGRP_VER, ver); e |= nvlist_add_uint32(pgnvl, INV_PGRP_NPROP, pcnt); if (e != 0 || (apl = topo_mod_zalloc(mp, pcnt * sizeof (nvlist_t *))) == NULL) { @@ -608,7 +617,7 @@ pgroups_record(topo_mod_t *mp, xmlNodePtr pxn, tf_pad_t *rpad) xmlNodePtr cn; int pi = 0; - topo_mod_dprintf(mp, "pgroups record\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "pgroups record\n"); for (cn = pxn->xmlChildrenNode; cn != NULL; cn = cn->next) { if (xmlStrcmp(cn->name, (xmlChar *)Propgrp) == 0) { if (pgroup_record(mp, cn, rpad, pi++) < 0) @@ -627,41 +636,47 @@ pad_process(topo_mod_t *mp, tf_info_t *xinfo, xmlNodePtr pxn, tnode_t *ptn, tf_pad_t **rpad) { xmlNodePtr cn; + tf_pad_t *new = *rpad; int pgcnt = 0; int dcnt = 0; - topo_mod_dprintf(mp, "pad process beneath %s\n", topo_node_name(ptn)); - if (*rpad == NULL) { + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, + "pad process beneath %s\n", topo_node_name(ptn)); + if (new == NULL) { for (cn = pxn->xmlChildrenNode; cn != NULL; cn = cn->next) { if (xmlStrcmp(cn->name, (xmlChar *)Dependents) == 0) dcnt++; else if (xmlStrcmp(cn->name, (xmlChar *)Propgrp) == 0) pgcnt++; } - if ((*rpad = tf_pad_new(mp, pgcnt, dcnt)) == NULL) + if ((new = tf_pad_new(mp, pgcnt, dcnt)) == NULL) return (-1); - if (dcnt == 0 && pgcnt == 0) + if (dcnt == 0 && pgcnt == 0) { + *rpad = new; return (0); + } + if (pgcnt > 0) { - (*rpad)->tpad_pgs = + new->tpad_pgs = topo_mod_zalloc(mp, pgcnt * sizeof (nvlist_t *)); - if ((*rpad)->tpad_pgs == NULL) { - tf_pad_free(mp, *rpad); - return (-1); + if (new->tpad_pgs == NULL) { + tf_pad_free(mp, new); + return (NULL); } - if (pgroups_record(mp, pxn, *rpad) < 0) { - tf_pad_free(mp, *rpad); - return (-1); + if (pgroups_record(mp, pxn, new) < 0) { + tf_pad_free(mp, new); + return (NULL); } } + *rpad = new; } - if ((*rpad)->tpad_dcnt > 0) - if (dependents_create(mp, xinfo, *rpad, pxn, ptn) < 0) + if (new->tpad_dcnt > 0) + if (dependents_create(mp, xinfo, new, pxn, ptn) < 0) return (-1); - if ((*rpad)->tpad_pgcnt > 0) - if (pgroups_create(mp, *rpad, ptn) < 0) + if (new->tpad_pgcnt > 0) + if (pgroups_create(mp, new, ptn) < 0) return (-1); return (0); } @@ -669,37 +684,49 @@ pad_process(topo_mod_t *mp, static int node_process(topo_mod_t *mp, xmlNodePtr nn, tf_rdata_t *rd) { + xmlChar *str; topo_instance_t inst; tf_idata_t *newi; tnode_t *ntn; uint64_t ui; int rv = -1; + int s = 0; + + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, + "node process %s\n", rd->rd_name); - topo_mod_dprintf(mp, "node process %s\n", rd->rd_name); if (xmlattr_to_int(mp, nn, Instance, &ui) < 0) goto nodedone; inst = (topo_instance_t)ui; - if (topo_mod_enumerate(rd->rd_mod, - rd->rd_pn, rd->rd_finfo->tf_scheme, rd->rd_name, inst, inst) < 0) + if ((str = xmlGetProp(nn, (xmlChar *)Static)) != NULL) { + if (xmlStrcmp(str, (xmlChar *)True) == 0) + s = 1; + } + + if (topo_mod_enumerate(rd->rd_mod, rd->rd_pn, rd->rd_finfo->tf_scheme, + rd->rd_name, inst, inst, s == 1 ? &s : NULL) < 0) goto nodedone; ntn = topo_node_lookup(rd->rd_pn, rd->rd_name, inst); if (ntn == NULL) goto nodedone; if ((newi = tf_idata_new(mp, inst, ntn)) == NULL) { - topo_mod_dprintf(mp, "tf_idata_new failed.\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "tf_idata_new failed.\n"); goto nodedone; } - if (tf_idata_insert(mp, &rd->rd_instances, newi) < 0) { - topo_mod_dprintf(mp, "tf_idata_insert failed.\n"); + if (tf_idata_insert(&rd->rd_instances, newi) < 0) { + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "tf_idata_insert failed.\n"); goto nodedone; } if (pad_process(mp, rd->rd_finfo, nn, ntn, &newi->ti_pad) < 0) goto nodedone; rv = 0; nodedone: - topo_mod_dprintf(mp, "done with node %s.\n", rd->rd_name); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "done with node %s.\n", + rd->rd_name); return (rv); } @@ -709,20 +736,15 @@ enum_attributes_process(topo_mod_t *mp, xmlNodePtr en) tf_edata_t *einfo; uint64_t ui; - topo_mod_dprintf(mp, "enum attributes process\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "enum attributes process\n"); if ((einfo = topo_mod_zalloc(mp, sizeof (tf_edata_t))) == NULL) { (void) topo_mod_seterrno(mp, ETOPO_NOMEM); return (NULL); } einfo->te_name = (char *)xmlGetProp(en, (xmlChar *)Name); if (einfo->te_name == NULL) { - topo_mod_dprintf(mp, "Enumerator name attribute missing.\n"); - (void) topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR); - goto enodedone; - } - einfo->te_path = (char *)xmlGetProp(en, (xmlChar *)Path); - if (einfo->te_path == NULL) { - topo_mod_dprintf(mp, "Enumerator path attribute missing.\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "Enumerator name attribute missing.\n"); (void) topo_mod_seterrno(mp, ETOPO_PRSR_NOATTR); goto enodedone; } @@ -738,58 +760,47 @@ enum_attributes_process(topo_mod_t *mp, xmlNodePtr en) enodedone: if (einfo->te_name != NULL) xmlFree(einfo->te_name); - if (einfo->te_path != NULL) - xmlFree(einfo->te_path); return (NULL); } static int enum_run(topo_mod_t *mp, tf_rdata_t *rd) { + topo_hdl_t *thp = mp->tm_hdl; int e = -1; /* - * first see if the module is already loaded + * Check if the enumerator module is already loaded. + * Module loading is single-threaded at this point so there's + * no need to worry about the module going away or bumping the + * ref count. */ - rd->rd_mod = topo_mod_lookup(mp->tm_hdl, rd->rd_einfo->te_name); - if (rd->rd_mod == NULL) { - char *mostpath = topo_mod_alloc(mp, PATH_MAX); - char *skip; - int prepend = 0; - - if (mostpath == NULL) - return (-1); - skip = rd->rd_einfo->te_path; - if (*skip == '%' && *(skip + 1) == 'r') { - prepend = 1; - skip += 2; - } - (void) snprintf(mostpath, - PATH_MAX, "%s%s/%s.so", - (prepend == 1) ? topo_mod_rootdir(mp) : "", - skip, rd->rd_einfo->te_name); - topo_mod_dprintf(mp, - "enum_run, load %s.\n", mostpath); - if ((rd->rd_mod = topo_mod_load(mp, mostpath)) == NULL) { - topo_mod_dprintf(mp, + if ((rd->rd_mod = topo_mod_lookup(thp, rd->rd_einfo->te_name, + 0)) == NULL) { + if ((rd->rd_mod = topo_mod_load(mp, rd->rd_einfo->te_name, + rd->rd_einfo->te_vers)) == NULL) { + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "mod_load of %s failed: %s.\n", - mostpath, topo_strerror(topo_mod_errno(mp))); - topo_free(mostpath, PATH_MAX); + rd->rd_einfo->te_name, + topo_strerror(topo_mod_errno(mp))); + (void) topo_hdl_seterrno(thp, topo_mod_errno(mp)); return (e); } - topo_free(mostpath, PATH_MAX); } /* * We're live, so let's enumerate. */ - topo_mod_dprintf(mp, "enumerate request. (%s)\n", + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "enumerate request. (%s)\n", rd->rd_einfo->te_name); e = topo_mod_enumerate(rd->rd_mod, rd->rd_pn, rd->rd_einfo->te_name, - rd->rd_name, rd->rd_min, rd->rd_max); - topo_mod_dprintf(mp, "back from enumeration. %d\n", e); + rd->rd_name, rd->rd_min, rd->rd_max, NULL); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "back from enumeration. %d\n", + e); if (e != 0) { - topo_mod_dprintf(mp, "Enumeration failed (%s)\n", + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "Enumeration failed (%s)\n", topo_strerror(topo_mod_errno(mp))); + (void) topo_hdl_seterrno(thp, EMOD_PARTIAL_ENUM); return (topo_mod_seterrno(mp, EMOD_PARTIAL_ENUM)); } return (e); @@ -807,12 +818,13 @@ topo_xml_range_process(topo_mod_t *mp, xmlNodePtr rn, tf_rdata_t *rd) tnode_t *ct; int e; - topo_mod_dprintf(mp, "process %s range beneath %s\n", + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "process %s range beneath %s\n", rd->rd_name, topo_node_name(rd->rd_pn)); e = topo_node_range_create(mp, rd->rd_pn, rd->rd_name, rd->rd_min, rd->rd_max); if (e != 0) { - topo_mod_dprintf(mp, "Range create failed due to %s.\n", + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "Range create failed due to %s.\n", topo_strerror(topo_mod_errno(mp))); return (-1); } @@ -824,8 +836,11 @@ topo_xml_range_process(topo_mod_t *mp, xmlNodePtr rn, tf_rdata_t *rd) if ((rd->rd_einfo = enum_attributes_process(mp, cn)) == NULL) return (-1); if (enum_run(mp, rd) < 0) { - topo_mod_dprintf(mp, "Enumeration failed.\n"); - return (-1); + /* + * Note the failure but continue on + */ + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, + "Enumeration failed.\n"); } } @@ -833,7 +848,7 @@ topo_xml_range_process(topo_mod_t *mp, xmlNodePtr rn, tf_rdata_t *rd) for (cn = rn->xmlChildrenNode; cn != NULL; cn = cn->next) { if (xmlStrcmp(cn->name, (xmlChar *)Node) == 0) if (node_process(mp, cn, rd) < 0) { - topo_mod_dprintf(mp, + topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "node processing failed: %s.\n", topo_strerror(topo_mod_errno(mp))); return (topo_mod_seterrno(mp, @@ -853,7 +868,7 @@ topo_xml_range_process(topo_mod_t *mp, xmlNodePtr rn, tf_rdata_t *rd) return (-1); ct = topo_child_next(rd->rd_pn, ct); } - topo_mod_dprintf(mp, "end range process %s\n", + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "end range process %s\n", rd->rd_name); return (0); } @@ -870,15 +885,16 @@ topo_xml_walk(topo_mod_t *mp, * as 'ranges', these define topology nodes may exist, and need * to be verified. */ - topo_mod_dprintf(mp, "topo_xml_walk\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "topo_xml_walk\n"); rr = pr = NULL; for (curr = croot->xmlChildrenNode; curr != NULL; curr = curr->next) { if (curr->name == NULL) { - topo_mod_dprintf(mp, "Ignoring nameless xmlnode.\n"); + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, + "Ignoring nameless xmlnode\n"); continue; } if (xmlStrcmp(curr->name, (xmlChar *)Range) != 0) { - topo_mod_dprintf(mp, + topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "Ignoring non-range %s.\n", curr->name); continue; } @@ -906,11 +922,12 @@ topo_xml_enum(topo_mod_t *tmp, tf_info_t *xinfo, tnode_t *troot) xmlNodePtr xroot; if ((xroot = xmlDocGetRootElement(xinfo->tf_xdoc)) == NULL) { - topo_mod_dprintf(tmp, "Couldn't get root xmlNode.\n"); + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, + "Couldn't get root xmlNode.\n"); return (-1); } if ((xinfo->tf_rd = topo_xml_walk(tmp, xinfo, xroot, troot)) == NULL) { - topo_mod_dprintf(tmp, + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, "error within .xml topology: %s\n", topo_strerror(topo_mod_errno(tmp))); return (-1); @@ -933,7 +950,7 @@ txml_file_parse(topo_mod_t *tmp, char *dtdpath = NULL; int readflags = 0; tf_info_t *r; - int e; + int e, validate = 0; /* * Since topologies can XInclude other topologies, and libxml2 @@ -947,6 +964,7 @@ txml_file_parse(topo_mod_t *tmp, dtdpath = getenv("TOPO_DTD"); if (dtdpath != NULL) xmlLoadExtDtdDefaultValue = 0; + validate = 1; } /* @@ -957,7 +975,8 @@ txml_file_parse(topo_mod_t *tmp, readflags = XML_PARSE_NOERROR | XML_PARSE_NOWARNING; if ((document = xmlReadFd(fd, filenm, NULL, readflags)) == NULL) { - topo_mod_dprintf(tmp, "couldn't parse document.\n"); + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, + "couldn't parse document.\n"); return (NULL); } @@ -965,18 +984,19 @@ txml_file_parse(topo_mod_t *tmp, * Verify that this is a document type we understand. */ if ((dtd = xmlGetIntSubset(document)) == NULL) { - topo_mod_dprintf(tmp, "document has no DTD.\n"); + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, + "document has no DTD.\n"); return (NULL); } - if (strcmp((const char *)dtd->SystemID, TOPO_DTD_PATH) == -1) { - topo_mod_dprintf(tmp, - "document DTD unknown; bad topology file?\n"); + if (strcmp((const char *)dtd->SystemID, TOPO_DTD_PATH) != 0) { + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, + "document DTD unknown; bad topology file\n"); return (NULL); } if ((cursor = xmlDocGetRootElement(document)) == NULL) { - topo_mod_dprintf(tmp, "document is empty.\n"); + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, "document is empty.\n"); xmlFreeDoc(document); return (NULL); } @@ -986,19 +1006,20 @@ txml_file_parse(topo_mod_t *tmp, * expected scheme. */ if (xmlStrcmp(cursor->name, (xmlChar *)Topology) != 0) { - topo_mod_dprintf(tmp, + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, "document is not a topology description.\n"); xmlFreeDoc(document); return (NULL); } if ((scheme = xmlGetProp(cursor, (xmlChar *)Scheme)) == NULL) { - topo_mod_dprintf(tmp, "topology lacks a scheme.\n"); + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, + "topology lacks a scheme.\n"); (void) topo_mod_seterrno(tmp, ETOPO_PRSR_NOATTR); xmlFreeDoc(document); return (NULL); } if (xmlStrcmp(scheme, (xmlChar *)escheme) != 0) { - topo_mod_dprintf(tmp, + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, "topology in unrecognized scheme, %s, expecting %s\n", scheme, escheme); (void) topo_mod_seterrno(tmp, ETOPO_PRSR_BADSCH); @@ -1010,7 +1031,7 @@ txml_file_parse(topo_mod_t *tmp, if (dtdpath != NULL) { dtd = xmlParseDTD(NULL, (xmlChar *)dtdpath); if (dtd == NULL) { - topo_mod_dprintf(tmp, + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, "Could not parse DTD \"%s\".\n", dtdpath); return (NULL); @@ -1023,34 +1044,32 @@ txml_file_parse(topo_mod_t *tmp, } if (xmlXIncludeProcessFlags(document, XML_PARSE_XINCLUDE) == -1) {; - topo_mod_dprintf(tmp, + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, "couldn't handle XInclude statements in document\n"); return (NULL); } - if ((vcp = xmlNewValidCtxt()) == NULL) { - xmlFree(scheme); - scheme = NULL; - return (NULL); - } - vcp->warning = xmlParserValidityWarning; - vcp->error = xmlParserValidityError; + if (validate) { + if ((vcp = xmlNewValidCtxt()) == NULL) { + xmlFree(scheme); + scheme = NULL; + return (NULL); + } + vcp->warning = xmlParserValidityWarning; + vcp->error = xmlParserValidityError; - e = xmlValidateDocument(vcp, document); + e = xmlValidateDocument(vcp, document); - xmlFreeValidCtxt(vcp); + xmlFreeValidCtxt(vcp); - if (e == 0) { - topo_mod_dprintf(tmp, "Document is not valid.\n"); - xmlFreeDoc(document); - return (NULL); + if (e == 0) + topo_dprintf(tmp->tm_hdl, TOPO_DBG_ERR, + "Document is not valid.\n"); } - if ((r = tf_info_new(tmp, filenm, document, scheme)) == NULL) + if ((r = tf_info_new(tmp, document, scheme)) == NULL) return (NULL); - /* txml_dump(0, cursor); */ - xmlFree(scheme); scheme = NULL; return (r); diff --git a/usr/src/lib/fm/topo/files/Makefile b/usr/src/lib/fm/topo/maps/Makefile index bbb8af7ecc..5286fba502 100644 --- a/usr/src/lib/fm/topo/files/Makefile +++ b/usr/src/lib/fm/topo/maps/Makefile @@ -30,8 +30,7 @@ sparc_SUBDIRS = sun4u \ SUNW,Sun-Fire \ SUNW,Sun-Fire-T200 \ SUNW,Sun-Fire-15000 \ - SUNW,SPARC-Enterprise \ - SUNW,Sun-Blade-T6300 + SUNW,SPARC-Enterprise i386_SUBDIRS = i86pc diff --git a/usr/src/lib/fm/topo/files/Makefile.file b/usr/src/lib/fm/topo/maps/Makefile.map index da113c1af8..3012590183 100644 --- a/usr/src/lib/fm/topo/files/Makefile.file +++ b/usr/src/lib/fm/topo/maps/Makefile.map @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -26,24 +25,37 @@ # # ident "%Z%%M% %I% %E% SMI" +.KEEP_STATE: +.SUFFIXES: .xml + +MODCLASS = maps + include ../../../Makefile.lib include ../../../../Makefile.lib DTDSRC = $(DTDFILE:%=../common/%) DTDTARG = $(DTDFILE:%=%) -ROOT_DTDTARG = $(DTDTARG:%=$(ROOT)/usr/share/lib/xml/dtd/%) +ROOTDTDTARG = $(DTDTARG:%=$(ROOT)/usr/share/lib/xml/dtd/%) + +common_ROOTTOPOROOT = $(ROOT)/usr/lib/fm/topo/$(MODCLASS) +arch_ROOTTOPOROOT = $(ROOT)/usr/platform/$(ARCH)/lib/fm/topo/$(MODCLASS) +platform_ROOTTOPOROOT = \ + $(PLATFORMS:%=$(ROOT)/usr/platform/%/lib/fm/topo/$(MODCLASS)) +ROOTTOPOROOT = $($(CLASS)_ROOTTOPOROOT) +ROOTTOPOMAPS = $(TOPOFILE:%=$(ROOTTOPOROOT)/%) + +install:= FILEMODE = 0444 + +.xml: + $(RM) $@ + $(CAT) $< > $@ -TOPOTARG = $(TOPOFILE:%=%) -common_TOPOTARG = $(ROOT)/usr/lib/fm/topo/$(TOPOTARG) -arch_TOPOTARG = $(ROOT)/usr/platform/$(ARCH)/lib/fm/topo/$(TOPOTARG) -platform_TOPOTARG = \ - $(PLATFORMS:%=$(ROOT)/usr/platform/%/lib/fm/topo/$(TOPOTARG)) -ROOT_TOPOTARG = $($(CLASS)_TOPOTARG) +include ../../Makefile.rootdirs -all: $(ROOT_DTDTARG) $(ROOT_TOPOTARG) +all: $(TOPOFILE) clean: - $(RM) $(ROOT_DTDTARG) $(ROOT_TOPOTARG) + $(RM) $(ROOTTOPOMAPS) clobber: clean @@ -51,13 +63,11 @@ check: $(CHECKHDRS) install_h lint _msg: -$(ROOT_DTDTARG): $$(@D) - $(RM) $@; $(INS) -s -m 0444 -f $(@D) $(DTDSRC) - -$(ROOT_TOPOTARG): $$(@D) - $(RM) $@; $(INS) -s -m 0444 -f $(@D) $(TOPOTARG) +$($(CLASS)_ROOTTOPOROOT)/%: % + $(INS.file) -install: $(ROOT_DTDTARG) $(ROOT_TOPOTARG) +$(ROOTDTDTARG): $$(@D) + $(RM) $@; $(INS) -s -m 0444 -f $(@D) $(DTDSRC) -include ../../Makefile.rootdirs +install: all $(ROOTDTDTARG) $(ROOTTOPOROOT) $(ROOTTOPOMAPS) diff --git a/usr/src/lib/fm/topo/files/SUNW,SPARC-Enterprise/Makefile b/usr/src/lib/fm/topo/maps/SUNW,SPARC-Enterprise/Makefile index 678a1c9e2d..32a6fcb198 100644 --- a/usr/src/lib/fm/topo/files/SUNW,SPARC-Enterprise/Makefile +++ b/usr/src/lib/fm/topo/maps/SUNW,SPARC-Enterprise/Makefile @@ -27,8 +27,8 @@ PLATFORMS = SUNW,SPARC-Enterprise CLASS = platform -DTDFILE = -TOPOFILE = hc-topology.xml +DTDFILE = +TOPOFILE = SPARC-Enterprise-hc-topology.xml SRCDIR = ../SUNW,SPARC-Enterprise -include ../Makefile.file +include ../Makefile.map diff --git a/usr/src/lib/fm/topo/files/SUNW,SPARC-Enterprise/hc-topology.xml b/usr/src/lib/fm/topo/maps/SUNW,SPARC-Enterprise/SPARC-Enterprise-hc-topology.xml index 950e1b8fba..a05552e2bd 100644 --- a/usr/src/lib/fm/topo/files/SUNW,SPARC-Enterprise/hc-topology.xml +++ b/usr/src/lib/fm/topo/maps/SUNW,SPARC-Enterprise/SPARC-Enterprise-hc-topology.xml @@ -29,7 +29,8 @@ <topology name='SUNW,SPARC-Enterprise' scheme='hc'> <range name='chassis' min='0' max='0'> <node instance='0'> - <propgroup name='protocol'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > <propval name='FRU' type='fmri' value='hc:///chassis=0' /> </propgroup> diff --git a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire-15000/Makefile b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Makefile index c876d2ff4a..4e78cee563 100644 --- a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire-15000/Makefile +++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Makefile @@ -27,8 +27,8 @@ PLATFORMS = SUNW,Sun-Fire-15000 CLASS = platform -DTDFILE = -TOPOFILE = hc-topology.xml +DTDFILE = +TOPOFILE = Sun-Fire-15000-hc-topology.xml SRCDIR = ../SUNW,Sun-Fire-15000 -include ../Makefile.file +include ../Makefile.map diff --git a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire-15000/hc-topology.xml b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Sun-Fire-15000-hc-topology.xml index 04eea53854..3339129b84 100644 --- a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire-15000/hc-topology.xml +++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Sun-Fire-15000-hc-topology.xml @@ -29,19 +29,20 @@ <topology name='SUNW,Sun-Fire-15000' scheme='hc'> <range name='interconnect' min='0' max='0'> <node instance='0'> - <propgroup name='protocol'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > <propval name='FRU' type='fmri' - value='hc:///interconnect=0' /> + value='hc:///component=interconnect' /> + <propval name='label' type='string' + value='interconnect' /> </propgroup> </node> <dependents grouping='children'> <range name='ioboard' min='0' max='17'> - <enum-method name='ioboard' version='1' - path='%r/usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/plugins' /> + <enum-method name='ioboard' version='1' /> </range> <range name='cpu' min='0' max='100'> - <enum-method name='chip' version='1' - path='%r/usr/platform/sun4u/lib/fm/topo/plugins' /> + <enum-method name='chip' version='1' /> </range> </dependents> </range> diff --git a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire-T200/Makefile b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Makefile index 51ac282be8..e94704027d 100644 --- a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire-T200/Makefile +++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Makefile @@ -27,8 +27,12 @@ PLATFORMS = SUNW,Sun-Fire-T200 CLASS = platform -DTDFILE = -TOPOFILE = hc-topology.xml +DTDFILE = +TOPOFILE = Sun-Fire-T200-hc-topology.xml \ + Sun-Fire-T1000-hc-topology.xml \ + SPARC-Enterprise-T1000-hc-topology.xml \ + Sun-Blade-T6300-hc-topology.xml + SRCDIR = ../SUNW,Sun-Fire-T200 -include ../Makefile.file +include ../Makefile.map diff --git a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire-T200/hc-topology.xml b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/SPARC-Enterprise-T1000-hc-topology.xml index 6555039a92..59872ddef3 100644 --- a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire-T200/hc-topology.xml +++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/SPARC-Enterprise-T1000-hc-topology.xml @@ -26,10 +26,11 @@ ident "%Z%%M% %I% %E% SMI" --> -<topology name='SUNW,Sun-Fire-T200' scheme='hc'> +<topology name='SUNW,SPARC-Enterprise-T1000' scheme='hc'> <range name='motherboard' min='0' max='0'> <node instance='0'> - <propgroup name='protocol'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > <propval name='FRU' type='fmri' value='hc:///component=MB' /> <propval name='label' type='string' @@ -37,14 +38,9 @@ </propgroup> </node> <dependents grouping='children'> - <range name='ioboard' min='0' max='0'> - <enum-method name='ioboard' version='1' - path='%r/usr/platform/sun4v/lib/fm/topo/plugins' /> - </range> + <range name='hostbridge' min='0' max='254'> + <enum-method name='hostbridge' version='1' /> + </range> </dependents> </range> - <range name='ioboard' min='0' max='0'> - <enum-method name='ioboard' version='1' - path='%r/usr/platform/sun4v/lib/fm/topo/plugins' /> - </range> </topology> diff --git a/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/hc-topology.xml b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Blade-T6300-hc-topology.xml index c70843acfe..e81d59fff9 100644 --- a/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/hc-topology.xml +++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Blade-T6300-hc-topology.xml @@ -29,17 +29,17 @@ <topology name='SUNW,Sun-Blade-T6300' scheme='hc'> <range name='motherboard' min='0' max='0'> <node instance='0'> - <propgroup name='protocol'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > <propval name='FRU' type='fmri' - value='hc:///motherboard=0' /> + value='hc:///component=MB' /> <propval name='label' type='string' value='MB' /> </propgroup> </node> <dependents grouping='children'> <range name='hostbridge' min='0' max='254'> - <enum-method name='hostbridge' version='1' - path='%r/usr/platform/sun4v/lib/fm/topo/plugins' /> + <enum-method name='hostbridge' version='1' /> </range> </dependents> </range> diff --git a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T1000-hc-topology.xml b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T1000-hc-topology.xml new file mode 100644 index 0000000000..fa4fb7d918 --- /dev/null +++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T1000-hc-topology.xml @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1"> +<!-- + Copyright 2006 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + CDDL HEADER START + + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. + + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. + + When distributing Covered Code, include this CDDL HEADER in each + file and include the License file at usr/src/OPENSOLARIS.LICENSE. + If applicable, add the following below this CDDL HEADER, with the + fields enclosed by brackets "[]" replaced with your own identifying + information: Portions Copyright [yyyy] [name of copyright owner] + + CDDL HEADER END + + ident "%Z%%M% %I% %E% SMI" +--> + +<topology name='SUNW,Sun-Fire-T1000' scheme='hc'> + <range name='motherboard' min='0' max='0'> + <node instance='0'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > + <propval name='FRU' type='fmri' + value='hc:///component=MB' /> + <propval name='label' type='string' + value='MB' /> + </propgroup> + </node> + <dependents grouping='children'> + <range name='hostbridge' min='0' max='254'> + <enum-method name='hostbridge' version='1' /> + </range> + </dependents> + </range> +</topology> diff --git a/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T200-hc-topology.xml b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T200-hc-topology.xml new file mode 100644 index 0000000000..7e8ab5d295 --- /dev/null +++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T200-hc-topology.xml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1"> +<!-- + Copyright 2006 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + CDDL HEADER START + + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. + + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. + + When distributing Covered Code, include this CDDL HEADER in each + file and include the License file at usr/src/OPENSOLARIS.LICENSE. + If applicable, add the following below this CDDL HEADER, with the + fields enclosed by brackets "[]" replaced with your own identifying + information: Portions Copyright [yyyy] [name of copyright owner] + + CDDL HEADER END + + ident "%Z%%M% %I% %E% SMI" +--> + +<topology name='SUNW,Sun-Fire-T200' scheme='hc'> + <range name='motherboard' min='0' max='0'> + <node instance='0'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > + <propval name='FRU' type='fmri' + value='hc:///component=MB' /> + <propval name='label' type='string' + value='MB' /> + </propgroup> + </node> + </range> + <range name='ioboard' min='0' max='0'> + <node instance='0'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > + <propval name='FRU' type='fmri' + value='hc:///component=IOBD' /> + <propval name='label' type='string' + value='IOBD' /> + </propgroup> + </node> + <dependents grouping='children'> + <range name='hostbridge' min='0' max='254'> + <enum-method name='hostbridge' version='1' /> + </range> + </dependents> + </range> +</topology> diff --git a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire/Makefile b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire/Makefile index feba1c71fa..e214bf89cc 100644 --- a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire/Makefile +++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire/Makefile @@ -27,8 +27,8 @@ PLATFORMS = SUNW,Sun-Fire CLASS = platform -DTDFILE = -TOPOFILE = hc-topology.xml +DTDFILE = +TOPOFILE = Sun-Fire-hc-topology.xml SRCDIR = ../SUNW,Sun-Fire -include ../Makefile.file +include ../Makefile.map diff --git a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire/hc-topology.xml b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire/Sun-Fire-hc-topology.xml index 4dedd2237a..5f58411ed6 100644 --- a/usr/src/lib/fm/topo/files/SUNW,Sun-Fire/hc-topology.xml +++ b/usr/src/lib/fm/topo/maps/SUNW,Sun-Fire/Sun-Fire-hc-topology.xml @@ -29,19 +29,20 @@ <topology name='SUNW,Sun-Fire' scheme='hc'> <range name='centerplane' min='0' max='0'> <node instance='0'> - <propgroup name='protocol'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > <propval name='FRU' type='fmri' - value='hc:///centerplane=0' /> + value='hc:///component=centerplane' /> + <propval name='label' type='string' + value='centerplane' /> </propgroup> </node> <dependents grouping='children'> <range name='ioboard' min='0' max='9'> - <enum-method name='ioboard' version='1' - path='%r/usr/platform/SUNW,Sun-Fire/lib/fm/topo/plugins' /> + <enum-method name='ioboard' version='1' /> </range> <range name='cpu' min='0' max='100'> - <enum-method name='chip' version='1' - path='%r/usr/platform/sun4u/lib/fm/topo/plugins' /> + <enum-method name='chip' version='1' /> </range> </dependents> </range> diff --git a/usr/src/lib/fm/topo/files/common/topology.dtd.1 b/usr/src/lib/fm/topo/maps/common/topology.dtd.1 index fd772bcac8..7400b3c638 100644 --- a/usr/src/lib/fm/topo/files/common/topology.dtd.1 +++ b/usr/src/lib/fm/topo/maps/common/topology.dtd.1 @@ -6,9 +6,8 @@ CDDL HEADER START The contents of this file are subject to the terms of the - Common Development and Distribution License, Version 1.0 only - (the "License"). You may not use this file except in compliance - with the License. + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. @@ -59,42 +58,6 @@ xmlns:xi CDATA #FIXED "http://www.w3.org/2001/XInclude" > -<!-- - data-stability - - This element associates an SMI stability level with the parent - element's data. See attributes(5) for an explanation of interface - stability levels. - - Its attribute is - - value The stability level of the parent element's data. ---> - -<!ELEMENT data-stability EMPTY> - -<!ATTLIST data-stability - value ( Standard | Stable | Evolving | Unstable | - External | Obsolete ) #REQUIRED > - -<!-- - name-stability - - This element associates an SMI stability level with the parent - element's name. See attributes(5) for an explanation of interface - stability levels. - - Its attribute is - - value The stability level of the parent element's name. ---> - -<!ELEMENT name-stability EMPTY> - -<!ATTLIST name-stability - value ( Standard | Stable | Evolving | Unstable | - External | Obsolete ) #REQUIRED > - <!-- Properties and property groups --> <!-- @@ -115,8 +78,7 @@ immutable This value remains unchanged for the lifetime of a snapshot. --> -<!ELEMENT propval - (name-stability?, data-stability?) > +<!ELEMENT propval EMPTY > <!ATTLIST propval name CDATA #REQUIRED @@ -134,34 +96,27 @@ Its attributes are - name The name of this property group. + name The name of this property group. + name-stability Stability level of the property group name + data-stability Stability level of the property names and content + version Version of the propery group definition --> <!ELEMENT propgroup - ( name-stability?, propval* ) > + ( propval* ) > <!ATTLIST propgroup - name CDATA #REQUIRED> + name CDATA #REQUIRED + version CDATA #REQUIRED + name-stability ( Private | Standard | Stable | Evolving | Unstable | + External | Obsolete ) #REQUIRED + data-stability ( Private | Standard | Stable | Evolving | Unstable | + External | Obsolete ) #REQUIRED > <!-- Methods --> <!-- - argval - - An method argument. It has two attributes: - - name The name of the argument. - type The data type of the argument. ---> - -<!ELEMENT argval EMPTY> - -<!ATTLIST argval - name CDATA #REQUIRED - type CDATA #REQUIRED > - -<!-- enum-method This element describes the enumeration method used to @@ -176,65 +131,36 @@ usually a defined interface of the enumerator to which a topo instance assigned. - path location of enumerator - version Version of the enumeration API + --> -<!ELEMENT enum-method - ( apply-method* ) > +<!ELEMENT enum-method EMPTY > <!ATTLIST enum-method name CDATA #REQUIRED - path CDATA #REQUIRED version CDATA #REQUIRED > <!-- - apply-method - - This element describes one of the methods used by an enumerator - to act populate a composition of topo nodes. Its interpretation is - left to the enumerator to which a particular topo node is - assigned. It contains a set of attributes, context, and an optional - stability element for the optional args that can be included. - - Its attributes are - - name Name of this method. The method names are - usually a defined interface of the enumerator to which a - topo instance assigned. - - version Version of the function API - - description English description of the method ---> - -<!ELEMENT apply-method - ( name-stability?, argval* ) > - -<!ATTLIST apply-method - name CDATA #REQUIRED - version CDATA #REQUIRED - description CDATA #REQUIRED > - -<!-- node This element identifies a known topology node. Its attributes are - name The name of the topo node - instance The instance number of the known node + static Boolean to determine if node is statically created + by the XML parser or an enumerator + --> <!ELEMENT node ( propgroup*, dependents* ) > <!ATTLIST node - instance CDATA #REQUIRED > + instance CDATA #REQUIRED + static ( true | false ) "false" > <!-- dependents diff --git a/usr/src/lib/fm/topo/maps/i86pc/Makefile b/usr/src/lib/fm/topo/maps/i86pc/Makefile new file mode 100644 index 0000000000..f9507c6729 --- /dev/null +++ b/usr/src/lib/fm/topo/maps/i86pc/Makefile @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +ARCH = i86pc +CLASS = arch +DTDFILE = topology.dtd.1 +TOPOFILE = i86pc-hc-topology.xml storage-hc-topology.xml +SRCDIR = ../i86pc + +include ../Makefile.map diff --git a/usr/src/lib/fm/topo/files/i86pc/hc-topology.xml b/usr/src/lib/fm/topo/maps/i86pc/i86pc-hc-topology.xml index 6b5e409f5b..f7101649cd 100644 --- a/usr/src/lib/fm/topo/files/i86pc/hc-topology.xml +++ b/usr/src/lib/fm/topo/maps/i86pc/i86pc-hc-topology.xml @@ -30,25 +30,21 @@ <range name='motherboard' min='0' max='0'> <node instance='0'> - <propgroup name='protocol'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > <propval name='FRU' type='fmri' - value='hc:///motherboard=0' /> + value='hc:///component=motherboard' /> <propval name='label' type='string' value='MB' /> </propgroup> </node> <dependents grouping='children'> - <range name='chip' min='0' max='100'> - <enum-method name='chip' version='1' - path='%r/usr/platform/i86pc/lib/fm/topo/plugins' /> + <enum-method name='chip' version='1' /> </range> - <range name='hostbridge' min='0' max='254'> - <enum-method name='hostbridge' version='1' - path='%r/usr/platform/i86pc/lib/fm/topo/plugins' /> + <enum-method name='hostbridge' version='1' /> </range> - </dependents> </range> diff --git a/usr/src/lib/fm/topo/maps/i86pc/storage-hc-topology.xml b/usr/src/lib/fm/topo/maps/i86pc/storage-hc-topology.xml new file mode 100644 index 0000000000..f6acb64f58 --- /dev/null +++ b/usr/src/lib/fm/topo/maps/i86pc/storage-hc-topology.xml @@ -0,0 +1,39 @@ +<?xml version="1.0"?> +<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1"> +<!-- + Copyright 2006 Sun Microsystems, Inc. All rights reserved. + Use is subject to license terms. + + CDDL HEADER START + + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. + + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. + + When distributing Covered Code, include this CDDL HEADER in each + file and include the License file at usr/src/OPENSOLARIS.LICENSE. + If applicable, add the following below this CDDL HEADER, with the + fields enclosed by brackets "[]" replaced with your own identifying + information: Portions Copyright [yyyy] [name of copyright owner] + + CDDL HEADER END + + ident "%Z%%M% %I% %E% SMI" +--> + +<topology name='storage' scheme='hc'> + + <range name='sata-port' min='0' max='7'> + <enum-method name='sata' version='1' /> + </range> + + <range name='disk' min='0' max='15'> + <enum-method name='scsi' version='1' /> + </range> + +</topology> diff --git a/usr/src/lib/fm/topo/files/sun4u/Makefile b/usr/src/lib/fm/topo/maps/sun4u/Makefile index 7f44ddd4f8..eb09d092c2 100644 --- a/usr/src/lib/fm/topo/files/sun4u/Makefile +++ b/usr/src/lib/fm/topo/maps/sun4u/Makefile @@ -28,7 +28,7 @@ ARCH = sun4u CLASS = arch DTDFILE = topology.dtd.1 -TOPOFILE = hc-topology.xml +TOPOFILE = sun4u-hc-topology.xml SRCDIR = ../sun4u -include ../Makefile.file +include ../Makefile.map diff --git a/usr/src/lib/fm/topo/files/sun4u/hc-topology.xml b/usr/src/lib/fm/topo/maps/sun4u/sun4u-hc-topology.xml index a92532f575..e8be8934fd 100644 --- a/usr/src/lib/fm/topo/files/sun4u/hc-topology.xml +++ b/usr/src/lib/fm/topo/maps/sun4u/sun4u-hc-topology.xml @@ -29,21 +29,20 @@ <topology name='sun4u' scheme='hc'> <range name='motherboard' min='0' max='0'> <node instance='0'> - <propgroup name='protocol'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > <propval name='FRU' type='fmri' - value='hc:///motherboard=0' /> + value='hc:///component=MB' /> <propval name='label' type='string' value='MB' /> </propgroup> </node> <dependents grouping='children'> <range name='hostbridge' min='0' max='254'> - <enum-method name='hostbridge' version='1' - path='%r/usr/platform/sun4u/lib/fm/topo/plugins' /> + <enum-method name='hostbridge' version='1' /> </range> <range name='cpu' min='0' max='100'> - <enum-method name='chip' version='1' - path='%r/usr/platform/sun4u/lib/fm/topo/plugins' /> + <enum-method name='chip' version='1' /> </range> </dependents> </range> diff --git a/usr/src/lib/fm/topo/files/sun4v/Makefile b/usr/src/lib/fm/topo/maps/sun4v/Makefile index 1cbb332e04..524939b73c 100644 --- a/usr/src/lib/fm/topo/files/sun4v/Makefile +++ b/usr/src/lib/fm/topo/maps/sun4v/Makefile @@ -27,8 +27,8 @@ ARCH = sun4v CLASS = arch -DTDFILE = -TOPOFILE = hc-topology.xml +DTDFILE = +TOPOFILE = sun4v-hc-topology.xml SRCDIR = ../sun4v -include ../Makefile.file +include ../Makefile.map diff --git a/usr/src/lib/fm/topo/files/sun4v/hc-topology.xml b/usr/src/lib/fm/topo/maps/sun4v/sun4v-hc-topology.xml index 388ba3f09b..cddf2b4349 100644 --- a/usr/src/lib/fm/topo/files/sun4v/hc-topology.xml +++ b/usr/src/lib/fm/topo/maps/sun4v/sun4v-hc-topology.xml @@ -29,17 +29,17 @@ <topology name='sun4v' scheme='hc'> <range name='motherboard' min='0' max='0'> <node instance='0'> - <propgroup name='protocol'> + <propgroup name='protocol' version='1' + name-stability='Private' data-stability='Private' > <propval name='FRU' type='fmri' - value='hc:///motherboard=0' /> + value='hc:///component=MB' /> <propval name='label' type='string' value='MB' /> </propgroup> </node> <dependents grouping='children'> <range name='hostbridge' min='0' max='254'> - <enum-method name='hostbridge' version='1' - path='%r/usr/platform/sun4v/lib/fm/topo/plugins' /> + <enum-method name='hostbridge' version='1' /> </range> </dependents> </range> diff --git a/usr/src/lib/fm/topo/modules/Makefile.plugin b/usr/src/lib/fm/topo/modules/Makefile.plugin index 82a3cff0d9..c0e27f79a0 100644 --- a/usr/src/lib/fm/topo/modules/Makefile.plugin +++ b/usr/src/lib/fm/topo/modules/Makefile.plugin @@ -64,7 +64,7 @@ MAPFILES = # use APIMAP instead CFLAGS += $(CTF_FLAGS) $(CCVERBOSE) $(XSTRCONST) $(CC_PICFLAGS) CFLAGS += -G $(XREGSFLAG) -CPPFLAGS += -I. -I../../common -I../../../libtopo/common +CPPFLAGS += -I. CPPFLAGS += -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT LDFLAGS += $(ZIGNORE) -M$(APIMAP) LDLIBS += -L$(ROOTLIBDIR)/fm -R/usr/lib/fm -ltopo -lnvpair -lc @@ -79,7 +79,7 @@ $(PROG): $(OBJS) $(APIMAP) $(CTFMERGE) -L VERSION -o $@ $(OBJS) $(POST_PROCESS_SO) -%.o: ../../common/%.c +%.o: ../../common/$(MODULE)/%.c $(COMPILE.c) $< $(CTFCONVERT_O) @@ -93,7 +93,7 @@ clean: clobber: clean $(RM) $(PROG) -%.ln: ../../common/%.c +%.ln: ../../common/$(MODULE)/%.c $(LINT.c) -c $< %.ln: %.c diff --git a/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_hostbridge.c b/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_hostbridge.c index 62d382a0fc..f4dc2ea4ed 100644 --- a/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_hostbridge.c +++ b/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_hostbridge.c @@ -30,42 +30,31 @@ #include <strings.h> #include <libdevinfo.h> #include <fm/topo_mod.h> +#include <fm/topo_hc.h> #include <sys/fm/protocol.h> #include "opl_topo.h" -/* - * The following #define's are also in did_props.h, but I can't include that - * header file here. They should probably be moved to a centrally-located - * header file somewhere, since they may also be needed by diagnosis engines - * or agents. - */ -#define TOPO_PGROUP_IO "io" -#define TOPO_PROP_DEVTYPE "DEVTYPE" -#define TOPO_PROP_DRIVER "DRIVER" -#define TOPO_PROP_DEV "DEV" - -#define TOPO_PGROUP_PCI "pci" -#define TOPO_PROP_EXCAP "EXCAP" -#define TOPO_PROP_BDF "BDF" -#define TOPO_PROP_VENDID "VENDOR-ID" -#define TOPO_PROP_DEVID "DEVICE-ID" -#define TOPO_PROP_CLASS "CLASS-CODE" - -#define PCIEX_ROOT "pciexrc" - +static const topo_pgroup_info_t io_pgroup = + { TOPO_PGROUP_IO, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; +static const topo_pgroup_info_t pci_pgroup = + { TOPO_PGROUP_PCI, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; /* * Check the root complex device node for a slot-names property. */ const char * -opl_get_slot_name(di_node_t n, di_prom_handle_t opl_promtree) +opl_get_slot_name(topo_mod_t *mod, di_node_t n) { + di_prom_handle_t ptp = DI_PROM_HANDLE_NIL; di_prom_prop_t pp = DI_PROM_PROP_NIL; uchar_t *buf; - for (pp = di_prom_prop_next(opl_promtree, n, pp); + if ((ptp = topo_mod_prominfo(mod)) == DI_PROM_PROP_NIL) + return (NULL); + + for (pp = di_prom_prop_next(ptp, n, pp); pp != DI_PROM_PROP_NIL; - pp = di_prom_prop_next(opl_promtree, n, pp)) { + pp = di_prom_prop_next(ptp, n, pp)) { if (strcmp(di_prom_prop_name(pp), OPL_SLOT_NAMES) == 0) { if (di_prom_prop_data(pp, &buf) <= sizeof (uint32_t)) continue; @@ -79,51 +68,35 @@ static tnode_t * opl_node_create(topo_mod_t *mp, tnode_t *parent, const char *name, int inst, void *priv) { - int err; tnode_t *node; nvlist_t *fmri; - nvlist_t *args = NULL; - nvlist_t *pfmri = NULL; - topo_hdl_t *thp = topo_mod_handle(mp); + nvlist_t *auth = topo_mod_auth(mp, parent); if (parent == NULL || inst < 0) { return (NULL); } - /* Get parent FMRI */ - (void) topo_node_resource(parent, &pfmri, &err); - if (pfmri != NULL) { - if (topo_mod_nvalloc(mp, &args, NV_UNIQUE_NAME) != 0 || - nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri) - != 0) { - nvlist_free(pfmri); - nvlist_free(args); - (void) topo_mod_seterrno(mp, EMOD_FMRI_NVL); - return (NULL); - } - nvlist_free(pfmri); - } - /* Create FMRI */ - if ((fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, inst, - args, &err)) == NULL) { - topo_mod_dprintf(mp, "create of tnode for %s failed: %s\n", + if ((fmri = topo_mod_hcfmri(mp, parent, FM_HC_SCHEME_VERSION, name, + inst, NULL, auth, NULL, NULL, NULL)) == NULL) { + topo_mod_dprintf(mp, "create of tnode for %s failed: %s", name, topo_strerror(topo_mod_errno(mp))); - (void) topo_mod_seterrno(mp, err); - nvlist_free(args); + nvlist_free(auth); return (NULL); } - nvlist_free(args); + nvlist_free(auth); /* Create and bind node */ - node = topo_node_bind(mp, parent, name, inst, fmri, priv); + node = topo_node_bind(mp, parent, name, inst, fmri); if (node == NULL) { nvlist_free(fmri); topo_mod_dprintf(mp, "unable to bind root complex: %s\n", topo_strerror(topo_mod_errno(mp))); return (NULL); /* mod_errno already set */ } + nvlist_free(fmri); + topo_node_setspecific(node, priv); return (node); } @@ -132,16 +105,14 @@ opl_node_create(topo_mod_t *mp, tnode_t *parent, const char *name, int inst, * Create a root complex node. */ static tnode_t * -opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst, - di_prom_handle_t opl_promtree) +opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst) { int err; tnode_t *rcn; - topo_hdl_t *thp = topo_mod_handle(mp); const char *slot_name; char *dnpath; - rcn = opl_node_create(mp, parent, PCIEXRC, inst, (void *)dnode); + rcn = opl_node_create(mp, parent, PCIEX_ROOT, inst, (void *)dnode); if (rcn == NULL) { return (NULL); } @@ -150,14 +121,14 @@ opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst, * If this root complex connects to a slot, it will have a * slot-names property. */ - slot_name = opl_get_slot_name(dnode, opl_promtree); + slot_name = opl_get_slot_name(mp, dnode); if (slot_name) { char fru_str[64]; nvlist_t *fru_fmri; /* Add FRU fmri */ snprintf(fru_str, sizeof (fru_str), "hc:///component=%s", slot_name); - if (topo_fmri_str2nvl(thp, fru_str, &fru_fmri, &err) == 0) { + if (topo_mod_str2nvl(mp, fru_str, &fru_fmri) == 0) { (void) topo_node_fru_set(rcn, fru_fmri, 0, &err); nvlist_free(fru_fmri); } @@ -173,25 +144,10 @@ opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst, * Set ASRU to be the dev-scheme ASRU */ if ((dnpath = di_devfs_path(dnode)) != NULL) { - nvlist_t *in; nvlist_t *fmri; - if (topo_mod_nvalloc(mp, &in, NV_UNIQUE_NAME) != 0) { - topo_mod_dprintf(mp, "topo_mod_nvalloc failed\n"); - di_devfs_path_free(dnpath); - topo_mod_seterrno(mp, EMOD_FMRI_NVL); - return (NULL); - } - if (nvlist_add_string(in, FM_FMRI_DEV_PATH, - dnpath) != 0) { - topo_mod_dprintf(mp, "nvlist_add_string failed\n"); - nvlist_free(in); - di_devfs_path_free(dnpath); - topo_mod_seterrno(mp, EMOD_NOMEM); - return (NULL); - } - fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_DEV, - FM_FMRI_SCHEME_DEV, 0, in, &err); - nvlist_free(in); + + fmri = topo_mod_devfmri(mp, FM_DEV_SCHEME_VERSION, + dnpath, NULL); if (fmri == NULL) { topo_mod_dprintf(mp, "dev:///%s fmri creation failed.\n", @@ -217,15 +173,13 @@ opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst, */ /* Add the io and pci property groups */ - if (topo_pgroup_create(rcn, TOPO_PGROUP_IO, - TOPO_STABILITY_PRIVATE, &err) < 0) { + if (topo_pgroup_create(rcn, &io_pgroup, &err) < 0) { topo_mod_dprintf(mp, "topo_pgroup_create failed\n"); di_devfs_path_free(dnpath); topo_mod_seterrno(mp, err); return (NULL); } - if (topo_pgroup_create(rcn, TOPO_PGROUP_PCI, - TOPO_STABILITY_PRIVATE, &err) < 0) { + if (topo_pgroup_create(rcn, &pci_pgroup, &err) < 0) { topo_mod_dprintf(mp, "topo_pgroup_create failed\n"); di_devfs_path_free(dnpath); topo_mod_seterrno(mp, err); @@ -233,8 +187,8 @@ opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst, } /* Add the devfs path property */ if (dnpath) { - if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_PROP_DEV, - TOPO_PROP_SET_ONCE, dnpath, &err) != 0) { + if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEV, + TOPO_PROP_IMMUTABLE, dnpath, &err) != 0) { topo_mod_dprintf(mp, "Failed to set DEV property\n"); di_devfs_path_free(dnpath); topo_mod_seterrno(mp, err); @@ -242,23 +196,23 @@ opl_rc_node_create(topo_mod_t *mp, tnode_t *parent, di_node_t dnode, int inst, di_devfs_path_free(dnpath); } /* Oberon device type is always "pciex" */ - if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_PROP_DEVTYPE, - TOPO_PROP_SET_ONCE, OPL_PX_DEVTYPE, &err) != 0) { + if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DEVTYPE, + TOPO_PROP_IMMUTABLE, OPL_PX_DEVTYPE, &err) != 0) { topo_mod_dprintf(mp, "Failed to set DEVTYPE property\n"); } /* Oberon driver is always "px" */ - if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_PROP_DRIVER, - TOPO_PROP_SET_ONCE, OPL_PX_DRV, &err) != 0) { + if (topo_prop_set_string(rcn, TOPO_PGROUP_IO, TOPO_IO_DRIVER, + TOPO_PROP_IMMUTABLE, OPL_PX_DRV, &err) != 0) { topo_mod_dprintf(mp, "Failed to set DRIVER property\n"); } /* This is a PCIEX Root Complex */ - if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PROP_EXCAP, - TOPO_PROP_SET_ONCE, PCIEX_ROOT, &err) != 0) { + if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, TOPO_PCI_EXCAP, + TOPO_PROP_IMMUTABLE, PCIEX_ROOT, &err) != 0) { topo_mod_dprintf(mp, "Failed to set EXCAP property\n"); } /* BDF of Oberon root complex is constant */ if (topo_prop_set_string(rcn, TOPO_PGROUP_PCI, - TOPO_PROP_BDF, TOPO_PROP_SET_ONCE, OPL_PX_BDF, &err) != 0) { + TOPO_PCI_BDF, TOPO_PROP_IMMUTABLE, OPL_PX_BDF, &err) != 0) { topo_mod_dprintf(mp, "Failed to set EXCAP property\n"); } @@ -286,7 +240,7 @@ opl_hb_node_create(topo_mod_t *mp, tnode_t *parent, int inst) (void) topo_node_label_set(hbn, NULL, &err); /* Make room for children */ - topo_node_range_create(mp, hbn, PCIEXRC, 0, OPL_RC_MAX); + topo_node_range_create(mp, hbn, PCIEX_ROOT, 0, OPL_RC_MAX); return (hbn); } @@ -297,7 +251,7 @@ opl_hb_node_create(topo_mod_t *mp, tnode_t *parent, int inst) */ int opl_hb_enum(topo_mod_t *mp, const ioboard_contents_t *iob, tnode_t *ion, - int brd, di_prom_handle_t opl_promtree) + int brd) { int hb; int rc; @@ -307,7 +261,7 @@ opl_hb_enum(topo_mod_t *mp, const ioboard_contents_t *iob, tnode_t *ion, topo_mod_t *pcimod; /* Load the pcibus module. We'll need it later. */ - pcimod = topo_mod_load(mp, PCI_MOD_PATH); + pcimod = topo_mod_load(mp, PCI_BUS, PCI_BUS_VERS); if (pcimod == NULL) { topo_mod_dprintf(mp, "can't load pcibus module: %s\n", topo_strerror(topo_mod_errno(mp))); @@ -347,8 +301,7 @@ opl_hb_enum(topo_mod_t *mp, const ioboard_contents_t *iob, tnode_t *ion, } /* Create the root complex node */ - rcnode = opl_rc_node_create(mp, hbnode, p, rc, - opl_promtree); + rcnode = opl_rc_node_create(mp, hbnode, p, rc); if (rcnode == NULL) { topo_mod_dprintf(mp, "unable to create rcnode: %s\n", @@ -359,7 +312,7 @@ opl_hb_enum(topo_mod_t *mp, const ioboard_contents_t *iob, tnode_t *ion, /* Enumerate pcibus nodes under the root complex */ if (topo_mod_enumerate(pcimod, rcnode, - PCI_BUS, PCIEX_BUS, 0, 255) != 0) { + PCI_BUS, PCIEX_BUS, 0, 255, NULL) != 0) { topo_mod_dprintf(mp, "error enumerating pcibus: %s\n", topo_strerror(topo_mod_errno(mp))); diff --git a/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c b/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c index a2a240d921..144d901900 100644 --- a/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c +++ b/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_ioboard.c @@ -33,6 +33,7 @@ #include <strings.h> #include <libdevinfo.h> #include <fm/topo_mod.h> +#include <fm/topo_hc.h> #include <sys/fm/protocol.h> #include "opl_topo.h" @@ -42,13 +43,16 @@ #define IOBDFRU "hc:///component=" LABEL static int opl_iob_enum(topo_mod_t *hdl, tnode_t *parent, const char *name, - topo_instance_t imin, topo_instance_t imax, void *notused); + topo_instance_t imin, topo_instance_t imax, void *notused1, void *notused2); -const topo_modinfo_t IobInfo = { +static const topo_modops_t Iobops = + { opl_iob_enum, NULL }; + +static const topo_modinfo_t IobInfo = { IOBOARD, + FM_FMRI_SCHEME_HC, IOB_ENUMR_VERS, - opl_iob_enum, - NULL}; + &Iobops}; void _topo_init(topo_mod_t *modhdl) @@ -57,10 +61,10 @@ _topo_init(topo_mod_t *modhdl) * Turn on module debugging output */ if (getenv("TOPOIOBDBG") != NULL) - topo_mod_setdebug(modhdl, TOPO_DBG_ALL); + topo_mod_setdebug(modhdl); topo_mod_dprintf(modhdl, "initializing ioboard enumerator\n"); - topo_mod_register(modhdl, &IobInfo, NULL); + topo_mod_register(modhdl, &IobInfo, TOPO_VERSION); } void @@ -74,16 +78,19 @@ _topo_fini(topo_mod_t *modhdl) * device node. */ static int -opl_get_physical_board(di_node_t n, di_prom_handle_t opl_promtree) +opl_get_physical_board(topo_mod_t *mod, di_node_t n) { + di_prom_handle_t ptp = DI_PROM_HANDLE_NIL; di_prom_prop_t pp = DI_PROM_PROP_NIL; uchar_t *buf; int val; + if ((ptp = topo_mod_prominfo(mod)) == DI_PROM_HANDLE_NIL) + return (-1); - for (pp = di_prom_prop_next(opl_promtree, n, pp); + for (pp = di_prom_prop_next(ptp, n, pp); pp != DI_PROM_PROP_NIL; - pp = di_prom_prop_next(opl_promtree, n, pp)) { + pp = di_prom_prop_next(ptp, n, pp)) { if (strcmp(di_prom_prop_name(pp), OPL_PHYSICAL_BD) == 0) { if (di_prom_prop_data(pp, &buf) < sizeof (val)) continue; @@ -98,8 +105,8 @@ opl_get_physical_board(di_node_t n, di_prom_handle_t opl_promtree) * Creates a map of logical boards to physical location. */ static void -opl_map_boards(int lsb_to_psb[OPL_IOB_MAX], di_node_t opl_devtree, - di_prom_handle_t opl_promtree) +opl_map_boards(topo_mod_t *mod, di_node_t opl_devtree, + int lsb_to_psb[OPL_IOB_MAX]) { di_node_t n; int i; @@ -129,7 +136,7 @@ opl_map_boards(int lsb_to_psb[OPL_IOB_MAX], di_node_t opl_devtree, a = OPL_MC_STR2BA(ba); lsb = OPL_MC_LSB(a); - psb = opl_get_physical_board(n, opl_promtree); + psb = opl_get_physical_board(mod, n); if (psb < 0 || psb >= OPL_IOB_MAX) { /* psb mapping is out of range, skip */ continue; @@ -148,41 +155,25 @@ opl_iob_node_create(topo_mod_t *mp, tnode_t *parent, int inst) int err; tnode_t *ion; nvlist_t *fmri; - nvlist_t *args = NULL; - nvlist_t *pfmri = NULL; - topo_hdl_t *thp = topo_mod_handle(mp); char label[8]; char fmri_str[32]; + nvlist_t *auth = topo_mod_auth(mp, parent); if (parent == NULL || inst < 0) { return (NULL); } - /* Get parent FMRI */ - (void) topo_node_resource(parent, &pfmri, &err); - if (pfmri != NULL) { - if (topo_mod_nvalloc(mp, &args, NV_UNIQUE_NAME) != 0 || - nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri) - != 0) { - nvlist_free(pfmri); - nvlist_free(args); - (void) topo_mod_seterrno(mp, EMOD_FMRI_NVL); - return (NULL); - } - nvlist_free(pfmri); - } /* Create ioboard FMRI */ - if ((fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, IOBOARD, inst, - args, &err)) == NULL) { + if ((fmri = topo_mod_hcfmri(mp, parent, FM_HC_SCHEME_VERSION, IOBOARD, + inst, NULL, auth, NULL, NULL, NULL)) == NULL) { + nvlist_free(auth); topo_mod_dprintf(mp, "create of tnode for ioboard failed: %s\n", topo_strerror(topo_mod_errno(mp))); - (void) topo_mod_seterrno(mp, err); - nvlist_free(args); return (NULL); } - nvlist_free(args); + nvlist_free(auth); /* Create node for this ioboard */ - ion = topo_node_bind(mp, parent, IOBOARD, inst, fmri, NULL); + ion = topo_node_bind(mp, parent, IOBOARD, inst, fmri); if (ion == NULL) { nvlist_free(fmri); topo_mod_dprintf(mp, "unable to bind ioboard: %s\n", @@ -192,7 +183,7 @@ opl_iob_node_create(topo_mod_t *mp, tnode_t *parent, int inst) nvlist_free(fmri); /* Create and add FRU fmri for this ioboard */ snprintf(fmri_str, sizeof (fmri_str), IOBDFRU, inst); - if (topo_fmri_str2nvl(thp, fmri_str, &fmri, &err) == 0) { + if (topo_mod_str2nvl(mp, fmri_str, &fmri) == 0) { (void) topo_node_fru_set(ion, fmri, 0, &err); nvlist_free(fmri); } @@ -213,28 +204,20 @@ opl_iob_node_create(topo_mod_t *mp, tnode_t *parent, int inst) /*ARGSUSED*/ static int opl_iob_enum(topo_mod_t *mp, tnode_t *parent, const char *name, - topo_instance_t imin, topo_instance_t imax, void *notused) + topo_instance_t imin, topo_instance_t imax, void *notused1, void *notused2) { + di_node_t opl_devtree; di_node_t pnode; tnode_t *ion; topo_instance_t inst; int lsb_to_psb[OPL_IOB_MAX]; ioboard_contents_t ioboard_list[OPL_IOB_MAX]; int retval = 0; - di_prom_handle_t opl_promtree = DI_PROM_HANDLE_NIL; - di_node_t opl_devtree; /* Validate the name is correct */ if (strcmp(name, "ioboard") != 0) { return (-1); } - /* Initialize devinfo once for the module */ - if ((opl_promtree = di_prom_init()) == DI_PROM_HANDLE_NIL) { - (void) topo_mod_seterrno(mp, errno); - topo_mod_dprintf(mp, - "Ioboard enumerator: di_prom_handle_init failed.\n"); - return (-1); - } /* Make sure we don't exceed OPL_IOB_MAX */ if (imax >= OPL_IOB_MAX) { imax = OPL_IOB_MAX; @@ -242,7 +225,7 @@ opl_iob_enum(topo_mod_t *mp, tnode_t *parent, const char *name, bzero(ioboard_list, sizeof (ioboard_list)); - opl_devtree = di_init("/", DINFOCPYALL); + opl_devtree = topo_mod_devinfo(mp); if (opl_devtree == DI_NODE_NIL) { (void) topo_mod_seterrno(mp, errno); topo_mod_dprintf(mp, "devinfo init failed.\n"); @@ -254,7 +237,7 @@ opl_iob_enum(topo_mod_t *mp, tnode_t *parent, const char *name, * the device node bus address) to physical board numbers, so we * can create meaningful fru labels. */ - opl_map_boards(lsb_to_psb, opl_devtree, opl_promtree); + opl_map_boards(mp, opl_devtree, lsb_to_psb); /* * Figure out which boards are installed by finding hostbridges @@ -299,10 +282,7 @@ opl_iob_enum(topo_mod_t *mp, tnode_t *parent, const char *name, break; } /* Enumerate hostbridges on this ioboard, sets errno */ - retval = opl_hb_enum(mp, &ioboard_list[inst], ion, inst, - opl_promtree); + retval = opl_hb_enum(mp, &ioboard_list[inst], ion, inst); } - di_fini(opl_devtree); - di_prom_fini(opl_promtree); return (retval); } diff --git a/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_topo.h b/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_topo.h index 1da88ed77f..13c1ded036 100644 --- a/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_topo.h +++ b/usr/src/lib/fm/topo/modules/SUNW,SPARC-Enterprise/ioboard/opl_topo.h @@ -29,19 +29,14 @@ #pragma ident "%Z%%M% %I% %E% SMI" +#include <fm/topo_hc.h> +#include <fm/topo_mod.h> + #ifdef __cplusplus extern "C" { #endif -/* - * OPL-specific enumerators. - */ -#define IOBOARD "ioboard" -#define HOSTBRIDGE "hostbridge" -#define PCIEXRC "pciexrc" -#define PCI_BUS "pcibus" -#define PCIEX_BUS "pciexbus" -#define PCI_MOD_PATH "/usr/platform/sun4u/lib/fm/topo/plugins/pcibus.so" +#define PCI_BUS_VERS 1 /* * OPL uses the Jupiter Bus Bindings (see FWARC/2005/076) which specifies @@ -88,7 +83,7 @@ typedef struct { /* Shared device tree root node */ int opl_hb_enum(topo_mod_t *mp, const ioboard_contents_t *iob, - tnode_t *parent, int brd, di_prom_handle_t opl_promtree); + tnode_t *parent, int brd); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/iob_platform.c b/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/iob_platform.c index bd50173457..c62169f49c 100644 --- a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/iob_platform.c +++ b/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire-15000/ioboard/iob_platform.c @@ -33,16 +33,17 @@ #include <string.h> #include <libdevinfo.h> #include <fm/topo_mod.h> +#include <fm/topo_hc.h> -#include "did.h" -#include "hostbridge.h" -#include "ioboard.h" -#include "util.h" +#include <did.h> +#include <hostbridge.h> +#include <ioboard.h> +#include <util.h> /*ARGSUSED*/ int -platform_iob_label(tnode_t *node, nvlist_t *ignored, nvlist_t **out, - topo_mod_t *mod) +platform_iob_label(topo_mod_t *mod, tnode_t *node, nvlist_t *ignored, + nvlist_t **out) { /* * For E15K, the label is simply IOXX where XX is the @@ -65,8 +66,8 @@ platform_iob_label(tnode_t *node, nvlist_t *ignored, nvlist_t **out, /*ARGSUSED*/ int -platform_iob_enum(tnode_t *parent, topo_instance_t imin, topo_instance_t imax, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +platform_iob_enum(topo_mod_t *mod, tnode_t *parent, topo_instance_t imin, + topo_instance_t imax) { /* * An E15K and its successors may have up to 18 I/O boards, @@ -83,7 +84,7 @@ platform_iob_enum(tnode_t *parent, topo_instance_t imin, topo_instance_t imax, did_t *iobs[18][2][2]; int brd, br, bus, i; - devtree = di_init("/", DINFOCPYALL); + devtree = topo_mod_devinfo(mod); if (devtree == DI_NODE_NIL) { topo_mod_dprintf(mod, "devinfo init failed."); return (-1); @@ -98,9 +99,8 @@ platform_iob_enum(tnode_t *parent, topo_instance_t imin, topo_instance_t imax, while (pnode != DI_NODE_NIL) { did_t *d; - d = split_bus_address(didhash, - pnode, IOB_BASEADDR, BUS_ADDRDIST, 0, 17, &brd, &br, &bus, - promtree, mod); + d = split_bus_address(mod, + pnode, IOB_BASEADDR, BUS_ADDRDIST, 0, 17, &brd, &br, &bus); if (d == NULL) { pnode = di_drv_next_node(pnode); continue; @@ -120,27 +120,26 @@ platform_iob_enum(tnode_t *parent, topo_instance_t imin, topo_instance_t imax, did_did_link_set(iobs[i][0][0], iobs[i][0][1]); did_did_link_set(iobs[i][1][0], iobs[i][1][1]); did_did_chain_set(iobs[i][0][0], iobs[i][1][0]); - if ((ion = ioboard_declare(parent, i, iobs[i][0][0], - promtree, mod)) == NULL) { + if ((ion = ioboard_declare(mod, parent, i, iobs[i][0][0])) + == NULL) { topo_mod_dprintf(mod, "Creation of tnode for %s%d failed.\n", IOBOARD, i); continue; } - if (topo_mod_enumerate(mod, - ion, HOSTBRIDGE, HOSTBRIDGE, 0, 0) < 0) { + if (topo_mod_enumerate(mod, ion, HOSTBRIDGE, HOSTBRIDGE, 0, 0, + iobs[i][0][0]) < 0) { topo_mod_dprintf(mod, "Enumeration of %s%d/%s%d failed.\n", IOBOARD, i, HOSTBRIDGE, 0); continue; } - if (topo_mod_enumerate(mod, - ion, HOSTBRIDGE, HOSTBRIDGE, 1, 1) < 0) { + if (topo_mod_enumerate(mod, ion, HOSTBRIDGE, HOSTBRIDGE, 1, 1, + iobs[i][0][0]) < 0) { topo_mod_dprintf(mod, "Enumeration of %s%d/%s%d failed.\n", IOBOARD, i, HOSTBRIDGE, 1); continue; } } - di_fini(devtree); return (0); } diff --git a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire/ioboard/iob_platform.c b/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire/ioboard/iob_platform.c index ce258e1643..98ef8b20bc 100644 --- a/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire/ioboard/iob_platform.c +++ b/usr/src/lib/fm/topo/modules/SUNW,Sun-Fire/ioboard/iob_platform.c @@ -33,16 +33,17 @@ #include <string.h> #include <libdevinfo.h> #include <fm/topo_mod.h> +#include <fm/topo_hc.h> -#include "did.h" -#include "hostbridge.h" -#include "ioboard.h" -#include "util.h" +#include <did.h> +#include <hostbridge.h> +#include <ioboard.h> +#include <util.h> /*ARGSUSED*/ int -platform_iob_label(tnode_t *node, nvlist_t *ignored, nvlist_t **out, - topo_mod_t *mod) +platform_iob_label(topo_mod_t *mod, tnode_t *node, nvlist_t *ignored, + nvlist_t **out) { /* * For SUNW,Sun-Fire the label is simply N0.IBXX where XX is the @@ -65,8 +66,8 @@ platform_iob_label(tnode_t *node, nvlist_t *ignored, nvlist_t **out, /*ARGSUSED*/ int -platform_iob_enum(tnode_t *parent, topo_instance_t imin, topo_instance_t imax, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +platform_iob_enum(topo_mod_t *mod, tnode_t *parent, topo_instance_t imin, + topo_instance_t imax) { /* * A SUNW,Sun-Fire and its successors may have up to 4 I/O boards, @@ -83,7 +84,7 @@ platform_iob_enum(tnode_t *parent, topo_instance_t imin, topo_instance_t imax, did_t *iobs[18][2][2]; int brd, br, bus, i; - devtree = di_init("/", DINFOCPYALL); + devtree = topo_mod_devinfo(mod); if (devtree == DI_NODE_NIL) { topo_mod_dprintf(mod, "devinfo init failed."); return (-1); @@ -98,9 +99,8 @@ platform_iob_enum(tnode_t *parent, topo_instance_t imin, topo_instance_t imax, while (pnode != DI_NODE_NIL) { did_t *d; - d = split_bus_address(didhash, - pnode, IOB_BASEADDR, BUS_ADDRDIST, 6, 9, &brd, &br, &bus, - promtree, mod); + d = split_bus_address(mod, + pnode, IOB_BASEADDR, BUS_ADDRDIST, 6, 9, &brd, &br, &bus); if (d == NULL) { pnode = di_drv_next_node(pnode); continue; @@ -120,27 +120,26 @@ platform_iob_enum(tnode_t *parent, topo_instance_t imin, topo_instance_t imax, did_did_link_set(iobs[i][0][0], iobs[i][0][1]); did_did_link_set(iobs[i][1][0], iobs[i][1][1]); did_did_chain_set(iobs[i][0][0], iobs[i][1][0]); - if ((ion = ioboard_declare(parent, i, iobs[i][0][0], - promtree, mod)) == NULL) { + if ((ion = ioboard_declare(mod, parent, i, iobs[i][0][0])) + == NULL) { topo_mod_dprintf(mod, "Creation of tnode for %s%d failed.\n", IOBOARD, i); continue; } if (topo_mod_enumerate(mod, - ion, HOSTBRIDGE, HOSTBRIDGE, 0, 0) < 0) { + ion, HOSTBRIDGE, HOSTBRIDGE, 0, 0, iobs[i][0][0]) < 0) { topo_mod_dprintf(mod, "Enumeration of %s%d/%s%d failed.\n", IOBOARD, i, HOSTBRIDGE, 0); continue; } if (topo_mod_enumerate(mod, - ion, HOSTBRIDGE, HOSTBRIDGE, 1, 1) < 0) { + ion, HOSTBRIDGE, HOSTBRIDGE, 1, 1, iobs[i][0][0]) < 0) { topo_mod_dprintf(mod, "Enumeration of %s%d/%s%d failed.\n", IOBOARD, i, HOSTBRIDGE, 1); continue; } } - di_fini(devtree); return (0); } diff --git a/usr/src/lib/fm/topo/modules/common/hostbridge.c b/usr/src/lib/fm/topo/modules/common/hostbridge.c deleted file mode 100644 index 7dbca54af6..0000000000 --- a/usr/src/lib/fm/topo/modules/common/hostbridge.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <string.h> -#include <fm/topo_mod.h> -#include <libdevinfo.h> -#include <limits.h> -#include <sys/fm/protocol.h> -#include <sys/param.h> -#include <sys/systeminfo.h> -#include <assert.h> -#include <pthread.h> - -#include "pcibus.h" -#include "hostbridge.h" -#include "did.h" -#include "did_props.h" -#include "util.h" - -/* - * hostbridge.c - * Generic code shared by all the hostbridge enumerators - */ - -static void hb_release(topo_mod_t *, tnode_t *); -static int hb_contains(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int hb_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int hb_label(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int hb_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); - -extern txprop_t ExHB_common_props[]; -extern txprop_t HB_common_props[]; -extern txprop_t RC_common_props[]; -extern int ExHB_propcnt; -extern int HB_propcnt; -extern int RC_propcnt; - -static int specific_hb_enum(tnode_t *, const char *, topo_instance_t, - topo_instance_t, di_prom_handle_t, topo_mod_t *); - -const topo_modinfo_t Hb_info = - { HOSTBRIDGE, HB_ENUMR_VERS, hb_enum, hb_release }; - -const topo_method_t Hb_methods[] = { - { "hb_contains", "hb element contains other element", HB_ENUMR_VERS, - TOPO_STABILITY_INTERNAL, hb_contains }, - { "hb_present", "hb element currently present", HB_ENUMR_VERS, - TOPO_STABILITY_INTERNAL, hb_present }, - { TOPO_METH_LABEL, TOPO_METH_LABEL_DESC, - TOPO_METH_LABEL_VERSION, TOPO_STABILITY_INTERNAL, hb_label }, - { NULL } -}; - -void -_topo_init(topo_mod_t *modhdl) -{ - /* - * Turn on module debugging output - */ - if (getenv("TOPOHBDBG") != NULL) - topo_mod_setdebug(modhdl, TOPO_DBG_ALL); - topo_mod_dprintf(modhdl, "initializing hostbridge enumerator\n"); - - topo_mod_register(modhdl, &Hb_info, NULL); - topo_mod_dprintf(modhdl, "Hostbridge enumr initd\n"); -} - -void -_topo_fini(topo_mod_t *modhdl) -{ - topo_mod_unregister(modhdl); -} - -/*ARGSUSED*/ -static int -hb_contains(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (0); -} - -/*ARGSUSED*/ -static int -hb_present(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (0); -} - -static int -hb_label(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - if (version > TOPO_METH_LABEL_VERSION) - return (topo_mod_seterrno(mp, EMOD_VER_NEW)); - return (platform_hb_label(node, in, out, mp)); -} - -static topo_mod_t * -pci_enumr_load(topo_mod_t *mp, tnode_t *parent) -{ - topo_mod_t *rp = NULL; - char *plat, *mach; - char *pcipath; - 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); - } - pcipath = topo_mod_alloc(mp, PATH_MAX); - rootdir = topo_mod_rootdir(mp); - (void) snprintf(pcipath, - PATH_MAX, PATH_TO_PCI_ENUM, rootdir ? rootdir : "", plat); - - if ((rp = topo_mod_load(mp, pcipath)) == NULL) { - topo_mod_dprintf(mp, - "%s enumerator could not load %s.\n", HOSTBRIDGE, pcipath); - (void) snprintf(pcipath, - PATH_MAX, PATH_TO_PCI_ENUM, rootdir ? rootdir : "", mach); - if ((rp = topo_mod_load(mp, pcipath)) == NULL) { - topo_mod_dprintf(mp, - "%s enumerator could not load %s.\n", - HOSTBRIDGE, pcipath); - } - } - topo_mod_strfree(mp, plat); - topo_mod_strfree(mp, mach); - topo_mod_free(mp, pcipath, PATH_MAX); - return (rp); -} - -/*ARGSUSED*/ -static int -hb_enum(topo_mod_t *mp, tnode_t *pn, const char *name, topo_instance_t imin, - topo_instance_t imax, void *notused) -{ - topo_mod_t *pcimod; - did_hash_t *didhash; - di_prom_handle_t promtree; - int rv; - - if (strcmp(name, HOSTBRIDGE) != 0) { - topo_mod_dprintf(mp, - "Currently only know how to enumerate %s components.\n", - HOSTBRIDGE); - return (0); - } - - /* - * Load the pcibus enumerator, we'll soon need it! - */ - if ((pcimod = pci_enumr_load(mp, pn)) == NULL) - return (-1); - - if ((promtree = di_prom_init()) == DI_PROM_HANDLE_NIL) { - topo_mod_unload(pcimod); - topo_mod_dprintf(mp, - "Hostbridge enumerator: di_prom_handle_init failed.\n"); - return (-1); - } - - /* - * If we're asked to enumerate a whole range of hostbridges, then - * we need to find them all. If we're just asked to enumerate a - * single hostbridge, we expect our caller to have passed us linked - * did_t structures we can use to enumerate the singled out hostbridge. - */ - if (imin != imax) { - - if ((didhash = did_hash_init(mp)) == NULL) { - topo_mod_dprintf(mp, - "Hash initialization for hostbridge " - "enumerator failed.\n"); - topo_mod_unload(pcimod); - return (-1); - } - if ((rv = platform_hb_enum(pn, name, imin, imax, didhash, - promtree, mp)) < 0) - topo_mod_seterrno(mp, EMOD_PARTIAL_ENUM); - di_prom_fini(promtree); - did_hash_fini(didhash); - topo_mod_unload(pcimod); - return (rv); - } else { - rv = specific_hb_enum(pn, name, imin, imax, promtree, mp); - di_prom_fini(promtree); - topo_mod_unload(pcimod); - return (rv); - } -} - -/*ARGSUSED*/ -static void -hb_release(topo_mod_t *mp, tnode_t *node) -{ - topo_method_unregister_all(mp, node); -} - -static tnode_t * -hb_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) { - nvlist_free(pfmri); - nvlist_free(args); - (void) topo_mod_seterrno(mod, err); - topo_mod_dprintf(mod, - "Unable to make nvlist for %s bind: %s.\n", - name, topo_strerror(err)); - return (NULL); - } - - nvlist_free(pfmri); - nvlist_free(args); - 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, 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); -} - -tnode_t * -pcihostbridge_declare(tnode_t *parent, di_node_t din, topo_instance_t i, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) -{ - did_t *pd; - tnode_t *ntn; - - if ((pd = did_find(didhash, din)) == NULL) - return (NULL); - if ((ntn = hb_tnode_create(parent, HOSTBRIDGE, i, pd, mod)) == NULL) - return (NULL); - if (did_props_set(ntn, pd, HB_common_props, HB_propcnt, - promtree) < 0) { - topo_node_unbind(ntn); - return (NULL); - } - /* - * We expect to find pci buses beneath the hostbridge. - */ - if (child_range_add(mod, ntn, PCI_BUS, 0, MAX_HB_BUSES) < 0) { - topo_node_unbind(ntn); - return (NULL); - } - return (ntn); -} - -tnode_t * -pciexhostbridge_declare(tnode_t *parent, di_node_t din, topo_instance_t hi, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) -{ - did_t *pd; - tnode_t *ntn; - - if ((pd = did_find(didhash, din)) == NULL) - return (NULL); - if ((ntn = hb_tnode_create(parent, HOSTBRIDGE, hi, din, mod)) == NULL) - return (NULL); - if (did_props_set(ntn, pd, ExHB_common_props, ExHB_propcnt, - promtree) < 0) { - topo_node_unbind(ntn); - return (NULL); - } - /* - * We expect to find root complexes beneath the hostbridge. - */ - if (child_range_add(mod, ntn, PCIEX_ROOT, 0, MAX_HB_BUSES) < 0) { - topo_node_unbind(ntn); - return (NULL); - } - return (ntn); -} - -tnode_t * -pciexrc_declare(tnode_t *parent, di_node_t din, topo_instance_t ri, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) -{ - did_t *pd; - tnode_t *ntn; - - if ((pd = did_find(didhash, din)) == NULL) - return (NULL); - did_markrc(pd); - if ((ntn = hb_tnode_create(parent, PCIEX_ROOT, ri, din, mod)) == NULL) - return (NULL); - if (did_props_set(ntn, pd, RC_common_props, RC_propcnt, - promtree) < 0) { - topo_node_unbind(ntn); - return (NULL); - } - /* - * We expect to find pci-express buses beneath a root complex - */ - if (child_range_add(mod, ntn, PCIEX_BUS, 0, MAX_HB_BUSES) < 0) { - topo_node_range_destroy(ntn, PCIEX_BUS); - return (NULL); - } - return (ntn); -} - -/*ARGSUSED*/ -static int -specific_hb_enum(tnode_t *pn, const char *name, topo_instance_t imin, - topo_instance_t imax, di_prom_handle_t promtree, topo_mod_t *mod) -{ - tnode_t *hb; - did_t *iodid, *didp; - did_hash_t *didhash; - char *pname; - int brc = 0; - int bus; - - pname = topo_node_name(pn); - if ((iodid = topo_node_private(pn)) == NULL) { - topo_mod_dprintf(mod, - "Parent %s node missing private data.\n" - "Unable to proceed with %s enumeration.\n", - pname, name); - return (-1); - } - didhash = did_hash(iodid); - - /* - * Find the hostbridge of interest - */ - didp = iodid; - for (brc = 0; brc < imin; brc++) - didp = did_chain_get(didp); - assert(didp != NULL); - - if ((hb = pcihostbridge_declare(pn, did_dinode(didp), imin, didhash, - promtree, mod)) == NULL) - return (-1); - while (didp != NULL) { - did_BDF(didp, &bus, NULL, NULL); - if (topo_mod_enumerate(mod, - hb, PCI_BUS, PCI_BUS, bus, bus) != 0) - return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); - didp = did_link_get(didp); - } - return (0); -} diff --git a/usr/src/lib/fm/topo/modules/common/hostbridge/hostbridge.c b/usr/src/lib/fm/topo/modules/common/hostbridge/hostbridge.c new file mode 100644 index 0000000000..2ff4c768c1 --- /dev/null +++ b/usr/src/lib/fm/topo/modules/common/hostbridge/hostbridge.c @@ -0,0 +1,357 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <string.h> +#include <fm/topo_mod.h> +#include <fm/topo_hc.h> +#include <libdevinfo.h> +#include <limits.h> +#include <sys/fm/protocol.h> +#include <sys/param.h> +#include <sys/systeminfo.h> +#include <assert.h> + +#include <hostbridge.h> +#include <pcibus.h> +#include <did.h> +#include <did_props.h> +#include <util.h> + +/* + * hostbridge.c + * Generic code shared by all the hostbridge enumerators + */ +static void hb_release(topo_mod_t *, tnode_t *); +static int hb_label(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, + nvlist_t **); +static int hb_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, + topo_instance_t, void *, void *); + +extern int platform_hb_label(topo_mod_t *, tnode_t *, nvlist_t *, nvlist_t **); +extern int platform_hb_enum(topo_mod_t *, tnode_t *, + const char *, topo_instance_t, topo_instance_t); + +extern txprop_t ExHB_common_props[]; +extern txprop_t HB_common_props[]; +extern txprop_t RC_common_props[]; +extern int ExHB_propcnt; +extern int HB_propcnt; +extern int RC_propcnt; + +static int specific_hb_enum(topo_mod_t *, tnode_t *, const char *, + topo_instance_t, topo_instance_t, void *); + +static const topo_modops_t Hb_ops = + { hb_enum, hb_release }; +static const topo_modinfo_t Hb_info = + { HOSTBRIDGE, FM_FMRI_SCHEME_HC, HB_ENUMR_VERS, &Hb_ops }; + +static const topo_method_t Hb_methods[] = { + { TOPO_METH_LABEL, TOPO_METH_LABEL_DESC, + TOPO_METH_LABEL_VERSION, TOPO_STABILITY_INTERNAL, hb_label }, + { NULL } +}; + +static const topo_pgroup_info_t hb_auth_pgroup = { + FM_FMRI_AUTHORITY, + TOPO_STABILITY_PRIVATE, + TOPO_STABILITY_PRIVATE, + 1 +}; + +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); +} + +void +_topo_fini(topo_mod_t *modhdl) +{ + topo_mod_unregister(modhdl); +} + +static int +hb_label(topo_mod_t *mp, tnode_t *node, topo_version_t version, + nvlist_t *in, nvlist_t **out) +{ + if (version > TOPO_METH_LABEL_VERSION) + return (topo_mod_seterrno(mp, EMOD_VER_NEW)); + return (platform_hb_label(mp, node, in, out)); +} + +static topo_mod_t * +pci_enumr_load(topo_mod_t *mp) +{ + topo_mod_t *rp = NULL; + + if ((rp = topo_mod_load(mp, PCI_ENUM, PCI_ENUMR_VERS)) == NULL) { + topo_mod_dprintf(mp, + "%s enumerator could not load %s.\n", HOSTBRIDGE, PCI_ENUM); + } + return (rp); +} + +/*ARGSUSED*/ +static int +hb_enum(topo_mod_t *mp, tnode_t *pn, const char *name, topo_instance_t imin, + topo_instance_t imax, void *notused, void *data) +{ + topo_mod_t *pcimod; + + if (strcmp(name, HOSTBRIDGE) != 0) { + topo_mod_dprintf(mp, + "Currently only know how to enumerate %s components.\n", + HOSTBRIDGE); + return (0); + } + /* + * Load the pcibus enumerator + */ + if ((pcimod = pci_enumr_load(mp)) == NULL) + return (-1); + + /* + * If we're asked to enumerate a whole range of hostbridges, then + * we need to find them all. If we're just asked to enumerate a + * single hostbridge, we expect our caller to have passed us linked + * did_t structures we can use to enumerate the singled out hostbridge. + */ + if (imin != imax) { + int rv; + + if (did_hash_init(mp) < 0) { + topo_mod_dprintf(mp, + "Hash initialization for hostbridge " + "enumerator failed.\n"); + topo_mod_unload(pcimod); + return (-1); + } + if ((rv = platform_hb_enum(mp, pn, name, imin, imax)) < 0) + topo_mod_seterrno(mp, EMOD_PARTIAL_ENUM); + did_hash_fini(mp); + return (rv); + } else { + return (specific_hb_enum(mp, pn, name, imin, imax, + data)); + } +} + +/*ARGSUSED*/ +static void +hb_release(topo_mod_t *mp, tnode_t *node) +{ + topo_method_unregister_all(mp, node); + + /* + * node private data (did_t) for this node is destroyed in + * did_hash_destroy() + */ + +} + +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_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); +} + +tnode_t * +pcihostbridge_declare(topo_mod_t *mod, tnode_t *parent, di_node_t din, + topo_instance_t i) +{ + did_t *pd; + tnode_t *ntn; + + if ((pd = did_find(mod, din)) == NULL) + return (NULL); + if ((ntn = hb_tnode_create(mod, parent, HOSTBRIDGE, i, din)) == NULL) + return (NULL); + if (did_props_set(ntn, pd, HB_common_props, HB_propcnt) < 0) { + topo_node_unbind(ntn); + return (NULL); + } + /* + * We expect to find pci buses beneath the hostbridge. + */ + if (child_range_add(mod, ntn, PCI_BUS, 0, MAX_HB_BUSES) < 0) { + topo_node_unbind(ntn); + return (NULL); + } + return (ntn); +} + +tnode_t * +pciexhostbridge_declare(topo_mod_t *mod, tnode_t *parent, di_node_t din, + topo_instance_t hi) +{ + did_t *pd; + tnode_t *ntn; + + if ((pd = did_find(mod, din)) == NULL) + return (NULL); + if ((ntn = hb_tnode_create(mod, parent, HOSTBRIDGE, hi, din)) == NULL) + return (NULL); + if (did_props_set(ntn, pd, ExHB_common_props, ExHB_propcnt) < 0) { + topo_node_unbind(ntn); + return (NULL); + } + /* + * We expect to find root complexes beneath the hostbridge. + */ + if (child_range_add(mod, ntn, PCIEX_ROOT, 0, MAX_HB_BUSES) < 0) { + topo_node_unbind(ntn); + return (NULL); + } + return (ntn); +} + +tnode_t * +pciexrc_declare(topo_mod_t *mod, tnode_t *parent, di_node_t din, + topo_instance_t ri) +{ + did_t *pd; + tnode_t *ntn; + + if ((pd = did_find(mod, din)) == NULL) + return (NULL); + did_markrc(pd); + if ((ntn = hb_tnode_create(mod, parent, PCIEX_ROOT, ri, din)) == NULL) + return (NULL); + if (did_props_set(ntn, pd, RC_common_props, RC_propcnt) < 0) { + topo_node_unbind(ntn); + return (NULL); + } + /* + * We expect to find pci-express buses beneath a root complex + */ + if (child_range_add(mod, ntn, PCIEX_BUS, 0, MAX_HB_BUSES) < 0) { + topo_node_range_destroy(ntn, PCIEX_BUS); + return (NULL); + } + return (ntn); +} + +/*ARGSUSED*/ +static int +specific_hb_enum(topo_mod_t *mod, tnode_t *pn, const char *name, + topo_instance_t imin, topo_instance_t imax, void *priv) +{ + tnode_t *hb; + did_t *iodid = (did_t *)priv; + did_t *didp; + int brc = 0; + int bus; + + did_setspecific(mod, priv); + + /* + * Find the hostbridge of interest + */ + didp = iodid; + for (brc = 0; brc < imin; brc++) + didp = did_chain_get(didp); + assert(didp != NULL); + + if ((hb = pcihostbridge_declare(mod, pn, did_dinode(didp), imin)) + == NULL) { + return (-1); + } + while (didp != NULL) { + did_BDF(didp, &bus, NULL, NULL); + if (topo_mod_enumerate(mod, + hb, PCI_BUS, PCI_BUS, bus, bus, didp) != 0) { + return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); + } + didp = did_link_get(didp); + } + + return (0); +} diff --git a/usr/src/lib/fm/topo/modules/common/hostbridge.h b/usr/src/lib/fm/topo/modules/common/hostbridge/hostbridge.h index 039ad359ea..ee76315446 100644 --- a/usr/src/lib/fm/topo/modules/common/hostbridge.h +++ b/usr/src/lib/fm/topo/modules/common/hostbridge/hostbridge.h @@ -30,7 +30,6 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <libdevinfo.h> -#include "did.h" #ifdef __cplusplus extern "C" { @@ -38,22 +37,18 @@ extern "C" { #define HB_ENUMR_VERS 1 -#define PATH_TO_HB_ENUM "%s/usr/platform/%s/lib/fm/topo/plugins/hostbridge.so" - -#define HOSTBRIDGE "hostbridge" - #define MAX_HBS 255 /* * Solaris Drivers for hostbridge ASICs. */ -#define SCHIZO "pcisch" -#define PSYCHO "pcipsy" -#define NPE "npe" -#define PCIE_PCI "pcie_pci" -#define PCI_PCI "pci_pci" -#define PCI "pci" -#define PX "px" +#define SCHIZO "pcisch" +#define PSYCHO "pcipsy" +#define NPE "npe" +#define PCIE_PCI "pcie_pci" +#define PCI_PCI "pci_pci" +#define PCI "pci" +#define PX "px" /* * These #defines are special values of bus and root complex instance @@ -70,19 +65,12 @@ extern "C" { */ #define TO_PCI (1000) -struct did_hash; - -extern tnode_t *pcihostbridge_declare(tnode_t *, di_node_t, topo_instance_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern tnode_t *pciexhostbridge_declare(tnode_t *, di_node_t, topo_instance_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern tnode_t *pciexrc_declare(tnode_t *, di_node_t, topo_instance_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); - -extern int platform_hb_label(tnode_t *, nvlist_t *, nvlist_t **, topo_mod_t *); -extern int platform_hb_enum(tnode_t *, - const char *, topo_instance_t, topo_instance_t, did_hash_t *, - di_prom_handle_t, topo_mod_t *); +extern tnode_t *pcihostbridge_declare(topo_mod_t *, tnode_t *, di_node_t, + topo_instance_t); +extern tnode_t *pciexhostbridge_declare(topo_mod_t *, tnode_t *, di_node_t, + topo_instance_t); +extern tnode_t *pciexrc_declare(topo_mod_t *, tnode_t *, di_node_t, + topo_instance_t); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/common/did.c b/usr/src/lib/fm/topo/modules/common/pcibus/did.c index 1dc42eab66..e57d84a4a4 100644 --- a/usr/src/lib/fm/topo/modules/common/did.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.c @@ -40,16 +40,16 @@ #include <string.h> #include <strings.h> #include <sys/types.h> -#include <libtopo.h> +#include <fm/topo_mod.h> #include <libnvpair.h> #include <libdevinfo.h> #include <sys/pcie.h> -#include "topo_mod.h" -#include "hostbridge.h" -#include "pcibus.h" +#include <hostbridge.h> +#include <pcibus.h> +#include <did_props.h> + #include "did_impl.h" -#include "did_props.h" static void slotnm_destroy(slotnm_t *); @@ -115,15 +115,14 @@ slotnm_cp(did_t *from, did_t *to, int *nslots) static int di_physlotinfo_get(topo_mod_t *mp, di_node_t src, uint_t excap, - int *slotnum, char **slotnm, di_prom_handle_t promtree) + int *slotnum, char **slotnm) { char *slotbuf; int sz; uchar_t *buf; *slotnum = -1; - (void) di_uintprop_get(src, DI_PHYSPROP, (uint_t *)slotnum, - promtree); + (void) di_uintprop_get(mp, src, DI_PHYSPROP, (uint_t *)slotnum); /* * If no physical slot number property was found, then the * capabilities register may indicate the pci-express device @@ -132,8 +131,7 @@ di_physlotinfo_get(topo_mod_t *mp, di_node_t src, uint_t excap, if (*slotnum == -1 && (excap & PCIE_PCIECAP_SLOT_IMPL) != 0) { uint_t slotcap; int e; - e = di_uintprop_get(src, "pcie-slotcap-reg", &slotcap, - promtree); + e = di_uintprop_get(mp, src, "pcie-slotcap-reg", &slotcap); if (e == 0) *slotnum = slotcap >> PCIE_SLOTCAP_PHY_SLOT_NUM_SHIFT; } @@ -145,7 +143,7 @@ di_physlotinfo_get(topo_mod_t *mp, di_node_t src, uint_t excap, * a slot-names property, and if it exists, ignore the slotmask value * and use the string as the label. */ - if (di_bytes_get(src, DI_SLOTPROP, &sz, &buf, promtree) == 0 && + if (di_bytes_get(mp, src, DI_SLOTPROP, &sz, &buf) == 0 && sz > 4) { slotbuf = (char *)&buf[4]; } else { @@ -163,8 +161,7 @@ di_physlotinfo_get(topo_mod_t *mp, di_node_t src, uint_t excap, } static int -di_slotinfo_get(topo_mod_t *mp, di_node_t src, int *nslots, slotnm_t **slots, - di_prom_handle_t promtree) +di_slotinfo_get(topo_mod_t *mp, di_node_t src, int *nslots, slotnm_t **slots) { slotnm_t *lastslot = NULL; slotnm_t *newslot; @@ -176,7 +173,7 @@ di_slotinfo_get(topo_mod_t *mp, di_node_t src, int *nslots, slotnm_t **slots, *slots = NULL; *nslots = 0; - if (di_bytes_get(src, DI_SLOTPROP, &sz, &slotbuf, promtree) < 0) + if (di_bytes_get(mp, src, DI_SLOTPROP, &sz, &slotbuf) < 0) return (0); if (sz < sizeof (uint_t)) return (0); @@ -214,26 +211,16 @@ did_physslot(did_t *did) return (did->dp_physlot); } - -did_hash_t * -did_hash(did_t *did) -{ - assert(did != NULL); - return (did->dp_hash); -} - did_t * -did_create(did_hash_t *dhash, di_node_t src, - int ibrd, int ibrdge, int irc, int ibus, di_prom_handle_t promtree) +did_create(topo_mod_t *mp, di_node_t src, + int ibrd, int ibrdge, int irc, int ibus) { - topo_mod_t *mp; did_t *np; did_t *pd; uint_t code; uint_t reg; - mp = dhash->dph_mod; - if ((pd = did_hash_lookup(dhash, src)) != NULL) { + if ((pd = did_hash_lookup(mp, src)) != NULL) { topo_mod_dprintf(mp, "Attempt to create existing did_t.\n"); assert(ibus == TRUST_BDF || (pd->dp_bus == ibus)); return (pd); @@ -243,13 +230,13 @@ did_create(did_hash_t *dhash, di_node_t src, return (NULL); np->dp_mod = mp; np->dp_src = src; - np->dp_hash = dhash; + np->dp_hash = (did_hash_t *)topo_mod_getspecific(mp); /* * We must have a reg prop and from it we extract the bus #, * device #, and function #. */ - if (di_uintprop_get(src, DI_REGPROP, ®, promtree) < 0) { + if (di_uintprop_get(mp, src, DI_REGPROP, ®) < 0) { topo_mod_free(mp, np, sizeof (did_t)); return (NULL); } @@ -268,7 +255,7 @@ did_create(did_hash_t *dhash, di_node_t src, * There *may* be a class code we can capture. If there wasn't * one, capture that fact by setting the class value to -1. */ - if (di_uintprop_get(src, DI_CCPROP, &code, promtree) == 0) { + if (di_uintprop_get(mp, src, DI_CCPROP, &code) == 0) { np->dp_class = GETCLASS(code); np->dp_subclass = GETSUBCLASS(code); } else { @@ -279,28 +266,25 @@ did_create(did_hash_t *dhash, di_node_t src, * If there wasn't one, the capabilities will be the out-of-bounds * value of zero. */ - (void) di_uintprop_get(src, "pcie-capid-reg", &np->dp_excap, - promtree); + (void) di_uintprop_get(mp, src, "pcie-capid-reg", &np->dp_excap); /* * There *may* be a physical slot number property we can capture. */ if (di_physlotinfo_get(mp, - src, np->dp_excap, &np->dp_physlot, &np->dp_physlot_label, - promtree) < 0) { + src, np->dp_excap, &np->dp_physlot, &np->dp_physlot_label) < 0) { topo_mod_free(mp, np, sizeof (did_t)); return (NULL); } /* * There *may* be PCI slot info we can capture */ - if (di_slotinfo_get(mp, src, &np->dp_nslots, &np->dp_slotnames, - promtree) < 0) { + if (di_slotinfo_get(mp, src, &np->dp_nslots, &np->dp_slotnames) < 0) { if (np->dp_physlot_label != NULL) topo_mod_strfree(mp, np->dp_physlot_label); topo_mod_free(mp, np, sizeof (did_t)); return (NULL); } - did_hash_insert(dhash, src, np); + did_hash_insert(mp, src, np); did_hold(np); return (np); } @@ -320,12 +304,12 @@ did_chain_get(did_t *dp) } void -did_link_set(tnode_t *head, did_t *tail) +did_link_set(topo_mod_t *mod, tnode_t *head, did_t *tail) { did_t *hd, *pd; assert(head != NULL); - pd = hd = topo_node_private(head); + pd = hd = did_find(mod, topo_node_getspecific(head)); assert(hd != NULL); while ((hd = did_link_get(hd)) != NULL) pd = hd; @@ -474,17 +458,17 @@ did_label(did_t *dp, int dev) } did_t * -did_find(did_hash_t *dhash, di_node_t dn) +did_find(topo_mod_t *mp, di_node_t dn) { - return (did_hash_lookup(dhash, dn)); + return (did_hash_lookup(mp, dn)); } int -pci_BDF_get(did_hash_t *dhash, di_node_t dn, int *bus, int *dev, int *fn) +pci_BDF_get(topo_mod_t *mp, di_node_t dn, int *bus, int *dev, int *fn) { did_t *dp; - if ((dp = did_find(dhash, dn)) == NULL) + if ((dp = did_find(mp, dn)) == NULL) return (-1); *bus = dp->dp_bus; *dev = dp->dp_dev; @@ -494,12 +478,11 @@ pci_BDF_get(did_hash_t *dhash, di_node_t dn, int *bus, int *dev, int *fn) } int -pci_classcode_get(did_hash_t *dhash, - di_node_t dn, uint_t *class, uint_t *sub) +pci_classcode_get(topo_mod_t *mp, di_node_t dn, uint_t *class, uint_t *sub) { did_t *dp; - if ((dp = did_find(dhash, dn)) == NULL) + if ((dp = did_find(mp, dn)) == NULL) return (-1); if (dp->dp_class < 0) { did_rele(dp); @@ -512,11 +495,11 @@ pci_classcode_get(did_hash_t *dhash, } int -pciex_cap_get(did_hash_t *dhash, di_node_t dn) +pciex_cap_get(topo_mod_t *mp, di_node_t dn) { did_t *dp; - if ((dp = did_find(dhash, dn)) == NULL) + if ((dp = did_find(mp, dn)) == NULL) return (-1); did_rele(dp); return (dp->dp_excap); @@ -552,3 +535,12 @@ did_inherit(did_t *pdp, did_t *dp) return (-1); return (0); } + +void +did_setspecific(topo_mod_t *mp, void *data) +{ + did_t *hbdid; + + hbdid = (did_t *)data; + topo_mod_setspecific(mp, hbdid->dp_hash); +} diff --git a/usr/src/lib/fm/topo/modules/common/did.h b/usr/src/lib/fm/topo/modules/common/pcibus/did.h index 9a0342dcc0..ceddd3a32b 100644 --- a/usr/src/lib/fm/topo/modules/common/did.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.h @@ -33,12 +33,23 @@ #include <fm/topo_mod.h> #include <libdevinfo.h> #include <libnvpair.h> -#include "did_impl.h" #ifdef __cplusplus extern "C" { #endif +typedef struct did did_t; + +extern did_t *did_create(topo_mod_t *, di_node_t, int, int, int, + int); +extern did_t *did_find(topo_mod_t *, di_node_t); +extern did_t *did_hash_lookup(topo_mod_t *, di_node_t); +extern void did_hash_insert(topo_mod_t *, di_node_t, did_t *); +extern void did_hash_fini(topo_mod_t *); +extern int did_hash_init(topo_mod_t *); +extern void did_link_set(topo_mod_t *, tnode_t *, did_t *); +extern void did_setspecific(topo_mod_t *, void *); + extern topo_mod_t *did_mod(did_t *); extern di_node_t did_dinode(did_t *); extern void did_BDF(did_t *, int *, int *, int *); @@ -51,21 +62,14 @@ extern int did_physslot(did_t *); extern int did_inherit(did_t *, did_t *); extern int did_excap(did_t *); extern int did_bdf(did_t *); - -extern did_t *did_create(did_hash_t *, di_node_t, int, int, int, int, - di_prom_handle_t); -extern did_t *did_find(did_hash_t *, di_node_t); extern did_t *did_link_get(did_t *); extern did_t *did_chain_get(did_t *); extern void did_destroy(did_t *); -extern did_hash_t *did_hash(did_t *); -extern void did_hash_fini(did_hash_t *); extern void did_hold(did_t *); -extern void did_link_set(tnode_t *, did_t *); extern void did_did_link_set(did_t *, did_t *); extern void did_did_chain_set(did_t *, did_t *); extern void did_rele(did_t *); -extern did_hash_t *did_hash_init(topo_mod_t *); + #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/common/did_hash.c b/usr/src/lib/fm/topo/modules/common/pcibus/did_hash.c index ca0596a18f..f8a43ab884 100644 --- a/usr/src/lib/fm/topo/modules/common/did_hash.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_hash.c @@ -31,21 +31,35 @@ #include <assert.h> #include <sys/types.h> #include <libdevinfo.h> -#include <topo_mod.h> +#include <fm/topo_mod.h> +#include <pcibus.h> +#include <did.h> -#include "pcibus.h" #include "did_impl.h" #include "did_props.h" -did_hash_t * +static did_hash_t *did_hash_create(topo_mod_t *); +static void did_hash_destroy(did_hash_t *); + +int did_hash_init(topo_mod_t *hdl) { - return (did_hash_create(hdl)); + did_hash_t *dh = did_hash_create(hdl); + + if (dh != NULL) { + topo_mod_setspecific(hdl, (void *) dh); + return (0); + } else { + return (-1); + } } void -did_hash_fini(did_hash_t *dh) +did_hash_fini(topo_mod_t *mod) { + did_hash_t *dh = (did_hash_t *)topo_mod_getspecific(mod); + + topo_mod_setspecific(mod, NULL); if (dh == NULL) return; did_hash_destroy(dh); @@ -71,7 +85,7 @@ did_dnhash(di_node_t key) return (keyn / key_divisor); } -did_hash_t * +static did_hash_t * did_hash_create(topo_mod_t *hdl) { did_hash_t *r = topo_mod_zalloc(hdl, sizeof (did_hash_t)); @@ -92,7 +106,7 @@ did_hash_create(topo_mod_t *hdl) return (r); } -void +static void did_hash_destroy(did_hash_t *ht) { did_t *e, *n; @@ -113,8 +127,9 @@ did_hash_destroy(did_hash_t *ht) } void -did_hash_insert(did_hash_t *tab, di_node_t key, did_t *new) +did_hash_insert(topo_mod_t *mp, di_node_t key, did_t *new) { + did_hash_t *tab = (did_hash_t *)topo_mod_getspecific(mp); did_t *assertchk; int idx = did_dnhash(key) % tab->dph_hashlen; @@ -139,9 +154,10 @@ did_hash_insert(did_hash_t *tab, di_node_t key, did_t *new) } did_t * -did_hash_lookup(did_hash_t *tab, di_node_t key) +did_hash_lookup(topo_mod_t *mp, di_node_t key) { did_t *e; + did_hash_t *tab = (did_hash_t *)topo_mod_getspecific(mp); int idx = did_dnhash(key) % tab->dph_hashlen; e = tab->dph_hash[idx]; diff --git a/usr/src/lib/fm/topo/modules/common/did_impl.h b/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h index 3a27641353..4f97b9a28a 100644 --- a/usr/src/lib/fm/topo/modules/common/did_impl.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h @@ -33,6 +33,7 @@ #include <fm/libtopo.h> #include <libdevinfo.h> #include <libnvpair.h> +#include <did.h> #ifdef __cplusplus extern "C" { @@ -40,8 +41,6 @@ extern "C" { #define REC_HASHLEN 253 -struct did_hash; - /* * Slot name info is attached to devinfo nodes, compressed inside of * a "slot-names" property. When we dig this out we store each name @@ -54,6 +53,8 @@ typedef struct slotnm { char *snm_label; /* label describing the slot */ } slotnm_t; +typedef struct did_hash did_hash_t; + /* * Private data stored with a tnode_t. We collect slot-name info from * di_nodes that describe buses, but then don't use it until we get to @@ -61,11 +62,11 @@ typedef struct slotnm { * this struct to pass around bus, dev, function info so that doesn't * have to be re-computed. */ -typedef struct did { +struct did { struct did *dp_next; /* for chaining in a hash bucket */ struct did *dp_link; /* for chaining to related did_t */ struct did *dp_chain; /* for chaining to another chain of did_ts */ - struct did_hash *dp_hash; /* the hash table where we reside */ + did_hash_t *dp_hash; /* the hash table where we reside */ topo_mod_t *dp_mod; /* module that allocated the did private data */ di_node_t dp_src; /* di_node_t from which the info was derived */ int dp_refcnt; /* multiple nodes allowed to point at a did_t */ @@ -88,25 +89,14 @@ typedef struct did { */ int dp_nslots; /* number of slots actually described */ slotnm_t *dp_slotnames; /* the slot names as labels */ -} did_t; +}; -typedef struct did_hash { +struct did_hash { did_t **dph_hash; /* hash bucket array */ uint_t dph_hashlen; /* size of hash bucket array */ uint_t dph_nelems; /* number of elements in the hash */ topo_mod_t *dph_mod; /* module that allocated the hash table */ -} did_hash_t; - -extern did_hash_t *did_hash_create(topo_mod_t *); -extern did_t *did_hash_lookup(did_hash_t *, di_node_t); -extern void did_hash_destroy(did_hash_t *); -extern void did_hash_insert(did_hash_t *, di_node_t, did_t *); - -extern did_t *did_create(did_hash_t *, di_node_t, int, int, int, int, - di_prom_handle_t); -extern void did_destroy(did_t *); -extern void did_hold(did_t *); -extern void did_rele(did_t *); +}; #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/common/did_props.c b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c index 3830de2e63..4d06535268 100644 --- a/usr/src/lib/fm/topo/modules/common/did_props.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c @@ -36,32 +36,32 @@ #include <sys/pcie.h> #include <sys/fm/protocol.h> #include <fm/topo_mod.h> +#include <fm/topo_hc.h> #include <libdevinfo.h> -#include <topo_error.h> -#include "hostbridge.h" -#include "pcibus.h" -#include "did.h" -#include "did_props.h" +#include <hostbridge.h> +#include <pcibus.h> +#include <did.h> +#include <did_props.h> static int ASRU_set(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); static int FRU_set(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); static int DEVprop_set(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); static int DRIVERprop_set(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); static int EXCAP_set(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); static int BDF_set(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); static int label_set(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); static int maybe_di_chars_copy(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); static int maybe_di_uint_to_str(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); /* * Arrays of "property translation routines" to set the properties a @@ -74,99 +74,74 @@ static int maybe_di_uint_to_str(tnode_t *, did_t *, * */ +static const topo_pgroup_info_t io_pgroup = + { TOPO_PGROUP_IO, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; +static const topo_pgroup_info_t pci_pgroup = + { TOPO_PGROUP_PCI, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; + +static const topo_pgroup_info_t protocol_pgroup = { + TOPO_PGROUP_PROTOCOL, + TOPO_STABILITY_PRIVATE, + TOPO_STABILITY_PRIVATE, + 1 +}; /* Request to create protocol will be ignored by libtopo */ + txprop_t Fn_common_props[] = { - { NULL, TOPO_PGROUP_IO, TOPO_PROP_DEV, - TOPO_STABILITY_PRIVATE, DEVprop_set }, - { DI_DEVTYPPROP, TOPO_PGROUP_IO, TOPO_PROP_DEVTYPE, - TOPO_STABILITY_PRIVATE, maybe_di_chars_copy }, - { DI_DEVIDPROP, TOPO_PGROUP_PCI, TOPO_PROP_DEVID, - TOPO_STABILITY_PRIVATE, maybe_di_uint_to_str }, - { NULL, TOPO_PGROUP_IO, TOPO_PROP_DRIVER, - TOPO_STABILITY_PRIVATE, DRIVERprop_set }, - { NULL, TOPO_PGROUP_PCI, TOPO_PROP_EXCAP, - TOPO_STABILITY_PRIVATE, EXCAP_set }, - { DI_CLASSPROP, TOPO_PGROUP_PCI, TOPO_PROP_CLASS, - TOPO_STABILITY_PRIVATE, maybe_di_uint_to_str }, - { DI_VENDIDPROP, TOPO_PGROUP_PCI, TOPO_PROP_VENDID, - TOPO_STABILITY_PRIVATE, maybe_di_uint_to_str }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, - TOPO_STABILITY_PRIVATE, label_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU, - TOPO_STABILITY_PRIVATE, FRU_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU, - TOPO_STABILITY_PRIVATE, ASRU_set } + { NULL, &io_pgroup, TOPO_IO_DEV, DEVprop_set }, + { DI_DEVTYPPROP, &io_pgroup, TOPO_IO_DEVTYPE, maybe_di_chars_copy }, + { DI_DEVIDPROP, &pci_pgroup, TOPO_PCI_DEVID, maybe_di_uint_to_str }, + { NULL, &io_pgroup, TOPO_IO_DRIVER, DRIVERprop_set }, + { NULL, &pci_pgroup, TOPO_PCI_EXCAP, EXCAP_set }, + { DI_CLASSPROP, &pci_pgroup, TOPO_PCI_CLASS, maybe_di_uint_to_str }, + { DI_VENDIDPROP, &pci_pgroup, TOPO_PCI_VENDID, maybe_di_uint_to_str }, + { NULL, &protocol_pgroup, TOPO_PROP_LABEL, label_set }, + { NULL, &protocol_pgroup, TOPO_PROP_FRU, FRU_set }, + { NULL, &protocol_pgroup, TOPO_PROP_ASRU, ASRU_set } }; txprop_t Dev_common_props[] = { - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, - TOPO_STABILITY_PRIVATE, label_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU, - TOPO_STABILITY_PRIVATE, FRU_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU, - TOPO_STABILITY_PRIVATE, ASRU_set } + { NULL, &protocol_pgroup, TOPO_PROP_LABEL, label_set }, + { NULL, &protocol_pgroup, TOPO_PROP_FRU, FRU_set }, + { NULL, &protocol_pgroup, TOPO_PROP_ASRU, ASRU_set } }; txprop_t Bus_common_props[] = { - { DI_DEVTYPPROP, TOPO_PGROUP_IO, TOPO_PROP_DEVTYPE, - TOPO_STABILITY_PRIVATE, maybe_di_chars_copy }, - { NULL, TOPO_PGROUP_IO, TOPO_PROP_DRIVER, - TOPO_STABILITY_PRIVATE, DRIVERprop_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, - TOPO_STABILITY_PRIVATE, label_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU, - TOPO_STABILITY_PRIVATE, FRU_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU, - TOPO_STABILITY_PRIVATE, ASRU_set } + { DI_DEVTYPPROP, &io_pgroup, TOPO_IO_DEVTYPE, maybe_di_chars_copy }, + { NULL, &io_pgroup, TOPO_IO_DRIVER, DRIVERprop_set }, + { NULL, &protocol_pgroup, TOPO_PROP_LABEL, label_set }, + { NULL, &protocol_pgroup, TOPO_PROP_FRU, FRU_set }, + { NULL, &protocol_pgroup, TOPO_PROP_ASRU, ASRU_set } }; txprop_t RC_common_props[] = { - { NULL, TOPO_PGROUP_IO, TOPO_PROP_DEV, - TOPO_STABILITY_PRIVATE, DEVprop_set }, - { DI_DEVTYPPROP, TOPO_PGROUP_IO, TOPO_PROP_DEVTYPE, - TOPO_STABILITY_PRIVATE, maybe_di_chars_copy }, - { NULL, TOPO_PGROUP_IO, TOPO_PROP_DRIVER, - TOPO_STABILITY_PRIVATE, DRIVERprop_set }, - { NULL, TOPO_PGROUP_PCI, TOPO_PROP_EXCAP, - TOPO_STABILITY_PRIVATE, EXCAP_set }, - { NULL, TOPO_PGROUP_PCI, TOPO_PROP_BDF, - TOPO_STABILITY_PRIVATE, BDF_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, - TOPO_STABILITY_PRIVATE, label_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU, - TOPO_STABILITY_PRIVATE, FRU_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU, - TOPO_STABILITY_PRIVATE, ASRU_set } + { NULL, &io_pgroup, TOPO_IO_DEV, DEVprop_set }, + { DI_DEVTYPPROP, &io_pgroup, TOPO_IO_DEVTYPE, maybe_di_chars_copy }, + { NULL, &io_pgroup, TOPO_IO_DRIVER, DRIVERprop_set }, + { NULL, &pci_pgroup, TOPO_PCI_EXCAP, EXCAP_set }, + { NULL, &pci_pgroup, TOPO_PCI_BDF, BDF_set }, + { NULL, &protocol_pgroup, TOPO_PROP_LABEL, label_set }, + { NULL, &protocol_pgroup, TOPO_PROP_FRU, FRU_set }, + { NULL, &protocol_pgroup, TOPO_PROP_ASRU, ASRU_set } }; txprop_t ExHB_common_props[] = { - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, - TOPO_STABILITY_PRIVATE, label_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU, - TOPO_STABILITY_PRIVATE, FRU_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU, - TOPO_STABILITY_PRIVATE, ASRU_set } + { NULL, &protocol_pgroup, TOPO_PROP_LABEL, label_set }, + { NULL, &protocol_pgroup, TOPO_PROP_FRU, FRU_set }, + { NULL, &protocol_pgroup, TOPO_PROP_ASRU, ASRU_set } }; txprop_t IOB_common_props[] = { - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, - TOPO_STABILITY_PRIVATE, label_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU, - TOPO_STABILITY_PRIVATE, FRU_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU, - TOPO_STABILITY_PRIVATE, ASRU_set } + { NULL, &protocol_pgroup, TOPO_PROP_LABEL, label_set }, + { NULL, &protocol_pgroup, TOPO_PROP_FRU, FRU_set }, + { NULL, &protocol_pgroup, TOPO_PROP_ASRU, ASRU_set } }; txprop_t HB_common_props[] = { - { NULL, TOPO_PGROUP_IO, TOPO_PROP_DEV, - TOPO_STABILITY_PRIVATE, DEVprop_set }, - { NULL, TOPO_PGROUP_IO, TOPO_PROP_DRIVER, - TOPO_STABILITY_PRIVATE, DRIVERprop_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, - TOPO_STABILITY_PRIVATE, label_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU, - TOPO_STABILITY_PRIVATE, FRU_set }, - { NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU, - TOPO_STABILITY_PRIVATE, ASRU_set } + { NULL, &io_pgroup, TOPO_IO_DEV, DEVprop_set }, + { NULL, &io_pgroup, TOPO_IO_DRIVER, DRIVERprop_set }, + { NULL, &protocol_pgroup, TOPO_PROP_LABEL, label_set }, + { NULL, &protocol_pgroup, TOPO_PROP_FRU, FRU_set }, + { NULL, &protocol_pgroup, TOPO_PROP_ASRU, ASRU_set } }; int Bus_propcnt = sizeof (Bus_common_props) / sizeof (txprop_t); @@ -187,13 +162,16 @@ int Fn_propcnt = sizeof (Fn_common_props) / sizeof (txprop_t); * gets updated with the property value and we return 0. */ static int -promprop2uint(di_node_t n, const char *propnm, uint_t *val, - di_prom_handle_t promtree) +promprop2uint(topo_mod_t *mod, di_node_t n, const char *propnm, uint_t *val) { + di_prom_handle_t ptp = DI_PROM_HANDLE_NIL; di_prom_prop_t pp = DI_PROM_PROP_NIL; uchar_t *buf; - while ((pp = di_prom_prop_next(promtree, n, pp)) != DI_PROM_PROP_NIL) { + if ((ptp = topo_mod_prominfo(mod)) == DI_PROM_HANDLE_NIL) + return (-1); + + while ((pp = di_prom_prop_next(ptp, n, pp)) != DI_PROM_PROP_NIL) { if (strcmp(di_prom_prop_name(pp), propnm) == 0) { if (di_prom_prop_data(pp, &buf) < sizeof (uint_t)) continue; @@ -232,22 +210,25 @@ hwprop2uint(di_node_t n, const char *propnm, uint_t *val) } int -di_uintprop_get(di_node_t n, const char *pnm, uint_t *pv, - di_prom_handle_t promtree) +di_uintprop_get(topo_mod_t *mod, di_node_t n, const char *pnm, uint_t *pv) { if (hwprop2uint(n, pnm, pv) < 0) - if (promprop2uint(n, pnm, pv, promtree) < 0) + if (promprop2uint(mod, n, pnm, pv) < 0) return (-1); return (0); } int -di_bytes_get(di_node_t n, const char *pnm, int *sz, uchar_t **db, - di_prom_handle_t promtree) +di_bytes_get(topo_mod_t *mod, di_node_t n, const char *pnm, int *sz, + uchar_t **db) { + di_prom_handle_t ptp = DI_PROM_HANDLE_NIL; di_prom_prop_t pp = DI_PROM_PROP_NIL; di_prop_t hp = DI_PROP_NIL; + if ((ptp = topo_mod_prominfo(mod)) == DI_PROM_HANDLE_NIL) + return (-1); + *sz = -1; while ((hp = di_prop_next(n, hp)) != DI_PROP_NIL) { if (strcmp(di_prop_name(hp), pnm) == 0) { @@ -257,7 +238,7 @@ di_bytes_get(di_node_t n, const char *pnm, int *sz, uchar_t **db, } } if (*sz < 0) { - while ((pp = di_prom_prop_next(promtree, n, pp)) != + while ((pp = di_prom_prop_next(ptp, n, pp)) != DI_PROM_PROP_NIL) { if (strcmp(di_prom_prop_name(pp), pnm) == 0) { *sz = di_prom_prop_data(pp, db); @@ -267,6 +248,7 @@ di_bytes_get(di_node_t n, const char *pnm, int *sz, uchar_t **db, } } } + if (*sz < 0) return (-1); return (0); @@ -361,12 +343,10 @@ dev_for_hostbridge(topo_mod_t *mp, char *path) /*ARGSUSED*/ static int ASRU_set(tnode_t *tn, did_t *pd, - const char *dpnm, const char *tpgrp, const char *tpnm, - di_prom_handle_t promtree) + const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; - topo_hdl_t *hp; - nvlist_t *fmri, *in; + nvlist_t *fmri; char *dnpath, *path, *fpath, *nm; int d, e, f; @@ -378,7 +358,6 @@ ASRU_set(tnode_t *tn, did_t *pd, * isn't a function, inherit any ASRU from the parent. */ mp = did_mod(pd); - hp = topo_mod_handle(mp); nm = topo_node_name(tn); if (strcmp(nm, PCI_FUNCTION) == 0 || strcmp(nm, PCIEX_FUNCTION) == 0 || strcmp(nm, PCIEX_ROOT) == 0) { @@ -397,24 +376,13 @@ ASRU_set(tnode_t *tn, did_t *pd, if ((fpath = dev_path_fix(mp, path, d, f)) == NULL) return (topo_mod_seterrno(mp, EMOD_NOMEM)); - if (topo_mod_nvalloc(mp, &in, NV_UNIQUE_NAME) != 0) { - topo_mod_strfree(mp, fpath); - return (topo_mod_seterrno(mp, EMOD_FMRI_NVL)); - } - if (nvlist_add_string(in, - FM_FMRI_DEV_PATH, fpath) != 0) { - nvlist_free(in); - topo_mod_strfree(mp, fpath); - return (topo_mod_seterrno(mp, EMOD_NOMEM)); - } - fmri = topo_fmri_create(hp, FM_FMRI_SCHEME_DEV, - FM_FMRI_SCHEME_DEV, 0, in, &e); - nvlist_free(in); + 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 (topo_mod_seterrno(mp, e)); + return (-1); } topo_mod_strfree(mp, fpath); } else { @@ -430,9 +398,8 @@ ASRU_set(tnode_t *tn, did_t *pd, nvlist_free(fmri); return (0); } - if (topo_node_asru_set(tn, NULL, 0, &e) < 0) - if (e != ETOPO_PROP_NOENT) - return (topo_mod_seterrno(mp, e)); + (void) topo_node_asru_set(tn, NULL, 0, &e); + return (0); } @@ -442,16 +409,14 @@ ASRU_set(tnode_t *tn, did_t *pd, static int FRU_fmri_hack(topo_mod_t *mp, tnode_t *tn, const char *label) { - topo_hdl_t *hp; char buf[PATH_MAX]; nvlist_t *fmri; int err, e; - hp = topo_mod_handle(mp); (void) snprintf(buf, PATH_MAX, "hc:///component=%s", label); - if (topo_fmri_str2nvl(hp, buf, &fmri, &err) < 0) - return (topo_mod_seterrno(mp, err)); + if (topo_mod_str2nvl(mp, buf, &fmri) < 0) + return (-1); e = topo_node_fru_set(tn, fmri, 0, &err); nvlist_free(fmri); @@ -463,8 +428,7 @@ FRU_fmri_hack(topo_mod_t *mp, tnode_t *tn, const char *label) /*ARGSUSED*/ static int FRU_set(tnode_t *tn, did_t *pd, - const char *dpnm, const char *tpgrp, const char *tpnm, - di_prom_handle_t promtree) + const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; char *label, *nm; @@ -482,10 +446,7 @@ FRU_set(tnode_t *tn, did_t *pd, */ if (strcmp(nm, "ioboard") != 0 && strcmp(nm, PCI_DEVICE) != 0 && strcmp(nm, PCIEX_DEVICE) != 0) { - if (topo_node_fru_set(tn, NULL, 0, &e) < 0) { - if (e != ETOPO_PROP_NOENT) - return (topo_mod_seterrno(mp, e)); - } + (void) topo_node_fru_set(tn, NULL, 0, &e); return (0); } @@ -493,10 +454,7 @@ FRU_set(tnode_t *tn, did_t *pd, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL, &label, &e) < 0) { if (e != ETOPO_PROP_NOENT) return (topo_mod_seterrno(mp, e)); - if (topo_node_fru_set(tn, NULL, 0, &e) < 0) { - if (e != ETOPO_PROP_NOENT) - return (topo_mod_seterrno(mp, e)); - } + (void) topo_node_fru_set(tn, NULL, 0, &e); return (0); } e = FRU_fmri_hack(mp, tn, label); @@ -507,8 +465,7 @@ FRU_set(tnode_t *tn, did_t *pd, /*ARGSUSED*/ static int label_set(tnode_t *tn, did_t *pd, - const char *dpnm, const char *tpgrp, const char *tpnm, - di_prom_handle_t promtree) + const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; nvlist_t *in, *out; @@ -532,7 +489,7 @@ label_set(tnode_t *tn, did_t *pd, 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_SET_ONCE, label, &err) != 0) { + TOPO_PROP_LABEL, TOPO_PROP_IMMUTABLE, label, &err) != 0) { nvlist_free(out); return (topo_mod_seterrno(mp, err)); } @@ -544,8 +501,7 @@ label_set(tnode_t *tn, did_t *pd, /*ARGSUSED*/ static int EXCAP_set(tnode_t *tn, did_t *pd, - const char *dpnm, const char *tpgrp, const char *tpnm, - di_prom_handle_t promtree) + const char *dpnm, const char *tpgrp, const char *tpnm) { int excap; int err; @@ -557,27 +513,27 @@ EXCAP_set(tnode_t *tn, did_t *pd, switch (excap & PCIE_PCIECAP_DEV_TYPE_MASK) { case PCIE_PCIECAP_DEV_TYPE_ROOT: e = topo_prop_set_string(tn, TOPO_PGROUP_PCI, - TOPO_PROP_EXCAP, TOPO_PROP_SET_ONCE, PCIEX_ROOT, &err); + 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_PROP_EXCAP, TOPO_PROP_SET_ONCE, PCIEX_SWUP, &err); + 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_PROP_EXCAP, TOPO_PROP_SET_ONCE, PCIEX_SWDWN, &err); + 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_PROP_EXCAP, TOPO_PROP_SET_ONCE, PCIEX_BUS, &err); + 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_PROP_EXCAP, TOPO_PROP_SET_ONCE, PCI_BUS, &err); + 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_PROP_EXCAP, TOPO_PROP_SET_ONCE, PCIEX_DEVICE, &err); + TOPO_PCI_EXCAP, TOPO_PROP_IMMUTABLE, PCIEX_DEVICE, &err); break; } if (e != 0) @@ -588,8 +544,7 @@ EXCAP_set(tnode_t *tn, did_t *pd, /*ARGSUSED*/ static int DEVprop_set(tnode_t *tn, did_t *pd, - const char *dpnm, const char *tpgrp, const char *tpnm, - di_prom_handle_t promtree) + const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; char *dnpath; @@ -618,7 +573,7 @@ DEVprop_set(tnode_t *tn, did_t *pd, if (fpath == NULL) return (-1); e = topo_prop_set_string(tn, - tpgrp, tpnm, TOPO_PROP_SET_ONCE, fpath, &err); + tpgrp, tpnm, TOPO_PROP_IMMUTABLE, fpath, &err); topo_mod_strfree(mp, fpath); if (e != 0) return (topo_mod_seterrno(mp, err)); @@ -628,8 +583,7 @@ DEVprop_set(tnode_t *tn, did_t *pd, /*ARGSUSED*/ static int DRIVERprop_set(tnode_t *tn, did_t *pd, - const char *dpnm, const char *tpgrp, const char *tpnm, - di_prom_handle_t promtree) + const char *dpnm, const char *tpgrp, const char *tpnm) { char *dnm; int err; @@ -637,7 +591,7 @@ DRIVERprop_set(tnode_t *tn, did_t *pd, if ((dnm = di_driver_name(did_dinode(pd))) == NULL) return (0); if (topo_prop_set_string(tn, - tpgrp, tpnm, TOPO_PROP_SET_ONCE, dnm, &err) < 0) + tpgrp, tpnm, TOPO_PROP_IMMUTABLE, dnm, &err) < 0) return (topo_mod_seterrno(did_mod(pd), err)); return (0); @@ -646,8 +600,7 @@ DRIVERprop_set(tnode_t *tn, did_t *pd, /*ARGSUSED*/ static int maybe_di_chars_copy(tnode_t *tn, did_t *pd, - const char *dpnm, const char *tpgrp, const char *tpnm, - di_prom_handle_t promtree) + const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; uchar_t *typbuf; @@ -655,15 +608,14 @@ maybe_di_chars_copy(tnode_t *tn, did_t *pd, int sz = -1; int err, e; - if (di_bytes_get(did_dinode(pd), dpnm, &sz, &typbuf, - promtree) < 0) + if (di_bytes_get(did_mod(pd), did_dinode(pd), dpnm, &sz, &typbuf) < 0) return (0); mp = did_mod(pd); tmpbuf = topo_mod_alloc(mp, sz + 1); bcopy(typbuf, tmpbuf, sz); tmpbuf[sz] = 0; e = topo_prop_set_string(tn, - tpgrp, tpnm, TOPO_PROP_SET_ONCE, tmpbuf, &err); + tpgrp, tpnm, TOPO_PROP_IMMUTABLE, tmpbuf, &err); topo_mod_free(mp, tmpbuf, sz + 1); if (e != 0) return (topo_mod_seterrno(mp, err)); @@ -679,20 +631,18 @@ uint_to_strprop(topo_mod_t *mp, uint_t v, tnode_t *tn, (void) snprintf(str, 21, "%x", v); if (topo_prop_set_string(tn, - tpgrp, tpnm, TOPO_PROP_SET_ONCE, str, &e) < 0) + tpgrp, tpnm, TOPO_PROP_IMMUTABLE, str, &e) < 0) return (topo_mod_seterrno(mp, e)); return (0); } static int maybe_di_uint_to_str(tnode_t *tn, did_t *pd, - const char *dpnm, const char *tpgrp, const char *tpnm, - di_prom_handle_t promtree) + const char *dpnm, const char *tpgrp, const char *tpnm) { uint_t v; - if (di_uintprop_get(did_dinode(pd), dpnm, &v, - promtree) < 0) + if (di_uintprop_get(did_mod(pd), did_dinode(pd), dpnm, &v) < 0) return (0); return (uint_to_strprop(did_mod(pd), v, tn, tpgrp, tpnm)); @@ -700,9 +650,8 @@ maybe_di_uint_to_str(tnode_t *tn, did_t *pd, /*ARGSUSED*/ static int -BDF_set(tnode_t *tn, did_t *pd, - const char *dpnm, const char *tpgrp, const char *tpnm, - di_prom_handle_t promtree) +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' */ @@ -713,17 +662,15 @@ BDF_set(tnode_t *tn, did_t *pd, (void) snprintf(str, 23, "0x%x", bdf); if (topo_prop_set_string(tn, - tpgrp, tpnm, TOPO_PROP_SET_ONCE, str, &e) < 0) + tpgrp, tpnm, TOPO_PROP_IMMUTABLE, str, &e) < 0) return (topo_mod_seterrno(did_mod(pd), e)); return (0); } int -did_props_set(tnode_t *tn, did_t *pd, txprop_t txarray[], int txnum, - di_prom_handle_t promtree) +did_props_set(tnode_t *tn, did_t *pd, txprop_t txarray[], int txnum) { topo_mod_t *mp; - const char *ppgroup = NULL; int i, r, e; mp = did_mod(pd); @@ -731,10 +678,9 @@ did_props_set(tnode_t *tn, did_t *pd, txprop_t txarray[], int txnum, /* * Ensure the property group has been created. */ - if (ppgroup == NULL || - strcmp(txarray[i].tx_tpgroup, ppgroup) != 0) { - if (topo_pgroup_create(tn, txarray[i].tx_tpgroup, - txarray[i].tx_pgstab, &e) < 0) { + if (txarray[i].tx_tpgroup != NULL) { + if (topo_pgroup_create(tn, txarray[i].tx_tpgroup, &e) + < 0) { if (e != ETOPO_PROP_DEFD) return (topo_mod_seterrno(mp, e)); } @@ -742,10 +688,10 @@ did_props_set(tnode_t *tn, did_t *pd, txprop_t txarray[], int txnum, topo_mod_dprintf(mp, "Setting property %s in group %s.\n", - txarray[i].tx_tprop, txarray[i].tx_tpgroup); + txarray[i].tx_tprop, txarray[i].tx_tpgroup->tpi_name); r = txarray[i].tx_xlate(tn, pd, - txarray[i].tx_diprop, txarray[i].tx_tpgroup, - txarray[i].tx_tprop, promtree); + txarray[i].tx_diprop, txarray[i].tx_tpgroup->tpi_name, + txarray[i].tx_tprop); if (r != 0) { topo_mod_dprintf(mp, "failed.\n"); topo_mod_dprintf(mp, "Error was %s.\n", diff --git a/usr/src/lib/fm/topo/modules/common/did_props.h b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h index c43d0ef29d..3711fa439e 100644 --- a/usr/src/lib/fm/topo/modules/common/did_props.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h @@ -30,10 +30,12 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <sys/pci.h> -#include <fm/libtopo.h> +#include <fm/topo_mod.h> #include <libdevinfo.h> #include <libnvpair.h> +#include <did.h> + #ifdef __cplusplus extern "C" { #endif @@ -48,30 +50,17 @@ extern "C" { */ typedef struct txprop { const char *tx_diprop; /* property examined off the di_node_t */ - const char *tx_tpgroup; /* property group defined on the tnode_t */ + const topo_pgroup_info_t *tx_tpgroup; /* pgroup defined for tnode_t */ const char *tx_tprop; /* property defined on the tnode_t */ - topo_stability_t tx_pgstab; /* stability of property group */ /* * translation function * If NULL, the devinfo prop's value is copied to the * topo property. */ int (*tx_xlate)(tnode_t *, did_t *, - const char *, const char *, const char *, di_prom_handle_t); + const char *, const char *, const char *); } txprop_t; -#define TOPO_PGROUP_PCI "pci" -#define TOPO_PGROUP_IO "io" - -#define TOPO_PROP_DEVTYPE "DEVTYPE" -#define TOPO_PROP_DRIVER "DRIVER" -#define TOPO_PROP_VENDID "VENDOR-ID" -#define TOPO_PROP_DEVID "DEVICE-ID" -#define TOPO_PROP_CLASS "CLASS-CODE" -#define TOPO_PROP_EXCAP "EXCAP" -#define TOPO_PROP_BDF "BDF" -#define TOPO_PROP_DEV "DEV" - #define DI_DEVTYPPROP "device_type" #define DI_VENDIDPROP "vendor-id" #define DI_DEVIDPROP "device-id" @@ -81,17 +70,15 @@ typedef struct txprop { #define DI_PHYSPROP "physical-slot#" #define DI_SLOTPROP "slot-names" -extern int did_props_set(tnode_t *, did_t *, txprop_t[], int, - di_prom_handle_t); +extern int did_props_set(tnode_t *, did_t *, txprop_t[], int); -extern int pciex_cap_get(did_hash_t *, di_node_t); -extern int pci_BDF_get(did_hash_t *, di_node_t, int *, int *, int *); -extern int pci_classcode_get(did_hash_t *, di_node_t, uint_t *, uint_t *); +extern int pciex_cap_get(topo_mod_t *, di_node_t); +extern int pci_BDF_get(topo_mod_t *, di_node_t, int *, int *, int *); +extern int pci_classcode_get(topo_mod_t *, di_node_t, uint_t *, uint_t *); -extern int di_uintprop_get(di_node_t, const char *, uint_t *, - di_prom_handle_t); -extern int di_bytes_get(di_node_t, const char *, int *, uchar_t **, - di_prom_handle_t); +extern int di_uintprop_get(topo_mod_t *, di_node_t, const char *, uint_t *); +extern int di_bytes_get(topo_mod_t *, di_node_t, const char *, int *, + uchar_t **); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/common/pcibus.c b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c index 069b24da46..5e5a400888 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c @@ -39,13 +39,13 @@ #include <libdevinfo.h> #include <libnvpair.h> #include <fm/topo_mod.h> -#include <pthread.h> +#include <fm/topo_hc.h> -#include "hostbridge.h" -#include "pcibus.h" -#include "did.h" -#include "did_props.h" -#include "util.h" +#include <hostbridge.h> +#include <pcibus.h> +#include <did.h> +#include <did_props.h> +#include <util.h> extern txprop_t Bus_common_props[]; extern txprop_t Dev_common_props[]; @@ -54,43 +54,43 @@ extern int Bus_propcnt; extern int Dev_propcnt; extern int Fn_propcnt; -extern int pcifn_enum(topo_mod_t *, tnode_t *); +extern int platform_pci_label(topo_mod_t *mod, tnode_t *, nvlist_t *, + nvlist_t **); static void pci_release(topo_mod_t *, tnode_t *); static int pci_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); -static int pci_contains(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int pci_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); + topo_instance_t, void *, void *); static int pci_label(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); -const topo_modinfo_t Pci_info = - { PCI_BUS, PCI_ENUMR_VERS, pci_enum, pci_release }; +static const topo_modops_t Pci_ops = + { pci_enum, pci_release }; +static const topo_modinfo_t Pci_info = + { PCI_BUS, FM_FMRI_SCHEME_HC, PCI_ENUMR_VERS, &Pci_ops }; -const topo_method_t Pci_methods[] = { - { "pci_contains", "pci element contains other element", PCI_ENUMR_VERS, - TOPO_STABILITY_INTERNAL, pci_contains }, - { "pci_present", "pci element currently present", PCI_ENUMR_VERS, - TOPO_STABILITY_INTERNAL, pci_present }, +static const topo_method_t Pci_methods[] = { { TOPO_METH_LABEL, TOPO_METH_LABEL_DESC, TOPO_METH_LABEL_VERSION, TOPO_STABILITY_INTERNAL, pci_label }, { NULL } }; -void -_topo_init(topo_mod_t *modhdl) +int +_topo_init(topo_mod_t *modhdl, topo_version_t version) { /* * Turn on module debugging output */ if (getenv("TOPOPCIDBG") != NULL) - topo_mod_setdebug(modhdl, TOPO_DBG_ALL); + topo_mod_setdebug(modhdl); topo_mod_dprintf(modhdl, "initializing pcibus builtin\n"); - topo_mod_register(modhdl, &Pci_info, NULL); + if (version != PCI_ENUMR_VERS) + return (topo_mod_seterrno(modhdl, EMOD_VER_NEW)); + + topo_mod_register(modhdl, &Pci_info, TOPO_VERSION); topo_mod_dprintf(modhdl, "PCI Enumr initd\n"); + + return (0); } void @@ -99,34 +99,18 @@ _topo_fini(topo_mod_t *modhdl) topo_mod_unregister(modhdl); } -/*ARGSUSED*/ -static int -pci_contains(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (0); -} - -/*ARGSUSED*/ -static int -pci_present(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (0); -} - static int pci_label(topo_mod_t *mp, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { if (version > TOPO_METH_LABEL_VERSION) return (topo_mod_seterrno(mp, EMOD_VER_NEW)); - return (platform_pci_label(node, in, out, mp)); + return (platform_pci_label(mp, node, in, out)); } static tnode_t * -pci_tnode_create(tnode_t *parent, - const char *name, topo_instance_t i, void *priv, topo_mod_t *mod) +pci_tnode_create(topo_mod_t *mod, tnode_t *parent, + const char *name, topo_instance_t i, void *priv) { tnode_t *ntn; @@ -143,37 +127,34 @@ pci_tnode_create(tnode_t *parent, /*ARGSUSED*/ static int -hostbridge_asdevice(tnode_t *bus, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +hostbridge_asdevice(topo_mod_t *mod, tnode_t *bus) { di_node_t di; tnode_t *dev32; - di = topo_node_private(bus); + di = topo_node_getspecific(bus); assert(di != DI_NODE_NIL); - if ((dev32 = pcidev_declare(bus, di, 32, didhash, promtree, mod)) - == NULL) + if ((dev32 = pcidev_declare(mod, bus, di, 32)) == NULL) return (-1); - if (pcifn_declare(dev32, di, 0, didhash, promtree, mod) == NULL) + if (pcifn_declare(mod, dev32, di, 0) == NULL) return (-1); return (0); } tnode_t * -pciexfn_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +pciexfn_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn, + topo_instance_t i) { did_t *pd; tnode_t *ntn; - if ((pd = did_find(didhash, dn)) == NULL) + if ((pd = did_find(mod, dn)) == NULL) return (NULL); - if ((ntn = pci_tnode_create(parent, PCIEX_FUNCTION, i, dn, mod)) + if ((ntn = pci_tnode_create(mod, parent, PCIEX_FUNCTION, i, dn)) == NULL) return (NULL); - if (did_props_set(ntn, pd, Fn_common_props, Fn_propcnt, - promtree) < 0) { + if (did_props_set(ntn, pd, Fn_common_props, Fn_propcnt) < 0) { topo_node_unbind(ntn); return (NULL); } @@ -192,21 +173,21 @@ pciexfn_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, } tnode_t * -pciexdev_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +pciexdev_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn, + topo_instance_t i) { did_t *pd; tnode_t *ntn; - if ((pd = did_find(didhash, dn)) == NULL) + if ((pd = did_find(mod, dn)) == NULL) return (NULL); - if ((ntn = pci_tnode_create(parent, PCIEX_DEVICE, i, dn, mod)) == NULL) + if ((ntn = pci_tnode_create(mod, parent, PCIEX_DEVICE, i, dn)) == NULL) return (NULL); - if (did_props_set(ntn, pd, Dev_common_props, Dev_propcnt, - promtree) < 0) { + if (did_props_set(ntn, pd, Dev_common_props, Dev_propcnt) < 0) { topo_node_unbind(ntn); return (NULL); } + /* * We can expect to find pci-express functions beneath the device */ @@ -219,18 +200,17 @@ pciexdev_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, } tnode_t * -pciexbus_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +pciexbus_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn, + topo_instance_t i) { did_t *pd; tnode_t *ntn; - if ((pd = did_find(didhash, dn)) == NULL) + if ((pd = did_find(mod, dn)) == NULL) return (NULL); - if ((ntn = pci_tnode_create(parent, PCIEX_BUS, i, dn, mod)) == NULL) + if ((ntn = pci_tnode_create(mod, parent, PCIEX_BUS, i, dn)) == NULL) return (NULL); - if (did_props_set(ntn, pd, Bus_common_props, Bus_propcnt, - promtree) < 0) { + if (did_props_set(ntn, pd, Bus_common_props, Bus_propcnt) < 0) { topo_node_range_destroy(ntn, PCI_DEVICE); topo_node_unbind(ntn); return (NULL); @@ -247,18 +227,17 @@ pciexbus_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, } tnode_t * -pcifn_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +pcifn_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn, + topo_instance_t i) { did_t *pd; tnode_t *ntn; - if ((pd = did_find(didhash, dn)) == NULL) + if ((pd = did_find(mod, dn)) == NULL) return (NULL); - if ((ntn = pci_tnode_create(parent, PCI_FUNCTION, i, dn, mod)) == NULL) + if ((ntn = pci_tnode_create(mod, parent, PCI_FUNCTION, i, dn)) == NULL) return (NULL); - if (did_props_set(ntn, pd, Fn_common_props, Fn_propcnt, - promtree) < 0) { + if (did_props_set(ntn, pd, Fn_common_props, Fn_propcnt) < 0) { topo_node_unbind(ntn); return (NULL); } @@ -273,21 +252,21 @@ pcifn_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, } tnode_t * -pcidev_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +pcidev_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn, + topo_instance_t i) { - di_node_t pdn; did_t *pd; - tnode_t *ntn; did_t *ppd; + di_node_t pdn; + tnode_t *ntn; - if ((pdn = topo_node_private(parent)) == DI_NODE_NIL) + if ((pdn = topo_node_getspecific(parent)) == DI_NODE_NIL) return (NULL); - if ((ppd = did_find(didhash, pdn)) == NULL) + if ((ppd = did_find(mod, pdn)) == NULL) return (NULL); - if ((pd = did_find(didhash, dn)) == NULL) + if ((pd = did_find(mod, dn)) == NULL) return (NULL); - if ((ntn = pci_tnode_create(parent, PCI_DEVICE, i, dn, mod)) == NULL) + if ((ntn = pci_tnode_create(mod, parent, PCI_DEVICE, i, dn)) == NULL) return (NULL); /* * If our devinfo node is lacking certain information of its @@ -295,11 +274,11 @@ pcidev_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, * from our parent node's private data. */ did_inherit(ppd, pd); - if (did_props_set(ntn, pd, Dev_common_props, Dev_propcnt, - promtree) < 0) { + if (did_props_set(ntn, pd, Dev_common_props, Dev_propcnt) < 0) { topo_node_unbind(ntn); return (NULL); } + /* * We can expect to find pci functions beneath the device */ @@ -312,16 +291,16 @@ pcidev_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, } tnode_t * -pcibus_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +pcibus_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn, + topo_instance_t i) { did_t *pd; tnode_t *ntn; int hbchild = 0; - if ((pd = did_find(didhash, dn)) == NULL) + if ((pd = did_find(mod, dn)) == NULL) return (NULL); - if ((ntn = pci_tnode_create(parent, PCI_BUS, i, dn, mod)) == NULL) + if ((ntn = pci_tnode_create(mod, parent, PCI_BUS, i, dn)) == NULL) return (NULL); /* * If our devinfo node is lacking certain information of its @@ -331,8 +310,7 @@ pcibus_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, */ if (strcmp(topo_node_name(parent), HOSTBRIDGE) == 0) hbchild = 1; - if (did_props_set(ntn, pd, Bus_common_props, Bus_propcnt, - promtree) < 0) { + if (did_props_set(ntn, pd, Bus_common_props, Bus_propcnt) < 0) { topo_node_unbind(ntn); return (NULL); } @@ -349,7 +327,7 @@ pcibus_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, * numbers. */ if (hbchild == 1) { - if (hostbridge_asdevice(ntn, didhash, promtree, mod) < 0) { + if (hostbridge_asdevice(mod, ntn) < 0) { topo_node_range_destroy(ntn, PCI_DEVICE); topo_node_unbind(ntn); return (NULL); @@ -359,68 +337,65 @@ pcibus_declare(tnode_t *parent, di_node_t dn, topo_instance_t i, } static int -pci_bridge_declare(tnode_t *fn, di_node_t din, int board, - int bridge, int rc, int depth, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +pci_bridge_declare(topo_mod_t *mod, tnode_t *fn, di_node_t din, int board, + int bridge, int rc, int depth) { int err, excap, extyp; - excap = pciex_cap_get(didhash, din); + excap = pciex_cap_get(mod, din); extyp = excap & PCIE_PCIECAP_DEV_TYPE_MASK; if (excap <= 0 || extyp != PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) - err = pci_children_instantiate(fn, - din, board, bridge, rc, TRUST_BDF, depth + 1, didhash, - promtree, mod); + err = pci_children_instantiate(mod, fn, din, board, bridge, + rc, TRUST_BDF, depth + 1); else - err = pci_children_instantiate(fn, - din, board, bridge, rc - TO_PCI, TRUST_BDF, depth + 1, - didhash, promtree, mod); + err = pci_children_instantiate(mod, fn, din, board, bridge, + rc - TO_PCI, TRUST_BDF, depth + 1); return (err); } static int -declare_dev_and_fn(tnode_t *bus, tnode_t **dev, di_node_t din, - int board, int bridge, int rc, int devno, int fnno, int depth, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +declare_dev_and_fn(topo_mod_t *mod, tnode_t *bus, tnode_t **dev, di_node_t din, + int board, int bridge, int rc, int devno, int fnno, int depth) { + int err = 0; tnode_t *fn; uint_t class, subclass; - int err; if (*dev == NULL) { if (rc >= 0) - *dev = pciexdev_declare(bus, din, devno, didhash, - promtree, mod); + *dev = pciexdev_declare(mod, bus, din, devno); else - *dev = pcidev_declare(bus, din, devno, didhash, - promtree, mod); + *dev = pcidev_declare(mod, bus, din, devno); if (*dev == NULL) return (-1); } if (rc >= 0) - fn = pciexfn_declare(*dev, din, fnno, didhash, promtree, mod); + fn = pciexfn_declare(mod, *dev, din, fnno); else - fn = pcifn_declare(*dev, din, fnno, didhash, promtree, mod); + fn = pcifn_declare(mod, *dev, din, fnno); if (fn == NULL) return (-1); - if (pci_classcode_get(didhash, din, &class, &subclass) < 0) + if (pci_classcode_get(mod, din, &class, &subclass) < 0) return (-1); + + /* + * This function may be a bridge. If not, check for a possible + * topology map file and kick off its enumeration of lower-level + * devices. + */ if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) - err = pci_bridge_declare(fn, din, board, bridge, rc, depth, - didhash, promtree, mod); - else - err = pcifn_enum(mod, fn); - if (err < 0) - return (-1); - else - return (0); + err = pci_bridge_declare(mod, fn, din, board, bridge, rc, + depth); + else if (class == PCI_CLASS_MASS) + (void) topo_mod_enummap(mod, fn, "storage", FM_FMRI_SCHEME_HC); + + return (err); } int -pci_children_instantiate(tnode_t *parent, di_node_t pn, - int board, int bridge, int rc, int bover, int depth, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +pci_children_instantiate(topo_mod_t *mod, tnode_t *parent, di_node_t pn, + int board, int bridge, int rc, int bover, int depth) { did_t *pps[MAX_PCIBUS_DEVS][MAX_PCIDEV_FNS]; did_t *bp = NULL; @@ -439,8 +414,7 @@ pci_children_instantiate(tnode_t *parent, di_node_t pn, /* start at the parent's first sibling */ sib = di_child_node(pn); while (sib != DI_NODE_NIL) { - np = did_create(didhash, sib, board, bridge, rc, bover, - promtree); + np = did_create(mod, sib, board, bridge, rc, bover); if (np == NULL) return (-1); did_BDF(np, &b, &d, &f); @@ -454,11 +428,9 @@ pci_children_instantiate(tnode_t *parent, di_node_t pn, if (pb < 0 && bover < 0) return (0); if (rc >= 0) - bn = pciexbus_declare(parent, pn, ((pb < 0) ? bover : pb), - didhash, promtree, mod); + bn = pciexbus_declare(mod, parent, pn, ((pb < 0) ? bover : pb)); else - bn = pcibus_declare(parent, pn, ((pb < 0) ? bover : pb), - didhash, promtree, mod); + bn = pcibus_declare(mod, parent, pn, ((pb < 0) ? bover : pb)); if (bn == NULL) return (-1); if (pb < 0) @@ -469,10 +441,14 @@ pci_children_instantiate(tnode_t *parent, di_node_t pn, if (pps[d][f] == NULL) continue; din = did_dinode(pps[d][f]); - if ((declare_dev_and_fn(bn, - &dn, din, board, bridge, rc, d, f, depth, - didhash, promtree, mod)) != 0) - return (-1); + /* + * Ignore error and try to enumerate as much as + * possible. If we ever need to check for an + * error all declared buses, devices and functions + * need to be cleaned up + */ + (void) declare_dev_and_fn(mod, bn, + &dn, din, board, bridge, rc, d, f, depth); did_rele(pps[d][f]); } dn = NULL; @@ -481,14 +457,12 @@ pci_children_instantiate(tnode_t *parent, di_node_t pn, } static int -pciexbus_enum(tnode_t *ptn, - char *pnm, topo_instance_t min, topo_instance_t max, - di_prom_handle_t promtree, topo_mod_t *mod) +pciexbus_enum(topo_mod_t *mp, tnode_t *ptn, char *pnm, topo_instance_t min, + topo_instance_t max) { di_node_t pdn; int rc; int retval; - did_hash_t *didhash; /* * PCI-Express; root complex shares the hostbridge's instance @@ -497,43 +471,35 @@ pciexbus_enum(tnode_t *ptn, */ rc = topo_node_instance(ptn); - if ((pdn = topo_node_private(ptn)) == DI_NODE_NIL) { - topo_mod_dprintf(mod, + if ((pdn = topo_node_getspecific(ptn)) == DI_NODE_NIL) { + topo_mod_dprintf(mp, "Parent %s node missing private data.\n" - "Unable to proceed with %s enumeration.\n", - pnm, PCIEX_BUS); + "Unable to proceed with %s enumeration.\n", pnm, PCIEX_BUS); return (0); } - if ((didhash = did_hash_init(mod)) == NULL || - (did_create(didhash, pdn, 0, 0, rc, TRUST_BDF, promtree) == NULL)) + did_hash_init(mp); + if (did_create(mp, pdn, 0, 0, rc, TRUST_BDF) == NULL) return (-1); /* errno already set */ - retval = pci_children_instantiate(ptn, - pdn, 0, 0, rc, (min == max) ? min : TRUST_BDF, 0, didhash, - promtree, mod); - did_hash_fini(didhash); + retval = pci_children_instantiate(mp, ptn, pdn, 0, 0, rc, + (min == max) ? min : TRUST_BDF, 0); + did_hash_fini(mp); + return (retval); } static int -pcibus_enum(tnode_t *ptn, char *pnm, topo_instance_t min, topo_instance_t max, - di_prom_handle_t promtree, topo_mod_t *mod) +pcibus_enum(topo_mod_t *mp, tnode_t *ptn, char *pnm, topo_instance_t min, + topo_instance_t max, void *data) { - did_t *hbdid, *didp; + did_t *didp, *hbdid = (did_t *)data; int retval; - did_hash_t *didhash; /* - * PCI Bus; Parent node's private data is a did_t. We'll + * XXTOPO: we should not be sharing private node data with another + * module. PCI Bus; Parent node's private data is a did_t. We'll * use the did hash established by the parent. */ - if ((hbdid = topo_node_private(ptn)) == NULL) { - topo_mod_dprintf(mod, - "Parent %s node missing private data.\n" - "Unable to proceed with %s enumeration.\n", - pnm, PCIEX_BUS); - return (0); - } - didhash = did_hash(hbdid); + did_setspecific(mp, data); /* * If we're looking for a specific bus-instance, find the right @@ -549,62 +515,63 @@ pcibus_enum(tnode_t *ptn, char *pnm, topo_instance_t min, topo_instance_t max, didp = did_link_get(didp); } if (didp == NULL) { - topo_mod_dprintf(mod, + topo_mod_dprintf(mp, "Parent %s node missing private data related\n" "to %s instance %d.\n", pnm, PCI_BUS, min); + topo_mod_setspecific(mp, NULL); return (0); } } else { assert(did_link_get(hbdid) == NULL); didp = hbdid; } - retval = pci_children_instantiate(ptn, did_dinode(didp), + retval = pci_children_instantiate(mp, ptn, did_dinode(didp), did_board(didp), did_bridge(didp), did_rc(didp), - (min == max) ? min : TRUST_BDF, 0, didhash, promtree, mod); + (min == max) ? min : TRUST_BDF, 0); + + topo_mod_setspecific(mp, NULL); + return (retval); } /*ARGSUSED*/ static int -pci_enum(topo_mod_t *mp, tnode_t *ptn, const char *name, - topo_instance_t min, topo_instance_t max, void *notused) +pci_enum(topo_mod_t *mod, tnode_t *ptn, const char *name, + topo_instance_t min, topo_instance_t max, void *notused, void *data) { - char *pnm; int retval; - di_prom_handle_t promtree; + char *pname; - topo_mod_dprintf(mp, "Enumerating pci!\n"); + topo_mod_dprintf(mod, "Enumerating pci!\n"); - if ((promtree = di_prom_init()) == DI_PROM_HANDLE_NIL) { - topo_mod_dprintf(mp, - "Pcibus enumerator: di_prom_handle_init failed.\n"); - return (-1); + if (strcmp(name, PCI_BUS) != 0 && strcmp(name, PCIEX_BUS) != 0) { + topo_mod_dprintf(mod, + "Currently only know how to enumerate %s or %s.\n", + PCI_BUS, PCIEX_BUS); + return (0); } - - pnm = topo_node_name(ptn); - if (strcmp(pnm, HOSTBRIDGE) != 0 && strcmp(pnm, PCIEX_ROOT) != 0) { - topo_mod_dprintf(mp, + pname = topo_node_name(ptn); + if (strcmp(pname, HOSTBRIDGE) != 0 && strcmp(pname, PCIEX_ROOT) != 0) { + topo_mod_dprintf(mod, "Currently can only enumerate a %s or %s directly\n", PCI_BUS, PCIEX_BUS); - topo_mod_dprintf(mp, + topo_mod_dprintf(mod, "descended from a %s or %s node.\n", HOSTBRIDGE, PCIEX_ROOT); - di_prom_fini(promtree); return (0); } if (strcmp(name, PCI_BUS) == 0) { - retval = pcibus_enum(ptn, pnm, min, max, promtree, mp); + retval = pcibus_enum(mod, ptn, pname, min, max, data); } else if (strcmp(name, PCIEX_BUS) == 0) { - retval = pciexbus_enum(ptn, pnm, min, max, promtree, mp); + retval = pciexbus_enum(mod, ptn, pname, min, max); } else { - topo_mod_dprintf(mp, + topo_mod_dprintf(mod, "Currently only know how to enumerate %s or %s not %s.\n", PCI_BUS, PCIEX_BUS, name); - di_prom_fini(promtree); return (0); } - di_prom_fini(promtree); + return (retval); } diff --git a/usr/src/lib/fm/topo/modules/common/pcibus.h b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.h index 21d61643cd..743eef62f2 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.h @@ -31,7 +31,6 @@ #include <sys/pci.h> #include <fm/topo_mod.h> -#include <fm/libtopo.h> #include <libdevinfo.h> #ifdef __cplusplus @@ -40,7 +39,7 @@ extern "C" { #define PCI_ENUMR_VERS 1 -#define PATH_TO_PCI_ENUM "%s/usr/platform/%s/lib/fm/topo/plugins/pcibus.so" +#define PCI_ENUM "pcibus" #define PCI_BUS "pcibus" #define PCI_DEVICE "pcidev" @@ -62,27 +61,22 @@ extern "C" { #define GETCLASS(x) (((x) & 0xff0000) >> 16) #define GETSUBCLASS(x) (((x) & 0xff00) >> 8) -struct did_hash; - -extern tnode_t *pcibus_declare(tnode_t *, di_node_t, topo_instance_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern tnode_t *pcidev_declare(tnode_t *, di_node_t, topo_instance_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern tnode_t *pcifn_declare(tnode_t *, di_node_t, topo_instance_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern tnode_t *pciexbus_declare(tnode_t *, di_node_t, topo_instance_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern tnode_t *pciexdev_declare(tnode_t *, di_node_t, topo_instance_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern tnode_t *pciexfn_declare(tnode_t *, di_node_t, topo_instance_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern int pci_children_instantiate(tnode_t *, di_node_t, - int, int, int, int, int, struct did_hash *, di_prom_handle_t, - topo_mod_t *); - -extern int platform_pci_label(tnode_t *, nvlist_t *, nvlist_t **, topo_mod_t *); - -extern const topo_method_t Pci_methods[]; +extern tnode_t *pcibus_declare(topo_mod_t *, tnode_t *, di_node_t, + topo_instance_t); +extern tnode_t *pcidev_declare(topo_mod_t *, tnode_t *, di_node_t, + topo_instance_t); +extern tnode_t *pcifn_declare(topo_mod_t *, tnode_t *, di_node_t, + topo_instance_t); +extern tnode_t *pciexbus_declare(topo_mod_t *, tnode_t *, di_node_t, + topo_instance_t); +extern tnode_t *pciexdev_declare(topo_mod_t *, tnode_t *, di_node_t, + topo_instance_t); +extern tnode_t *pciexfn_declare(topo_mod_t *, tnode_t *, di_node_t, + topo_instance_t); +extern int pci_children_instantiate(topo_mod_t *, tnode_t *, di_node_t, + int, int, int, int, int); + +extern int platform_pci_label(topo_mod_t *, tnode_t *, nvlist_t *, nvlist_t **); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/common/pcibus_labels.c b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c index 5a48004081..86e839c6a3 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus_labels.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c @@ -30,11 +30,11 @@ #include <fm/topo_mod.h> #include <assert.h> #include <string.h> +#include <sys/fm/protocol.h> -#include "topo_error.h" -#include "did.h" -#include "pcibus.h" -#include "pcibus_labels.h" +#include <did.h> +#include <pcibus.h> +#include <pcibus_labels.h> extern slotnm_rewrite_t *Slot_Rewrites; extern physlot_names_t *Physlot_Names; @@ -96,7 +96,7 @@ pci_slotname_rewrite(char *platform, const char *label) } static const char * -pci_missing_match(char *platform, did_t *dp, topo_mod_t *mod) +pci_missing_match(topo_mod_t *mod, char *platform, did_t *dp) { const char *rlabel = NULL; int board, bridge, rc, bus, dev; @@ -132,31 +132,38 @@ pci_missing_match(char *platform, did_t *dp, topo_mod_t *mod) } static const char * -pci_slotname_lookup(tnode_t *node, did_t *dp, topo_mod_t *mod) +pci_slotname_lookup(topo_mod_t *mod, tnode_t *node, did_t *dp) { const char *l; - char *plat; + char *plat, *pp; int err; int d; if (topo_prop_get_string(node, - TOPO_PGROUP_SYSTEM, TOPO_PROP_PLATFORM, &plat, &err) < 0) { + FM_FMRI_AUTHORITY, FM_FMRI_AUTH_PRODUCT, &plat, &err) < 0) { (void) topo_mod_seterrno(mod, err); return (NULL); } + + /* + * Trim SUNW, from the platform name + */ + pp = strchr(plat, ','); + ++pp; + did_BDF(dp, NULL, &d, NULL); - if ((l = pci_physslot_name_lookup(plat, dp)) == NULL) + if ((l = pci_physslot_name_lookup(pp, dp)) == NULL) if ((l = did_label(dp, d)) != NULL) { - l = pci_slotname_rewrite(plat, l); + l = pci_slotname_rewrite(pp, l); } else { - l = pci_missing_match(plat, dp, mod); + l = pci_missing_match(mod, pp, dp); } topo_mod_strfree(mod, plat); return (l); } int -pci_label_cmn(tnode_t *node, nvlist_t *in, nvlist_t **out, topo_mod_t *mod) +pci_label_cmn(topo_mod_t *mod, tnode_t *node, nvlist_t *in, nvlist_t **out) { uint64_t ptr; const char *l; @@ -189,7 +196,7 @@ pci_label_cmn(tnode_t *node, nvlist_t *in, nvlist_t **out, topo_mod_t *mod) /* * Is there a slotname associated with the device? */ - if ((l = pci_slotname_lookup(node, dp, mod)) != NULL) { + if ((l = pci_slotname_lookup(mod, node, dp)) != NULL) { nvlist_t *rnvl; if (topo_mod_nvalloc(mod, &rnvl, NV_UNIQUE_NAME) != 0 || diff --git a/usr/src/lib/fm/topo/modules/common/pcibus_labels.h b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.h index a5cb823003..2eae7d7ef5 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus_labels.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.h @@ -101,7 +101,7 @@ typedef struct missing_names { struct pdevlabs *mn_names; /* platform entries */ } missing_names_t; -extern int pci_label_cmn(tnode_t *, nvlist_t *, nvlist_t **, topo_mod_t *mod); +extern int pci_label_cmn(topo_mod_t *mod, tnode_t *, nvlist_t *, nvlist_t **); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/common/util.c b/usr/src/lib/fm/topo/modules/common/pcibus/util.c index 43adf4e66c..f619862eda 100644 --- a/usr/src/lib/fm/topo/modules/common/util.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/util.c @@ -29,8 +29,8 @@ #include <stdlib.h> #include <sys/fm/protocol.h> #include <fm/topo_mod.h> - -#include "topo_error.h" +#include <fm/topo_hc.h> +#include <fm/libtopo.h> int child_range_add(topo_mod_t *mp, tnode_t *tn, const char *cnm, @@ -68,44 +68,21 @@ tnode_t * tnode_create(topo_mod_t *mp, tnode_t *parent, const char *name, topo_instance_t i, void *priv) { - topo_hdl_t *thp; - nvlist_t *fmri, *pfmri, *nvl; + nvlist_t *fmri; tnode_t *ntn; - int err; - - thp = topo_mod_handle(mp); + nvlist_t *auth; - if (topo_node_resource(parent, &pfmri, &err) < 0) { - topo_mod_seterrno(mp, err); - topo_mod_dprintf(mp, "Unable to retrieve parent resource.\n"); - return (NULL); - } - if (topo_mod_nvalloc(mp, &nvl, NV_UNIQUE_NAME) != 0) { - (void) topo_mod_seterrno(mp, EMOD_FMRI_NVL); - nvlist_free(pfmri); - return (NULL); - } - err = nvlist_add_nvlist(nvl, TOPO_METH_FMRI_ARG_PARENT, pfmri); - if (err != 0) { - nvlist_free(pfmri); - nvlist_free(nvl); - (void) topo_mod_seterrno(mp, EMOD_FMRI_NVL); - return (NULL); - } - - fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, i, nvl, &err); + auth = topo_mod_auth(mp, parent); + fmri = topo_mod_hcfmri(mp, parent, FM_HC_SCHEME_VERSION, name, i, NULL, + auth, NULL, NULL, NULL); + nvlist_free(auth); if (fmri == NULL) { - nvlist_free(pfmri); - nvlist_free(nvl); - topo_mod_seterrno(mp, err); topo_mod_dprintf(mp, "Unable to make nvlist for %s bind.\n", name); return (NULL); } - nvlist_free(pfmri); - nvlist_free(nvl); - ntn = topo_node_bind(mp, parent, name, i, fmri, priv); + ntn = topo_node_bind(mp, parent, name, i, fmri); if (ntn == NULL) { topo_mod_dprintf(mp, "topo_node_bind (%s%d/%s%d) failed: %s\n", @@ -116,6 +93,8 @@ tnode_create(topo_mod_t *mp, tnode_t *parent, return (NULL); } nvlist_free(fmri); + topo_node_setspecific(ntn, priv); + return (ntn); } diff --git a/usr/src/lib/fm/topo/modules/common/util.h b/usr/src/lib/fm/topo/modules/common/pcibus/util.h index 8dda2b6304..8dda2b6304 100644 --- a/usr/src/lib/fm/topo/modules/common/util.h +++ b/usr/src/lib/fm/topo/modules/common/pcibus/util.h diff --git a/usr/src/lib/fm/topo/modules/common/pcifn_enum.c b/usr/src/lib/fm/topo/modules/common/pcifn_enum.c deleted file mode 100644 index 30ae12c372..0000000000 --- a/usr/src/lib/fm/topo/modules/common/pcifn_enum.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <limits.h> -#include <fm/libtopo.h> -#include "did.h" -#include "did_props.h" -#include "pcifn_enum.h" - -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); -} - -static int -module_run(topo_mod_t *mp, tnode_t *parent, pfn_enum_t *ep) -{ - return (topo_mod_enumerate(mp, parent, - ep->pfne_modname, ep->pfne_childname, - ep->pfne_imin, ep->pfne_imax)); -} - -int -pcifn_enum(topo_mod_t *mp, tnode_t *parent) -{ - char *ccstr; - int rv = 0; - int i, e; - uint_t cc; - topo_mod_t *child_mod; - - topo_mod_dprintf(mp, "Enumerating beneath pci(ex) function.\n"); - - /* - * Extract the class code of the PCI function and make sure - * it matches the type that the module cares about. - */ - if (topo_prop_get_string(parent, - TOPO_PGROUP_PCI, TOPO_PROP_CLASS, &ccstr, &e) < 0) - return (0); - if (sscanf(ccstr, "%x", &cc) != 1) { - topo_mod_strfree(mp, ccstr); - return (0); - } - topo_mod_strfree(mp, ccstr); - cc = cc >> 16; - - for (i = 0; i < Pcifn_enumerator_count; i++) { - - if (cc != Pcifn_enumerators[i].pfne_class) - continue; - - child_mod = module_load(mp, parent, - Pcifn_enumerators[i].pfne_modname); - - if (child_mod) { - rv = module_run(mp, parent, - &Pcifn_enumerators[i]) != 0 ? -1 : 0; - topo_mod_unload(child_mod); - } - } - return (rv); -} diff --git a/usr/src/lib/fm/topo/modules/common/pcifn_enum.h b/usr/src/lib/fm/topo/modules/common/pcifn_enum.h deleted file mode 100644 index 26f5f60225..0000000000 --- a/usr/src/lib/fm/topo/modules/common/pcifn_enum.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _PCIFN_ENUM_H -#define _PCIFN_ENUM_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/pci.h> -#include <fm/topo_mod.h> - -#define PATH_TEMPLATE "%s/usr/platform/%s/lib/fm/topo/plugins/%s.so" - -/* - * When a pci or pci-express function is enumerated in the topology - * we'll attempt to load modules that can expand the topology - * beneath that function. This data structure helps us track which modules - * to attempt to load, whether or not the loading was successful - * so we don't waste time trying again, and if loading is successful, - * the module pointer returned by topo_mod_load(). - */ -typedef struct pfn_enum { - uint_t pfne_class; /* expected PCI class of the parent function */ - const char *pfne_modname; /* enumerator module name */ - const char *pfne_childname; /* name of nodes to enumerate */ - topo_instance_t pfne_imin; /* minimum instance number to enumerate */ - topo_instance_t pfne_imax; /* maximum instance number to enumerate */ -} pfn_enum_t; - -/* - * The current list of modules to potentially load and expand topology - * beneath pci(-express) functions. - */ -pfn_enum_t Pcifn_enumerators[] = { - { PCI_CLASS_MASS, "sata", "sata-port", 0, 7 }, - { PCI_CLASS_MASS, "scsi", "disk", 0, 15 } -}; - -int Pcifn_enumerator_count = sizeof (Pcifn_enumerators) / sizeof (pfn_enum_t); - -#endif /* _PCIFN_ENUM_H */ diff --git a/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c b/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c index b00d45c3fc..aa73958c9b 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c +++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip.c @@ -64,13 +64,28 @@ */ static int chip_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); static int mem_asru_compute(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); -const topo_modinfo_t chip_info = - { "chip", CHIP_VERSION, chip_enum, NULL}; +static const topo_modops_t chip_ops = + { chip_enum, NULL}; +static const topo_modinfo_t chip_info = + { "chip", FM_FMRI_SCHEME_HC, CHIP_VERSION, &chip_ops }; + +static const topo_pgroup_info_t cs_pgroup = + { CS_PGROUP, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; +static const topo_pgroup_info_t dimm_pgroup = + { DIMM_PGROUP, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; +static const topo_pgroup_info_t mc_pgroup = + { MCT_PGROUP, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; +static const topo_pgroup_info_t chip_pgroup = + { CHIP_PGROUP, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; +static const topo_pgroup_info_t rank_pgroup = + { RANK_PGROUP, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; +static const topo_pgroup_info_t chan_pgroup = + { CHAN_PGROUP, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; const topo_method_t rank_methods[] = { { TOPO_METH_ASRU_COMPUTE, TOPO_METH_ASRU_COMPUTE_DESC, @@ -79,18 +94,6 @@ const topo_method_t rank_methods[] = { { NULL } }; -static const struct debugopt { - const char *optname; - int optval; -} debugopts[] = { - { "err", TOPO_DBG_ERR }, - { "mod", TOPO_DBG_MOD }, - { "log", TOPO_DBG_LOG }, - { "walk", TOPO_DBG_WALK }, - { "tree", TOPO_DBG_TREE }, - { "all", TOPO_DBG_ALL } -}; - static nvlist_t *cs_fmri[MC_CHIP_NCS]; static void @@ -112,21 +115,10 @@ whinge(topo_mod_t *mod, int *nerr, const char *fmt, ...) int _topo_init(topo_mod_t *mod) { - const char *debugstr = getenv("TOPOCHPDBG"); chip_t *chip; - int i; - - if (debugstr != NULL) { - for (i = 0; i < sizeof (debugopts) / sizeof (struct debugopt); - i++) { - if (strncmp(debugstr, debugopts[i].optname, 4) == 0) { - topo_mod_clrdebug(mod); - topo_mod_setdebug(mod, debugopts[i].optval); - break; /* handle a single option only */ - } - } - } + if (getenv("TOPOCHIPDBG")) + topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing chip enumerator\n"); if ((chip = topo_mod_zalloc(mod, sizeof (chip_t))) == NULL) @@ -147,7 +139,7 @@ _topo_init(topo_mod_t *mod) return (topo_mod_seterrno(mod, EMOD_NOMEM)); } - if (topo_mod_register(mod, &chip_info, (void *)chip) != 0) { + if (topo_mod_register(mod, &chip_info, TOPO_VERSION) != 0) { whinge(mod, NULL, "failed to register hc: " "%s\n", topo_mod_errmsg(mod)); topo_mod_free(mod, chip->chip_cpustats, @@ -156,6 +148,7 @@ _topo_init(topo_mod_t *mod) topo_mod_free(mod, chip, sizeof (chip_t)); return (-1); /* mod errno set */ } + topo_mod_setspecific(mod, (void *)chip); return (0); } @@ -163,7 +156,7 @@ _topo_init(topo_mod_t *mod) void _topo_fini(topo_mod_t *mod) { - chip_t *chip = topo_mod_private(mod); + chip_t *chip = topo_mod_getspecific(mod); if (chip->chip_cpustats != NULL) topo_mod_free(mod, chip->chip_cpustats, @@ -185,7 +178,7 @@ chip_strprop(tnode_t *cnode, kstat_t *ksp, const char *name) return (0); (void) topo_prop_set_string(cnode, CHIP_PGROUP, name, - TOPO_PROP_SET_ONCE, k->value.str.addr.ptr, &err); + TOPO_PROP_IMMUTABLE, k->value.str.addr.ptr, &err); return (-1); } @@ -199,32 +192,18 @@ chip_longprop(tnode_t *cnode, kstat_t *ksp, const char *name) if ((k = kstat_data_lookup(ksp, (char *)name)) == NULL) return (0); - (void) topo_prop_set_int32(cnode, CHIP_PGROUP, name, TOPO_PROP_SET_ONCE, - k->value.l, &err); + (void) topo_prop_set_int32(cnode, CHIP_PGROUP, name, + TOPO_PROP_IMMUTABLE, k->value.l, &err); return (-1); } static int mkrsrc(topo_mod_t *mod, tnode_t *pnode, const char *name, int inst, - nvlist_t **nvl) + nvlist_t *auth, nvlist_t **nvl) { - nvlist_t *args = NULL, *pfmri = NULL; - topo_hdl_t *thp = topo_mod_handle(mod); - int err; - - if (topo_node_resource(pnode, &pfmri, &err) < 0 || - topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0 || - nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri) != 0) { - nvlist_free(pfmri); - nvlist_free(args); - return (-1); - } - - *nvl = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, inst, args, &err); - nvlist_free(pfmri); - nvlist_free(args); - + *nvl = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION, name, + inst, NULL, auth, NULL, NULL, NULL); return (nvl != NULL ? 0 : -1); /* caller must free nvlist */ } @@ -271,7 +250,7 @@ mem_fmri_create(topo_mod_t *mod) static int cpu_create(topo_mod_t *mod, tnode_t *pnode, const char *name, int chipid, - chip_t *chip) + chip_t *chip, nvlist_t *auth) { kstat_named_t *k; nvlist_t *fmri, *asru; @@ -320,13 +299,13 @@ cpu_create(topo_mod_t *mod, tnode_t *pnode, const char *name, int chipid, } clogid = k->value.l; - if (mkrsrc(mod, pnode, name, clogid, &fmri) != 0) { + if (mkrsrc(mod, pnode, name, clogid, auth, &fmri) != 0) { whinge(mod, &nerr, "cpu_create: mkrsrc failed\n"); continue; } - if ((cnode = topo_node_bind(mod, pnode, name, clogid, fmri, - NULL)) == NULL) { + if ((cnode = topo_node_bind(mod, pnode, name, clogid, fmri)) + == NULL) { whinge(mod, &nerr, "cpu_create: node bind failed\n"); nvlist_free(fmri); continue; @@ -358,7 +337,7 @@ nvprop_add(topo_mod_t *mod, nvpair_t *nvp, const char *pgname, tnode_t *node) if (nvpair_value_boolean_value(nvp, &val) == 0) { (void) topo_prop_set_string(node, pgname, pname, - TOPO_PROP_SET_ONCE, (val ? "true" : "false"), &err); + TOPO_PROP_IMMUTABLE, val ? "true" : "false", &err); } return (0); } @@ -368,7 +347,7 @@ nvprop_add(topo_mod_t *mod, nvpair_t *nvp, const char *pgname, tnode_t *node) if (nvpair_value_uint64(nvp, &val) == 0) { (void) topo_prop_set_uint64(node, pgname, pname, - TOPO_PROP_SET_ONCE, val, &err); + TOPO_PROP_IMMUTABLE, val, &err); } return (0); } @@ -378,7 +357,7 @@ nvprop_add(topo_mod_t *mod, nvpair_t *nvp, const char *pgname, tnode_t *node) if (nvpair_value_string(nvp, &str) == 0) (void) topo_prop_set_string(node, pgname, pname, - TOPO_PROP_SET_ONCE, str, &err); + TOPO_PROP_IMMUTABLE, str, &err); return (0); } @@ -391,7 +370,8 @@ nvprop_add(topo_mod_t *mod, nvpair_t *nvp, const char *pgname, tnode_t *node) } static int -dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name) +dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name, + nvlist_t *auth) { tnode_t *chnode; nvlist_t *fmri; @@ -419,14 +399,14 @@ dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name) return (-1); for (i = 0; i < nchan; i++) { - if (mkrsrc(mod, pnode, name, i, &fmri) != 0) { + if (mkrsrc(mod, pnode, name, i, auth, &fmri) != 0) { whinge(mod, &nerr, "dramchan_create: mkrsrc " "failed\n"); continue; } - if ((chnode = topo_node_bind(mod, pnode, name, i, fmri, - NULL)) == NULL) { + if ((chnode = topo_node_bind(mod, pnode, name, i, fmri)) + == NULL) { nvlist_free(fmri); whinge(mod, &nerr, "dramchan_create: node bind " "failed\n"); @@ -435,18 +415,18 @@ dramchan_create(topo_mod_t *mod, tnode_t *pnode, const char *name) nvlist_free(fmri); - (void) topo_pgroup_create(chnode, CHAN_PGROUP, - TOPO_STABILITY_PRIVATE, &err); + (void) topo_pgroup_create(chnode, &chan_pgroup, &err); (void) topo_prop_set_string(chnode, CHAN_PGROUP, "channel", - TOPO_PROP_SET_ONCE, i == 0 ? "A" : "B", &err); + TOPO_PROP_IMMUTABLE, i == 0 ? "A" : "B", &err); } return (nerr == 0 ? 0 : -1); } static int -cs_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc) +cs_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc, + nvlist_t *auth) { int i, err, nerr = 0; nvpair_t *nvp; @@ -471,13 +451,13 @@ cs_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc) continue; } - if (mkrsrc(mod, pnode, name, csnum, &fmri) != 0) { + if (mkrsrc(mod, pnode, name, csnum, auth, &fmri) != 0) { whinge(mod, &nerr, "cs_create: mkrsrc failed\n"); continue; } - if ((csnode = topo_node_bind(mod, pnode, name, csnum, fmri, - NULL)) == NULL) { + if ((csnode = topo_node_bind(mod, pnode, name, csnum, fmri)) + == NULL) { nvlist_free(fmri); whinge(mod, &nerr, "cs_create: node bind failed\n"); continue; @@ -487,8 +467,7 @@ cs_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc) (void) topo_node_asru_set(csnode, fmri, 0, &err); - (void) topo_pgroup_create(csnode, CS_PGROUP, - TOPO_STABILITY_PRIVATE, &err); + (void) topo_pgroup_create(csnode, &cs_pgroup, &err); for (nvp = nvlist_next_nvpair(csarr[i], NULL); nvp != NULL; nvp = nvlist_next_nvpair(csarr[i], nvp)) { @@ -552,7 +531,7 @@ mem_asru_compute(topo_mod_t *mod, tnode_t *node, topo_version_t version, } /* use 'in' to obtain resource path; could use node resource */ - if (topo_fmri_nvl2str(topo_mod_handle(mod), in, &unum, &err) < 0) + if (topo_mod_nvl2str(mod, in, &unum) < 0) return (topo_mod_seterrno(mod, err)); if ((asru = mem_fmri_create(mod)) == NULL) { @@ -577,7 +556,7 @@ mem_asru_compute(topo_mod_t *mod, tnode_t *node, topo_version_t version, } static int -rank_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *dimmnvl) +rank_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *dimmnvl, nvlist_t *auth) { uint64_t *csnumarr; char **csnamearr; @@ -617,13 +596,13 @@ rank_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *dimmnvl) } for (i = 0; i < ncs; i++) { - if (mkrsrc(mod, pnode, RANK_NODE_NAME, i, &fmri) < 0) { + if (mkrsrc(mod, pnode, RANK_NODE_NAME, i, auth, &fmri) < 0) { whinge(mod, &nerr, "rank_create: mkrsrc failed\n"); continue; } if ((ranknode = topo_node_bind(mod, pnode, RANK_NODE_NAME, i, - fmri, NULL)) == NULL) { + fmri)) == NULL) { nvlist_free(fmri); whinge(mod, &nerr, "rank_create: node bind " "failed\n"); @@ -647,17 +626,16 @@ rank_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *dimmnvl) whinge(mod, &nerr, "rank_create: " "topo_method_register failed"); - (void) topo_pgroup_create(ranknode, RANK_PGROUP, - TOPO_STABILITY_PRIVATE, &err); + (void) topo_pgroup_create(ranknode, &rank_pgroup, &err); (void) topo_prop_set_uint64(ranknode, RANK_PGROUP, "size", - TOPO_PROP_SET_ONCE, rsz, &err); + TOPO_PROP_IMMUTABLE, rsz, &err); (void) topo_prop_set_string(ranknode, RANK_PGROUP, "csname", - TOPO_PROP_SET_ONCE, csnamearr[i], &err); + TOPO_PROP_IMMUTABLE, csnamearr[i], &err); (void) topo_prop_set_uint64(ranknode, RANK_PGROUP, "csnum", - TOPO_PROP_SET_ONCE, csnumarr[i], &err); + TOPO_PROP_IMMUTABLE, csnumarr[i], &err); } nvlist_free(pfmri); @@ -666,7 +644,8 @@ rank_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *dimmnvl) } static int -dimm_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc) +dimm_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc, + nvlist_t *auth) { int i, err, nerr = 0; nvpair_t *nvp; @@ -695,13 +674,13 @@ dimm_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc) continue; } - if (mkrsrc(mod, pnode, name, num, &fmri) < 0) { + if (mkrsrc(mod, pnode, name, num, auth, &fmri) < 0) { whinge(mod, &nerr, "dimm_create: mkrsrc failed\n"); continue; } - if ((dimmnode = topo_node_bind(mod, pnode, name, num, fmri, - NULL)) == NULL) { + if ((dimmnode = topo_node_bind(mod, pnode, name, num, fmri)) + == NULL) { nvlist_free(fmri); whinge(mod, &nerr, "dimm_create: node bind " "failed\n"); @@ -729,8 +708,7 @@ dimm_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc) nvlist_free(fmri); - (void) topo_pgroup_create(dimmnode, DIMM_PGROUP, - TOPO_STABILITY_PRIVATE, &err); + (void) topo_pgroup_create(dimmnode, &dimm_pgroup, &err); for (nvp = nvlist_next_nvpair(dimmarr[i], NULL); nvp != NULL; nvp = nvlist_next_nvpair(dimmarr[i], nvp)) { @@ -743,7 +721,7 @@ dimm_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *mc) nerr += nvprop_add(mod, nvp, DIMM_PGROUP, dimmnode); } - nerr += rank_create(mod, dimmnode, dimmarr[i]); + nerr += rank_create(mod, dimmnode, dimmarr[i], auth); } return (nerr == 0 ? 0 : -1); @@ -811,7 +789,7 @@ mc_lookup_by_mcid(topo_mod_t *mod, topo_instance_t id) } static int -mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name) +mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_t *auth) { int err, rc = 0; tnode_t *mcnode; @@ -820,7 +798,7 @@ mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name) nvlist_t *mc = NULL; int i; - if (mkrsrc(mod, pnode, name, 0, &fmri) != 0) { + if (mkrsrc(mod, pnode, name, 0, auth, &fmri) != 0) { whinge(mod, NULL, "mc_create: mkrsrc failed\n"); return (-1); } @@ -836,7 +814,7 @@ mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name) */ if ((mc = mc_lookup_by_mcid(mod, topo_node_instance(pnode))) == NULL || (mcnode = topo_node_bind(mod, pnode, - name, 0, fmri, NULL)) == NULL) { + name, 0, fmri)) == NULL) { if (mc != NULL) nvlist_free(mc); topo_node_range_destroy(pnode, name); @@ -851,8 +829,7 @@ mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name) /* * Add memory controller properties */ - (void) topo_pgroup_create(mcnode, MCT_PGROUP, - TOPO_STABILITY_PRIVATE, &err); + (void) topo_pgroup_create(mcnode, &mc_pgroup, &err); for (nvp = nvlist_next_nvpair(mc, NULL); nvp != NULL; nvp = nvlist_next_nvpair(mc, nvp)) { @@ -869,9 +846,9 @@ mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name) } } - if (dramchan_create(mod, mcnode, CHAN_NODE_NAME) != 0 || - cs_create(mod, mcnode, CS_NODE_NAME, mc) != 0 || - dimm_create(mod, mcnode, DIMM_NODE_NAME, mc) != 0) + if (dramchan_create(mod, mcnode, CHAN_NODE_NAME, auth) != 0 || + cs_create(mod, mcnode, CS_NODE_NAME, mc, auth) != 0 || + dimm_create(mod, mcnode, DIMM_NODE_NAME, mc, auth) != 0) rc = -1; /* @@ -890,7 +867,7 @@ mc_create(topo_mod_t *mod, tnode_t *pnode, const char *name) static int chip_create(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t min, topo_instance_t max, chip_t *chip) + topo_instance_t min, topo_instance_t max, chip_t *chip, nvlist_t *auth) { int i, nerr = 0; kstat_t *ksp; @@ -935,13 +912,13 @@ chip_create(topo_mod_t *mod, tnode_t *pnode, const char *name, if (chipid < min || chipid > max) continue; - if (mkrsrc(mod, pnode, name, chipid, &fmri) != 0) { + if (mkrsrc(mod, pnode, name, chipid, auth, &fmri) != 0) { whinge(mod, &nerr, "chip_create: mkrsrc failed\n"); continue; } - if ((cnode = topo_node_bind(mod, pnode, name, chipid, fmri, - NULL)) == NULL) { + if ((cnode = topo_node_bind(mod, pnode, name, chipid, fmri)) + == NULL) { nvlist_free(fmri); whinge(mod, &nerr, "chip_create: node bind " "failed for chipid %d\n", chipid); @@ -953,15 +930,14 @@ chip_create(topo_mod_t *mod, tnode_t *pnode, const char *name, nvlist_free(fmri); - (void) topo_pgroup_create(cnode, CHIP_PGROUP, - TOPO_STABILITY_PRIVATE, &err); + (void) topo_pgroup_create(cnode, &chip_pgroup, &err); (void) chip_strprop(cnode, ksp, CHIP_VENDOR_ID); (void) chip_longprop(cnode, ksp, CHIP_FAMILY); (void) chip_longprop(cnode, ksp, CHIP_MODEL); (void) chip_longprop(cnode, ksp, CHIP_STEPPING); - if (cpu_create(mod, cnode, CPU_NODE_NAME, chipid, chip) != 0 || - mc_create(mod, cnode, MCT_NODE_NAME) != 0) + if (cpu_create(mod, cnode, CPU_NODE_NAME, chipid, chip, auth) + != 0 || mc_create(mod, cnode, MCT_NODE_NAME, auth) != 0) nerr++; /* have whinged elsewhere */ } @@ -975,14 +951,21 @@ chip_create(topo_mod_t *mod, tnode_t *pnode, const char *name, } } +/*ARGSUSED*/ static int chip_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t min, topo_instance_t max, void *arg) + topo_instance_t min, topo_instance_t max, void *arg, void *notused) { + int rv = 0; chip_t *chip = (chip_t *)arg; + nvlist_t *auth = NULL; + + auth = topo_mod_auth(mod, pnode); if (strcmp(name, "chip") == 0) - return (chip_create(mod, pnode, name, min, max, chip)); + rv = chip_create(mod, pnode, name, min, max, chip, auth); - return (0); + nvlist_free(auth); + + return (rv); } diff --git a/usr/src/lib/fm/topo/modules/i86pc/hostbridge/Makefile b/usr/src/lib/fm/topo/modules/i86pc/hostbridge/Makefile index c333b37290..bc863f51df 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/hostbridge/Makefile +++ b/usr/src/lib/fm/topo/modules/i86pc/hostbridge/Makefile @@ -27,9 +27,29 @@ MODULE = hostbridge ARCH = i86pc CLASS = arch -HBSRCS = hostbridge.c did.c did_hash.c did_props.c util.c -MODULESRCS = $(HBSRCS) hb_i86pc.c +UTILDIR = ../../common/pcibus +UTILSRCS = did.c did_hash.c did_props.c util.c +HBDIR = ../../common/hostbridge +HBSRCS = hostbridge.c hb_$(ARCH).c +MODULESRCS = $(HBSRCS) $(UTILSRCS) include ../../Makefile.plugin LDLIBS += -ldevinfo + +CPPFLAGS += -I$(UTILDIR) -I$(HBDIR) + +%.o: $(UTILDIR)/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + +%.o: $(HBDIR)/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + +%.ln: $(UTILDIR)/%.c + $(LINT.c) -c $< + +%.ln: $(HBDIR)/%.c + $(LINT.c) -c $< + diff --git a/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c b/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c index a0dea333b5..be47f7c98f 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c +++ b/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c @@ -27,58 +27,55 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <fm/topo_mod.h> +#include <fm/topo_hc.h> #include <libdevinfo.h> #include <strings.h> -#include "pcibus.h" -#include "hostbridge.h" -#include "did.h" -#include "util.h" +#include <pcibus.h> +#include <hostbridge.h> +#include <did.h> +#include <util.h> static int -hb_process(tnode_t *ptn, topo_instance_t hbi, di_node_t bn, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +hb_process(topo_mod_t *mod, tnode_t *ptn, topo_instance_t hbi, di_node_t bn) { tnode_t *hb; + did_t *hbdid; - if (did_create(didhash, bn, 0, hbi, NO_RC, TRUST_BDF, promtree) == NULL) + if ((hbdid = did_create(mod, bn, 0, hbi, NO_RC, TRUST_BDF)) == NULL) return (-1); - if ((hb = pcihostbridge_declare(ptn, bn, hbi, didhash, - promtree, mod)) == NULL) + if ((hb = pcihostbridge_declare(mod, ptn, bn, hbi)) == NULL) return (-1); - return (topo_mod_enumerate(mod, hb, PCI_BUS, PCI_BUS, 0, - MAX_HB_BUSES)); + return (topo_mod_enumerate(mod, + hb, PCI_BUS, PCI_BUS, 0, MAX_HB_BUSES, (void *)hbdid)); } static int -rc_process(tnode_t *ptn, topo_instance_t hbi, di_node_t bn, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +rc_process(topo_mod_t *mod, tnode_t *ptn, topo_instance_t hbi, di_node_t bn) { tnode_t *hb; tnode_t *rc; + did_t *hbdid; - if (did_create(didhash, bn, 0, hbi, hbi, TRUST_BDF, promtree) == NULL) + if ((hbdid = did_create(mod, bn, 0, hbi, hbi, TRUST_BDF)) == NULL) return (-1); - if ((hb = pciexhostbridge_declare(ptn, bn, hbi, didhash, promtree, mod)) - == NULL) + if ((hb = pciexhostbridge_declare(mod, ptn, bn, hbi)) == NULL) return (-1); - if ((rc = pciexrc_declare(hb, bn, hbi, didhash, promtree, mod)) == NULL) + if ((rc = pciexrc_declare(mod, hb, bn, hbi)) == NULL) return (-1); return (topo_mod_enumerate(mod, - rc, PCI_BUS, PCIEX_BUS, 0, MAX_HB_BUSES)); + rc, PCI_BUS, PCIEX_BUS, 0, MAX_HB_BUSES, (void *)hbdid)); } int -pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +pci_hostbridges_find(topo_mod_t *mod, tnode_t *ptn) { di_node_t devtree; - di_node_t pnode; - di_node_t cnode; + di_node_t pnode, cnode; int hbcnt = 0; /* Scan for buses, top-level devinfo nodes with the right driver */ - devtree = di_init("/", DINFOCPYALL); + devtree = topo_mod_devinfo(mod); if (devtree == DI_NODE_NIL) { topo_mod_dprintf(mod, "devinfo init failed."); topo_node_range_destroy(ptn, HOSTBRIDGE); @@ -87,9 +84,8 @@ pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, pnode = di_drv_first_node(PCI, devtree); while (pnode != DI_NODE_NIL) { - if (hb_process(ptn, hbcnt++, pnode, didhash, promtree, mod) + if (hb_process(mod, ptn, hbcnt++, pnode) < 0) { - di_fini(devtree); topo_node_range_destroy(ptn, HOSTBRIDGE); return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); } @@ -103,9 +99,7 @@ pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, if (di_driver_name(cnode) == NULL) continue; if (strcmp(di_driver_name(cnode), PCI_PCI) == 0) { - if (hb_process(ptn, hbcnt++, cnode, didhash, - promtree, mod) < 0) { - di_fini(devtree); + if (hb_process(mod, ptn, hbcnt++, cnode) < 0) { topo_node_range_destroy(ptn, HOSTBRIDGE); return (topo_mod_seterrno(mod, @@ -113,9 +107,7 @@ pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, } } if (strcmp(di_driver_name(cnode), PCIE_PCI) == 0) { - if (rc_process(ptn, hbcnt++, cnode, didhash, - promtree, mod) < 0) { - di_fini(devtree); + if (rc_process(mod, ptn, hbcnt++, cnode) < 0) { topo_node_range_destroy(ptn, HOSTBRIDGE); return (topo_mod_seterrno(mod, @@ -125,22 +117,20 @@ pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, } pnode = di_drv_next_node(pnode); } - di_fini(devtree); return (0); } /*ARGSUSED*/ int -platform_hb_enum(tnode_t *parent, const char *name, - topo_instance_t imin, topo_instance_t imax, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +platform_hb_enum(topo_mod_t *mod, tnode_t *parent, const char *name, + topo_instance_t imin, topo_instance_t imax) { - return (pci_hostbridges_find(parent, didhash, promtree, mod)); + return (pci_hostbridges_find(mod, parent)); } /*ARGSUSED*/ int -platform_hb_label(tnode_t *node, nvlist_t *in, nvlist_t **out, topo_mod_t *mod) +platform_hb_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in, nvlist_t **out) { return (labelmethod_inherit(mod, node, in, out)); } diff --git a/usr/src/lib/fm/topo/modules/i86pc/pcibus/Makefile b/usr/src/lib/fm/topo/modules/i86pc/pcibus/Makefile index ab2b444854..977e9df692 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/pcibus/Makefile +++ b/usr/src/lib/fm/topo/modules/i86pc/pcibus/Makefile @@ -29,16 +29,15 @@ MODULE = pcibus ARCH = i86pc CLASS = arch -PCISRCS = did.c \ - did_hash.c \ - did_props.c \ - pcibus.c \ - pcibus_labels.c \ - pcifn_enum.c \ - util.c +UTILDIR = ../../common/pcibus +HBDIR = ../../common/hostbridge +UTILSRCS = did.c did_hash.c did_props.c util.c +PCISRCS = pcibus.c pcibus_labels.c -MODULESRCS = $(PCISRCS) pci_i86pc.c +MODULESRCS = $(UTILSRCS) $(PCISRCS) pci_i86pc.c include ../../Makefile.plugin LDLIBS += -ldevinfo + +CPPFLAGS += -I$(UTILDIR) -I$(HBDIR) diff --git a/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c b/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c index abb7250fc5..2ee2c79fe8 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c +++ b/usr/src/lib/fm/topo/modules/i86pc/pcibus/pci_i86pc.c @@ -36,7 +36,8 @@ physlot_names_t *Physlot_Names = NULL; missing_names_t *Missing_Names = NULL; int -platform_pci_label(tnode_t *node, nvlist_t *in, nvlist_t **out, topo_mod_t *mod) +platform_pci_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in, + nvlist_t **out) { - return (pci_label_cmn(node, in, out, mod)); + return (pci_label_cmn(mod, node, in, out)); } diff --git a/usr/src/lib/fm/topo/modules/i86pc/sata/sata.c b/usr/src/lib/fm/topo/modules/i86pc/sata/sata.c index 890626736b..5a3ea47846 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/sata/sata.c +++ b/usr/src/lib/fm/topo/modules/i86pc/sata/sata.c @@ -55,8 +55,6 @@ #include <sys/dkio.h> #include <pthread.h> -#include "did_impl.h" -#include "did_props.h" #include "sata.h" #include "sfx4500_props.h" @@ -69,17 +67,27 @@ struct sata_machine_specific_properties *machprops[] = { &SFX4500_machprops, NULL }; +static const topo_pgroup_info_t io_pgroup = + { TOPO_PGROUP_IO, TOPO_STABILITY_PRIVATE, TOPO_STABILITY_PRIVATE, 1 }; + +static const topo_pgroup_info_t storage_pgroup = { + TOPO_STORAGE_PGROUP, + TOPO_STABILITY_PRIVATE, + TOPO_STABILITY_PRIVATE, + 1 +}; + int _topo_init(topo_mod_t *mod); void _topo_fini(topo_mod_t *mod); static char *devpath_from_asru(topo_mod_t *mp, tnode_t *pnode, int *dpathlen); static tnode_t *node_create(topo_mod_t *mod, tnode_t *pnode, const char *name, int instance, boolean_t add_fru, nvlist_t *fru, nvlist_t *asru, - char *label, int *err); + char *label, cfga_list_data_t *, int *err); static char *trimdup(const char *s, int *slen, topo_mod_t *mod); static boolean_t get_machine_name(char **name, int *namelen, topo_mod_t *mod); -static int make_legacyhc_fmri(topo_hdl_t *thp, const char *str, - nvlist_t **fmri, int *err); +static int make_legacyhc_fmri(topo_mod_t *mod, const char *str, + nvlist_t **fmri); static int sata_minorname_to_ap(char *minorname, char **ap, int *apbuflen, cfga_list_data_t **list_array, topo_mod_t *mod); static sata_dev_prop_t *lookup_sdp_by_minor(char *minorpath); @@ -101,7 +109,7 @@ static int sata_disks_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *pasru, static int sata_port_create(topo_mod_t *mod, tnode_t *pnode, const char *name, topo_instance_t min, topo_instance_t max); static int sata_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t min, topo_instance_t max, void *arg); + topo_instance_t min, topo_instance_t max, void *notused1, void *notused2); static int sata_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); static void sata_release(topo_mod_t *mod, tnode_t *nodep); @@ -115,7 +123,7 @@ static void sata_release(topo_mod_t *mod, tnode_t *nodep); * a presence method, and in those cases, the correct default is to * assert presence). */ -const topo_method_t SATA_METHODS[] = { +static const topo_method_t SATA_METHODS[] = { { TOPO_METH_PRESENT, TOPO_METH_PRESENT_DESC, TOPO_METH_PRESENT_VERSION, TOPO_STABILITY_INTERNAL, sata_present }, { NULL } @@ -138,8 +146,11 @@ static sata_dev_prop_t *sata_dev_props = NULL; static const char *pgroupname = NULL; -const topo_modinfo_t sata_info = - { "sata", SATA_VERSION, sata_enum, sata_release }; +static const topo_modops_t sata_ops = + { sata_enum, sata_release }; + +static const topo_modinfo_t sata_info = + { "sata", FM_FMRI_SCHEME_HC, SATA_VERSION, &sata_ops }; static void @@ -209,23 +220,38 @@ devpath_from_asru(topo_mod_t *mp, tnode_t *pnode, int *dpathlen) */ static tnode_t * node_create(topo_mod_t *mod, tnode_t *pnode, const char *name, int instance, - boolean_t add_fru, nvlist_t *fru, nvlist_t *asru, char *label, int *err) + boolean_t add_fru, nvlist_t *fru, nvlist_t *asru, char *label, + cfga_list_data_t *cfgap, int *err) { - nvlist_t *pfmri = NULL, *fmri = NULL, *args = NULL; + int len = 0; + nvlist_t *fmri = NULL; + nvlist_t *auth = NULL; tnode_t *cnode = NULL; - topo_hdl_t *thp; + char *mm = NULL, *model = NULL, *manuf = NULL, *serial = NULL; + char *firm = NULL; + int manuf_len, model_len, serial_len, firm_len; - thp = topo_mod_handle(mod); + if (cfgap != NULL) { + char *s; + + sata_info_to_fru(cfgap->ap_info, &model, &model_len, &manuf, + &manuf_len, &serial, &serial_len, &firm, &firm_len, mod); + if ((s = strchr(model, ' ')) != NULL) + *s = '-'; + len = manuf_len + model_len + 1; + if ((mm = topo_mod_alloc(mod, len)) != NULL) + (void) snprintf(mm, len, "%s-%s", manuf, model); + else + mm = model; + } - if (topo_node_resource(pnode, &pfmri, err) == 0 && - topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) == 0 && - nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri) == 0 && - (fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, name, instance, - args, err)) != NULL && - (cnode = topo_node_bind(mod, pnode, name, instance, fmri, - NULL)) != NULL) { + auth = topo_mod_auth(mod, pnode); + if ((fmri = topo_mod_hcfmri(mod, pnode, FM_HC_SCHEME_VERSION, name, + instance, NULL, auth, mm, serial, firm)) + != NULL && (cnode = topo_node_bind(mod, pnode, name, instance, + fmri)) != NULL) { - /* Set the FRU to the node's FMRI if called didn't specify it */ + /* Set the FRU to the node's FMRI if caller didn't specify it */ if (add_fru) (void) topo_node_fru_set(cnode, fru ? fru : fmri, 0, err); @@ -237,12 +263,20 @@ node_create(topo_mod_t *mod, tnode_t *pnode, const char *name, int instance, (void) topo_node_label_set(cnode, label, err); } - if (pfmri) - nvlist_free(pfmri); + if (len != 0) + topo_mod_free(mod, mm, len); + if (model) + topo_mod_free(mod, model, model_len); + if (manuf) + topo_mod_free(mod, manuf, manuf_len); + if (serial) + topo_mod_free(mod, serial, serial_len); + if (firm) + topo_mod_free(mod, firm, firm_len); if (fmri) nvlist_free(fmri); - if (args) - nvlist_free(args); + if (auth) + nvlist_free(auth); return (cnode); } @@ -294,7 +328,8 @@ _topo_init(topo_mod_t *mod) int mnamelen; char *mname; - topo_mod_setdebug(mod, TOPO_DBG_ALL); + if (getenv("SATADBG")) + topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing sata enumerator\n"); (void) pthread_mutex_lock(&global_data_mutex); @@ -323,7 +358,7 @@ _topo_init(topo_mod_t *mod) } (void) pthread_mutex_unlock(&global_data_mutex); - if (topo_mod_register(mod, &sata_info, NULL) != 0) { + if (topo_mod_register(mod, &sata_info, TOPO_VERSION) != 0) { topo_mod_dprintf(mod, "failed to register sata module: " "%s\n", topo_mod_errmsg(mod)); return (-1); /* mod errno set */ @@ -338,13 +373,13 @@ _topo_fini(topo_mod_t *mod) } static int -make_legacyhc_fmri(topo_hdl_t *thp, const char *str, nvlist_t **fmri, int *err) +make_legacyhc_fmri(topo_mod_t *mod, const char *str, nvlist_t **fmri) { char buf[PATH_MAX]; (void) snprintf(buf, PATH_MAX, "hc:///component=%s", str); - return (topo_fmri_str2nvl(thp, buf, fmri, err)); + return (topo_mod_str2nvl(mod, buf, fmri)); } @@ -490,7 +525,14 @@ sata_present(topo_mod_t *mod, tnode_t *nodep, topo_version_t vers, } } - return (present); + if (topo_mod_nvalloc(mod, out_nvl, NV_UNIQUE_NAME) != 0) + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); + if (nvlist_add_uint32(*out_nvl, TOPO_METH_PRESENT_RET, present) != 0) { + nvlist_free(*out_nvl); + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); + } + + return (0); } /* @@ -627,6 +669,7 @@ sata_maximum_port(char *dpath, topo_mod_t *mod) dentlen = pathconf(devpath, _PC_NAME_MAX); dentlen = ((dentlen <= 0) ? MAXNAMELEN : dentlen) + sizeof (struct dirent); + dentlen = sizeof (struct dirent) + pathconf(devpath, _PC_NAME_MAX); dent = topo_mod_alloc(mod, dentlen); /* @@ -663,26 +706,29 @@ sata_add_port_props(tnode_t *cnode, sata_dev_prop_t *sdp, int *err) int i; #define MAX_PNAME_LEN 128 char pname[MAX_PNAME_LEN]; + topo_pgroup_info_t pgroup; /* * Save the attachment point physical path */ - (void) topo_pgroup_create(cnode, TOPO_PGROUP_IO, - TOPO_STABILITY_PRIVATE, err); + (void) topo_pgroup_create(cnode, &io_pgroup, err); (void) topo_prop_set_string(cnode, TOPO_PGROUP_IO, - TOPO_IO_AP_PATH, TOPO_PROP_SET_ONCE, + TOPO_IO_AP_PATH, TOPO_PROP_IMMUTABLE, sdp->ap_node, err); /* * The private properties are the core of the configuration * mechanism for the sfx4500-disk Diagnosis Engine. */ - (void) topo_pgroup_create(cnode, pgroupname, - TOPO_STABILITY_PRIVATE, err); + pgroup.tpi_name = pgroupname; + pgroup.tpi_namestab = TOPO_STABILITY_PRIVATE; + pgroup.tpi_datastab = TOPO_STABILITY_PRIVATE; + pgroup.tpi_version = 1; + (void) topo_pgroup_create(cnode, &pgroup, err); for (i = 0; sdp->properties[i].name != NULL; i++) { (void) topo_prop_set_string(cnode, pgroupname, - sdp->properties[i].name, TOPO_PROP_SET_ONCE, + sdp->properties[i].name, TOPO_PROP_IMMUTABLE, (char *)sdp->properties[i].value, err); } @@ -696,13 +742,13 @@ sata_add_port_props(tnode_t *cnode, sata_dev_prop_t *sdp, int *err) (void) snprintf(pname, MAX_PNAME_LEN, SATA_IND_NAME "-%d", i); (void) topo_prop_set_string(cnode, pgroupname, pname, - TOPO_PROP_SET_ONCE, (char *)sdp->indicators[i].indicator, + TOPO_PROP_IMMUTABLE, (char *)sdp->indicators[i].indicator, err); (void) snprintf(pname, MAX_PNAME_LEN, SATA_IND_ACTION "-%d", i); (void) topo_prop_set_string(cnode, pgroupname, pname, - TOPO_PROP_SET_ONCE, (char *)sdp->indicators[i].action, + TOPO_PROP_IMMUTABLE, (char *)sdp->indicators[i].action, err); } @@ -711,13 +757,13 @@ sata_add_port_props(tnode_t *cnode, sata_dev_prop_t *sdp, int *err) (void) snprintf(pname, MAX_PNAME_LEN, SATA_INDRULE_STATES "-%d", i); (void) topo_prop_set_string(cnode, pgroupname, pname, - TOPO_PROP_SET_ONCE, (char *)ruleset[i].states, + TOPO_PROP_IMMUTABLE, (char *)ruleset[i].states, err); (void) snprintf(pname, MAX_PNAME_LEN, SATA_INDRULE_ACTIONS "-%d", i); (void) topo_prop_set_string(cnode, pgroupname, pname, - TOPO_PROP_SET_ONCE, (char *)ruleset[i].actions, + TOPO_PROP_IMMUTABLE, (char *)ruleset[i].actions, err); } } @@ -813,18 +859,16 @@ sata_add_disk_props(tnode_t *cnode, int portnum, cfga_list_data_t *cfgap, if (find_physical_disk_node(physpath, PATH_MAX, portnum, mod)) { - (void) topo_pgroup_create(cnode, TOPO_PGROUP_IO, - TOPO_STABILITY_PRIVATE, err); + (void) topo_pgroup_create(cnode, &io_pgroup, err); (void) topo_prop_set_string(cnode, TOPO_PGROUP_IO, - TOPO_IO_DEV_PATH, TOPO_PROP_SET_ONCE, + TOPO_IO_DEV_PATH, TOPO_PROP_IMMUTABLE, physpath + 8 /* strlen("/devices") */, err); physpath_found = B_TRUE; } - (void) topo_pgroup_create(cnode, TOPO_STORAGE_PGROUP, - TOPO_STABILITY_PRIVATE, err); + (void) topo_pgroup_create(cnode, &storage_pgroup, err); if ((ldev = strstr(cfgap->ap_log_id, "::")) != NULL) { ldev += 2 /* strlen("::") */; @@ -832,7 +876,7 @@ sata_add_disk_props(tnode_t *cnode, int portnum, cfga_list_data_t *cfgap, ldev = p + 1; } (void) topo_prop_set_string(cnode, TOPO_STORAGE_PGROUP, - TOPO_STORAGE_LOGICAL_DISK_NAME, TOPO_PROP_SET_ONCE, + TOPO_STORAGE_LOGICAL_DISK_NAME, TOPO_PROP_IMMUTABLE, ldev, err); } @@ -840,22 +884,22 @@ sata_add_disk_props(tnode_t *cnode, int portnum, cfga_list_data_t *cfgap, &serial, &serial_len, &firm, &firm_len, mod); if (model) { (void) topo_prop_set_string(cnode, TOPO_STORAGE_PGROUP, - TOPO_STORAGE_MODEL, TOPO_PROP_SET_ONCE, model, err); + TOPO_STORAGE_MODEL, TOPO_PROP_IMMUTABLE, model, err); topo_mod_free(mod, model, model_len); } if (manuf) { (void) topo_prop_set_string(cnode, TOPO_STORAGE_PGROUP, - TOPO_STORAGE_MANUFACTURER, TOPO_PROP_SET_ONCE, manuf, err); + TOPO_STORAGE_MANUFACTURER, TOPO_PROP_IMMUTABLE, manuf, err); topo_mod_free(mod, manuf, manuf_len); } if (serial) { (void) topo_prop_set_string(cnode, TOPO_STORAGE_PGROUP, - TOPO_STORAGE_SERIAL_NUM, TOPO_PROP_SET_ONCE, serial, err); + TOPO_STORAGE_SERIAL_NUM, TOPO_PROP_IMMUTABLE, serial, err); topo_mod_free(mod, serial, serial_len); } if (firm) { (void) topo_prop_set_string(cnode, TOPO_STORAGE_PGROUP, - TOPO_STORAGE_FIRMWARE_REV, TOPO_PROP_SET_ONCE, firm, err); + TOPO_STORAGE_FIRMWARE_REV, TOPO_PROP_IMMUTABLE, firm, err); topo_mod_free(mod, firm, firm_len); } @@ -885,7 +929,7 @@ sata_add_disk_props(tnode_t *cnode, int portnum, cfga_list_data_t *cfgap, (void) snprintf(capstr, sizeof (capstr), "%llu", capacity); (void) topo_prop_set_string(cnode, TOPO_STORAGE_PGROUP, - TOPO_STORAGE_CAPACITY, TOPO_PROP_SET_ONCE, capstr, + TOPO_STORAGE_CAPACITY, TOPO_PROP_IMMUTABLE, capstr, err); } } @@ -918,13 +962,10 @@ sata_disks_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *pasru, int ndisks, int *err) { tnode_t *cnode; - topo_hdl_t *thp; sata_dev_prop_t *sdp; nvlist_t *fru = NULL; int i, nerrs = 0; - thp = topo_mod_handle(mod); - if (topo_node_range_create(mod, pnode, name, 0, ndisks - 1) < 0) { topo_mod_dprintf(mod, "Unable to create " SATA_DISK " range [%d..%d]: %s\n", @@ -942,12 +983,12 @@ sata_disks_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *pasru, if ((sdp = lookup_sdp_by_minor(cfglist[i].ap_phys_id)) != NULL) { - if (make_legacyhc_fmri(thp, sdp->label, &fru, - err) != 0) { + if (make_legacyhc_fmri(mod, sdp->label, &fru) + != 0) { topo_mod_dprintf(mod, "Error creating " "FRU while creating " SATA_DISK " nodes: %s\n", - topo_strerror(*err)); + topo_mod_errmsg(mod)); } } @@ -962,7 +1003,7 @@ sata_disks_create(topo_mod_t *mod, tnode_t *pnode, nvlist_t *pasru, */ if ((cnode = node_create(mod, pnode, name, i, B_TRUE, fru, pasru, sdp ? (char *)sdp->label : NULL, - err)) != NULL) { + &cfglist[i], err)) != NULL) { sata_add_disk_props(cnode, portnum, &cfglist[i], err, mod); @@ -998,13 +1039,10 @@ sata_port_create(topo_mod_t *mod, tnode_t *pnode, const char *name, char *dpath; char *ap = NULL; char minorname[PATH_MAX]; - topo_hdl_t *thp; int apbuflen; int dpathlen; cfga_list_data_t *cfglist = NULL; - thp = topo_mod_handle(mod); - if (min < 0) min = 0; @@ -1028,16 +1066,8 @@ sata_port_create(topo_mod_t *mod, tnode_t *pnode, const char *name, return (-1); } - if (topo_node_range_create(mod, pnode, name, 0, max) < 0) { - topo_mod_dprintf(mod, "Unable to create " - SATA_PORT " range [%d..%d]: %s\n", - min, max, topo_mod_errmsg(mod)); - topo_mod_free(mod, dpath, dpathlen); - return (-1); - } - /* Create the FRU - a legacy component FMRI */ - if (make_legacyhc_fmri(thp, "MB", &fru, &err) != 0) { + if (make_legacyhc_fmri(mod, "motherboard", &fru) != 0) { topo_mod_dprintf(mod, "Unable to create legacy FRU FMRI for " "node " SATA_PORT ": %s\n", topo_strerror(err)); @@ -1059,7 +1089,7 @@ sata_port_create(topo_mod_t *mod, tnode_t *pnode, const char *name, } /* Create the ASRU - a legacy component FMRI */ - if (make_legacyhc_fmri(thp, ap, &asru, &err) != 0) { + if (make_legacyhc_fmri(mod, ap, &asru) != 0) { free(cfglist); topo_mod_free(mod, ap, apbuflen); topo_mod_dprintf(mod, "failed to make ASRU FMRI: " @@ -1075,7 +1105,7 @@ sata_port_create(topo_mod_t *mod, tnode_t *pnode, const char *name, * component being "MB". */ if ((cnode = node_create(mod, pnode, name, i, B_TRUE, fru, - asru, ap, &err)) == NULL) { + asru, ap, NULL, &err)) == NULL) { nvlist_free(asru); free(cfglist); topo_mod_free(mod, ap, apbuflen); @@ -1127,7 +1157,7 @@ sata_port_create(topo_mod_t *mod, tnode_t *pnode, const char *name, /*ARGSUSED*/ static int sata_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, - topo_instance_t min, topo_instance_t max, void *arg) + topo_instance_t min, topo_instance_t max, void *notused1, void *notused2) { if (strcmp(name, SATA_PORT) == 0) return (sata_port_create(mod, pnode, name, min, max)); diff --git a/usr/src/lib/fm/topo/modules/i86pc/sata/sata.h b/usr/src/lib/fm/topo/modules/i86pc/sata/sata.h index e19d70f96a..d44b9d4e63 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/sata/sata.h +++ b/usr/src/lib/fm/topo/modules/i86pc/sata/sata.h @@ -33,12 +33,13 @@ extern "C" { #endif +#include <fm/libtopo.h> + /* Topo plugin version */ #define SATA_VERSION 1 /* The names of the two nodes the plugin creates: */ -#define SATA_DISK "disk" -#define SATA_PORT "sata-port" +#define SATA_DISK DISK /* from topo_hc.h */ #define TOPO_STORAGE_PGROUP "storage" @@ -50,10 +51,6 @@ extern "C" { #define TOPO_STORAGE_FIRMWARE_REV "disk-firmware-revision" #define TOPO_STORAGE_CAPACITY "disk-capacity-in-bytes" -/* Properties added to the "io" pgroup: */ -#define TOPO_IO_DEV_PATH "dev-path" -#define TOPO_IO_AP_PATH "ap-path" - /* Properties added to the machine-specific properties pgroup */ #define SATA_IND_NAME "indicator-name" #define SATA_IND_ACTION "indicator-action" diff --git a/usr/src/lib/fm/topo/modules/sun4/chip/chip.c b/usr/src/lib/fm/topo/modules/sun4/chip/chip.c index 85d09da2a4..e743a9bca6 100644 --- a/usr/src/lib/fm/topo/modules/sun4/chip/chip.c +++ b/usr/src/lib/fm/topo/modules/sun4/chip/chip.c @@ -65,17 +65,20 @@ typedef struct chip { } chip_t; static int chip_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); -const topo_modinfo_t chip_info = - { "chip", CHIP_VERSION, chip_enum, NULL}; +static const topo_modops_t chip_ops = + { chip_enum, NULL}; +static const topo_modinfo_t chip_info = + { "chip", FM_FMRI_SCHEME_HC, CHIP_VERSION, &chip_ops }; int _topo_init(topo_mod_t *mod) { chip_t *chip; - topo_mod_setdebug(mod, TOPO_DBG_ALL); + if (getenv("TOPOCHIPDBG")) + topo_mod_setdebug(mod); topo_mod_dprintf(mod, "initializing chip enumerator\n"); if ((chip = topo_mod_zalloc(mod, sizeof (chip_t))) == NULL) @@ -96,7 +99,7 @@ _topo_init(topo_mod_t *mod) return (-1); } - if (topo_mod_register(mod, &chip_info, (void *)chip) != 0) { + if (topo_mod_register(mod, &chip_info, TOPO_VERSION) != 0) { topo_mod_dprintf(mod, "failed to register hc: " "%s\n", topo_mod_errmsg(mod)); topo_mod_free(mod, chip->chip_cpustats, @@ -105,6 +108,7 @@ _topo_init(topo_mod_t *mod) topo_mod_free(mod, chip, sizeof (chip_t)); return (-1); } + topo_mod_setspecific(mod, (void *)chip); return (0); } @@ -114,7 +118,7 @@ _topo_fini(topo_mod_t *mod) { chip_t *chip; - chip = topo_mod_private(mod); + chip = topo_mod_getspecific(mod); if (chip->chip_cpustats != NULL) topo_mod_free(mod, chip->chip_cpustats, @@ -177,9 +181,8 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, char *s, sbuf[21]; tnode_t *cnode; kstat_named_t *ks, *kf; - nvlist_t *pfmri, *fmri, *asru; - nvlist_t *args = NULL; - topo_hdl_t *thp; + nvlist_t *fmri, *asru; + nvlist_t *auth = topo_mod_auth(mod, rnode); /* * Override what was created for us @@ -189,7 +192,6 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, < 0) return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); - thp = topo_mod_handle(mod); for (i = 0; i <= chip->chip_ncpustats; i++) { if ((chip_id = cpu_kstat_init(chip, i)) < 0) @@ -203,29 +205,10 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, s = NULL; } - pfmri = NULL; - if (topo_node_resource(rnode, &pfmri, &err) < 0 || - topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0) { - nvlist_free(pfmri); - ++nerr; - continue; - } - err = nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri); - if (err != 0 || - (s != NULL && - nvlist_add_string(args, TOPO_METH_FMRI_ARG_SER, s) != 0)) { - nvlist_free(pfmri); - nvlist_free(args); - ++nerr; - continue; - } - nvlist_free(pfmri); - - fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, - name, (topo_instance_t)chip_id, args, &err); - nvlist_free(args); + fmri = topo_mod_hcfmri(mod, rnode, FM_HC_SCHEME_VERSION, name, + (topo_instance_t)chip_id, NULL, auth, NULL, NULL, s); if (fmri == NULL || (cnode = topo_node_bind(mod, - rnode, name, i, fmri, NULL)) == NULL) { + rnode, name, i, fmri)) == NULL) { ++nerr; nvlist_free(fmri); continue; @@ -252,29 +235,38 @@ cpu_create(topo_mod_t *mod, tnode_t *rnode, const char *name, != NULL && strcmp(KSTAT_NAMED_STR_PTR(kf), "hc:///component=") != 0) { nvlist_t *fru; + char *lp; - if (topo_fmri_str2nvl(thp, KSTAT_NAMED_STR_PTR(kf), - &fru, &err) == 0) { + if (topo_mod_str2nvl(mod, KSTAT_NAMED_STR_PTR(kf), + &fru) == 0) { (void) topo_node_fru_set(cnode, fru, 0, &err); nvlist_free(fru); } - (void) topo_node_label_set(cnode, - KSTAT_NAMED_STR_PTR(kf), &err); + if ((lp = strchr(KSTAT_NAMED_STR_PTR(kf), '=')) + == NULL) { + (void) topo_node_label_set(cnode, NULL, &err); + } else { + ++lp; + (void) topo_node_label_set(cnode, lp, &err); + } } else { (void) topo_node_label_set(cnode, NULL, &err); } } + nvlist_free(auth); + if (nerr != 0) return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); else return (0); } +/*ARGSUSED*/ static int chip_enum(topo_mod_t *mod, tnode_t *rnode, const char *name, - topo_instance_t min, topo_instance_t max, void *arg) + topo_instance_t min, topo_instance_t max, void *arg, void *notused) { chip_t *chip = (chip_t *)arg; diff --git a/usr/src/lib/fm/topo/modules/sun4/hostbridge/Makefile.hb b/usr/src/lib/fm/topo/modules/sun4/hostbridge/Makefile.hb index ccd5d4ec9a..4ed69097d6 100644 --- a/usr/src/lib/fm/topo/modules/sun4/hostbridge/Makefile.hb +++ b/usr/src/lib/fm/topo/modules/sun4/hostbridge/Makefile.hb @@ -28,17 +28,26 @@ MODULE = hostbridge CLASS = arch SUN4DIR = ../../sun4/$(MODULE) +UTILDIR = ../../common/pcibus +HBDIR = ../../common/hostbridge HBSRCS = hostbridge.c hb_sun4.c did.c did_hash.c did_props.c util.c MODULESRCS = $(HBSRCS) hb_$(ARCH).c include ../../Makefile.plugin LDLIBS += -ldevinfo -CPPFLAGS += -I$(SUN4DIR) +CPPFLAGS += -I$(SUN4DIR) -I$(UTILDIR) -I$(HBDIR) %.o: $(SUN4DIR)/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) +%.o: $(UTILDIR)/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) + %.ln: $(SUN4DIR)/%.c $(LINT.c) -c $< + +%.ln: $(UTILDIR)/%.c + $(LINT.c) -c $< diff --git a/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.c b/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.c index 0f8e26b505..de32982786 100644 --- a/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.c +++ b/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.c @@ -32,15 +32,14 @@ #include <sys/param.h> #include <sys/systeminfo.h> -#include "hb_sun4.h" -#include "util.h" -#include "topo_error.h" -#include "hostbridge.h" -#include "pcibus.h" -#include "did.h" +#include <hb_sun4.h> +#include <util.h> +#include <hostbridge.h> +#include <pcibus.h> +#include <did.h> busorrc_t * -busorrc_new(const char *bus_addr, di_node_t di, topo_mod_t *mod) +busorrc_new(topo_mod_t *mod, const char *bus_addr, di_node_t di) { busorrc_t *pp; char *comma; @@ -83,7 +82,7 @@ busorrc_new(const char *bus_addr, di_node_t di, topo_mod_t *mod) } void -busorrc_insert(busorrc_t **head, busorrc_t *new, topo_mod_t *mod) +busorrc_insert(topo_mod_t *mod, busorrc_t **head, busorrc_t *new) { busorrc_t *ppci, *pci; @@ -122,7 +121,7 @@ busorrc_insert(busorrc_t **head, busorrc_t *new, topo_mod_t *mod) } int -busorrc_add(busorrc_t **list, di_node_t n, topo_mod_t *mod) +busorrc_add(topo_mod_t *mod, busorrc_t **list, di_node_t n) { busorrc_t *nb; char *ba; @@ -130,49 +129,45 @@ busorrc_add(busorrc_t **list, di_node_t n, topo_mod_t *mod) topo_mod_dprintf(mod, "busorrc_add\n"); ba = di_bus_addr(n); if (ba == NULL || - (nb = busorrc_new(ba, n, mod)) == NULL) { + (nb = busorrc_new(mod, ba, n)) == NULL) { topo_mod_dprintf(mod, "busorrc_new() failed.\n"); return (-1); } - busorrc_insert(list, nb, mod); + busorrc_insert(mod, list, nb); return (0); } void -busorrc_free(busorrc_t *pb, topo_mod_t *mod) +busorrc_free(topo_mod_t *mod, busorrc_t *pb) { if (pb == NULL) return; - busorrc_free(pb->br_nextbus, mod); + busorrc_free(mod, pb->br_nextbus); topo_mod_free(mod, pb, sizeof (busorrc_t)); } tnode_t * -hb_process(tnode_t *ptn, topo_instance_t hbi, topo_instance_t bi, - di_node_t bn, did_hash_t *didhash, di_prom_handle_t promtree, - topo_mod_t *mod) +hb_process(topo_mod_t *mod, tnode_t *ptn, topo_instance_t hbi, + topo_instance_t bi, di_node_t bn, did_t *hbdid) { tnode_t *hb; - if ((hb = pcihostbridge_declare(ptn, bn, hbi, didhash, - promtree, mod)) == NULL) + if ((hb = pcihostbridge_declare(mod, ptn, bn, hbi)) == NULL) return (NULL); - if (topo_mod_enumerate(mod, hb, PCI_BUS, PCI_BUS, bi, bi) == 0) + if (topo_mod_enumerate(mod, hb, PCI_BUS, PCI_BUS, bi, bi, hbdid) == 0) return (hb); return (NULL); } tnode_t * -rc_process(tnode_t *ptn, topo_instance_t rci, di_node_t bn, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +rc_process(topo_mod_t *mod, tnode_t *ptn, topo_instance_t rci, di_node_t bn) { tnode_t *rc; - if ((rc = pciexrc_declare(ptn, bn, rci, didhash, promtree, mod)) - == NULL) + if ((rc = pciexrc_declare(mod, ptn, bn, rci)) == NULL) return (NULL); if (topo_mod_enumerate(mod, - rc, PCI_BUS, PCIEX_BUS, 0, MAX_HB_BUSES) == 0) + rc, PCI_BUS, PCIEX_BUS, 0, MAX_HB_BUSES, NULL) == 0) return (rc); return (NULL); } @@ -199,8 +194,8 @@ rc_process(tnode_t *ptn, topo_instance_t rci, di_node_t bn, * (Hostbridge #nhb, Root Complex #(rcs/hostbridge), ExBus #(buses/rc)) */ int -declare_exbuses(busorrc_t *list, tnode_t *ptn, int nhb, int nrc, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +declare_exbuses(topo_mod_t *mod, busorrc_t *list, tnode_t *ptn, int nhb, + int nrc) { tnode_t **rcs; tnode_t **hb; @@ -211,37 +206,36 @@ declare_exbuses(busorrc_t *list, tnode_t *ptn, int nhb, int nrc, * Allocate an array to point at the hostbridge tnode_t pointers. */ if ((hb = topo_mod_zalloc(mod, nhb * sizeof (tnode_t *))) == NULL) - return (topo_mod_seterrno(mod, ETOPO_NOMEM)); + return (topo_mod_seterrno(mod, EMOD_NOMEM)); /* * Allocate an array to point at the root complex tnode_t pointers. */ if ((rcs = topo_mod_zalloc(mod, nrc * sizeof (tnode_t *))) == NULL) - return (topo_mod_seterrno(mod, ETOPO_NOMEM)); + return (topo_mod_seterrno(mod, EMOD_NOMEM)); br = rc = 0; for (p = list; p != NULL; p = p->br_nextbus) { topo_mod_dprintf(mod, "declaring (%x,%x)\n", p->br_ba_bc, p->br_ba_ac); - if (did_create(didhash, p->br_din, 0, br, rc, rc, - promtree) == NULL) + if (did_create(mod, p->br_din, 0, br, rc, rc) == NULL) return (-1); if (hb[br] == NULL) { - hb[br] = pciexhostbridge_declare(ptn, p->br_din, br, - didhash, promtree, mod); + hb[br] = pciexhostbridge_declare(mod, ptn, p->br_din, + br); if (hb[br] == NULL) return (-1); } if (rcs[rc] == NULL) { - rcs[rc] = rc_process(hb[br], rc, p->br_din, didhash, - promtree, mod); + rcs[rc] = rc_process(mod, hb[br], rc, p->br_din); if (rcs[rc] == NULL) return (-1); } else { if (topo_mod_enumerate(mod, - rcs[rc], PCI_BUS, PCIEX_BUS, 0, MAX_HB_BUSES) < 0) + rcs[rc], PCI_BUS, PCIEX_BUS, 0, MAX_HB_BUSES, + NULL) < 0) return (-1); } rc++; @@ -271,8 +265,7 @@ declare_exbuses(busorrc_t *list, tnode_t *ptn, int nhb, int nrc, * (Hostbridge #nhb, Bus #(buses/hostbridge)) */ int -declare_buses(busorrc_t *list, tnode_t *ptn, int nhb, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +declare_buses(topo_mod_t *mod, busorrc_t *list, tnode_t *ptn, int nhb) { busorrc_t *p; tnode_t **hb; @@ -290,19 +283,18 @@ declare_buses(busorrc_t *list, tnode_t *ptn, int nhb, did_hash_t *didhash, topo_mod_dprintf(mod, "declaring (%x,%x)\n", p->br_ba_bc, p->br_ba_ac); - if ((link = did_create(didhash, p->br_din, 0, br, NO_RC, bus, - promtree)) == NULL) + if ((link = + did_create(mod, p->br_din, 0, br, NO_RC, bus)) == NULL) return (-1); if (hb[br] == NULL) { - hb[br] = hb_process(ptn, br, bus, p->br_din, didhash, - promtree, mod); + hb[br] = hb_process(mod, ptn, br, bus, p->br_din, link); if (hb[br] == NULL) return (-1); } else { - did_link_set(hb[br], link); + did_link_set(mod, hb[br], link); if (topo_mod_enumerate(mod, - hb[br], PCI_BUS, PCI_BUS, bus, bus) < 0) { + hb[br], PCI_BUS, PCI_BUS, bus, bus, link) < 0) { return (-1); } } diff --git a/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.h b/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.h index 586a18e41c..22b85efe37 100644 --- a/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.h +++ b/usr/src/lib/fm/topo/modules/sun4/hostbridge/hb_sun4.h @@ -47,20 +47,14 @@ typedef struct busorrc { struct did_hash; -extern busorrc_t *busorrc_new(const char *, di_node_t, topo_mod_t *); -extern void busorrc_insert(busorrc_t **, busorrc_t *, topo_mod_t *); -extern int busorrc_add(busorrc_t **, di_node_t, topo_mod_t *); -extern void busorrc_free(busorrc_t *, topo_mod_t *); - -extern tnode_t *hb_process(tnode_t *, - topo_instance_t, topo_instance_t, di_node_t, struct did_hash *, - di_prom_handle_t, topo_mod_t *); -extern tnode_t *rc_process(tnode_t *, topo_instance_t, di_node_t, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern int declare_buses(busorrc_t *, tnode_t *, int, - struct did_hash *, di_prom_handle_t, topo_mod_t *); -extern int declare_exbuses(busorrc_t *, tnode_t *, int, int, - struct did_hash *, di_prom_handle_t, topo_mod_t *); +extern busorrc_t *busorrc_new(topo_mod_t *, const char *, di_node_t); +extern void busorrc_insert(topo_mod_t *, busorrc_t **, busorrc_t *); +extern int busorrc_add(topo_mod_t *, busorrc_t **, di_node_t); +extern void busorrc_free(topo_mod_t *, busorrc_t *); + +extern tnode_t *rc_process(topo_mod_t *, tnode_t *, topo_instance_t, di_node_t); +extern int declare_buses(topo_mod_t *, busorrc_t *, tnode_t *, int); +extern int declare_exbuses(topo_mod_t *, busorrc_t *, tnode_t *, int, int); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/sun4/ioboard/Makefile.iob b/usr/src/lib/fm/topo/modules/sun4/ioboard/Makefile.iob index 834883ac1a..68a6bfeef5 100644 --- a/usr/src/lib/fm/topo/modules/sun4/ioboard/Makefile.iob +++ b/usr/src/lib/fm/topo/modules/sun4/ioboard/Makefile.iob @@ -27,17 +27,27 @@ MODULE = ioboard SUN4DIR = ../../sun4/$(MODULE) -IOBSRCS = ioboard.c did.c did_hash.c did_props.c util.c -MODULESRCS = $(IOBSRCS) iob_platform.c +UTILDIR = ../../common/pcibus +UTILSRCS = did.c did_hash.c did_props.c util.c +HBDIR = ../../common/hostbridge +IOBSRCS = ioboard.c +MODULESRCS = $(UTILSRCS) $(IOBSRCS) iob_platform.c include ../../Makefile.plugin LDLIBS += -ldevinfo -CPPFLAGS += -I$(SUN4DIR) +CPPFLAGS += -I$(UTILDIR) -I$(HBDIR) -I$(SUN4DIR) + +%.o: $(UTILDIR)/%.c + $(COMPILE.c) -o $@ $< + $(CTFCONVERT_O) %.o: $(SUN4DIR)/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) +%.ln: $(UTILDIR)/%.c + $(LINT.c) -c $< + %.ln: $(SUN4DIR)/%.c $(LINT.c) -c $< diff --git a/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.c b/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.c index 98eecaffba..e351cb1773 100644 --- a/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.c +++ b/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.c @@ -29,42 +29,42 @@ #include <string.h> #include <sys/fm/protocol.h> #include <fm/topo_mod.h> +#include <fm/topo_hc.h> #include <libdevinfo.h> #include <limits.h> #include <sys/param.h> #include <sys/systeminfo.h> -#include "hostbridge.h" -#include "ioboard.h" -#include "did.h" -#include "did_props.h" -#include "util.h" +#include <hostbridge.h> +#include <ioboard.h> +#include <did.h> +#include <did_props.h> +#include <util.h> /* * ioboard.c * Generic code shared by all the ioboard enumerators */ + static void iob_release(topo_mod_t *, tnode_t *); -static int iob_contains(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); -static int iob_present(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, - nvlist_t **); static int iob_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, - topo_instance_t, void *); + topo_instance_t, void *, void *); static int iob_label(topo_mod_t *, tnode_t *, topo_version_t, nvlist_t *, nvlist_t **); +extern int platform_iob_enum(topo_mod_t *, tnode_t *, topo_instance_t, + topo_instance_t); +extern int platform_iob_label(topo_mod_t *, tnode_t *, nvlist_t *, nvlist_t **); + extern txprop_t IOB_common_props[]; extern int IOB_propcnt; -const topo_modinfo_t Iob_info = - { IOBOARD, IOB_ENUMR_VERS, iob_enum, iob_release }; +static const topo_modops_t Iob_ops = + { iob_enum, iob_release }; +static const topo_modinfo_t Iob_info = + { IOBOARD, FM_FMRI_SCHEME_HC, IOB_ENUMR_VERS, &Iob_ops }; -const topo_method_t Iob_methods[] = { - { "iob_contains", "ioboard element contains other element", - IOB_ENUMR_VERS, TOPO_STABILITY_INTERNAL, iob_contains }, - { "iob_present", "ioboard element currently present", - IOB_ENUMR_VERS, TOPO_STABILITY_INTERNAL, iob_present }, +static const topo_method_t Iob_methods[] = { { TOPO_METH_LABEL, TOPO_METH_LABEL_DESC, TOPO_METH_LABEL_VERSION, TOPO_STABILITY_INTERNAL, iob_label }, { NULL } @@ -77,96 +77,50 @@ _topo_init(topo_mod_t *modhdl) * Turn on module debugging output */ if (getenv("TOPOIOBDBG") != NULL) - topo_mod_setdebug(modhdl, TOPO_DBG_ALL); + topo_mod_setdebug(modhdl); topo_mod_dprintf(modhdl, "initializing ioboard enumerator\n"); - topo_mod_register(modhdl, &Iob_info, NULL); + topo_mod_register(modhdl, &Iob_info, TOPO_VERSION); + + did_hash_init(modhdl); topo_mod_dprintf(modhdl, "Ioboard enumr initd\n"); } void _topo_fini(topo_mod_t *modhdl) { + did_hash_fini(modhdl); topo_mod_unregister(modhdl); } -/*ARGSUSED*/ -static int -iob_contains(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (0); -} - -/*ARGSUSED*/ -static int -iob_present(topo_mod_t *mp, tnode_t *node, topo_version_t version, - nvlist_t *in, nvlist_t **out) -{ - return (0); -} - static int iob_label(topo_mod_t *mp, tnode_t *node, topo_version_t version, nvlist_t *in, nvlist_t **out) { if (version > TOPO_METH_LABEL_VERSION) return (topo_mod_seterrno(mp, EMOD_VER_NEW)); - return (platform_iob_label(node, in, out, mp)); + return (platform_iob_label(mp, node, in, out)); } static topo_mod_t * -hb_enumr_load(topo_mod_t *mp, tnode_t *parent) +hb_enumr_load(topo_mod_t *mp) { 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) { + if ((rp = topo_mod_load(mp, HOSTBRIDGE, HB_ENUMR_VERS)) == 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); - } + "%s enumerator could not load %s.\n", IOBOARD, HOSTBRIDGE); } - topo_mod_strfree(mp, plat); - topo_mod_strfree(mp, mach); - topo_mod_free(mp, hbpath, PATH_MAX); return (rp); } /*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_instance_t imax, void *notused1, void *notused2) { topo_mod_t *hbmod; int rv; - did_hash_t *didhash; - di_prom_handle_t promtree; if (strcmp(name, IOBOARD) != 0) { topo_mod_dprintf(mp, @@ -174,33 +128,18 @@ iob_enum(topo_mod_t *mp, tnode_t *pn, const char *name, topo_instance_t imin, 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); + if ((hbmod = hb_enumr_load(mp)) == NULL) { 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); - } + did_hash_init(mp); - rv = platform_iob_enum(pn, imin, imax, didhash, promtree, mp); + rv = platform_iob_enum(mp, pn, imin, imax); - did_hash_fini(didhash); - di_prom_fini(promtree); + did_hash_fini(mp); topo_mod_unload(hbmod); if (rv < 0) @@ -223,41 +162,22 @@ iob_release(topo_mod_t *mp, tnode_t *node) } static tnode_t * -iob_tnode_create(tnode_t *parent, - const char *name, topo_instance_t i, void *priv, topo_mod_t *mod) +iob_tnode_create(topo_mod_t *mod, tnode_t *parent, + const char *name, topo_instance_t i, void *priv) { - topo_hdl_t *thp; - nvlist_t *args, *fmri, *pfmri; + nvlist_t *fmri; tnode_t *ntn; - int err; - - thp = topo_mod_handle(mod); + nvlist_t *auth = topo_mod_auth(mod, parent); - 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); + 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.\n", name); return (NULL); } - ntn = topo_node_bind(mod, parent, name, i, fmri, priv); + 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", @@ -268,6 +188,8 @@ iob_tnode_create(tnode_t *parent, return (NULL); } nvlist_free(fmri); + topo_node_setspecific(ntn, priv); + 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))); @@ -278,15 +200,13 @@ iob_tnode_create(tnode_t *parent, } tnode_t * -ioboard_declare(tnode_t *parent, topo_instance_t i, void *priv, - di_prom_handle_t promtree, topo_mod_t *mod) +ioboard_declare(topo_mod_t *mod, tnode_t *parent, topo_instance_t i, void *priv) { tnode_t *ntn; - if ((ntn = iob_tnode_create(parent, IOBOARD, i, priv, mod)) == NULL) + if ((ntn = iob_tnode_create(mod, parent, IOBOARD, i, priv)) == NULL) return (NULL); - if (did_props_set(ntn, priv, IOB_common_props, IOB_propcnt, - promtree) < 0) { + if (did_props_set(ntn, priv, IOB_common_props, IOB_propcnt) < 0) { topo_node_unbind(ntn); return (NULL); } @@ -301,9 +221,8 @@ ioboard_declare(tnode_t *parent, topo_instance_t i, void *priv, } did_t * -split_bus_address(did_hash_t *dhash, di_node_t dp, uint_t baseaddr, - uint_t bussep, int minbrd, int maxbrd, int *brd, int *br, int *bus, - di_prom_handle_t promtree, topo_mod_t *mod) +split_bus_address(topo_mod_t *mod, di_node_t dp, uint_t baseaddr, + uint_t bussep, int minbrd, int maxbrd, int *brd, int *br, int *bus) { uint_t bc, ac; char *comma; @@ -350,5 +269,5 @@ split_bus_address(did_hash_t *dhash, di_node_t dp, uint_t baseaddr, *brd, *br, *bus, bc, ac); return (NULL); } - return (did_create(dhash, dp, *brd, *br, NO_RC, *bus, promtree)); + return (did_create(mod, dp, *brd, *br, NO_RC, *bus)); } diff --git a/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.h b/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.h index 494366da5e..6bd3058da5 100644 --- a/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.h +++ b/usr/src/lib/fm/topo/modules/sun4/ioboard/ioboard.h @@ -38,8 +38,6 @@ extern "C" { #define IOB_ENUMR_VERS 1 -#define IOBOARD "ioboard" - /* * For all machines that currently use this enumerator, buses have one * of the following addresses. @@ -47,19 +45,19 @@ extern "C" { #define IOB_BUSADDR1 0x600000 #define IOB_BUSADDR2 0x700000 -extern tnode_t *ioboard_declare(tnode_t *, topo_instance_t, void *, - di_prom_handle_t, topo_mod_t *); +extern tnode_t *ioboard_declare(topo_mod_t *, tnode_t *, topo_instance_t, + void *); -extern int platform_iob_enum(tnode_t *, topo_instance_t, topo_instance_t, - did_hash_t *, di_prom_handle_t, topo_mod_t *); -extern int platform_iob_label(tnode_t *, nvlist_t *, nvlist_t **, topo_mod_t *); +extern int platform_iob_enum(topo_mod_t *, tnode_t *, topo_instance_t, + topo_instance_t); +extern int platform_iob_label(topo_mod_t *, tnode_t *, nvlist_t *, nvlist_t **); /* * This routine works for splitting up the string we get from * di_bus_addr() for all machines that currently use this enumerator. */ -extern did_t *split_bus_address(did_hash_t *, di_node_t, uint_t, uint_t, - int, int, int *, int *, int *, di_prom_handle_t, topo_mod_t *); +extern did_t *split_bus_address(topo_mod_t *, di_node_t, uint_t, uint_t, + int, int, int *, int *, int *); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/sun4u/hostbridge/hb_sun4u.c b/usr/src/lib/fm/topo/modules/sun4u/hostbridge/hb_sun4u.c index 5123119096..58c251f9d5 100644 --- a/usr/src/lib/fm/topo/modules/sun4u/hostbridge/hb_sun4u.c +++ b/usr/src/lib/fm/topo/modules/sun4u/hostbridge/hb_sun4u.c @@ -26,14 +26,15 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#include "hb_sun4.h" -#include "hostbridge.h" -#include "pcibus.h" -#include "util.h" -#include "did.h" +#include <fm/topo_hc.h> + +#include <hb_sun4.h> +#include <hostbridge.h> +#include <pcibus.h> +#include <util.h> int -count_busorrc(busorrc_t *list, int *hbc, int *bph, topo_mod_t *mod) +count_busorrc(topo_mod_t *mod, busorrc_t *list, int *hbc, int *bph) { ulong_t start; busorrc_t *p; @@ -68,8 +69,7 @@ count_busorrc(busorrc_t *list, int *hbc, int *bph, topo_mod_t *mod) } static int -busorrc_process(busorrc_t *list, int isrc, tnode_t *ptn, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) +busorrc_process(topo_mod_t *mod, busorrc_t *list, int isrc, tnode_t *ptn) { int hbc, busper; @@ -104,18 +104,16 @@ busorrc_process(busorrc_t *list, int isrc, tnode_t *ptn, * values of X2 maintains the correct associations of * buses/root complexes and bridges. */ - if (count_busorrc(list, &hbc, &busper, mod) < 0) + if (count_busorrc(mod, list, &hbc, &busper) < 0) return (-1); if (isrc == 1) - return (declare_exbuses(list, ptn, hbc, busper, didhash, - promtree, mod)); + return (declare_exbuses(mod, list, ptn, hbc, busper)); else - return (declare_buses(list, ptn, hbc, didhash, promtree, mod)); + return (declare_buses(mod, list, ptn, hbc)); } static int -pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +pci_hostbridges_find(topo_mod_t *mod, tnode_t *ptn) { busorrc_t *buses = NULL; busorrc_t *rcs = NULL; @@ -123,7 +121,7 @@ pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, di_node_t pnode; /* Scan for buses, top-level devinfo nodes with the right driver */ - devtree = di_init("/", DINFOCPYALL); + devtree = topo_mod_devinfo(mod); if (devtree == DI_NODE_NIL) { topo_mod_dprintf(mod, "devinfo init failed."); topo_node_range_destroy(ptn, HOSTBRIDGE); @@ -132,60 +130,54 @@ pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, pnode = di_drv_first_node(PCI, devtree); while (pnode != DI_NODE_NIL) { - if (busorrc_add(&buses, pnode, mod) < 0) { - di_fini(devtree); + if (busorrc_add(mod, &buses, pnode) < 0) { return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); } pnode = di_drv_next_node(pnode); } pnode = di_drv_first_node(PSYCHO, devtree); while (pnode != DI_NODE_NIL) { - if (busorrc_add(&buses, pnode, mod) < 0) { - di_fini(devtree); + if (busorrc_add(mod, &buses, pnode) < 0) { return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); } pnode = di_drv_next_node(pnode); } pnode = di_drv_first_node(SCHIZO, devtree); while (pnode != DI_NODE_NIL) { - if (busorrc_add(&buses, pnode, mod) < 0) { - di_fini(devtree); + if (busorrc_add(mod, &buses, pnode) < 0) { return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); } pnode = di_drv_next_node(pnode); } pnode = di_drv_first_node(PX, devtree); while (pnode != DI_NODE_NIL) { - if (busorrc_add(&rcs, pnode, mod) < 0) { - di_fini(devtree); + if (busorrc_add(mod, &rcs, pnode) < 0) { return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); } pnode = di_drv_next_node(pnode); } - if (busorrc_process(buses, 0, ptn, didhash, promtree, mod) < 0) + if (busorrc_process(mod, buses, 0, ptn) < 0) return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); - if (busorrc_process(rcs, 1, ptn, didhash, promtree, mod) < 0) + if (busorrc_process(mod, rcs, 1, ptn) < 0) return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); - busorrc_free(buses, mod); - busorrc_free(rcs, mod); - di_fini(devtree); + busorrc_free(mod, buses); + busorrc_free(mod, rcs); return (0); } /*ARGSUSED*/ int -platform_hb_enum(tnode_t *parent, const char *name, - topo_instance_t imin, topo_instance_t imax, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +platform_hb_enum(topo_mod_t *mod, tnode_t *parent, const char *name, + topo_instance_t imin, topo_instance_t imax) { - return (pci_hostbridges_find(parent, didhash, promtree, mod)); + return (pci_hostbridges_find(mod, parent)); } /*ARGSUSED*/ int -platform_hb_label(tnode_t *node, nvlist_t *in, nvlist_t **out, topo_mod_t *mod) +platform_hb_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in, nvlist_t **out) { return (labelmethod_inherit(mod, node, in, out)); } diff --git a/usr/src/lib/fm/topo/modules/sun4u/pcibus/Makefile b/usr/src/lib/fm/topo/modules/sun4u/pcibus/Makefile index a74b383143..092feef21f 100644 --- a/usr/src/lib/fm/topo/modules/sun4u/pcibus/Makefile +++ b/usr/src/lib/fm/topo/modules/sun4u/pcibus/Makefile @@ -29,16 +29,15 @@ MODULE = pcibus ARCH = sun4u CLASS = arch -PCISRCS = did.c \ - did_hash.c \ - did_props.c \ - pcibus.c \ - pcibus_labels.c \ - pcifn_enum.c \ - util.c +UTILDIR = ../../common/pcibus +HBDIR = ../../common/hostbridge +UTILSRCS = did.c did_hash.c did_props.c util.c +PCISRCS = pcibus.c pcibus_labels.c -MODULESRCS = $(PCISRCS) pci_sun4u.c +MODULESRCS = $(UTILSRCS) $(PCISRCS) pci_sun4u.c include ../../Makefile.plugin LDLIBS += -ldevinfo + +CPPFLAGS += -I$(UTILDIR) -I$(HBDIR) diff --git a/usr/src/lib/fm/topo/modules/sun4u/pcibus/pci_sun4u.c b/usr/src/lib/fm/topo/modules/sun4u/pcibus/pci_sun4u.c index c83b14e7c4..052af61b51 100644 --- a/usr/src/lib/fm/topo/modules/sun4u/pcibus/pci_sun4u.c +++ b/usr/src/lib/fm/topo/modules/sun4u/pcibus/pci_sun4u.c @@ -37,7 +37,8 @@ #include "pci_sun4u.h" int -platform_pci_label(tnode_t *node, nvlist_t *in, nvlist_t **out, topo_mod_t *mod) +platform_pci_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in, + nvlist_t **out) { - return (pci_label_cmn(node, in, out, mod)); + return (pci_label_cmn(mod, node, in, out)); } diff --git a/usr/src/lib/fm/topo/modules/sun4v/Makefile b/usr/src/lib/fm/topo/modules/sun4v/Makefile index 0bef6cde3c..7b5c6b10dc 100644 --- a/usr/src/lib/fm/topo/modules/sun4v/Makefile +++ b/usr/src/lib/fm/topo/modules/sun4v/Makefile @@ -25,6 +25,6 @@ # # ident "%Z%%M% %I% %E% SMI" -SUBDIRS = chip hostbridge ioboard pcibus +SUBDIRS = chip hostbridge pcibus include ../../../Makefile.subdirs diff --git a/usr/src/lib/fm/topo/modules/sun4v/hostbridge/hb_sun4v.c b/usr/src/lib/fm/topo/modules/sun4v/hostbridge/hb_sun4v.c index a830a4fae3..4daf1f6e73 100644 --- a/usr/src/lib/fm/topo/modules/sun4v/hostbridge/hb_sun4v.c +++ b/usr/src/lib/fm/topo/modules/sun4v/hostbridge/hb_sun4v.c @@ -26,15 +26,15 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#include "hb_sun4.h" -#include "hostbridge.h" -#include "pcibus.h" -#include "util.h" -#include "did.h" +#include <fm/topo_hc.h> + +#include <hb_sun4.h> +#include <hostbridge.h> +#include <pcibus.h> +#include <util.h> static int -rcs_process(busorrc_t *list, tnode_t *ptn, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +rcs_process(topo_mod_t *mod, busorrc_t *list, tnode_t *ptn) { busorrc_t *p; int nrc = 0; @@ -53,19 +53,18 @@ rcs_process(busorrc_t *list, tnode_t *ptn, did_hash_t *didhash, nrc++; topo_mod_dprintf(mod, "root complex count: %d\n", nrc); - return (declare_exbuses(list, ptn, 1, nrc, didhash, promtree, mod)); + return (declare_exbuses(mod, list, ptn, 1, nrc)); } static int -pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +pci_hostbridges_find(topo_mod_t *mod, tnode_t *ptn) { busorrc_t *rcs = NULL; di_node_t devtree; di_node_t pnode; /* Scan for buses, top-level devinfo nodes with the right driver */ - devtree = di_init("/", DINFOCPYALL); + devtree = topo_mod_devinfo(mod); if (devtree == DI_NODE_NIL) { topo_mod_dprintf(mod, "devinfo init failed."); topo_node_range_destroy(ptn, HOSTBRIDGE); @@ -73,30 +72,27 @@ pci_hostbridges_find(tnode_t *ptn, did_hash_t *didhash, } pnode = di_drv_first_node(PX, devtree); while (pnode != DI_NODE_NIL) { - if (busorrc_add(&rcs, pnode, mod) < 0) { - di_fini(devtree); + if (busorrc_add(mod, &rcs, pnode) < 0) { return (-1); } pnode = di_drv_next_node(pnode); } - rcs_process(rcs, ptn, didhash, promtree, mod); - busorrc_free(rcs, mod); - di_fini(devtree); + rcs_process(mod, rcs, ptn); + busorrc_free(mod, rcs); return (0); } /*ARGSUSED*/ int -platform_hb_enum(tnode_t *parent, const char *name, - topo_instance_t imin, topo_instance_t imax, did_hash_t *didhash, - di_prom_handle_t promtree, topo_mod_t *mod) +platform_hb_enum(topo_mod_t *mod, tnode_t *parent, const char *name, + topo_instance_t imin, topo_instance_t imax) { - return (pci_hostbridges_find(parent, didhash, promtree, mod)); + return (pci_hostbridges_find(mod, parent)); } /*ARGSUSED*/ int -platform_hb_label(tnode_t *node, nvlist_t *in, nvlist_t **out, topo_mod_t *mod) +platform_hb_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in, nvlist_t **out) { return (labelmethod_inherit(mod, node, in, out)); } diff --git a/usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile b/usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile deleted file mode 100644 index ff974924f7..0000000000 --- a/usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" - -CLASS = arch -ARCH = sun4v - -include ../../sun4/ioboard/Makefile.iob diff --git a/usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c b/usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c deleted file mode 100644 index a3796223a6..0000000000 --- a/usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * SUNW,Sun-Fire platform ioboard topology enumerator - */ - -#include <string.h> -#include <libdevinfo.h> -#include <fm/topo_mod.h> -#include <sys/fm/protocol.h> - -#include <ioboard.h> -#include <hostbridge.h> -#include <util.h> - -#define IOBOARD "ioboard" -#define LABEL "IOBD" -#define IOBDFRU "hc:///component="LABEL -#define ERIE "SUNW,Sun-Fire-T1000" -#define ERIE2 "SUNW,SPARC-Enterprise-T1000" -#define HB_MAX 1 - -/*ARGSUSED*/ -int -platform_iob_label(tnode_t *node, nvlist_t *ignored, nvlist_t **out, - topo_mod_t *mod) -{ - return (0); -} - -static tnode_t * -iob_node_create(tnode_t *parent, topo_mod_t *mod) -{ - int err; - tnode_t *ion; - nvlist_t *fmri, *args = NULL, *pfmri = NULL; - topo_hdl_t *thp = topo_mod_handle(mod); - - (void) topo_node_resource(parent, &pfmri, &err); - if (pfmri != NULL) { - if (topo_mod_nvalloc(mod, &args, NV_UNIQUE_NAME) != 0 || - nvlist_add_nvlist(args, TOPO_METH_FMRI_ARG_PARENT, pfmri) - != 0) { - nvlist_free(pfmri); - nvlist_free(args); - (void) topo_mod_seterrno(mod, EMOD_FMRI_NVL); - return (NULL); - } - nvlist_free(pfmri); - } - - if ((fmri = topo_fmri_create(thp, FM_FMRI_SCHEME_HC, IOBOARD, 0, args, - &err)) == NULL) { - topo_mod_dprintf(mod, "creation of tnode for ioboard=0 " - "failed: %s\n", topo_strerror(err)); - (void) topo_mod_seterrno(mod, err); - nvlist_free(args); - return (NULL); - } - nvlist_free(args); - ion = topo_node_bind(mod, parent, IOBOARD, 0, fmri, NULL); - if (ion == NULL) { - nvlist_free(fmri); - topo_mod_dprintf(mod, "unable to bind ioboard=0: %s", - topo_strerror(topo_mod_errno(mod))); - return (NULL); /* mod_errno already set */ - } - nvlist_free(fmri); - - if (topo_fmri_str2nvl(thp, IOBDFRU, &fmri, &err) == 0) { - (void) topo_node_fru_set(ion, fmri, 0, &err); - nvlist_free(fmri); - } - (void) topo_node_label_set(ion, "IOBD", &err); - - return (ion); -} - -/*ARGSUSED*/ -int -platform_iob_enum(tnode_t *parent, topo_instance_t imin, topo_instance_t imax, - did_hash_t *didhash, di_prom_handle_t promtree, topo_mod_t *mod) -{ - int err; - tnode_t *ion; - char *plat; - - if (topo_prop_get_string(parent, - TOPO_PGROUP_SYSTEM, TOPO_PROP_PLATFORM, &plat, &err) < 0) { - return (topo_mod_seterrno(mod, err)); - } - - /* - * The SUNW,SunFireT1000 (Erie) platform links in the SUNW,SunFireT200 - * (Ontario) top-level /usr/platform/SUNW,SunFireT200 and its - * hc-topology. Unfortunately, the SUNW,SunFireT1000 does not contain an - * ioboard. For SUNW,SunFireT1000 systems, we must begin the I/O - * topology directly below the motherboard. - * - * To further the mess, on the SUNW,SunFireT200 (Ontario) platform, a - * mistake was made with the topology defintion. The ioboard was made - * a peer to the motherboard. This is incorrect in terms of - * what we allow for an hc topology according the Fault - * Managed Resources specification and what is physically - * possible in the system. Nevertheless, a change to - * the topology will result in mis-diagnoses for systems - * that have already shipped. In the interest of backward - * compatibility, we continue to allow the - * ioboard to be a peer to the motherboard SUNW,SunFireT200 systems. - */ - if ((strcmp(plat, ERIE) == 0) || - (strcmp(plat, ERIE2) == 0)) { - if (strcmp(topo_node_name(parent), "motherboard") != 0) { - topo_mod_strfree(mod, plat); - return (0); - } - ion = parent; - } else if (strcmp(topo_node_name(parent), "motherboard") == 0) { - topo_mod_strfree(mod, plat); - return (0); - } else { - ion = iob_node_create(parent, mod); - } - - topo_mod_strfree(mod, plat); - - if (ion == NULL) { - topo_mod_dprintf(mod, "Enumeration of ioboard failed: %s\n", - topo_strerror(topo_mod_errno(mod))); - return (-1); /* mod_errno already set */ - } - - if (child_range_add(mod, ion, HOSTBRIDGE, 0, HB_MAX) < 0 || - topo_mod_enumerate(mod, ion, HOSTBRIDGE, HOSTBRIDGE, 0, HB_MAX) - < 0) { - topo_mod_dprintf(mod, "Enumeration of %s=%d " - "failed: %s\n", HOSTBRIDGE, 0, - topo_strerror(topo_mod_errno(mod))); - return (-1); /* mod_errno already set */ - } - - return (0); -} diff --git a/usr/src/lib/fm/topo/modules/sun4v/pcibus/Makefile b/usr/src/lib/fm/topo/modules/sun4v/pcibus/Makefile index 71252e3f20..a6251ef618 100644 --- a/usr/src/lib/fm/topo/modules/sun4v/pcibus/Makefile +++ b/usr/src/lib/fm/topo/modules/sun4v/pcibus/Makefile @@ -29,16 +29,15 @@ MODULE = pcibus ARCH = sun4v CLASS = arch -PCISRCS = did.c \ - did_hash.c \ - did_props.c \ - pcibus.c \ - pcibus_labels.c \ - pcifn_enum.c \ - util.c +UTILDIR = ../../common/pcibus +HBDIR = ../../common/hostbridge +UTILSRCS = did.c did_hash.c did_props.c util.c +PCISRCS = pcibus.c pcibus_labels.c -MODULESRCS = $(PCISRCS) pci_sun4v.c +MODULESRCS = $(UTILSRCS) $(PCISRCS) pci_sun4v.c include ../../Makefile.plugin LDLIBS += -ldevinfo + +CPPFLAGS += -I$(UTILDIR) -I$(HBDIR) diff --git a/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.c b/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.c index 3c9835ae99..a61322ce58 100644 --- a/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.c +++ b/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.c @@ -37,7 +37,8 @@ #include "pci_sun4v.h" int -platform_pci_label(tnode_t *node, nvlist_t *in, nvlist_t **out, topo_mod_t *mod) +platform_pci_label(topo_mod_t *mod, tnode_t *node, nvlist_t *in, + nvlist_t **out) { - return (pci_label_cmn(node, in, out, mod)); + return (pci_label_cmn(mod, node, in, out)); } diff --git a/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h b/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h index d533346a43..ea355e81a0 100644 --- a/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h +++ b/usr/src/lib/fm/topo/modules/sun4v/pcibus/pci_sun4v.h @@ -43,7 +43,7 @@ physnm_t t200_pnms[] = { }; pphysnm_t plat_pnames[] = { - { "SUNW,Sun-Fire-T200", + { "Sun-Fire-T200", sizeof (t200_pnms) / sizeof (physnm_t), t200_pnms } }; @@ -60,7 +60,7 @@ devlab_t t200_missing[] = { }; pdevlabs_t plats_missing[] = { - { "SUNW,Sun-Fire-T200", + { "Sun-Fire-T200", sizeof (t200_missing) / sizeof (devlab_t), t200_missing } }; |
