diff options
| author | cindi <none@none> | 2006-11-04 01:18:55 -0800 |
|---|---|---|
| committer | cindi <none@none> | 2006-11-04 01:18:55 -0800 |
| commit | 0eb822a1c0c2bea495647510b75f77f0e57633eb (patch) | |
| tree | d104741eef4bddb27171407d1243e37790c7d499 | |
| parent | 389056bd4327caca73482e60b80da00f4eaf3de9 (diff) | |
| download | illumos-joyent-0eb822a1c0c2bea495647510b75f77f0e57633eb.tar.gz | |
6396916 verification of dtd file name is wrong
6399876 libtopo does not properly support an alternate root path
6399927 libtopo debug information indicates "no topology file found" when it is unable to parse file.
6421101 fmsim doesn't allow simulated topology to be specified with new libtopo
6422759 fmd memory leaks detected on system experiencing significant pcie fabric errors
6429072 memory leak in iob_tnode_create
6448718 libtopo needs better enum module APIs
6467144 topo_fmri_str2nvl doesn't handle authority or properties
6473916 fmd should return a full populated topo snapshot in fmd_hdl_topology() and fmd_fmri_topology()
6473918 hc scheme plugin is_present routine is broken
6477382 Need public header file for hc scheme component names and properties
6477385 fmtopo -V needs to be more friendly
6477426 fmtopo -d should not be so chatty
6477430 Need ability to load additional libtopo map files
6477442 libtopo should allow alternate platform topo map files
6477446 Remove unused topo methods from enumerator modules
6477453 pcibus and hostbridge interface boundaries are a mess
6477456 hc enumerators must support authority information
6477461 topo_fru_compute and topo_asru_compute should return static props when computation fails
6480930 fmtopo should support a -x option
--HG--
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile => deleted_files/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile
rename : usr/src/lib/fm/topo/modules/common/pcifn_enum.c => deleted_files/usr/src/lib/fm/topo/modules/common/pcibus/pcifn_enum.c
rename : usr/src/lib/fm/topo/modules/common/pcifn_enum.h => deleted_files/usr/src/lib/fm/topo/modules/common/pcibus/pcifn_enum.h
rename : usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile => deleted_files/usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile
rename : usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c => deleted_files/usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c
rename : usr/src/lib/fm/topo/libtopo/common/hc_canon.h => usr/src/lib/fm/topo/libtopo/common/topo_hc.h
rename : usr/src/lib/fm/topo/files/Makefile => usr/src/lib/fm/topo/maps/Makefile
rename : usr/src/lib/fm/topo/files/Makefile.file => usr/src/lib/fm/topo/maps/Makefile.map
rename : usr/src/lib/fm/topo/files/SUNW,SPARC-Enterprise/Makefile => usr/src/lib/fm/topo/maps/SUNW,SPARC-Enterprise/Makefile
rename : usr/src/lib/fm/topo/files/SUNW,SPARC-Enterprise/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,SPARC-Enterprise/SPARC-Enterprise-hc-topology.xml
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire-15000/Makefile => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Makefile
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire-15000/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-15000/Sun-Fire-15000-hc-topology.xml
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire-T200/Makefile => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Makefile
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Blade-T6300-hc-topology.xml
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire-T200/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire-T200/Sun-Fire-T200-hc-topology.xml
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire/Makefile => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire/Makefile
rename : usr/src/lib/fm/topo/files/SUNW,Sun-Fire/hc-topology.xml => usr/src/lib/fm/topo/maps/SUNW,Sun-Fire/Sun-Fire-hc-topology.xml
rename : usr/src/lib/fm/topo/files/common/topology.dtd.1 => usr/src/lib/fm/topo/maps/common/topology.dtd.1
rename : usr/src/lib/fm/topo/files/i86pc/Makefile => usr/src/lib/fm/topo/maps/i86pc/Makefile
rename : usr/src/lib/fm/topo/files/i86pc/hc-topology.xml => usr/src/lib/fm/topo/maps/i86pc/i86pc-hc-topology.xml
rename : usr/src/lib/fm/topo/files/sun4u/Makefile => usr/src/lib/fm/topo/maps/sun4u/Makefile
rename : usr/src/lib/fm/topo/files/sun4u/hc-topology.xml => usr/src/lib/fm/topo/maps/sun4u/sun4u-hc-topology.xml
rename : usr/src/lib/fm/topo/files/sun4v/Makefile => usr/src/lib/fm/topo/maps/sun4v/Makefile
rename : usr/src/lib/fm/topo/files/sun4v/hc-topology.xml => usr/src/lib/fm/topo/maps/sun4v/sun4v-hc-topology.xml
rename : usr/src/lib/fm/topo/modules/common/hostbridge.c => usr/src/lib/fm/topo/modules/common/hostbridge/hostbridge.c
rename : usr/src/lib/fm/topo/modules/common/hostbridge.h => usr/src/lib/fm/topo/modules/common/hostbridge/hostbridge.h
rename : usr/src/lib/fm/topo/modules/common/did.c => usr/src/lib/fm/topo/modules/common/pcibus/did.c
rename : usr/src/lib/fm/topo/modules/common/did.h => usr/src/lib/fm/topo/modules/common/pcibus/did.h
rename : usr/src/lib/fm/topo/modules/common/did_hash.c => usr/src/lib/fm/topo/modules/common/pcibus/did_hash.c
rename : usr/src/lib/fm/topo/modules/common/did_impl.h => usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h
rename : usr/src/lib/fm/topo/modules/common/did_props.c => usr/src/lib/fm/topo/modules/common/pcibus/did_props.c
rename : usr/src/lib/fm/topo/modules/common/did_props.h => usr/src/lib/fm/topo/modules/common/pcibus/did_props.h
rename : usr/src/lib/fm/topo/modules/common/pcibus.c => usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c
rename : usr/src/lib/fm/topo/modules/common/pcibus.h => usr/src/lib/fm/topo/modules/common/pcibus/pcibus.h
rename : usr/src/lib/fm/topo/modules/common/pcibus_labels.c => usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.c
rename : usr/src/lib/fm/topo/modules/common/pcibus_labels.h => usr/src/lib/fm/topo/modules/common/pcibus/pcibus_labels.h
rename : usr/src/lib/fm/topo/modules/common/util.c => usr/src/lib/fm/topo/modules/common/pcibus/util.c
rename : usr/src/lib/fm/topo/modules/common/util.h => usr/src/lib/fm/topo/modules/common/pcibus/util.h
141 files changed, 5982 insertions, 3774 deletions
diff --git a/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile b/deleted_files/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile index 8ca6b9208b..8ca6b9208b 100644 --- a/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile +++ b/deleted_files/usr/src/lib/fm/topo/files/SUNW,Sun-Blade-T6300/Makefile diff --git a/usr/src/lib/fm/topo/modules/common/pcifn_enum.c b/deleted_files/usr/src/lib/fm/topo/modules/common/pcibus/pcifn_enum.c index 30ae12c372..30ae12c372 100644 --- a/usr/src/lib/fm/topo/modules/common/pcifn_enum.c +++ b/deleted_files/usr/src/lib/fm/topo/modules/common/pcibus/pcifn_enum.c diff --git a/usr/src/lib/fm/topo/modules/common/pcifn_enum.h b/deleted_files/usr/src/lib/fm/topo/modules/common/pcibus/pcifn_enum.h index 26f5f60225..26f5f60225 100644 --- a/usr/src/lib/fm/topo/modules/common/pcifn_enum.h +++ b/deleted_files/usr/src/lib/fm/topo/modules/common/pcibus/pcifn_enum.h diff --git a/usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile b/deleted_files/usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile index ff974924f7..ff974924f7 100644 --- a/usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile +++ b/deleted_files/usr/src/lib/fm/topo/modules/sun4v/ioboard/Makefile diff --git a/usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c b/deleted_files/usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c index a3796223a6..a3796223a6 100644 --- a/usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c +++ b/deleted_files/usr/src/lib/fm/topo/modules/sun4v/ioboard/iob_platform.c diff --git a/usr/src/cmd/fm/eversholt/files/Makefile.com b/usr/src/cmd/fm/eversholt/files/Makefile.com index f6de31926a..92173e8b7d 100644 --- a/usr/src/cmd/fm/eversholt/files/Makefile.com +++ b/usr/src/cmd/fm/eversholt/files/Makefile.com @@ -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. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -52,7 +51,7 @@ clean clobber: $(USR_PLAT_EFT_FILES) $(ROOT_COMMON_EFT_FILES) %.eft: ../common/%.esc - $(ESC) -o $@ $< + $(ESC) -I$(ROOT)/usr/include -o $@ $< %.eft: %.esc $(ESC) -o $@ $< diff --git a/usr/src/cmd/fm/eversholt/files/common/pci.esc b/usr/src/cmd/fm/eversholt/files/common/pci.esc index 0fb4ffee1f..59067236a7 100644 --- a/usr/src/cmd/fm/eversholt/files/common/pci.esc +++ b/usr/src/cmd/fm/eversholt/files/common/pci.esc @@ -27,6 +27,8 @@ #pragma dictionary "PCI" +#include <fm/topo_hc.h> + #define PCI_DEV_FIT 1000 #define PCI_BUS_FIT 500 @@ -50,17 +52,17 @@ #define NONFATAL_DPE_D_TIME 168h #define IS_LEAF \ - (confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") != "60400" && \ - confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") != "60401") + (confprop(asru(pcibus/pcidev/pcifn), TOPO_PCI_CLASS) != "60400" && \ + confprop(asru(pcibus/pcidev/pcifn), TOPO_PCI_CLASS) != "60401") #define IS_BDG \ - (confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") == "60400" || \ - confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") == "60401") + (confprop(asru(pcibus/pcidev/pcifn), TOPO_PCI_CLASS) == "60400" || \ + confprop(asru(pcibus/pcidev/pcifn), TOPO_PCI_CLASS) == "60401") #define FD_IS_LEAF \ - (confprop(asru(pcibus/pcidev[fromdev]/pcifn), "CLASS-CODE") != \ + (confprop(asru(pcibus/pcidev[fromdev]/pcifn), TOPO_PCI_CLASS) != \ "60400" && \ - confprop(asru(pcibus/pcidev[fromdev]/pcifn), "CLASS-CODE") != "60401") + confprop(asru(pcibus/pcidev[fromdev]/pcifn), TOPO_PCI_CLASS) != "60401") /* * note general rule for errors is that for upstream propagations diff --git a/usr/src/cmd/fm/eversholt/files/common/pciex.esc b/usr/src/cmd/fm/eversholt/files/common/pciex.esc index 191b70abc8..7acca8ccf0 100644 --- a/usr/src/cmd/fm/eversholt/files/common/pciex.esc +++ b/usr/src/cmd/fm/eversholt/files/common/pciex.esc @@ -27,6 +27,8 @@ #pragma dictionary "PCIEX" +#include <fm/topo_hc.h> + /* * FIT rates - assume leaf devices are somewhat less reliable than * root complexes, switches and bridges @@ -87,7 +89,7 @@ #define SOURCE_ID_MATCHES_OWN_BDF \ (payloadprop("source-valid") == 1 && \ - payloadprop("source-id") == (confprop(asru(pciexrc), "BDF") + 0)) + payloadprop("source-id") == (confprop(asru(pciexrc), TOPO_PCI_BDF) + 0)) /* * Other useful macros. These use the EXCAP property (PCI Express Capabilities @@ -109,35 +111,39 @@ is_under(pciexbus/pciexdev/pciexfn, pcibus[b]/pcidev[d]/pcifn[f]) #define IS_SWD \ - (confprop(asru(pciexbus/pciexdev/pciexfn), "EXCAP") == "pciexswd") + (confprop(asru(pciexbus/pciexdev/pciexfn), TOPO_PCI_EXCAP) == \ + "pciexswd") #define IS_SWU \ - (confprop(asru(pciexbus/pciexdev/pciexfn), "EXCAP") == "pciexswu") + (confprop(asru(pciexbus/pciexdev/pciexfn), TOPO_PCI_EXCAP) == \ + "pciexswu") #define IS_LEAF \ - (confprop(asru(pciexbus/pciexdev/pciexfn), "EXCAP") == "pciexdev") + (confprop(asru(pciexbus/pciexdev/pciexfn), TOPO_PCI_EXCAP) == \ + "pciexdev") #define IS_PCI_LEAF \ - (confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") != "60400" && \ - confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") != "60401") + (confprop(asru(pcibus/pcidev/pcifn), TOPO_PCI_CLASS) != "60400" && \ + confprop(asru(pcibus/pcidev/pcifn), TOPO_PCI_CLASS) != "60401") #define BDF_IS_PCI_LEAF \ - (confprop(asru(pcibus[b]/pcidev[d]/pcifn[f]),"CLASS-CODE") != \ + (confprop(asru(pcibus[b]/pcidev[d]/pcifn[f]),TOPO_PCI_CLASS) != \ "60400" && \ - confprop(asru(pcibus[b]/pcidev[d]/pcifn[f]), "CLASS-CODE") != "60401") + confprop(asru(pcibus[b]/pcidev[d]/pcifn[f]), TOPO_PCI_CLASS) != "60401") #define BDF_IS_PCI_IMM_LEAF \ - (confprop(asru(pciexfn/pcibus[b]/pcidev[d]/pcifn[f]),"CLASS-CODE") != \ - "60400" && \ - confprop(asru(pciexfn/pcibus[b]/pcidev[d]/pcifn[f]), "CLASS-CODE") != \ - "60401") + (confprop(asru(pciexfn/pcibus[b]/pcidev[d]/pcifn[f]),TOPO_PCI_CLASS) \ + != "60400" && \ + confprop(asru(pciexfn/pcibus[b]/pcidev[d]/pcifn[f]), TOPO_PCI_CLASS) \ + != "60401") #define IS_BDG \ - (confprop(asru(pciexbus/pciexdev/pciexfn), "EXCAP") == "pcibus") + (confprop(asru(pciexbus/pciexdev/pciexfn), TOPO_PCI_EXCAP) == \ + "pcibus") #define BDF_IS_LEAF \ - (confprop(asru(pciexbus[b]/pciexdev[d]/pciexfn[f]), "EXCAP") == \ - "pciexdev") + (confprop(asru(pciexbus[b]/pciexdev[d]/pciexfn[f]), \ + TOPO_PCI_EXCAP) == "pciexdev") /* * define faults @@ -1837,11 +1843,11 @@ prop error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn (0)-> prop error.io.pciex.badreq-u@pciexbus[b]/pciexdev[d] (0)-> ereport.io.pciex.tl.ur@pciexfn { - (confprop(asru(pciexfn), "EXCAP") == "pciexswd") && + (confprop(asru(pciexfn), TOPO_PCI_EXCAP) == "pciexswd") && (payloadprop("source-valid") == 0 || (payloadprop("source-id") & 0xfff8) == ((b << 8) | (d << 3))) }, ereport.io.pciex.tl.ca@pciexfn { - (confprop(asru(pciexfn), "EXCAP") == "pciexswd") && + (confprop(asru(pciexfn), TOPO_PCI_EXCAP) == "pciexswd") && (payloadprop("source-valid") == 0 || (payloadprop("source-id") & 0xfff8) == ((b << 8) | (d << 3))) }; diff --git a/usr/src/cmd/fm/fmd/Makefile.fmd b/usr/src/cmd/fm/fmd/Makefile.fmd index 00a325b6eb..44d33a8344 100644 --- a/usr/src/cmd/fm/fmd/Makefile.fmd +++ b/usr/src/cmd/fm/fmd/Makefile.fmd @@ -66,6 +66,7 @@ SRCS += fmd.c \ fmd_thread.c \ fmd_time.c \ fmd_timerq.c \ + fmd_topo.c \ fmd_trace.c \ fmd_ustat.c \ fmd_xdr_adm.c \ diff --git a/usr/src/cmd/fm/fmd/common/fmd.c b/usr/src/cmd/fm/fmd/common/fmd.c index b69e5ac751..902995da14 100644 --- a/usr/src/cmd/fm/fmd/common/fmd.c +++ b/usr/src/cmd/fm/fmd/common/fmd.c @@ -31,7 +31,6 @@ #include <sys/param.h> #include <sys/systeminfo.h> #include <sys/fm/util.h> -#include <fm/libtopo.h> #include <smbios.h> #include <limits.h> @@ -60,6 +59,7 @@ #include <fmd_idspace.h> #include <fmd_rpc.h> #include <fmd_dr.h> +#include <fmd_topo.h> #include <fmd_xprt.h> #include <fmd_ctl.h> #include <sys/openpromio.h> @@ -313,6 +313,8 @@ static fmd_statistics_t _fmd_stats = { { "fltlog.enospc", FMD_TYPE_UINT64, "events not appended to fltlog (ENOSPC)" }, { "log.enospc", FMD_TYPE_UINT64, "events not appended to other logs (ENOSPC)" }, { "dr.gen", FMD_TYPE_UINT64, "dynamic reconfiguration generation" }, +{ "topo.gen", FMD_TYPE_UINT64, "topology snapshot generation" }, +{ "topo.drgen", FMD_TYPE_UINT64, "current topology DR generation number" }, }; void @@ -371,6 +373,7 @@ fmd_create(fmd_t *dp, const char *arg0, const char *root, const char *conf) (void) pthread_mutex_init(&dp->d_thr_lock, NULL); (void) pthread_mutex_init(&dp->d_mod_lock, NULL); (void) pthread_mutex_init(&dp->d_stats_lock, NULL); + (void) pthread_mutex_init(&dp->d_topo_lock, NULL); (void) pthread_rwlock_init(&dp->d_log_lock, NULL); /* @@ -614,8 +617,7 @@ fmd_destroy(fmd_t *dp) if (dp->d_conf != NULL) fmd_conf_close(dp->d_conf); - if (dp->d_topo != NULL) - topo_close(dp->d_topo); + fmd_topo_fini(); nvlist_free(dp->d_auth); (void) nv_alloc_fini(&dp->d_nva); @@ -736,7 +738,7 @@ fmd_run(fmd_t *dp, int pfd) const char *name; fmd_conf_path_t *pap; fmd_event_t *e; - int dbout, err; + int dbout; /* * Cache all the current debug property settings in d_fmd_debug, @@ -768,10 +770,7 @@ fmd_run(fmd_t *dp, int pfd) name = dp->d_rootdir != NULL && *dp->d_rootdir != '\0' ? dp->d_rootdir : NULL; - if ((dp->d_topo = topo_open(TOPO_VERSION, name, &err)) == NULL) { - fmd_error(EFMD_EXIT, "failed to initialize " - "topology library: %s\n", topo_strerror(err)); - } + fmd_topo_init(); dp->d_clockptr = dp->d_clockops->fto_init(); dp->d_xprt_ids = fmd_idspace_create("xprt_ids", 1, INT_MAX); diff --git a/usr/src/cmd/fm/fmd/common/fmd.h b/usr/src/cmd/fm/fmd/common/fmd.h index 06c858c88a..a25be1abb0 100644 --- a/usr/src/cmd/fm/fmd/common/fmd.h +++ b/usr/src/cmd/fm/fmd/common/fmd.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. @@ -60,6 +59,8 @@ typedef struct fmd_statistics { fmd_stat_t ds_flt_enospc; /* number of events w/ ENOSPC fltlog */ fmd_stat_t ds_oth_enospc; /* number of events w/ ENOSPC others */ fmd_stat_t ds_dr_gen; /* dynamic reconfiguration generation */ + fmd_stat_t ds_topo_gen; /* topology snapshot generation */ + fmd_stat_t ds_topo_drgen; /* topology DR generation */ } fmd_statistics_t; typedef struct fmd { @@ -110,7 +111,8 @@ typedef struct fmd { void *d_dr_hdl; /* DR event handle (see fmd_dr.c) */ nv_alloc_t d_nva; /* libnvpair allocator handle */ nvlist_t *d_auth; /* FMRI authority nvlist */ - struct topo_hdl *d_topo; /* libtopo handle */ + pthread_mutex_t d_topo_lock; /* lock for topo hdl */ + fmd_list_t d_topo_list; /* list of all topology snapshots */ struct fmd_conf *d_conf; /* global configuration properties */ uint_t d_fg; /* cached value of "fg" property */ diff --git a/usr/src/cmd/fm/fmd/common/fmd_api.c b/usr/src/cmd/fm/fmd/common/fmd_api.c index 659d52f787..4389f70feb 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_api.c +++ b/usr/src/cmd/fm/fmd/common/fmd_api.c @@ -28,7 +28,6 @@ #include <sys/types.h> #include <sys/fm/protocol.h> -#include <fm/libtopo.h> #include <unistd.h> #include <signal.h> @@ -52,6 +51,7 @@ #include <fmd_buf.h> #include <fmd_asru.h> #include <fmd_fmri.h> +#include <fmd_topo.h> #include <fmd_ckpt.h> #include <fmd_xprt.h> @@ -701,7 +701,8 @@ fmd_hdl_topology(fmd_hdl_t *hdl, int v) "fmd version %d != client version %d\n", TOPO_VERSION, v); } - thp = fmd.d_topo; + thp = fmd_topo_handle(v); + fmd_module_unlock(mp); return (thp); } diff --git a/usr/src/cmd/fm/fmd/common/fmd_fmri.c b/usr/src/cmd/fm/fmd/common/fmd_fmri.c index 1eb317c88b..6953247df5 100644 --- a/usr/src/cmd/fm/fmd/common/fmd_fmri.c +++ b/usr/src/cmd/fm/fmd/common/fmd_fmri.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. @@ -37,10 +36,9 @@ #include <fmd_string.h> #include <fmd_scheme.h> #include <fmd_fmri.h> +#include <fmd_topo.h> #include <fmd.h> -#include <fm/libtopo.h> - /* * Interfaces to be used by the plugins */ @@ -234,8 +232,7 @@ fmd_fmri_get_drgen(void) struct topo_hdl * fmd_fmri_topology(int version) { - ASSERT(version == TOPO_VERSION); - return (fmd.d_topo); + return (fmd_topo_handle(version)); } /* diff --git a/usr/src/cmd/fm/fmd/common/fmd_topo.c b/usr/src/cmd/fm/fmd/common/fmd_topo.c new file mode 100644 index 0000000000..bef8f4fbdd --- /dev/null +++ b/usr/src/cmd/fm/fmd/common/fmd_topo.c @@ -0,0 +1,128 @@ +/* + * 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" + +/* + * FMD Topology Handling + * + * Fault manager scheme and module plug-ins may need access to the latest + * libtopo snapshot. Upon fmd initialization, a snapshot is taken and + * made available via fmd_fmri_topology() and fmd_hdl_topology(). Each + * of these routines returns a libtopo snapshot handle back to the caller. + * New snapshots are taken if and when a DR event causes the DR generation + * number to increase. The current snapshot is retained to assure consistency + * for modules still using older snapshots and the latest snapshot handle is + * returned to the caller. + */ + +#include <fmd_alloc.h> +#include <fmd_error.h> +#include <fmd_subr.h> +#include <fmd_topo.h> +#include <fmd.h> + +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <fm/fmd_fmri.h> +#include <fm/libtopo.h> + +static void +fmd_topo_update(void) +{ + int err; + topo_hdl_t *tp; + fmd_topo_t *ftp; + char *id; + const char *name; + + ASSERT(MUTEX_HELD(&fmd.d_topo_lock)); + + name = fmd.d_rootdir != NULL && + *fmd.d_rootdir != '\0' ? fmd.d_rootdir : NULL; + + /* + * Update the topology snapshot. + */ + if ((tp = topo_open(TOPO_VERSION, name, &err)) == NULL) + fmd_panic("failed to open topology library: %s", + topo_strerror(err)); + + if ((id = topo_snap_hold(tp, NULL, &err)) == NULL) + fmd_panic("failed to get topology snapshot: %s", + topo_strerror(err)); + + topo_hdl_strfree(tp, id); + + ftp = fmd_alloc(sizeof (fmd_topo_t), FMD_SLEEP); + ftp->ft_hdl = tp; + fmd.d_stats->ds_topo_gen.fmds_value.ui64++; + fmd_list_prepend(&fmd.d_topo_list, ftp); + +} + +topo_hdl_t * +fmd_topo_handle(int version) +{ + uint64_t curgen; + fmd_topo_t *ftp; + + if (version != TOPO_VERSION) + return (NULL); + + (void) pthread_mutex_lock(&fmd.d_topo_lock); + if ((curgen = fmd_fmri_get_drgen()) > + fmd.d_stats->ds_topo_drgen.fmds_value.ui64) { + fmd.d_stats->ds_topo_drgen.fmds_value.ui64 = curgen; + fmd_topo_update(); + } + ftp = fmd_list_next(&fmd.d_topo_list); + (void) pthread_mutex_unlock(&fmd.d_topo_lock); + + return ((topo_hdl_t *)ftp->ft_hdl); +} + +void +fmd_topo_init(void) +{ + (void) pthread_mutex_lock(&fmd.d_topo_lock); + fmd_topo_update(); + (void) pthread_mutex_unlock(&fmd.d_topo_lock); +} + +void +fmd_topo_fini(void) +{ + fmd_topo_t *ftp; + + (void) pthread_mutex_lock(&fmd.d_topo_lock); + while ((ftp = fmd_list_next(&fmd.d_topo_list)) != NULL) { + fmd_list_delete(&fmd.d_topo_list, ftp); + topo_close(ftp->ft_hdl); + fmd_free(ftp, sizeof (fmd_topo_t)); + } + (void) pthread_mutex_unlock(&fmd.d_topo_lock); +} diff --git a/usr/src/cmd/fm/fmd/common/fmd_topo.h b/usr/src/cmd/fm/fmd/common/fmd_topo.h new file mode 100644 index 0000000000..f5e1bc2f8e --- /dev/null +++ b/usr/src/cmd/fm/fmd/common/fmd_topo.h @@ -0,0 +1,52 @@ +/* + * 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 _FMD_TOPO_H +#define _FMD_TOPO_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <fm/libtopo.h> + +#include <fmd_list.h> + +extern void fmd_topo_init(void); +extern void fmd_topo_fini(void); +extern topo_hdl_t *fmd_topo_handle(int); + +typedef struct fmd_topo { + fmd_list_t ft_list; + topo_hdl_t *ft_hdl; +} fmd_topo_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _FMD_TOPO_H */ diff --git a/usr/src/cmd/fm/fmtopo/common/fmtopo.c b/usr/src/cmd/fm/fmtopo/common/fmtopo.c index 63c614f9ab..14f62a850c 100644 --- a/usr/src/cmd/fm/fmtopo/common/fmtopo.c +++ b/usr/src/cmd/fm/fmtopo/common/fmtopo.c @@ -28,39 +28,50 @@ #include <sys/fm/protocol.h> #include <fm/libtopo.h> +#include <ctype.h> #include <limits.h> #include <strings.h> #include <stdio.h> #include <errno.h> +#include <sys/param.h> #define FMTOPO_EXIT_SUCCESS 0 #define FMTOPO_EXIT_ERROR 1 #define FMTOPO_EXIT_USAGE 2 +#define STDERR "stderr" +#define DOTS "..." +#define ALL "all" + static const char *g_pname; static const char *opt_R = "/"; +static const char *opt_P = NULL; static const char *opt_s = FM_FMRI_SCHEME_HC; -static int opt_e; -static int opt_d; -static int opt_v; -static int opt_V; +static int opt_e = 0; +static int opt_d = 0; +static int opt_V = 0; +static int opt_p = 0; +static int opt_x = 0; static int usage(FILE *fp) { (void) fprintf(fp, - "Usage: %s [-Cdev] [-R root] [-s scheme]\n", g_pname); + "Usage: %s [-edpvVx] [-Cdev] [-P properties] [-R root] " + "[-s scheme]\n", g_pname); (void) fprintf(fp, "\t-C dump core after completing execution\n" - "\t-d set debug mode for libtopo\n" - "\t-e display nodes as paths using esc/eft notation\n" + "\t-d set debug mode for libtopo modules\n" + "\t-e display FMRIs as paths using esc/eft notation\n" + "\t-P display of FMRI with the specified properties\n" + "\t-p display of FMRI protocol properties\n" "\t-R set root directory for libtopo plug-ins and other files\n" "\t-s display topology for the specified FMRI scheme\n" - "\t-v set verbose mode (display node ASRU, FRU and label)\n" - "\t-V set verbose mode (display node properties)\n"); + "\t-V set verbose mode\n" + "\t-x display a xml formatted topology\n"); return (FMTOPO_EXIT_USAGE); } @@ -89,7 +100,7 @@ print_fmri(topo_hdl_t *thp, tnode_t *node) (void) printf("%s\n", name); - if (opt_v) { + if (opt_p) { char *aname = NULL, *fname = NULL, *lname = NULL; nvlist_t *asru = NULL; nvlist_t *fru = NULL; @@ -120,23 +131,8 @@ print_fmri(topo_hdl_t *thp, tnode_t *node) (void) printf("\tLabel: -\n"); } } - nvlist_free(fmri); - if (opt_d) { - fmri = NULL; - - if (topo_fmri_str2nvl(thp, name, &fmri, &err) < 0) { - (void) fprintf(stderr, "%s: failed to convert " - "alternate fmri for %s=%d: %s\n", g_pname, - topo_node_name(node), topo_node_instance(node), - topo_strerror(err)); - } else { - nvlist_print(stderr, fmri); - nvlist_free(fmri); - } - } - topo_hdl_strfree(thp, name); } @@ -194,28 +190,302 @@ print_everstyle(tnode_t *node) (void) printf("%s\n", buf); } +static void +print_prop_nameval(topo_hdl_t *thp, nvlist_t *nvl, int skip) +{ + int err; + topo_type_t type; + char *tstr, *propn, buf[48]; + nvpair_t *pv_nvp; + + if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL) + return; + + /* Print property name */ + if ((pv_nvp = nvlist_next_nvpair(nvl, NULL)) == NULL || + nvpair_name(pv_nvp) == NULL || + strcmp(TOPO_PROP_VAL_NAME, nvpair_name(pv_nvp)) != 0) { + (void) fprintf(stderr, "%s: malformed property name\n", + g_pname); + return; + } else { + (void) nvpair_value_string(pv_nvp, &propn); + } + + if ((pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL || + nvpair_name(pv_nvp) == NULL || + strcmp(nvpair_name(pv_nvp), TOPO_PROP_VAL_TYPE) != 0 || + nvpair_type(pv_nvp) != DATA_TYPE_INT32) { + (void) fprintf(stderr, "%s: malformed property type for %s\n", + g_pname, propn); + return; + } else { + (void) nvpair_value_int32(pv_nvp, (int32_t *)&type); + } + + switch (type) { + case TOPO_TYPE_BOOLEAN: tstr = "boolean"; break; + case TOPO_TYPE_INT32: tstr = "int32"; break; + case TOPO_TYPE_UINT32: tstr = "uint32"; break; + case TOPO_TYPE_INT64: tstr = "int64"; break; + case TOPO_TYPE_UINT64: tstr = "uint64"; break; + case TOPO_TYPE_STRING: tstr = "string"; break; + case TOPO_TYPE_FMRI: tstr = "fmri"; break; + case TOPO_TYPE_INT32_ARRAY: tstr = "int32[]"; break; + case TOPO_TYPE_UINT32_ARRAY: tstr = "uint32[]"; break; + case TOPO_TYPE_INT64_ARRAY: tstr = "int64[]"; break; + case TOPO_TYPE_UINT64_ARRAY: tstr = "uint64[]"; break; + case TOPO_TYPE_STRING_ARRAY: tstr = "string[]"; break; + case TOPO_TYPE_FMRI_ARRAY: tstr = "fmri[]"; break; + default: tstr = "unknown type"; + } + + if (!skip) + printf(" %-17s %-8s ", propn, tstr); + + /* + * Get property value + */ + if (nvpair_name(pv_nvp) == NULL || + (pv_nvp = nvlist_next_nvpair(nvl, pv_nvp)) == NULL) { + (void) fprintf(stderr, "%s: malformed property value\n", + g_pname); + return; + } + + if (skip) + return; + + switch (nvpair_type(pv_nvp)) { + case DATA_TYPE_INT32: { + int32_t val; + (void) nvpair_value_int32(pv_nvp, &val); + (void) printf(" %d", val); + break; + } + case DATA_TYPE_UINT32: { + uint32_t val; + (void) nvpair_value_uint32(pv_nvp, &val); + (void) printf(" 0x%x", val); + break; + } + case DATA_TYPE_INT64: { + int64_t val; + (void) nvpair_value_int64(pv_nvp, &val); + (void) printf(" %lld", (longlong_t)val); + break; + } + case DATA_TYPE_UINT64: { + uint64_t val; + (void) nvpair_value_uint64(pv_nvp, &val); + (void) printf(" 0x%llx", (u_longlong_t)val); + break; + } + case DATA_TYPE_STRING: { + char *val; + (void) nvpair_value_string(pv_nvp, &val); + if (!opt_V && strlen(val) > 48) { + (void) snprintf(buf, 48, "%s...", val); + (void) printf(" %s", buf); + } else { + (void) printf(" %s", val); + } + break; + } + case DATA_TYPE_NVLIST: { + nvlist_t *val; + char *fmri; + (void) nvpair_value_nvlist(pv_nvp, &val); + if (topo_fmri_nvl2str(thp, val, &fmri, &err) != 0) { + if (opt_V) + nvlist_print(stdout, nvl); + break; + } + + if (!opt_V && strlen(fmri) > 48) { + (void) snprintf(buf, 48, "%s", fmri); + (void) snprintf(&buf[45], 4, "%s", DOTS); + (void) printf(" %s", buf); + } else { + (void) printf(" %s", fmri); + } + + topo_hdl_strfree(thp, fmri); + break; + } + default: + (void) fprintf(stderr, " unknown data type (%d)", + nvpair_type(pv_nvp)); + break; + } + (void) printf("\n"); +} + +static void +print_pgroup(char *pgn, char *dstab, char *nstab, int32_t version, int skip) +{ + char buf[30]; + + if (skip) + return; + + if (!opt_V && strlen(pgn) > 30) { + (void) snprintf(buf, 26, "%s", pgn); + (void) snprintf(&buf[27], 4, "%s", DOTS); + printf(" group: %-30s version: %-3d stability: %s/%s\n", + buf, version, nstab, dstab); + } else { + printf(" group: %-30s version: %-3d stability: %s/%s\n", + pgn, version, nstab, dstab); + } +} + +static int +cmp_name(const char *props, char *pgn) +{ + char buf[MAXNAMELEN]; + size_t count; + char *begin, *end, *value, *next; + char *np; + + if (props == NULL) + return (0); + + if (strcmp(props, ALL) == 0) + return (0); + + + value = np = strdup(props); + + for (end = np; *end != '\0'; value = next) { + end = strchr(value, ','); + if (end != NULL) + next = end + 1; /* skip the comma */ + else + next = end = value + strlen(value); + + /* + * Eat up white space at beginning or end of the + * property group name + */ + begin = value; + while (begin < end && isspace(*begin)) + begin++; + while (begin < end && isspace(*(end - 1))) + end--; + + if (begin >= end) + return (1); + + count = end - begin; + count += 1; + + if (count > sizeof (buf)) + return (1); + + (void) snprintf(buf, count, "%s", begin); + if (strcmp(pgn, buf) == 0) { + free(np); + return (0); + } + } + + free(np); + return (1); +} + +static void +print_props(topo_hdl_t *thp, nvlist_t *p_nv, const char *props) +{ + char *pgn = NULL, *dstab = NULL, *nstab = NULL; + int32_t version = 0; + nvlist_t *pg_nv, *pv_nv; + nvpair_t *nvp, *pg_nvp; + int pg_done = 0, skip = 0; + + for (nvp = nvlist_next_nvpair(p_nv, NULL); nvp != NULL; + nvp = nvlist_next_nvpair(p_nv, nvp)) { + if (strcmp(TOPO_PROP_GROUP, nvpair_name(nvp)) != 0 || + nvpair_type(nvp) != DATA_TYPE_NVLIST) + continue; + + (void) nvpair_value_nvlist(nvp, &pg_nv); + for (pg_nvp = nvlist_next_nvpair(pg_nv, NULL); pg_nvp != NULL; + pg_nvp = nvlist_next_nvpair(pg_nv, pg_nvp)) { + /* + * Print property group name and stability levels + */ + if (strcmp(TOPO_PROP_GROUP_NAME, nvpair_name(pg_nvp)) + == 0 && nvpair_type(pg_nvp) == DATA_TYPE_STRING) { + (void) nvpair_value_string(pg_nvp, &pgn); + + skip = cmp_name(props, pgn); + + } else if (strcmp(TOPO_PROP_GROUP_NSTAB, + nvpair_name(pg_nvp)) == 0 && + nvpair_type(pg_nvp) == DATA_TYPE_STRING) { + (void) nvpair_value_string(pg_nvp, &nstab); + } else if (strcmp(TOPO_PROP_GROUP_DSTAB, + nvpair_name(pg_nvp)) == 0 && + nvpair_type(pg_nvp) == DATA_TYPE_STRING) { + (void) nvpair_value_string(pg_nvp, &dstab); + } else if (strcmp(TOPO_PROP_GROUP_VERSION, + nvpair_name(pg_nvp)) == 0 && + nvpair_type(pg_nvp) == DATA_TYPE_INT32) { + (void) nvpair_value_int32(pg_nvp, &version); + } + + if (!pg_done) { + if (pgn && dstab && nstab && version) { + print_pgroup(pgn, dstab, nstab, + version, skip); + pg_done++; + } else { + continue; + } + /* + * Print property name-value pair + */ + } else if (strcmp(TOPO_PROP_VAL, nvpair_name(pg_nvp)) + == 0 && nvpair_type(pg_nvp) == DATA_TYPE_NVLIST) { + (void) nvpair_value_nvlist(pg_nvp, &pv_nv); + print_prop_nameval(thp, pv_nv, skip); + + } + } + pg_done = 0; + skip = 0; + } +} + /*ARGSUSED*/ static int print_tnode(topo_hdl_t *thp, tnode_t *node, void *arg) { - if (opt_e && strcmp(opt_s, FM_FMRI_SCHEME_HC) == 0) + int err; + nvlist_t *nvl; + + if (opt_e && strcmp(opt_s, FM_FMRI_SCHEME_HC) == 0) { print_everstyle(node); - else - print_fmri(thp, node); + return (TOPO_WALK_NEXT); + } - if (opt_V) { - nvlist_t *nvl = topo_prop_get_all(thp, node); + print_fmri(thp, node); - if (nvl == NULL) { - (void) fprintf(stderr, "%s: failed to get properties " - "for %s=%d\n", g_pname, topo_node_name(node), - topo_node_instance(node)); + if (opt_V || opt_P) { + if ((nvl = topo_prop_getprops(node, &err)) == NULL) { + (void) fprintf(stderr, "%s: failed to get " + "properties for %s=%d: %s\n", g_pname, + topo_node_name(node), topo_node_instance(node), + topo_strerror(err)); } else { - nvlist_print(stdout, nvl); + print_props(thp, nvl, opt_P); nvlist_free(nvl); } } + printf("\n"); + return (TOPO_WALK_NEXT); } @@ -225,12 +495,12 @@ main(int argc, char *argv[]) topo_hdl_t *thp; topo_walk_t *twp; char *uuid; - int c, err; + int c, err = 0; g_pname = argv[0]; while (optind < argc) { - while ((c = getopt(argc, argv, "aCdeR:s:vV")) != -1) { + while ((c = getopt(argc, argv, "aCdeP:pR:s:vVx")) != -1) { switch (c) { case 'C': atexit(abort); @@ -241,8 +511,11 @@ main(int argc, char *argv[]) case 'e': opt_e++; break; - case 'v': - opt_v++; + case 'P': + opt_P = optarg; + break; + case 'p': + opt_p++; break; case 'V': opt_V++; @@ -253,6 +526,9 @@ main(int argc, char *argv[]) case 's': opt_s = optarg; break; + case 'x': + opt_x++; + break; default: return (usage(stderr)); } @@ -272,15 +548,31 @@ main(int argc, char *argv[]) } if (opt_d) - topo_debug_set(thp, TOPO_DBG_ALL, "stderr"); + topo_debug_set(thp, "module", "stderr"); if ((uuid = topo_snap_hold(thp, NULL, &err)) == NULL) { (void) fprintf(stderr, "%s: failed to snapshot topology: %s\n", g_pname, topo_strerror(err)); topo_close(thp); return (FMTOPO_EXIT_ERROR); + } else if (err != 0) { + (void) fprintf(stderr, "%s: topology snapshot incomplete\n", + g_pname); } + + if (opt_x) { + err = 0; + if (topo_xml_print(thp, stdout, opt_s, &err) < 0) + (void) fprintf(stderr, "%s: failed to print xml " + "formatted topology:%s", g_pname, + topo_strerror(err)); + + topo_hdl_strfree(thp, uuid); + topo_snap_release(thp); + topo_close(thp); + return (err ? FMTOPO_EXIT_ERROR : FMTOPO_EXIT_SUCCESS); + } if ((twp = topo_walk_init(thp, opt_s, print_tnode, NULL, &err)) == NULL) { (void) fprintf(stderr, "%s: failed to walk %s topology:" @@ -293,8 +585,18 @@ main(int argc, char *argv[]) return (err ? FMTOPO_EXIT_ERROR : FMTOPO_EXIT_SUCCESS); } - if (!opt_e) - (void) printf("Topology Snapshot %s\n", uuid); + /* + * Print standard header + */ + if (!opt_e) { + char buf[32]; + time_t tod = time(NULL); + + printf("TIME UUID\n"); + (void) strftime(buf, sizeof (buf), "%b %d %T", localtime(&tod)); + (void) printf("%-15s %-32s\n", buf, uuid); + (void) printf("\n"); + } topo_hdl_strfree(thp, uuid); @@ -307,9 +609,6 @@ main(int argc, char *argv[]) return (FMTOPO_EXIT_ERROR); } - if (opt_d) - (void) printf("--------------------\n"); - topo_walk_fini(twp); topo_snap_release(thp); topo_close(thp); diff --git a/usr/src/cmd/fm/modules/common/eversholt/config.c b/usr/src/cmd/fm/modules/common/eversholt/config.c index 896164f401..96a0a6e63c 100644 --- a/usr/src/cmd/fm/modules/common/eversholt/config.c +++ b/usr/src/cmd/fm/modules/common/eversholt/config.c @@ -41,6 +41,7 @@ #include <ctype.h> #include <string.h> #include <strings.h> +#include <fm/topo_hc.h> #include "alloc.h" #include "out.h" #include "literals.h" @@ -341,7 +342,7 @@ config_cook(struct cfgdata *cdata) /* * If this property is a device path, cache it for quick lookup */ - if (pn == stable("DEV")) { + if (pn == stable(TOPO_IO_DEV)) { sv = stable(pv); out(O_ALTFP|O_VERB3, "caching %s\n", sv); cdata->devcache = lut_add(cdata->devcache, diff --git a/usr/src/cmd/fm/modules/common/eversholt/platform.c b/usr/src/cmd/fm/modules/common/eversholt/platform.c index 1b7b2bf8b2..8c1b80f49f 100644 --- a/usr/src/cmd/fm/modules/common/eversholt/platform.c +++ b/usr/src/cmd/fm/modules/common/eversholt/platform.c @@ -48,7 +48,9 @@ #include <sys/param.h> #include <sys/fm/protocol.h> #include <fm/fmd_api.h> +#include <fm/fmd_fmri.h> #include <fm/libtopo.h> +#include <fm/topo_hc.h> #include "alloc.h" #include "out.h" #include "tree.h" @@ -395,6 +397,12 @@ add_prop_val(topo_hdl_t *thp, struct cfgdata *rawdata, char *propn, char buf[32]; /* big enough for any 64-bit int */ /* + * malformed prop nvpair + */ + if (propn == NULL) + return; + + /* * We can only handle properties of string type */ switch (nvpair_type(pv_nvp)) { @@ -427,6 +435,8 @@ add_prop_val(topo_hdl_t *thp, struct cfgdata *rawdata, char *propn, break; default: + out(O_ALTFP, "cfgcollect: failed to get property value for " + "%s", propn); return; } @@ -436,6 +446,9 @@ add_prop_val(topo_hdl_t *thp, struct cfgdata *rawdata, char *propn, (void) snprintf(rawdata->nextfree, rawdata->end - rawdata->nextfree, "%s=%s", propn, propv); + if (strcmp(propn, TOPO_PROP_RESOURCE) == 0) + out(O_ALTFP, "cfgcollect: %s", propv); + rawdata->nextfree += addlen; if (fmristr != NULL) @@ -450,7 +463,7 @@ static int cfgcollect(topo_hdl_t *thp, tnode_t *node, void *arg) { struct cfgdata *rawdata = (struct cfgdata *)arg; - int addlen; + int err, addlen; char *propn, *path = NULL; nvlist_t *p_nv, *pg_nv, *pv_nv; nvpair_t *nvp, *pg_nvp, *pv_nvp; @@ -472,7 +485,7 @@ cfgcollect(topo_hdl_t *thp, tnode_t *node, void *arg) * Better yet, topo properties could be represented as * a packed nvlist */ - p_nv = topo_prop_get_all(thp, node); + p_nv = topo_prop_getprops(node, &err); for (nvp = nvlist_next_nvpair(p_nv, NULL); nvp != NULL; nvp = nvlist_next_nvpair(p_nv, nvp)) { if (strcmp(TOPO_PROP_GROUP, nvpair_name(nvp)) != 0 || @@ -490,22 +503,24 @@ cfgcollect(topo_hdl_t *thp, tnode_t *node, void *arg) (void) nvpair_value_nvlist(pg_nvp, &pv_nv); + propn = NULL; for (pv_nvp = nvlist_next_nvpair(pv_nv, NULL); pv_nvp != NULL; pv_nvp = nvlist_next_nvpair(pv_nv, pv_nvp)) { /* Get property name */ - propn = nvpair_name(pv_nvp); - if (strcmp(TOPO_PROP_VAL_NAME, propn) != 0) - continue; - if (nvpair_value_string(pv_nvp, &propn) != 0) - continue; + if (strcmp(TOPO_PROP_VAL_NAME, + nvpair_name(pv_nvp)) == 0) + (void) nvpair_value_string(pv_nvp, + &propn); /* * Get property value */ - pv_nvp = nvlist_next_nvpair(pv_nv, pv_nvp); - add_prop_val(thp, rawdata, propn, pv_nvp); + if (strcmp(TOPO_PROP_VAL_VAL, + nvpair_name(pv_nvp)) == 0) + add_prop_val(thp, rawdata, propn, + pv_nvp); } } @@ -523,22 +538,21 @@ struct cfgdata * platform_config_snapshot(void) { int err; - char *uuid; topo_walk_t *twp; + static uint64_t lastgen; + uint64_t curgen; /* - * * If the DR generation number has changed, * we need to grab a new snapshot, otherwise we * can simply point them at the last config. - * - * svgen = DRgen; - * if (svgen == (Drgen = fmd_drgen_get()) && Lastcfg != NULL) { - * Lastcfg->refcnt++; - * return (Lastcfg); - * } */ + if ((curgen = fmd_fmri_get_drgen()) <= lastgen && Lastcfg != NULL) { + Lastcfg->refcnt++; + return (Lastcfg); + } + lastgen = curgen; /* we're getting a new config, so clean up the last one */ if (Lastcfg != NULL) config_free(Lastcfg); @@ -551,19 +565,16 @@ platform_config_snapshot(void) Lastcfg->cpucache = NULL; out(O_ALTFP, "platform_config_snapshot(): topo snapshot"); - if ((uuid = topo_snap_hold(Eft_topo_hdl, NULL, &err)) == NULL) - out(O_DIE, "platform_config_snapshot: topo snapshot failed: %s", - topo_strerror(err)); + + Eft_topo_hdl = fmd_hdl_topology(Hdl, TOPO_VERSION); if ((twp = topo_walk_init(Eft_topo_hdl, FM_FMRI_SCHEME_HC, cfgcollect, Lastcfg, &err)) == NULL) { - topo_hdl_strfree(Eft_topo_hdl, uuid); out(O_DIE, "platform_config_snapshot: NULL topology tree: %s", topo_strerror(err)); } if (topo_walk_step(twp, TOPO_WALK_CHILD) == TOPO_WALK_ERR) { - topo_hdl_strfree(Eft_topo_hdl, uuid); topo_walk_fini(twp); out(O_DIE, "platform_config_snapshot: error walking topology " "tree"); @@ -571,8 +582,6 @@ platform_config_snapshot(void) topo_walk_fini(twp); - topo_hdl_strfree(Eft_topo_hdl, uuid); - topo_snap_release(Eft_topo_hdl); return (Lastcfg); } @@ -641,14 +650,15 @@ defect_units(nvlist_t **ap, nvlist_t **fp, struct config *croot, char *path) * Find the driver for this resource and use that to get * mod and pkg fmris for ASRU and FRU respectively. */ - if ((driverstr = cfgstrprop_lookup(croot, path, "DRIVER")) == NULL) + if ((driverstr = cfgstrprop_lookup(croot, path, TOPO_IO_DRIVER)) + == NULL) return; if (topo_hdl_nvalloc(Eft_topo_hdl, &arg, NV_UNIQUE_NAME) != 0) { out(O_ALTFP, "Can not allocate nvlist for MOD fmri lookup"); return; } - if (nvlist_add_string(arg, "DRIVER", driverstr) != 0) { + if (nvlist_add_string(arg, TOPO_IO_DRIVER, driverstr) != 0) { out(O_ALTFP, "Failed to add DRIVER string to arg nvlist"); nvlist_free(arg); return; diff --git a/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/diskmon_conf.c b/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/diskmon_conf.c index bf7901a7a4..4bf0e0c229 100644 --- a/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/diskmon_conf.c +++ b/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/diskmon_conf.c @@ -857,7 +857,7 @@ config_get(fmd_hdl_t *hdl, const fmd_prop_t *fmd_props) u64 = fmd_prop_get_int32(hdl, GLOBAL_PROP_LOG_LEVEL); g_verbose = (int)u64; - err = update_configuration_from_topo(NULL); + err = update_configuration_from_topo(hdl, NULL); /* Pull in the properties from the DE configuration file */ while (fmd_props[i].fmdp_name != NULL) { diff --git a/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/schg_mgr.c b/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/schg_mgr.c index 5bbca4d064..cf96f122f8 100644 --- a/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/schg_mgr.c +++ b/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/schg_mgr.c @@ -234,7 +234,7 @@ static void schg_update_fru_info(diskmon_t *diskp) { if (diskp->initial_configuration || - update_configuration_from_topo(diskp) == TOPO_SUCCESS) { + update_configuration_from_topo(g_fm_hdl, diskp) == TOPO_SUCCESS) { diskp->initial_configuration = B_FALSE; dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0); if (diskp->frup != NULL) diff --git a/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/topo_gather.c b/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/topo_gather.c index f9a6d75112..53ec759361 100644 --- a/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/topo_gather.c +++ b/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/topo_gather.c @@ -43,6 +43,7 @@ #include <config_admin.h> #include <sys/fm/protocol.h> #include <fm/libtopo.h> +#include <fm/topo_hc.h> #include "sata.h" #include "sfx4500_props.h" @@ -114,7 +115,7 @@ dm_fmri_to_diskmon(fmd_hdl_t *hdl, nvlist_t *fmri) (void) nvlist_remove(dupfmri, FM_FMRI_HC_PART, DATA_TYPE_STRING); thdl = fmd_hdl_topology(hdl, TOPO_VERSION); - if (thdl == NULL || topo_fmri_nvl2str(thdl, dupfmri, &buf, &err) != 0) { + if (topo_fmri_nvl2str(thdl, dupfmri, &buf, &err) != 0) { nvlist_free(dupfmri); return (NULL); } @@ -128,8 +129,9 @@ dm_fmri_to_diskmon(fmd_hdl_t *hdl, nvlist_t *fmri) } static nvlist_t * -find_sfx4500_private_pgroup(topo_hdl_t *thp, tnode_t *node) +find_sfx4500_private_pgroup(tnode_t *node) { + int err; nvlist_t *list_of_lists, *nvlp, *dupnvlp; nvlist_t *sfx4500_pgrp = NULL; nvpair_t *nvp = NULL; @@ -144,7 +146,7 @@ find_sfx4500_private_pgroup(topo_hdl_t *thp, tnode_t *node) * check inside each embedded nvlist to see if it's the pgroup we're * looking for. */ - if ((list_of_lists = topo_prop_get_all(thp, node)) != NULL) { + if ((list_of_lists = topo_prop_getprops(node, &err)) != NULL) { /* * Go through the list of nvlists, looking for the * property group we need. @@ -257,9 +259,15 @@ transform_model_string(char *manuf, char *model, char **finalstring, *finalstringbuflen = buflen; } +typedef struct walk_diskmon { + diskmon_t *target; + char *pfmri; +} walk_diskmon_t; + static int -topo_add_disk(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp) +topo_add_disk(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp) { + diskmon_t *target_diskp = wdp->target; nvlist_t *fmri = NULL; nvlist_t *asru_fmri; nvlist_t *fru_fmri; @@ -269,53 +277,25 @@ topo_add_disk(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp) char *serial = NULL; char *manuf = NULL; char *model = NULL; - char *cstr = NULL; char *buf; char *label; - char *p; uint64_t ptr = 0; int buflen; int err; - int orig_cstr_len; dm_fru_t *frup; diskmon_t *diskp; - /* - * Match this node to a disk in the configuration by looking at - * our parent's fmri (and do that by getting our FMRI and chopping - * off the last part). - */ - if (topo_node_resource(node, &fmri, &err) != 0) { - log_msg(MM_TOPO, "topo_add_disk: Could not generate FMRI for " - "node %p!\n", (void *)node); - return (-1); - } - - if (topo_fmri_nvl2str(thp, fmri, &cstr, &err) != 0) { - log_msg(MM_TOPO, "topo_add_disk: Could not create string for " - "node %p's FMRI!\n", (void *)node); - nvlist_free(fmri); - return (-1); - } - - nvlist_free(fmri); - - /* - * Chop off all but last path (since there's no way to get - * the node's parent in the libtopo API). - */ - orig_cstr_len = strlen(cstr) + 1; - p = strrchr(cstr, '/'); - dm_assert(p != NULL); - *p = 0; - if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &ptr) != 0) { - log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node); - topo_hdl_free(thp, cstr, orig_cstr_len); + dm_assert(wdp->pfmri != NULL); + if (nvlist_lookup_uint64(g_topo2diskmon, wdp->pfmri, &ptr) != 0) { + log_msg(MM_TOPO, "No diskmon for %s: parent of node %p.\n", + wdp->pfmri, node); + dstrfree(wdp->pfmri); /* Skip this disk: */ return (0); } - topo_hdl_free(thp, cstr, orig_cstr_len); + dstrfree(wdp->pfmri); + wdp->pfmri = NULL; diskp = (diskmon_t *)(uintptr_t)ptr; @@ -584,9 +564,10 @@ topoprop_indrule_add(indrule_t **indrp, char *sts, char *acts) static int -topo_add_sata_port(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp) +topo_add_sata_port(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp) { - nvlist_t *nvlp = find_sfx4500_private_pgroup(thp, node); + diskmon_t *target_diskp = wdp->target; + nvlist_t *nvlp = find_sfx4500_private_pgroup(node); nvlist_t *prop_nvlp; nvpair_t *nvp = NULL; char *prop_name, *prop_value; @@ -636,7 +617,7 @@ topo_add_sata_port(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp) dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0); } - dstrfree(cstr); + wdp->pfmri = cstr; nvlist_free(nvlp); return (0); } @@ -833,7 +814,7 @@ topo_add_sata_port(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp) nvlist_free(diskprops); } - dstrfree(cstr); + wdp->pfmri = cstr; } @@ -847,60 +828,59 @@ gather_topo_cfg(topo_hdl_t *thp, tnode_t *node, void *arg) { char *nodename = topo_node_name(node); if (strcmp(SATA_DISK, nodename) == 0) - return (topo_add_disk(thp, node, (diskmon_t *)arg) + return (topo_add_disk(thp, node, (walk_diskmon_t *)arg) ? TOPO_WALK_ERR : TOPO_WALK_NEXT); else if (strcmp(SATA_PORT, nodename) == 0) - return (topo_add_sata_port(thp, node, (diskmon_t *)arg) + return (topo_add_sata_port(thp, node, (walk_diskmon_t *)arg) ? TOPO_WALK_ERR : TOPO_WALK_NEXT); return (TOPO_WALK_NEXT); } +/*ARGSUSED*/ int -update_configuration_from_topo(diskmon_t *diskp) +update_configuration_from_topo(fmd_hdl_t *hdl, diskmon_t *diskp) { int err; topo_hdl_t *thp; topo_walk_t *twp; + walk_diskmon_t wd; char *uuid; if ((thp = topo_open(TOPO_VERSION, NULL, &err)) == NULL) { - return (TOPO_OPEN_ERROR); } if ((uuid = topo_snap_hold(thp, NULL, &err)) == NULL) { - topo_close(thp); return (TOPO_SNAP_ERROR); } + topo_hdl_strfree(thp, uuid); + wd.target = diskp; + wd.pfmri = NULL; if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, gather_topo_cfg, - diskp, &err)) == NULL) { - - topo_snap_release(thp); - topo_hdl_strfree(thp, uuid); - topo_close(thp); - + &wd, &err)) == NULL) { + topo_close(thp); /* topo_close() will release the snapshot */ return (err ? TOPO_WALK_INIT_ERROR : TOPO_SUCCESS); } - topo_hdl_strfree(thp, uuid); - if (topo_walk_step(twp, TOPO_WALK_CHILD) == TOPO_WALK_ERR) { topo_walk_fini(twp); - topo_snap_release(thp); - topo_close(thp); + if (wd.pfmri != NULL) + dstrfree(wd.pfmri); + topo_close(thp); return (TOPO_WALK_ERROR); } topo_walk_fini(twp); - topo_snap_release(thp); topo_close(thp); + if (wd.pfmri != NULL) + dstrfree(wd.pfmri); return (TOPO_SUCCESS); } diff --git a/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/topo_gather.h b/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/topo_gather.h index db4f0fbd8e..cf196976f0 100644 --- a/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/topo_gather.h +++ b/usr/src/cmd/fm/modules/i86pc/sfx4500-disk/topo_gather.h @@ -44,7 +44,7 @@ extern "C" { #define TOPO_SNAP_ERROR 3 #define TOPO_OPEN_ERROR 4 -int update_configuration_from_topo(diskmon_t *diskp); +int update_configuration_from_topo(fmd_hdl_t *, diskmon_t *diskp); int init_configuration_from_topo(void); void fini_configuration_from_topo(void); diskmon_t *dm_fmri_to_diskmon(fmd_hdl_t *hdl, nvlist_t *fmri); diff --git a/usr/src/cmd/fm/schemes/hc/scheme.c b/usr/src/cmd/fm/schemes/hc/scheme.c index a8defec38e..11b840c2b8 100644 --- a/usr/src/cmd/fm/schemes/hc/scheme.c +++ b/usr/src/cmd/fm/schemes/hc/scheme.c @@ -25,67 +25,56 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#include <fm/topo_mod.h> +#include <strings.h> #include <fm/fmd_fmri.h> #include <fm/libtopo.h> - -typedef struct hc_walk_arg { - void *p; - int *resultp; -} hc_walk_arg_t; - -static topo_hdl_t *HC_thp = NULL; -static char *HC_uuid = NULL; +#include <fm/topo_mod.h> int fmd_fmri_init(void) { - int err; - - if ((HC_thp = topo_open(TOPO_VERSION, NULL, &err)) == NULL) - return (-1); - return (0); } void fmd_fmri_fini(void) { - if (HC_uuid) { - topo_snap_release(HC_thp); - topo_hdl_strfree(HC_thp, HC_uuid); - HC_uuid = NULL; - } - topo_close(HC_thp); } -static int -hc_update_topology(void) +ssize_t +fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) { - static uint64_t lastgen = 0; int err; - uint64_t curgen; + uint8_t version; + ssize_t len; + topo_hdl_t *thp; + char *str; - if (HC_uuid == NULL || - (curgen = fmd_fmri_get_drgen()) > lastgen) { + if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || + version > FM_HC_SCHEME_VERSION) + return (fmd_fmri_set_errno(EINVAL)); - lastgen = curgen; + thp = fmd_fmri_topology(TOPO_VERSION); + if (topo_fmri_nvl2str(thp, nvl, &str, &err) != 0) + return (fmd_fmri_set_errno(EINVAL)); - if (HC_uuid) { - topo_snap_release(HC_thp); - topo_hdl_strfree(HC_thp, HC_uuid); - HC_uuid = NULL; - } + if (buf != NULL) + len = snprintf(buf, buflen, "%s", str); + else + len = strlen(str); - if ((HC_uuid = topo_snap_hold(HC_thp, NULL, &err)) == NULL) { - return (-1); - } - } - return (0); + topo_hdl_strfree(thp, str); + + return (len); } +typedef struct hc_walk_arg { + void *p; + int *resultp; +} hc_walk_arg_t; + static int -hc_topo_walk(topo_walk_cb_t fn, void *arg, int *resultp) +hc_topo_walk(topo_hdl_t *thp, topo_walk_cb_t fn, void *arg, int *resultp) { int err, rv; topo_walk_t *twp; @@ -94,7 +83,7 @@ hc_topo_walk(topo_walk_cb_t fn, void *arg, int *resultp) hcarg.p = arg; hcarg.resultp = resultp; - if ((twp = topo_walk_init(HC_thp, FM_FMRI_SCHEME_HC, fn, + if ((twp = topo_walk_init(thp, FM_FMRI_SCHEME_HC, fn, &hcarg, &err)) == NULL) return (-1); @@ -105,163 +94,21 @@ hc_topo_walk(topo_walk_cb_t fn, void *arg, int *resultp) return (rv); } -/* - * buf_append -- Append str to buf (if it's non-NULL). Place prepend - * in buf in front of str and append behind it (if they're non-NULL). - * Continue to update size even if we run out of space to actually - * stuff characters in the buffer. - */ -static void -buf_append(ssize_t *sz, char *buf, size_t buflen, char *str, - char *prepend, char *append) -{ - ssize_t left; - - if (str == NULL) - return; - - if (buflen == 0 || (left = buflen - *sz) < 0) - left = 0; - - if (buf != NULL && left != 0) - buf += *sz; - - if (prepend == NULL && append == NULL) - *sz += snprintf(buf, left, "%s", str); - else if (append == NULL) - *sz += snprintf(buf, left, "%s%s", prepend, str); - else if (prepend == NULL) - *sz += snprintf(buf, left, "%s%s", str, append); - else - *sz += snprintf(buf, left, "%s%s%s", prepend, str, append); -} - -ssize_t -fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) -{ - nvlist_t **hcprs = NULL; - nvlist_t *anvl = NULL; - uint8_t version; - ssize_t size = 0; - uint_t hcnprs; - char *achas = NULL; - char *adom = NULL; - char *aprod = NULL; - char *asrvr = NULL; - char *ahost = NULL; - char *serial = NULL; - char *part = NULL; - char *root = NULL; - char *rev = NULL; - int more_auth = 0; - int err, i; - - if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 || - version > FM_HC_SCHEME_VERSION) - return (fmd_fmri_set_errno(EINVAL)); - - /* Get authority, if present */ - err = nvlist_lookup_nvlist(nvl, FM_FMRI_AUTHORITY, &anvl); - if (err != 0 && err != ENOENT) - return (fmd_fmri_set_errno(err)); - - if ((err = nvlist_lookup_string(nvl, FM_FMRI_HC_ROOT, &root)) != 0) - return (fmd_fmri_set_errno(EINVAL)); - - err = nvlist_lookup_nvlist_array(nvl, FM_FMRI_HC_LIST, &hcprs, &hcnprs); - if (err != 0 || hcprs == NULL) - return (fmd_fmri_set_errno(EINVAL)); - - if (anvl != NULL) { - (void) nvlist_lookup_string(anvl, - FM_FMRI_AUTH_PRODUCT, &aprod); - (void) nvlist_lookup_string(anvl, - FM_FMRI_AUTH_CHASSIS, &achas); - (void) nvlist_lookup_string(anvl, - FM_FMRI_AUTH_DOMAIN, &adom); - (void) nvlist_lookup_string(anvl, - FM_FMRI_AUTH_SERVER, &asrvr); - (void) nvlist_lookup_string(anvl, - FM_FMRI_AUTH_HOST, &ahost); - if (aprod != NULL) - more_auth++; - if (achas != NULL) - more_auth++; - if (adom != NULL) - more_auth++; - if (asrvr != NULL) - more_auth++; - if (ahost != NULL) - more_auth++; - } - - (void) nvlist_lookup_string(nvl, FM_FMRI_HC_SERIAL_ID, &serial); - (void) nvlist_lookup_string(nvl, FM_FMRI_HC_PART, &part); - (void) nvlist_lookup_string(nvl, FM_FMRI_HC_REVISION, &rev); - - /* hc:// */ - buf_append(&size, buf, buflen, FM_FMRI_SCHEME_HC, NULL, "://"); - - /* authority, if any */ - if (aprod != NULL) - buf_append(&size, buf, buflen, aprod, FM_FMRI_AUTH_PRODUCT "=", - --more_auth > 0 ? "," : NULL); - if (achas != NULL) - buf_append(&size, buf, buflen, achas, FM_FMRI_AUTH_CHASSIS "=", - --more_auth > 0 ? "," : NULL); - if (adom != NULL) - buf_append(&size, buf, buflen, adom, FM_FMRI_AUTH_DOMAIN "=", - --more_auth > 0 ? "," : NULL); - if (asrvr != NULL) - buf_append(&size, buf, buflen, asrvr, FM_FMRI_AUTH_SERVER "=", - --more_auth > 0 ? "," : NULL); - if (ahost != NULL) - buf_append(&size, buf, buflen, ahost, FM_FMRI_AUTH_HOST "=", - NULL); - - /* separating slash */ - if (serial != NULL || part != NULL || rev != NULL) - buf_append(&size, buf, buflen, "/", NULL, NULL); - - /* hardware-id part */ - buf_append(&size, buf, buflen, serial, ":" FM_FMRI_HC_SERIAL_ID "=", - NULL); - buf_append(&size, buf, buflen, part, ":" FM_FMRI_HC_PART "=", NULL); - buf_append(&size, buf, buflen, rev, ":" FM_FMRI_HC_REVISION "=", NULL); - - /* separating slash */ - buf_append(&size, buf, buflen, "/", NULL, NULL); - - /* hc-root */ - buf_append(&size, buf, buflen, root, NULL, NULL); - - /* all the pairs */ - for (i = 0; i < hcnprs; i++) { - char *nm = NULL; - char *id = NULL; - - if (i > 0) - buf_append(&size, buf, buflen, "/", NULL, NULL); - (void) nvlist_lookup_string(hcprs[i], FM_FMRI_HC_NAME, &nm); - (void) nvlist_lookup_string(hcprs[i], FM_FMRI_HC_ID, &id); - if (nm == NULL || id == NULL) - return (fmd_fmri_set_errno(EINVAL)); - buf_append(&size, buf, buflen, nm, NULL, "="); - buf_append(&size, buf, buflen, id, NULL, NULL); - } - - return (size); -} - /*ARGSUSED*/ static int hc_topo_present(topo_hdl_t *thp, tnode_t *node, void *arg) { int cmp, err; - nvlist_t *out = NULL; - nvlist_t *asru; + nvlist_t *out, *asru; hc_walk_arg_t *hcargp = (hc_walk_arg_t *)arg; + /* + * Only care about sata-ports and disks + */ + if (strcmp(topo_node_name(node), SATA_PORT) != 0 && + strcmp(topo_node_name(node), DISK) != 0) + return (TOPO_WALK_NEXT); + if (topo_node_asru(node, &asru, NULL, &err) != 0 || asru == NULL) { return (TOPO_WALK_NEXT); @@ -280,49 +127,80 @@ hc_topo_present(topo_hdl_t *thp, tnode_t *node, void *arg) /* * Yes, so try to execute the topo-present method. */ - cmp = topo_method_invoke(node, TOPO_METH_PRESENT, - TOPO_METH_PRESENT_VERSION, (nvlist_t *)hcargp->p, &out, &err); - - if (out) + if (topo_method_invoke(node, TOPO_METH_PRESENT, + TOPO_METH_PRESENT_VERSION, (nvlist_t *)hcargp->p, &out, &err) + == 0) { + (void) nvlist_lookup_uint32(out, TOPO_METH_PRESENT_RET, + (uint32_t *)hcargp->resultp); nvlist_free(out); - - if (cmp == 1) { - *(hcargp->resultp) = 1; - return (TOPO_WALK_TERMINATE); - } else if (cmp == 0) { - *(hcargp->resultp) = 0; return (TOPO_WALK_TERMINATE); + } else { + return (TOPO_WALK_ERR); } - return (TOPO_WALK_NEXT); } - /* - * fmd_fmri_present() is called by fmadm to determine if a faulty ASRU - * is still present in the system. In general we don't expect to get - * ASRUs in this scheme, so it's unlikely this routine will get called. - * In case it does, though, we just traverse our libtopo snapshot, - * looking for a matching ASRU (minus the serial number information), - * then invoke the "topo_present" method to determine presence. + * The SATA disk topology permits an ASRU to be declared as a pseudo-hc + * FMRI, something like this: + * + * hc:///motherboard=0/hostbridge=0/pcibus=0/pcidev=1/pcifn=0/sata-port=1 + * ASRU: hc:///component=sata0/1 + * FRU: hc:///component=MB + * Label: sata0/1 + * + * This is a hack to support cfgadm attachment point ASRUs without defining + * a new scheme. As a result, we need to support an is_present function for + * something * that begins with hc:///component=. To do this, we compare the + * nvlist provided by the caller against the ASRU property for all possible + * topology nodes. + * + * The SATA phase 2 project will address the lack of a proper FMRI scheme + * for cfgadm attachment points. This code may be removed when the SATA + * phase 2 FMA work is completed. */ -int -fmd_fmri_present(nvlist_t *nvl) +static int +hc_sata_hack(nvlist_t *nvl) { int ispresent = 1; + topo_hdl_t *thp; /* * If there's an error during the topology update, punt by * indicating presence. */ - if (hc_update_topology() < 0) - return (1); - - (void) hc_topo_walk(hc_topo_present, nvl, &ispresent); + thp = fmd_fmri_topology(TOPO_VERSION); + (void) hc_topo_walk(thp, hc_topo_present, nvl, &ispresent); return (ispresent); } +int +fmd_fmri_present(nvlist_t *nvl) +{ + int err, present; + topo_hdl_t *thp; + nvlist_t **hcprs; + char *nm; + uint_t hcnprs; + + err = nvlist_lookup_nvlist_array(nvl, FM_FMRI_HC_LIST, &hcprs, &hcnprs); + err |= nvlist_lookup_string(hcprs[0], FM_FMRI_HC_NAME, &nm); + if (err != 0) + return (0); + + if (strcmp(nm, "component") == 0) + return (hc_sata_hack(nvl)); + + thp = fmd_fmri_topology(TOPO_VERSION); + present = topo_fmri_present(thp, nvl, &err); + + if (err != 0) + return (present); + else + return (1); +} + /* * fmd_fmri_unusable() is called by fmadm to determine if a faulty ASRU * is usable. In general we don't expect to get ASRUs in this scheme, diff --git a/usr/src/cmd/fm/schemes/mem/mem.c b/usr/src/cmd/fm/schemes/mem/mem.c index 3ef591e91f..0a926c81ac 100644 --- a/usr/src/cmd/fm/schemes/mem/mem.c +++ b/usr/src/cmd/fm/schemes/mem/mem.c @@ -348,7 +348,7 @@ fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) * If we have a well-formed unum (hc-FMRI), use the string verbatim * to form the initial mem:/// components. Otherwise use unum=%s. */ - if (strncmp(rawunum, "hc:///", 6) != 0) + if (strncmp(rawunum, "hc://", 5) != 0) prefix = FM_FMRI_MEM_UNUM "="; else prefix = ""; @@ -371,14 +371,18 @@ fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) } /* - * If we have a well-formed unum (hc-FMRI), leave it as is. + * If we have a well-formed unum (hc-FMRI), we skip over the + * the scheme and authority prefix. * Otherwise, the spaces and colons will be escaped, * rendering the resulting FMRI pretty much unreadable. * We're therefore going to do some escaping of our own first. */ - if (strncmp(rawunum, "hc:///", 6) == 0) { + if (strncmp(rawunum, "hc://", 5) == 0) { + rawunum += 5; + rawunum = strchr(rawunum, '/'); + ++rawunum; /* LINTED: variable format specifier */ - size = snprintf(buf, buflen, format, rawunum + 6, val); + size = snprintf(buf, buflen, format, rawunum, val); } else { preunum = fmd_fmri_strdup(rawunum); presz = strlen(preunum) + 1; diff --git a/usr/src/cmd/fm/scripts/fmsim.ksh b/usr/src/cmd/fm/scripts/fmsim.ksh index aeffcadbaf..6e20f25d43 100644 --- a/usr/src/cmd/fm/scripts/fmsim.ksh +++ b/usr/src/cmd/fm/scripts/fmsim.ksh @@ -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. @@ -21,7 +20,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -76,12 +75,21 @@ function cp_so case $name in _fmd_init) cp $1 $2/usr/lib/fm/fmd/plugins; return ;; fmd_fmri_nvl2str) cp $1 $2/usr/lib/fm/fmd/schemes; return ;; - topo_load) cp $1 $2/usr/lib/fm/topo; return ;; + topo_load) cp $1 $2/usr/lib/fm/topo/plugins; return ;; esac done die "\nunknown .so type -- $1" } +function cp_topo +{ + mkdir -p $2/usr/lib/fm/topo/maps + cp $1 $2/usr/lib/fm/topo/maps; + for platdir in $2/usr/platform/*/lib/fm/topo/maps; do + rm -f $platdir/* 2>/dev/null + done +} + function list_cmds { for cmd in fmadm fmdump fmstat; do @@ -220,14 +228,15 @@ for file in $files; do fmd.conf) cp $file $simroot/etc/fm/fmd ;; *.conf) cp $file $simroot/usr/lib/fm/fmd/plugins ;; *.dict) cp $file $simroot/usr/lib/fm/dict ;; - *.eft) die "\neversholt fault tree file not yet supported -- $file" ;; + *.eft) cp $file $simroot/usr/lib/fm/eft ;; *.esc) die "\neversholt source file not yet supported -- $file" ;; *.inj) inj_args="$inj_args $file" ;; *.log) inj_args="$inj_args $file" ;; *log) inj_args="$inj_args $file" ;; *.mo) cp $file $simroot/usr/lib/locale/$LANG/LC_MESSAGES ;; *.so) cp_so $file $simroot ;; - *.topo) cp $file $simroot/usr/lib/fm/topo ;; + *.topo) die "\n .topo files not supported -- $file" ;; + *.xml) cp_topo $file $simroot ;; *) die "\nunknown file type or suffix -- $file" ;; esac echo " $base\c" @@ -243,7 +252,7 @@ cat >$simscript <<EOS # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" +#ident "@(#)fmsim.ksh 1.5 06/10/11 SMI" # # fmsim(1M) script generated for $simroot $(date) 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/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/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/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 } }; diff --git a/usr/src/pkgdefs/SUNWfmd/prototype_com b/usr/src/pkgdefs/SUNWfmd/prototype_com index 4b91587a3a..a8b329f784 100644 --- a/usr/src/pkgdefs/SUNWfmd/prototype_com +++ b/usr/src/pkgdefs/SUNWfmd/prototype_com @@ -41,6 +41,7 @@ f none usr/include/fm/fmd_log.h 644 root bin f none usr/include/fm/fmd_snmp.h 644 root bin f none usr/include/fm/libtopo.h 644 root bin f none usr/include/fm/topo_mod.h 644 root bin +f none usr/include/fm/topo_hc.h 644 root bin d none usr/lib 755 root bin d none usr/lib/fm 755 root bin d none usr/lib/fm/dict 755 root bin diff --git a/usr/src/pkgdefs/SUNWfmd/prototype_i386 b/usr/src/pkgdefs/SUNWfmd/prototype_i386 index f4005bfcf4..34d8cc9545 100644 --- a/usr/src/pkgdefs/SUNWfmd/prototype_i386 +++ b/usr/src/pkgdefs/SUNWfmd/prototype_i386 @@ -68,7 +68,9 @@ f none usr/platform/i86pc/lib/fm/topo/plugins/chip.so 555 root bin f none usr/platform/i86pc/lib/fm/topo/plugins/hostbridge.so 555 root bin f none usr/platform/i86pc/lib/fm/topo/plugins/pcibus.so 555 root bin f none usr/platform/i86pc/lib/fm/topo/plugins/sata.so 555 root bin -f none usr/platform/i86pc/lib/fm/topo/hc-topology.xml 444 root bin +d none usr/platform/i86pc/lib/fm/topo/maps 755 root bin +f none usr/platform/i86pc/lib/fm/topo/maps/i86pc-hc-topology.xml 444 root bin +f none usr/platform/i86pc/lib/fm/topo/maps/storage-hc-topology.xml 444 root bin d none usr/platform/i86pc/lib/fm/fmd 755 root bin d none usr/platform/i86pc/lib/fm/fmd/plugins 755 root bin f none usr/platform/i86pc/lib/fm/fmd/plugins/sfx4500-disk.so 555 root bin diff --git a/usr/src/pkgdefs/SUNWfmd/prototype_sparc b/usr/src/pkgdefs/SUNWfmd/prototype_sparc index e3532d8686..e3060aa792 100644 --- a/usr/src/pkgdefs/SUNWfmd/prototype_sparc +++ b/usr/src/pkgdefs/SUNWfmd/prototype_sparc @@ -94,7 +94,8 @@ f none usr/platform/sun4u/lib/fm/fmd/plugins/datapath-retire.conf 644 root bin f none usr/platform/sun4u/lib/fm/fmd/plugins/USII-io-diagnosis.so 555 root bin f none usr/platform/sun4u/lib/fm/fmd/plugins/USII-io-diagnosis.conf 644 root bin d none usr/platform/sun4u/lib/fm/topo 755 root bin -f none usr/platform/sun4u/lib/fm/topo/hc-topology.xml 444 root bin +d none usr/platform/sun4u/lib/fm/topo/maps 755 root bin +f none usr/platform/sun4u/lib/fm/topo/maps/sun4u-hc-topology.xml 444 root bin d none usr/platform/sun4u/lib/fm/topo/plugins 755 root bin f none usr/platform/sun4u/lib/fm/topo/plugins/chip.so 555 root bin f none usr/platform/sun4u/lib/fm/topo/plugins/hostbridge.so 555 root bin @@ -117,12 +118,12 @@ f none usr/platform/sun4v/lib/fm/fmd/plugins/cpumem-retire.conf 644 root bin f none usr/platform/sun4v/lib/fm/fmd/plugins/etm.so 555 root bin f none usr/platform/sun4v/lib/fm/fmd/plugins/etm.conf 644 root bin d none usr/platform/sun4v/lib/fm/topo 755 root bin -f none usr/platform/sun4v/lib/fm/topo/hc-topology.xml 444 root bin +d none usr/platform/sun4v/lib/fm/topo/maps 755 root bin +f none usr/platform/sun4v/lib/fm/topo/maps/sun4v-hc-topology.xml 444 root bin d none usr/platform/sun4v/lib/fm/topo/plugins 755 root bin f none usr/platform/sun4v/lib/fm/topo/plugins/chip.so 555 root bin f none usr/platform/sun4v/lib/fm/topo/plugins/hostbridge.so 555 root bin f none usr/platform/sun4v/lib/fm/topo/plugins/pcibus.so 555 root bin -f none usr/platform/sun4v/lib/fm/topo/plugins/ioboard.so 555 root bin d none usr/platform/SUNW,SPARC-Enterprise 755 root sys d none usr/platform/SUNW,SPARC-Enterprise/lib 755 root bin d none usr/platform/SUNW,SPARC-Enterprise/lib/fm 755 root bin @@ -133,14 +134,16 @@ f none usr/platform/SUNW,SPARC-Enterprise/lib/fm/fmd/plugins/cpumem-retire.conf f none usr/platform/SUNW,SPARC-Enterprise/lib/fm/fmd/plugins/event-transport.so 555 root bin f none usr/platform/SUNW,SPARC-Enterprise/lib/fm/fmd/plugins/event-transport.conf 644 root bin d none usr/platform/SUNW,SPARC-Enterprise/lib/fm/topo 755 root bin -f none usr/platform/SUNW,SPARC-Enterprise/lib/fm/topo/hc-topology.xml 444 root bin +d none usr/platform/SUNW,SPARC-Enterprise/lib/fm/topo/maps 755 root bin +f none usr/platform/SUNW,SPARC-Enterprise/lib/fm/topo/maps/SPARC-Enterprise-hc-topology.xml 444 root bin d none usr/platform/SUNW,SPARC-Enterprise/lib/fm/topo/plugins 755 root bin f none usr/platform/SUNW,SPARC-Enterprise/lib/fm/topo/plugins/ioboard.so 555 root bin d none usr/platform/SUNW,Sun-Fire 755 root sys d none usr/platform/SUNW,Sun-Fire/lib 755 root bin d none usr/platform/SUNW,Sun-Fire/lib/fm 755 root bin d none usr/platform/SUNW,Sun-Fire/lib/fm/topo 755 root bin -f none usr/platform/SUNW,Sun-Fire/lib/fm/topo/hc-topology.xml 444 root bin +d none usr/platform/SUNW,Sun-Fire/lib/fm/topo/maps 755 root bin +f none usr/platform/SUNW,Sun-Fire/lib/fm/topo/maps/Sun-Fire-hc-topology.xml 444 root bin d none usr/platform/SUNW,Sun-Fire/lib/fm/topo/plugins 755 root bin f none usr/platform/SUNW,Sun-Fire/lib/fm/topo/plugins/ioboard.so 555 root bin d none usr/platform/SUNW,Sun-Fire-15000 755 root sys @@ -149,16 +152,16 @@ d none usr/platform/SUNW,Sun-Fire-15000/lib/fm 755 root bin d none usr/platform/SUNW,Sun-Fire-15000/lib/fm/eft 755 root bin f none usr/platform/SUNW,Sun-Fire-15000/lib/fm/eft/SUNW,Sun-Fire-15000.eft 444 root bin d none usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo 755 root bin -f none usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/hc-topology.xml 444 root bin +d none usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/maps 755 root bin +f none usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/maps/Sun-Fire-15000-hc-topology.xml 444 root bin d none usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/plugins 755 root bin f none usr/platform/SUNW,Sun-Fire-15000/lib/fm/topo/plugins/ioboard.so 555 root bin d none usr/platform/SUNW,Sun-Fire-T200 755 root sys d none usr/platform/SUNW,Sun-Fire-T200/lib 755 root bin d none usr/platform/SUNW,Sun-Fire-T200/lib/fm 755 root bin d none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo 755 root bin -f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/hc-topology.xml 444 root bin -d none usr/platform/SUNW,Sun-Blade-T6300 755 root sys -d none usr/platform/SUNW,Sun-Blade-T6300/lib 755 root bin -d none usr/platform/SUNW,Sun-Blade-T6300/lib/fm 755 root bin -d none usr/platform/SUNW,Sun-Blade-T6300/lib/fm/topo 755 root bin -f none usr/platform/SUNW,Sun-Blade-T6300/lib/fm/topo/hc-topology.xml 444 root bin +d none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps 755 root bin +f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/Sun-Fire-T200-hc-topology.xml 444 root bin +f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/Sun-Fire-T1000-hc-topology.xml 444 root bin +f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/SPARC-Enterprise-T1000-hc-topology.xml 444 root bin +f none usr/platform/SUNW,Sun-Fire-T200/lib/fm/topo/maps/Sun-Blade-T6300-hc-topology.xml 444 root bin diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh index c1fa6b528c..85a6406488 100644 --- a/usr/src/tools/scripts/bfu.sh +++ b/usr/src/tools/scripts/bfu.sh @@ -4616,6 +4616,7 @@ mondo_loop() { # Remove old topology data # rm -rf $usr/lib/fm/topo + rm -f $usr/platform/*/lib/fm/topo/hc-topology.xml # # Remove old prtopo and obsoleted include file. |
