diff options
author | km84432 <none@none> | 2007-07-30 14:32:47 -0700 |
---|---|---|
committer | km84432 <none@none> | 2007-07-30 14:32:47 -0700 |
commit | a83cadce5d3331b64803bfc641036cec23602c74 (patch) | |
tree | 1fde5ab89acaa2dedaca1f639c34da88fb26fd84 /usr/src | |
parent | d142717dd4be9294d8bf7efaaec924308825d5c1 (diff) | |
download | illumos-gate-a83cadce5d3331b64803bfc641036cec23602c74.tar.gz |
PSARC 2007/308: Removal of Sun Fire Link (Wildcat) Support
6269063 Remove support for Sun Fire Link (Wildcat)
--HG--
rename : usr/src/cmd/mdb/sun4u/modules/wrsm/Makefile => deleted_files/usr/src/cmd/mdb/sun4u/modules/wrsm/Makefile
rename : usr/src/cmd/mdb/sun4u/modules/wrsm/v9/Makefile => deleted_files/usr/src/cmd/mdb/sun4u/modules/wrsm/v9/Makefile
rename : usr/src/cmd/mdb/sun4u/modules/wrsm/wrsm.c => deleted_files/usr/src/cmd/mdb/sun4u/modules/wrsm/wrsm.c
rename : usr/src/cmd/mdb/sun4u/modules/wrsmd/Makefile => deleted_files/usr/src/cmd/mdb/sun4u/modules/wrsmd/Makefile
rename : usr/src/cmd/mdb/sun4u/modules/wrsmd/v9/Makefile => deleted_files/usr/src/cmd/mdb/sun4u/modules/wrsmd/v9/Makefile
rename : usr/src/cmd/mdb/sun4u/modules/wrsmd/wrsmd.c => deleted_files/usr/src/cmd/mdb/sun4u/modules/wrsmd/wrsmd.c
rename : usr/src/cmd/wrsmconf/Makefile => deleted_files/usr/src/cmd/wrsmconf/Makefile
rename : usr/src/cmd/wrsmconf/mkconfig.c => deleted_files/usr/src/cmd/wrsmconf/mkconfig.c
rename : usr/src/cmd/wrsmconf/wrsmcfg => deleted_files/usr/src/cmd/wrsmconf/wrsmcfg
rename : usr/src/cmd/wrsmconf/wrsmconf.c => deleted_files/usr/src/cmd/wrsmconf/wrsmconf.c
rename : usr/src/cmd/wrsmconf/wrsmconf_msgs.h => deleted_files/usr/src/cmd/wrsmconf/wrsmconf_msgs.h
rename : usr/src/cmd/wrsmstat/Makefile => deleted_files/usr/src/cmd/wrsmstat/Makefile
rename : usr/src/cmd/wrsmstat/wrsm_lastwci => deleted_files/usr/src/cmd/wrsmstat/wrsm_lastwci
rename : usr/src/cmd/wrsmstat/wrsmstat.c => deleted_files/usr/src/cmd/wrsmstat/wrsmstat.c
rename : usr/src/lib/libwrsmconf/Makefile => deleted_files/usr/src/lib/libwrsmconf/Makefile
rename : usr/src/lib/libwrsmconf/Makefile.com => deleted_files/usr/src/lib/libwrsmconf/Makefile.com
rename : usr/src/lib/libwrsmconf/confpack.c => deleted_files/usr/src/lib/libwrsmconf/confpack.c
rename : usr/src/lib/libwrsmconf/confparse.l => deleted_files/usr/src/lib/libwrsmconf/confparse.l
rename : usr/src/lib/libwrsmconf/confparse.y => deleted_files/usr/src/lib/libwrsmconf/confparse.y
rename : usr/src/lib/libwrsmconf/confprint.c => deleted_files/usr/src/lib/libwrsmconf/confprint.c
rename : usr/src/lib/libwrsmconf/libwrsmconf.c => deleted_files/usr/src/lib/libwrsmconf/libwrsmconf.c
rename : usr/src/lib/libwrsmconf/sparc/Makefile => deleted_files/usr/src/lib/libwrsmconf/sparc/Makefile
rename : usr/src/lib/libwrsmconf/sparcv9/Makefile => deleted_files/usr/src/lib/libwrsmconf/sparcv9/Makefile
rename : usr/src/lib/libwrsmconf/util.c => deleted_files/usr/src/lib/libwrsmconf/util.c
rename : usr/src/lib/libwrsmconf/util.h => deleted_files/usr/src/lib/libwrsmconf/util.h
rename : usr/src/lib/libwrsmconf/wrsm_confpack.c => deleted_files/usr/src/lib/libwrsmconf/wrsm_confpack.c
rename : usr/src/lib/libwrsmconf/wrsmconf.h => deleted_files/usr/src/lib/libwrsmconf/wrsmconf.h
rename : usr/src/lib/libwrsmconf/wrsmconf_impl.h => deleted_files/usr/src/lib/libwrsmconf/wrsmconf_impl.h
rename : usr/src/lib/wrsm/Makefile => deleted_files/usr/src/lib/wrsm/Makefile
rename : usr/src/lib/wrsm/Makefile.com => deleted_files/usr/src/lib/wrsm/Makefile.com
rename : usr/src/lib/wrsm/librsmwrsm.c => deleted_files/usr/src/lib/wrsm/librsmwrsm.c
rename : usr/src/lib/wrsm/librsmwrsm.h => deleted_files/usr/src/lib/wrsm/librsmwrsm.h
rename : usr/src/lib/wrsm/sparc/Makefile => deleted_files/usr/src/lib/wrsm/sparc/Makefile
rename : usr/src/lib/wrsm/sparcv9/Makefile => deleted_files/usr/src/lib/wrsm/sparcv9/Makefile
rename : usr/src/lib/wrsm/wrsmlib.s => deleted_files/usr/src/lib/wrsm/wrsmlib.s
rename : usr/src/pkgdefs/SUNWwrsa.u/Makefile => deleted_files/usr/src/pkgdefs/SUNWwrsa.u/Makefile
rename : usr/src/pkgdefs/SUNWwrsa.u/pkginfo.tmpl => deleted_files/usr/src/pkgdefs/SUNWwrsa.u/pkginfo.tmpl
rename : usr/src/pkgdefs/SUNWwrsa.u/prototype_sparc => deleted_files/usr/src/pkgdefs/SUNWwrsa.u/prototype_sparc
rename : usr/src/pkgdefs/SUNWwrsd.u/Makefile => deleted_files/usr/src/pkgdefs/SUNWwrsd.u/Makefile
rename : usr/src/pkgdefs/SUNWwrsd.u/depend => deleted_files/usr/src/pkgdefs/SUNWwrsd.u/depend
rename : usr/src/pkgdefs/SUNWwrsd.u/pkginfo.tmpl => deleted_files/usr/src/pkgdefs/SUNWwrsd.u/pkginfo.tmpl
rename : usr/src/pkgdefs/SUNWwrsd.u/postinstall => deleted_files/usr/src/pkgdefs/SUNWwrsd.u/postinstall
rename : usr/src/pkgdefs/SUNWwrsd.u/preremove => deleted_files/usr/src/pkgdefs/SUNWwrsd.u/preremove
rename : usr/src/pkgdefs/SUNWwrsd.u/prototype_sparc => deleted_files/usr/src/pkgdefs/SUNWwrsd.u/prototype_sparc
rename : usr/src/pkgdefs/SUNWwrsm.u/Makefile => deleted_files/usr/src/pkgdefs/SUNWwrsm.u/Makefile
rename : usr/src/pkgdefs/SUNWwrsm.u/depend => deleted_files/usr/src/pkgdefs/SUNWwrsm.u/depend
rename : usr/src/pkgdefs/SUNWwrsm.u/pkginfo.tmpl => deleted_files/usr/src/pkgdefs/SUNWwrsm.u/pkginfo.tmpl
rename : usr/src/pkgdefs/SUNWwrsm.u/postinstall => deleted_files/usr/src/pkgdefs/SUNWwrsm.u/postinstall
rename : usr/src/pkgdefs/SUNWwrsm.u/preremove => deleted_files/usr/src/pkgdefs/SUNWwrsm.u/preremove
rename : usr/src/pkgdefs/SUNWwrsm.u/prototype_sparc => deleted_files/usr/src/pkgdefs/SUNWwrsm.u/prototype_sparc
rename : usr/src/pkgdefs/SUNWwrsu.u/Makefile => deleted_files/usr/src/pkgdefs/SUNWwrsu.u/Makefile
rename : usr/src/pkgdefs/SUNWwrsu.u/pkginfo.tmpl => deleted_files/usr/src/pkgdefs/SUNWwrsu.u/pkginfo.tmpl
rename : usr/src/pkgdefs/SUNWwrsu.u/prototype_sparc => deleted_files/usr/src/pkgdefs/SUNWwrsu.u/prototype_sparc
rename : usr/src/uts/sun4u/io/wci_common.c => deleted_files/usr/src/uts/sun4u/io/wci_common.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm.conf => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm.conf
rename : usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_cf.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_cf.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_cmmu.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_cmmu.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_common.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_common.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_confpack.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_confpack.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_copy.s => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_copy.s
rename : usr/src/uts/sun4u/io/wrsm/wrsm_driver.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_driver.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_getput.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_getput.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_intr.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_intr.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_lc.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_lc.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_memseg.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_memseg.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_memseg_export.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_memseg_export.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_memseg_import.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_memseg_import.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_mh.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_mh.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_nc.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_nc.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_nr.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_nr.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_offsets.in => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_offsets.in
rename : usr/src/uts/sun4u/io/wrsm/wrsm_rsmpi.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_rsmpi.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_session.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_session.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_tl.c => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_tl.c
rename : usr/src/uts/sun4u/io/wrsm/wrsm_trap.s => deleted_files/usr/src/uts/sun4u/io/wrsm/wrsm_trap.s
rename : usr/src/uts/sun4u/io/wrsmd.c => deleted_files/usr/src/uts/sun4u/io/wrsmd.c
rename : usr/src/uts/sun4u/io/wrsmd.conf => deleted_files/usr/src/uts/sun4u/io/wrsmd.conf
rename : usr/src/uts/sun4u/serengeti/io/wrsmplat.c => deleted_files/usr/src/uts/sun4u/serengeti/io/wrsmplat.c
rename : usr/src/uts/sun4u/serengeti/wrsm/Makefile => deleted_files/usr/src/uts/sun4u/serengeti/wrsm/Makefile
rename : usr/src/uts/sun4u/serengeti/wrsmplat/Makefile => deleted_files/usr/src/uts/sun4u/serengeti/wrsmplat/Makefile
rename : usr/src/uts/sun4u/starcat/gptwo_wci/Makefile => deleted_files/usr/src/uts/sun4u/starcat/gptwo_wci/Makefile
rename : usr/src/uts/sun4u/starcat/io/gptwo_wci.c => deleted_files/usr/src/uts/sun4u/starcat/io/gptwo_wci.c
rename : usr/src/uts/sun4u/starcat/io/wrsmplat.c => deleted_files/usr/src/uts/sun4u/starcat/io/wrsmplat.c
rename : usr/src/uts/sun4u/starcat/ml/wrsmplat_asm.s => deleted_files/usr/src/uts/sun4u/starcat/ml/wrsmplat_asm.s
rename : usr/src/uts/sun4u/starcat/sys/gptwo_wci.h => deleted_files/usr/src/uts/sun4u/starcat/sys/gptwo_wci.h
rename : usr/src/uts/sun4u/starcat/sys/wrsmplat.h => deleted_files/usr/src/uts/sun4u/starcat/sys/wrsmplat.h
rename : usr/src/uts/sun4u/starcat/wrsmplat/Makefile => deleted_files/usr/src/uts/sun4u/starcat/wrsmplat/Makefile
rename : usr/src/uts/sun4u/sys/wci_cmmu.h => deleted_files/usr/src/uts/sun4u/sys/wci_cmmu.h
rename : usr/src/uts/sun4u/sys/wci_common.h => deleted_files/usr/src/uts/sun4u/sys/wci_common.h
rename : usr/src/uts/sun4u/sys/wci_masks.h => deleted_files/usr/src/uts/sun4u/sys/wci_masks.h
rename : usr/src/uts/sun4u/sys/wci_offsets.h => deleted_files/usr/src/uts/sun4u/sys/wci_offsets.h
rename : usr/src/uts/sun4u/sys/wci_regs.h => deleted_files/usr/src/uts/sun4u/sys/wci_regs.h
rename : usr/src/uts/sun4u/sys/wrsm.h => deleted_files/usr/src/uts/sun4u/sys/wrsm.h
rename : usr/src/uts/sun4u/sys/wrsm_barrier.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_barrier.h
rename : usr/src/uts/sun4u/sys/wrsm_cf.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_cf.h
rename : usr/src/uts/sun4u/sys/wrsm_cf_impl.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_cf_impl.h
rename : usr/src/uts/sun4u/sys/wrsm_cmmu.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_cmmu.h
rename : usr/src/uts/sun4u/sys/wrsm_common.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_common.h
rename : usr/src/uts/sun4u/sys/wrsm_config.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_config.h
rename : usr/src/uts/sun4u/sys/wrsm_driver.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_driver.h
rename : usr/src/uts/sun4u/sys/wrsm_intr.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_intr.h
rename : usr/src/uts/sun4u/sys/wrsm_intr_impl.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_intr_impl.h
rename : usr/src/uts/sun4u/sys/wrsm_lc.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_lc.h
rename : usr/src/uts/sun4u/sys/wrsm_memseg.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_memseg.h
rename : usr/src/uts/sun4u/sys/wrsm_memseg_impl.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_memseg_impl.h
rename : usr/src/uts/sun4u/sys/wrsm_nc.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_nc.h
rename : usr/src/uts/sun4u/sys/wrsm_nc_impl.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_nc_impl.h
rename : usr/src/uts/sun4u/sys/wrsm_plat.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_plat.h
rename : usr/src/uts/sun4u/sys/wrsm_plat_impl.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_plat_impl.h
rename : usr/src/uts/sun4u/sys/wrsm_plugin.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_plugin.h
rename : usr/src/uts/sun4u/sys/wrsm_rsmpi.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_rsmpi.h
rename : usr/src/uts/sun4u/sys/wrsm_sess_impl.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_sess_impl.h
rename : usr/src/uts/sun4u/sys/wrsm_session.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_session.h
rename : usr/src/uts/sun4u/sys/wrsm_transport.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_transport.h
rename : usr/src/uts/sun4u/sys/wrsm_types.h => deleted_files/usr/src/uts/sun4u/sys/wrsm_types.h
rename : usr/src/uts/sun4u/sys/wrsmd.h => deleted_files/usr/src/uts/sun4u/sys/wrsmd.h
rename : usr/src/uts/sun4u/wrsmd/Makefile => deleted_files/usr/src/uts/sun4u/wrsmd/Makefile
Diffstat (limited to 'usr/src')
140 files changed, 102 insertions, 76721 deletions
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint index c10810fc9e..0330fca261 100644 --- a/usr/src/Makefile.lint +++ b/usr/src/Makefile.lint @@ -440,12 +440,8 @@ sparc_SUBDIRS= \ cmd/prtfru \ cmd/sckmd \ cmd/vntsd \ - cmd/wrsmconf \ - cmd/wrsmstat \ lib/libdscp \ lib/libpri \ - lib/libwrsmconf \ - lib/wrsm \ lib/libpcp \ stand diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs index 6e65581c25..258449b826 100644 --- a/usr/src/Targetdirs +++ b/usr/src/Targetdirs @@ -313,12 +313,10 @@ ROOT.BIN= \ /var/spool sparcv9_ROOT.BIN64= \ - /platform/sun4u/sbin \ /platform/sun4u/lib \ /platform/sun4u/lib/$(MACH64) \ /usr/platform/sun4u/sbin \ /usr/platform/sun4u/lib \ - /usr/platform/sun4u/lib/$(MACH64) \ /platform/sun4v/lib \ /platform/sun4v/lib/$(MACH64) \ /usr/platform/sun4v/sbin \ @@ -1400,16 +1398,6 @@ $(ROOT)/usr/lib/$(MACH64)/nss_nisplus.so.1:= \ REALPATH=../../../lib/$(MACH64)/nss_nisplus.so.1 $(ROOT)/usr/lib/$(MACH64)/nss_user.so.1:= \ REALPATH=../../../lib/$(MACH64)/nss_user.so.1 -$(ROOT)/usr/platform/sun4u/lib/$(MACH64)/libwrsmconf.so.1:= \ - REALPATH=../../../../../platform/sun4u/lib/$(MACH64)/libwrsmconf.so.1 -$(ROOT)/usr/platform/sun4u/lib/$(MACH64)/libwrsmconf.so:= \ - REALPATH=../../../../../platform/sun4u/lib/$(MACH64)/libwrsmconf.so.1 -$(ROOT)/usr/platform/sun4u/lib/libwrsmconf.so.1:= \ - REALPATH=../../../../platform/sun4u/lib/libwrsmconf.so.1 -$(ROOT)/usr/platform/sun4u/lib/libwrsmconf.so:= \ - REALPATH=../../../../platform/sun4u/lib/libwrsmconf.so.1 -$(ROOT)/usr/platform/sun4u/sbin/wrsmconf:= \ - REALPATH=../../../../platform/sun4u/sbin/wrsmconf SYM.USRLIB= \ /lib/libposix4.so \ @@ -1646,12 +1634,7 @@ SYM.USRLIB= \ /usr/lib/nss_nisplus.so.1 \ /usr/lib/nss_user.so.1 -sparcv9_SYM.USRLIB64= \ - /usr/platform/sun4u/lib/$(MACH64)/libwrsmconf.so \ - /usr/platform/sun4u/lib/$(MACH64)/libwrsmconf.so.1 \ - /usr/platform/sun4u/lib/libwrsmconf.so \ - /usr/platform/sun4u/lib/libwrsmconf.so.1 \ - /usr/platform/sun4u/sbin/wrsmconf +sparcv9_SYM.USRLIB64= amd64_SYM.USRLIB64= diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 4c8f29506e..52ba9b89e0 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -472,9 +472,7 @@ sparc_SUBDIRS= \ scadm \ sckmd \ sf880drd \ - vntsd \ - wrsmconf \ - wrsmstat + vntsd # # Commands that are messaged. Note that 'lp' and 'man' come first @@ -722,9 +720,7 @@ sparc_MSGSUBDIRS= \ fruadm \ prtdscp \ prtfru \ - vntsd \ - wrsmconf \ - wrsmstat + vntsd i386_MSGSUBDIRS= \ ucodeadm diff --git a/usr/src/cmd/devfsadm/sparc/misc_link_sparc.c b/usr/src/cmd/devfsadm/sparc/misc_link_sparc.c index 0d0aa692bd..f93a5212fe 100644 --- a/usr/src/cmd/devfsadm/sparc/misc_link_sparc.c +++ b/usr/src/cmd/devfsadm/sparc/misc_link_sparc.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,8 +36,6 @@ extern int system_labeled; -static int node_name(di_minor_t minor, di_node_t node); - static int ddi_other(di_minor_t minor, di_node_t node); static int diskette(di_minor_t minor, di_node_t node); @@ -45,7 +43,6 @@ static int ecpp_create(di_minor_t minor, di_node_t node); static int mc_node(di_minor_t minor, di_node_t node); static int ddi_cardreader(di_minor_t minor, di_node_t node); static int starcat_sbbc_node(di_minor_t minor, di_node_t node); -static int wrsm(di_minor_t minor, di_node_t node); static int lom(di_minor_t minor, di_node_t node); static int ntwdt_create(di_minor_t minor, di_node_t node); @@ -68,12 +65,6 @@ static devfsadm_create_t misc_cbt[] = { { "card-reader", "ddi_smartcard_reader", NULL, TYPE_EXACT, ILEVEL_0, ddi_cardreader }, - { "pseudo", "(^ddi_pseudo$)|(^ddi_ctl:devctl$)", "wrsm", - TYPE_RE | DRV_EXACT, ILEVEL_0, wrsm, - }, - { "network", "ddi_net", "wrsmd", - TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name, - }, { "pseudo", "ddi_pseudo", "lw8", TYPE_EXACT | DRV_EXACT, ILEVEL_0, lom }, @@ -145,17 +136,6 @@ diskette(di_minor_t minor, di_node_t node) /* * Handles links of the form: - * type=ddi_pseudo;name=xyz \D - */ -static int -node_name(di_minor_t minor, di_node_t node) -{ - (void) devfsadm_mklink(di_node_name(node), node, minor, 0); - return (DEVFSADM_CONTINUE); -} - -/* - * Handles links of the form: * type=ddi_printer;name=ecpp ecpp\N0 */ static int @@ -297,59 +277,6 @@ starcat_sbbc_node(di_minor_t minor, di_node_t node) } -int -wrsm(di_minor_t minor, di_node_t node) -{ - const char *node_name = di_node_name(node); - const char *minor_name = di_minor_name(minor); - char path[PATH_MAX + 1]; - - if (minor_name == NULL || node_name == NULL) { - return (DEVFSADM_CONTINUE); - } - if (strcmp(minor_name, "admin") == 0) { - /* admin pseudo device */ - (void) snprintf(path, sizeof (path), "%s%s", node_name, - minor_name); - } else if (strcmp(minor_name, "ctrl") == 0) { - /* controller pseudo device */ - dev_t dev = di_minor_devt(minor); - minor_t dev_minor = minor(dev); - (void) snprintf(path, sizeof (path), "%s%u", node_name, - (uint_t)dev_minor); - } else { - /* - * For hardware devices, the devlink must be - * /dev/<node_name><portid>. devpath is of the format - * ".../<node_name>@<portid>,0". Need to extract the - * <portid> for use in bulding devlink. - */ - char devpath[PATH_MAX + 1]; - char *devfs_path; - int i; - - devfs_path = di_devfs_path(node); - if (devfs_path == NULL) { - return (DEVFSADM_CONTINUE); - } - (void) strcpy(devpath, devfs_path); - di_devfs_path_free(devfs_path); - - for (i = strlen(devpath); devpath[i] != '@' && i > 0; i--) { - if (devpath[i] == ',') { - devpath[i] = 0; - } - } - if (i == 0) { - return (DEVFSADM_CONTINUE); - } - (void) snprintf(path, sizeof (path), "wci%s", &devpath[i+1]); - } - (void) devfsadm_mklink(path, node, minor, 0); - - return (DEVFSADM_CONTINUE); -} - /* * Creates /dev/lom nodes for Platform Specific lom driver */ diff --git a/usr/src/cmd/mdb/sun4u/modules/Makefile b/usr/src/cmd/mdb/sun4u/modules/Makefile index 3b6bafeae4..89fcbb34f0 100644 --- a/usr/src/cmd/mdb/sun4u/modules/Makefile +++ b/usr/src/cmd/mdb/sun4u/modules/Makefile @@ -26,6 +26,6 @@ include $(SRC)/Makefile.master -SUBDIRS = unix wrsm lw8 serengeti wrsmd opl +SUBDIRS = unix lw8 serengeti opl include ../../Makefile.subdirs diff --git a/usr/src/cmd/mdb/sun4u/modules/wrsm/Makefile b/usr/src/cmd/mdb/sun4u/modules/wrsm/Makefile deleted file mode 100644 index d37e2fffd2..0000000000 --- a/usr/src/cmd/mdb/sun4u/modules/wrsm/Makefile +++ /dev/null @@ -1,29 +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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#ident "%Z%%M% %I% %E% SMI" - -SUBDIRS = v9 -include ../../../Makefile.subdirs diff --git a/usr/src/cmd/mdb/sun4u/modules/wrsm/v9/Makefile b/usr/src/cmd/mdb/sun4u/modules/wrsm/v9/Makefile deleted file mode 100644 index 780ca8144c..0000000000 --- a/usr/src/cmd/mdb/sun4u/modules/wrsm/v9/Makefile +++ /dev/null @@ -1,44 +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 2007 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" - -MODULE = wrsm.so -MDBTGT = kvm - -MODSRCS = wrsm.c - -include ../../../../../Makefile.cmd -include ../../../../../Makefile.cmd.64 -include ../../../../sparc/Makefile.sparcv9 -include ../../../Makefile.sun4u -include ../../../../Makefile.module - -CPPFLAGS += -DMP -D_MACHDEP -CPPFLAGS += -D_KERNEL -CPPFLAGS += -I../../../../common -CPPFLAGS += -I$(SRC)/uts/sun4u -CPPFLAGS += -I$(SRC)/uts/sun4 -CPPFLAGS += -I$(SRC)/uts/sfmmu -CPPFLAGS += -I$(SRC)/uts/sparc/v9 diff --git a/usr/src/cmd/mdb/sun4u/modules/wrsm/wrsm.c b/usr/src/cmd/mdb/sun4u/modules/wrsm/wrsm.c deleted file mode 100644 index ecb441e0ab..0000000000 --- a/usr/src/cmd/mdb/sun4u/modules/wrsm/wrsm.c +++ /dev/null @@ -1,1109 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/mdb_modapi.h> -#include <sys/wrsm.h> -#include <sys/wrsm_common.h> -#include <sys/wrsm_config.h> -#include <sys/wrsm_sess_impl.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_nc_impl.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_memseg_impl.h> - - -#define AVAIL_STATE_STR(x) \ - ((x == wrsm_disabled) ? "disabled" : \ - (x == wrsm_pending) ? "pending" : \ - (x == wrsm_installed) ? "installed" : \ - (x == wrsm_installed_up) ? "installed_up" : \ - (x == wrsm_enabled) ? "enabled" : \ - "unknown") - -#define SESS_STATE_STR(x) \ - ((x == SESS_STATE_UNREACH) ? "unreach" : \ - (x == SESS_STATE_DOWN) ? "down" : \ - (x == SESS_STATE_ESTAB) ? "enabling" : \ - (x == SESS_STATE_UP) ? "up" : \ - "unknown") - -#define ROUTE_STATE_STR(x) \ - ((x == ncslice_use_current) ? "use_current" : \ - (x == ncslice_use_new_route) ? "use_new_route" : \ - (x == ncslice_remove_route) ? "remove_route" : \ - (x == ncslice_use_errloopback) ? "use_errloopback" : \ - (x == ncslice_no_route) ? "no_route" : \ - "unknown") - - -#define EXPORTSEG_STATE_STR(x) \ - ((x == memseg_unpublished) ? "unpublished" : \ - (x == memseg_wait_for_disconnects) ? "wait_disconnects" : \ - (x == memseg_published) ? "published" : \ - "unknown") - - -#define LINKSTATE_STR(x) \ - ((x == lc_up) ? "up" : \ - (x == lc_down) ? "down" : \ - (x == lc_not_there) ? "not_there" : \ - (x == sc_wait_up) ? "wait_up" : \ - (x == sc_wait_down) ? "wait_down" : \ - (x == sc_wait_errdown) ? "wait_errdown" : \ - "unknown") - - -/* - * wrsm_ctlr - */ - - -/* - * Initialize the wrsm_ctlr walker by either using the given starting - * address, or reading the value of the kernel's wrsm_networks pointer. - */ -static int -wrsm_ctlr_walk_init(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "wrsm_networks") == -1) { - mdb_warn("failed to read 'wrsm_networks'"); - return (WALK_ERR); - } - - wsp->walk_data = NULL; - return (WALK_NEXT); -} - -/* - * At each step, read a wrsm_network_t into our private storage, and then - * invoke the callback function. We terminate when we reach a NULL next - * pointer. - */ -static int -wrsm_ctlr_walk_step(mdb_walk_state_t *wsp) -{ - int status; - wrsm_network_t net; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (mdb_vread(&net, sizeof (net), wsp->walk_addr) != sizeof (net)) { - mdb_warn("failed to read wrsm_network at %p", wsp->walk_addr); - return (WALK_DONE); - } - - status = wsp->walk_callback(wsp->walk_addr, &net, wsp->walk_cbdata); - - wsp->walk_addr = (uintptr_t)net.next; - - return (status); -} - -/* - * print list of valid nodes in wrsm_network_t - */ -void -wrsm_print_nodes(wrsm_network_t *net) -{ - int i; - - mdb_printf("known RSM addresses: "); - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (net->nodes[i]) { - mdb_printf("%d ", i); - } - } - - mdb_printf("\n"); -} - -/* - * dcmd for printing out information about a Wildcat RSM controller - * (wrsm_network_t). - */ -static int -wrsm_ctlr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - wrsm_network_t net; - int i; - - if (argc != 0) - return (DCMD_USAGE); - - /* - * If no wrsm_network_t address was specified on the command line, - * we can print out all wrsm networks (controllers) by invoking the - * walker, using this dcmd itself as the callback. - */ - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("wrsm_ctlr", "wrsm_ctlr", - argc, argv) == -1) { - mdb_warn("failed to walk 'wrsm_ctlr_walk'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - - if (mdb_vread(&net, sizeof (net), addr) != sizeof (net)) { - mdb_warn("failed to read wrsm_network_t at %p", addr); - return (DCMD_OK); - } - - /* - * print interesting information - */ - mdb_printf("\nController: %3d\n", net.rsm_ctlr_id); - mdb_printf("---------------\n"); - mdb_printf("availability: %s\nlocal RSM address: %3d\n", - AVAIL_STATE_STR(net.availability), - net.cnodeid); - - mdb_printf("exported ncslices:"); - for (i = 0; i < WRSM_NODE_NCSLICES; i++) { - if (net.exported_ncslices.id[i]) { - mdb_printf(" 0x%x", net.exported_ncslices.id[i]); - if (i == 0) { - mdb_printf(" (small)"); - } else { - mdb_printf(" (large)"); - } - } - } - mdb_printf("\n"); - wrsm_print_nodes(&net); - - mdb_printf("\n"); - return (DCMD_OK); -} - - - - -/* - * wrsm_expseg - */ - - -typedef struct { - boolean_t walkall; - exportseg_t *all_exportsegs_hash[WRSM_PTR_HASH_SIZE]; - exportseg_t *hash_next; - int hash_index; -} wrsm_expseg_walk_data_t; - - -/* - * Initialize the wrsm_expseg walker by either using the given starting - * address, or reading the value of the kernel's wrsm_networks pointer. We - * also allocate and initialize a wrsm_expseg_walk_data_t, and save this - * using the walk_data pointer. - */ -static int -wrsm_expseg_walk_init(mdb_walk_state_t *wsp) -{ - wrsm_expseg_walk_data_t *expseg_walk_data; - boolean_t walkall = B_FALSE; - - if (wsp->walk_addr == NULL) { - walkall = B_TRUE; - if (mdb_readvar(&wsp->walk_addr, "wrsm_networks") == -1) { - mdb_warn("failed to read 'wrsm_networks'"); - return (WALK_ERR); - } - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - } - - wsp->walk_data = mdb_alloc(sizeof (wrsm_expseg_walk_data_t), UM_SLEEP); - expseg_walk_data = (wrsm_expseg_walk_data_t *)wsp->walk_data; - expseg_walk_data->walkall = walkall; - - if (mdb_readsym(&(expseg_walk_data->all_exportsegs_hash), - sizeof (expseg_walk_data->all_exportsegs_hash), - "all_exportsegs_hash") != - sizeof (expseg_walk_data->all_exportsegs_hash)) { - mdb_warn("symbol 'all_exportsegs_hash' not found"); - mdb_free(expseg_walk_data, sizeof (wrsm_expseg_walk_data_t)); - return (WALK_ERR); - } - - expseg_walk_data->hash_index = -1; - expseg_walk_data->hash_next = NULL; - - return (WALK_NEXT); -} - -/* - * At each step, find the next exportseg_t structure in the - * all_exportsegs_hash hash that belongs to the current network. We - * terminate when we reach the end of the hash and there are no more - * networks to process. - */ -static int -wrsm_expseg_walk_step(mdb_walk_state_t *wsp) -{ - int status; - wrsm_network_t net; - wrsm_expseg_walk_data_t *expseg_walk_data; - exportseg_t expseg; - exportseg_t *hash_next; - - expseg_walk_data = (wrsm_expseg_walk_data_t *)wsp->walk_data; - hash_next = expseg_walk_data->hash_next; - - /* find next exportseg in hash */ - while (hash_next == NULL) { - do { - expseg_walk_data->hash_index++; - if (expseg_walk_data->hash_index == - WRSM_PTR_HASH_SIZE) { - break; - } - hash_next = expseg_walk_data-> - all_exportsegs_hash[expseg_walk_data->hash_index]; - - } while (hash_next == NULL); - - if (hash_next == NULL) { - /* - * At end of all_exportsegs_hash. - */ - if (!expseg_walk_data->walkall) { - /* - * only processing current network's exportsegs - */ - return (WALK_DONE); - } - - /* - * Get next network, then refresh copy of hash. - */ - if (mdb_vread(&net, sizeof (net), - wsp->walk_addr) != sizeof (net)) { - mdb_warn("failed to read wrsm_network " - "at %p", wsp->walk_addr); - return (WALK_DONE); - } - if (net.next == NULL) { - /* no more networks to process */ - return (WALK_DONE); - } - if (mdb_readsym( - &(expseg_walk_data->all_exportsegs_hash), - sizeof (expseg_walk_data->all_exportsegs_hash), - "all_exportsegs_hash") != - sizeof (expseg_walk_data->all_exportsegs_hash)) { - mdb_warn("symbol 'all_exportsegs_hash' " - "not found"); - return (WALK_ERR); - } - - wsp->walk_addr = (uintptr_t)net.next; - expseg_walk_data->hash_index = -1; - return (WALK_NEXT); - } - } - - if (mdb_vread(&expseg, sizeof (expseg), (uintptr_t)hash_next) != - sizeof (expseg)) { - mdb_warn("failed to read exportseg_t at %p", hash_next); - return (WALK_ERR); - } - expseg_walk_data->hash_next = expseg.all_next; - - /* - * if exportseg doesn't belong to current network, skip - */ - if (expseg.network != (wrsm_network_t *)wsp->walk_addr) { - return (WALK_NEXT); - } - - /* - * found exportseg belonging to current network - */ - - status = wsp->walk_callback((uintptr_t)hash_next, &expseg, - wsp->walk_cbdata); - - return (status); -} - - -/* - * The walker's fini function is invoked at the end of each walk. - * Free the memory pointed to by wsp->walk_data. - */ -static void -wrsm_expseg_walk_fini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (wrsm_expseg_walk_data_t)); -} - - -/* - * dcmd for printing out information about an exportseg_t - */ -static int -wrsm_expseg(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - exportseg_t expseg; - wrsm_network_t net; - int i; - - if (argc != 0) - return (DCMD_USAGE); - - /* - * If no wrsm_expseg_t address was specified on the command line, we - * can print out all wrsm expsegs in all wrsm networks (controllers) - * by invoking the walker, using this dcmd itself as the callback. - */ - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("wrsm_expseg", "wrsm_expseg", - argc, argv) == -1) { - mdb_warn("failed to walk 'wrsm_expseg_walk'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - - /* - * If this is the first invocation of the command, print a nice - * header line for the output that will follow. - */ - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%4s %18s %18s %16s %8s %s\n", - "ctlr", - "handle", - "size", - "state", - "segid", - "importing RSMaddrs"); - } - - if (mdb_vread(&expseg, sizeof (expseg), addr) != sizeof (expseg)) { - mdb_warn("failed to read wrsm_exportseg_t at %p", addr); - return (DCMD_OK); - } - - if (mdb_vread(&net, sizeof (net), (uintptr_t)expseg.network) != - sizeof (net)) { - mdb_warn("failed to read wrsm_network_t at %p", expseg.network); - return (DCMD_OK); - } - - - /* - * print interesting information - */ - mdb_printf("%4d 0x%016p 0x%016p %16s %8u ", - net.rsm_ctlr_id, - addr, - expseg.size, - EXPORTSEG_STATE_STR(expseg.state), - expseg.state == memseg_unpublished ? -1 : expseg.segid); - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (expseg.nodes[i].inuse) - mdb_printf("%d ", i); - } - mdb_printf("\n"); - - return (DCMD_OK); -} - - - - -/* - * wrsm_impseg - */ - - -typedef struct { - boolean_t walkall; - importseg_t *all_importsegs_hash[WRSM_PTR_HASH_SIZE]; - importseg_t *hash_next; - int hash_index; -} wrsm_impseg_walk_data_t; - - -/* - * Initialize the wrsm_impseg walker by either using the given starting - * address, or reading the value of the kernel's wrsm_networks pointer. We - * also allocate and initialize a wrsm_impseg_walk_data_t, and save this - * using the walk_data pointer. - */ -static int -wrsm_impseg_walk_init(mdb_walk_state_t *wsp) -{ - wrsm_impseg_walk_data_t *impseg_walk_data; - boolean_t walkall = B_FALSE; - - if (wsp->walk_addr == NULL) { - walkall = B_TRUE; - if (mdb_readvar(&wsp->walk_addr, "wrsm_networks") == -1) { - mdb_warn("failed to read 'wrsm_networks'"); - return (WALK_ERR); - } - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - } - - wsp->walk_data = mdb_alloc(sizeof (wrsm_impseg_walk_data_t), UM_SLEEP); - impseg_walk_data = (wrsm_impseg_walk_data_t *)wsp->walk_data; - impseg_walk_data->walkall = walkall; - - if (mdb_readsym(&(impseg_walk_data->all_importsegs_hash), - sizeof (impseg_walk_data->all_importsegs_hash), - "all_importsegs_hash") != - sizeof (impseg_walk_data->all_importsegs_hash)) { - mdb_warn("symbol 'all_importsegs_hash' not found"); - mdb_free(impseg_walk_data, sizeof (wrsm_impseg_walk_data_t)); - return (WALK_ERR); - } - - impseg_walk_data->hash_index = -1; - impseg_walk_data->hash_next = NULL; - - return (WALK_NEXT); -} - -/* - * At each step, find the next importseg_t structure in the - * all_importsegs_hash hash that belongs to the current network. We - * terminate when we reach the end of the hash and there are no more - * networks to process. - */ -static int -wrsm_impseg_walk_step(mdb_walk_state_t *wsp) -{ - int status; - wrsm_network_t net; - wrsm_impseg_walk_data_t *impseg_walk_data; - importseg_t impseg; - importseg_t *hash_next; - - impseg_walk_data = (wrsm_impseg_walk_data_t *)wsp->walk_data; - hash_next = impseg_walk_data->hash_next; - - /* find next importseg in hash */ - while (hash_next == NULL) { - do { - impseg_walk_data->hash_index++; - if (impseg_walk_data->hash_index == - WRSM_PTR_HASH_SIZE) { - break; - } - hash_next = impseg_walk_data-> - all_importsegs_hash[impseg_walk_data->hash_index]; - - } while (hash_next == NULL); - - if (hash_next == NULL) { - /* - * At end of all_importsegs_hash. - */ - if (!impseg_walk_data->walkall) { - /* - * only processing current network's importsegs - */ - return (WALK_DONE); - } - - /* - * Get next network, then refresh copy of hash. - */ - if (mdb_vread(&net, sizeof (net), - wsp->walk_addr) != sizeof (net)) { - mdb_warn("failed to read wrsm_network " - "at %p", wsp->walk_addr); - return (WALK_DONE); - } - if (net.next == NULL) { - /* no more networks to process */ - return (WALK_DONE); - } - if (mdb_readsym( - &(impseg_walk_data->all_importsegs_hash), - sizeof (impseg_walk_data->all_importsegs_hash), - "all_importsegs_hash") != - sizeof (impseg_walk_data->all_importsegs_hash)) { - mdb_warn("symbol 'all_importsegs_hash' " - "not found"); - return (WALK_ERR); - } - - wsp->walk_addr = (uintptr_t)net.next; - impseg_walk_data->hash_index = -1; - return (WALK_NEXT); - } - } - - if (mdb_vread(&impseg, sizeof (impseg), (uintptr_t)hash_next) != - sizeof (impseg)) { - mdb_warn("failed to read importseg_t at %p", hash_next); - return (WALK_ERR); - } - impseg_walk_data->hash_next = impseg.all_next; - - /* - * if importseg doesn't belong to current network, skip - */ - if (impseg.network != (wrsm_network_t *)wsp->walk_addr) { - return (WALK_NEXT); - } - - /* - * found next importseg belonging to current network - */ - - status = wsp->walk_callback((uintptr_t)hash_next, &impseg, - wsp->walk_cbdata); - - return (status); -} - - -/* - * The walker's fini function is invoked at the end of each walk. - * Free the memory pointed to by wsp->walk_data. - */ -static void -wrsm_impseg_walk_fini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (wrsm_impseg_walk_data_t)); -} - - -/* - * dcmd for printing out information about an importseg_t - */ -static int -wrsm_impseg(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - importseg_t impseg; - wrsm_network_t net; - iseginfo_t iseginfo; - - if (argc != 0) - return (DCMD_USAGE); - - /* - * If no wrsm_impseg_t address was specified on the command line, we - * can print out all wrsm impsegs in all wrsm networks (controllers) - * by invoking the walker, using this dcmd itself as the callback. - */ - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("wrsm_impseg", "wrsm_impseg", - argc, argv) == -1) { - mdb_warn("failed to walk 'wrsm_impseg_walk'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - - /* - * If this is the first invocation of the command, print a nice - * header line for the output that will follow. - */ - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%4s %18s %8s %7s %18s %9s %8s\n", - "ctlr", - "handle", - "segid", - "RSMaddr", - "size", - "published", - "mappings"); - } - - if (mdb_vread(&impseg, sizeof (impseg), addr) != sizeof (impseg)) { - mdb_warn("failed to read wrsm_importseg_t at %p", addr); - return (DCMD_OK); - } - - if (mdb_vread(&net, sizeof (net), (uintptr_t)impseg.network) != - sizeof (net)) { - mdb_warn("failed to read wrsm_network_t at %p", impseg.network); - return (DCMD_OK); - } - - if (mdb_vread(&iseginfo, sizeof (iseginfo), - (uintptr_t)impseg.iseginfo) != sizeof (iseginfo)) { - mdb_warn("failed to read iseginfo_t at %p", impseg.iseginfo); - return (DCMD_OK); - } - - /* - * print interesting information - */ - mdb_printf("%4d 0x%016p %8u %7d 0x%016p %9s %8s\n", - net.rsm_ctlr_id, - addr, - iseginfo.segid, - iseginfo.cnodeid, - iseginfo.size, - impseg.unpublished ? "no" : "yes", - impseg.have_mappings ? "yes" : "no"); - - return (DCMD_OK); -} - - - - - - -/* - * wrsm_wci - */ - - -typedef struct { - boolean_t walkall; -} wrsm_wci_walk_data_t; - - -/* - * Initialize the wrsm_wci walker by either using the given starting - * address, or reading the value of the kernel's wrsm_networks pointer. We - * also allocate a wrsm_wci_walk_data_t for storage, and save this using - * the walk_data pointer. - */ -static int -wrsm_wci_walk_init(mdb_walk_state_t *wsp) -{ - wrsm_wci_walk_data_t *wci_walk_data; - boolean_t walkall = B_FALSE; - - if (wsp->walk_addr == NULL) { - walkall = B_TRUE; - if (mdb_readvar(&wsp->walk_addr, "wrsm_networks") == -1) { - mdb_warn("failed to read 'wrsm_networks'"); - return (WALK_ERR); - } - } - - wsp->walk_data = mdb_alloc(sizeof (wrsm_wci_walk_data_t), UM_SLEEP); - wci_walk_data = (wrsm_wci_walk_data_t *)wsp->walk_data; - - wci_walk_data->walkall = walkall; - - return (WALK_NEXT); -} - -/* - * At each step, read a wrsm_network_t into our private storage, and then - * invoke the callback function for each wci for which there is a softstate - * structure in that network. We terminate when we reach a NULL - * wrsm_network_t pointer. - */ -static int -wrsm_wci_walk_step(mdb_walk_state_t *wsp) -{ - int status; - wrsm_network_t net; - wrsm_nr_t nr; - wrsm_ncwci_t wci; - wrsm_ncwci_t *next; - wrsm_wci_walk_data_t *wci_walk_data; - - wci_walk_data = (wrsm_wci_walk_data_t *)wsp->walk_data; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (mdb_vread(&net, sizeof (net), wsp->walk_addr) != sizeof (net)) { - mdb_warn("failed to read wrsm_network at %p", wsp->walk_addr); - return (WALK_DONE); - } - - if (mdb_vread(&nr, sizeof (nr), (uintptr_t)net.nr) != sizeof (nr)) { - mdb_warn("failed to read wrsm_nr_t at %p", net.nr); - return (WALK_DONE); - } - - next = nr.wcis; - while (next) { - if (mdb_vread(&wci, sizeof (wci), (uintptr_t)next) != - sizeof (wci)) { - mdb_warn("failed to read wsm_ncwci_t at %p", next); - break; - } - - if (wci.lcwci) { - status = wsp->walk_callback((uintptr_t)wci.lcwci, - NULL, wsp->walk_cbdata); - } - next = wci.next; - } - - if (wci_walk_data->walkall && net.next) { - wsp->walk_addr = (uintptr_t)net.next; - return (status); - } else { - return (WALK_DONE); - } -} - - -/* - * The walker's fini function is invoked at the end of each walk. - * Free the memory pointed to by wsp->walk_data. - */ -static void -wrsm_wci_walk_fini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (wrsm_wci_walk_data_t)); -} - - -/* - * dcmd for printing out information about a wrsm_wci_t. - */ -static int -wrsm_wci(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - wrsm_softstate_t wci; - wrsm_network_t net; - wrsm_ncwci_t ncwci; - int rsm_ctlr_id = -1; - int i; - - if (argc != 0) - return (DCMD_USAGE); - - /* - * If no wrsm_softstate_t address was specified on the command - * line, we can print out all wrsm wcis in all wrsm networks - * (controllers) by invoking the walker, using this dcmd itself as - * the callback. - */ - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("wrsm_wci", "wrsm_wci", - argc, argv) == -1) { - mdb_warn("failed to walk 'wrsm_wci_walk'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - - - if (mdb_vread(&wci, sizeof (wci), addr) != sizeof (wci)) { - mdb_warn("failed to read wrsm_softstate_t at %p", addr); - return (DCMD_OK); - } - - /* - * get controller id if this wci is part of a network - */ - if (mdb_vread(&ncwci, sizeof (ncwci), (uintptr_t)wci.nc) == - sizeof (ncwci)) { - - if (mdb_vread(&net, sizeof (net), (uintptr_t)ncwci.network) != - sizeof (net)) { - mdb_warn("failed to read wrsm_network_t at %p", - ncwci.network); - return (DCMD_OK); - } - rsm_ctlr_id = net.rsm_ctlr_id; - } - - - - /* - * print interesting information - */ - - mdb_printf("\nController: %d\nInstance: %d\nExt Safari Portid: %d\n", - rsm_ctlr_id, - wci.instance, - wci.portid); - - mdb_printf("%4s %8s\n", - "link#", - "state"); - - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - mdb_printf("%5d %8s\n", - i, - LINKSTATE_STR(wci.links[i].link_req_state)); - } - - return (DCMD_OK); -} - - - - - -/* - * wrsm_node - */ - - -typedef struct { - boolean_t walkall; -} wrsm_node_walk_data_t; - - -/* - * Initialize the wrsm_node walker by either using the given starting - * address, or reading the value of the kernel's wrsm_networks pointer. We - * also allocate a wrsm_node_walk_data_t for storage, and save this using - * the walk_data pointer. - */ -static int -wrsm_node_walk_init(mdb_walk_state_t *wsp) -{ - wrsm_node_walk_data_t *node_walk_data; - boolean_t walkall = B_FALSE; - - if (wsp->walk_addr == NULL) { - walkall = B_TRUE; - if (mdb_readvar(&wsp->walk_addr, "wrsm_networks") == -1) { - mdb_warn("failed to read 'wrsm_networks'"); - return (WALK_ERR); - } - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - } - - wsp->walk_data = mdb_alloc(sizeof (wrsm_node_walk_data_t), UM_SLEEP); - node_walk_data = (wrsm_node_walk_data_t *)wsp->walk_data; - - node_walk_data->walkall = walkall; - - return (WALK_NEXT); -} - -/* - * At each step, read a wrsm_network_t into our private storage, and then - * invoke the callback function for each valid node in that network. We - * terminate when we reach a NULL wrsm_network_t pointer. - */ -static int -wrsm_node_walk_step(mdb_walk_state_t *wsp) -{ - int status; - wrsm_network_t net; - wrsm_node_walk_data_t *node_walk_data; - int cnodeid = 0; - - node_walk_data = (wrsm_node_walk_data_t *)wsp->walk_data; - - if (mdb_vread(&net, sizeof (net), wsp->walk_addr) != sizeof (net)) { - mdb_warn("failed to read wrsm_network at %p", wsp->walk_addr); - return (WALK_DONE); - } - - while (cnodeid < WRSM_MAX_CNODES) { - if (net.nodes[cnodeid] != NULL) { - status = wsp->walk_callback( - (uintptr_t)net.nodes[cnodeid], - NULL, wsp->walk_cbdata); - } - cnodeid++; - } - - if (node_walk_data->walkall && net.next) { - wsp->walk_addr = (uintptr_t)net.next; - return (status); - } else { - return (WALK_DONE); - } -} - - -/* - * The walker's fini function is invoked at the end of each walk. - * Free the memory pointed to by wsp->walk_data. - */ -static void -wrsm_node_walk_fini(mdb_walk_state_t *wsp) -{ - mdb_free(wsp->walk_data, sizeof (wrsm_node_walk_data_t)); -} - - -/* - * dcmd for printing out information about a wrsm_node_t. - */ -static int -wrsm_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - wrsm_node_t node; - wrsm_net_member_t config; /* node config info */ - wrsm_network_t net; - wrsm_session_t sess; - wrsm_node_routeinfo_t routeinfo; /* routing config for node */ - - if (argc != 0) - return (DCMD_USAGE); - - /* - * If no wrsm_node_t address was specified on the command line, we - * can print out all wrsm nodes in all wrsm networks (controllers) - * by invoking the walker, using this dcmd itself as the callback. - */ - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("wrsm_node", "wrsm_node", - argc, argv) == -1) { - mdb_warn("failed to walk 'wrsm_node_walk'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - - /* - * If this is the first invocation of the command, print a nice - * header line for the output that will follow. - */ - if (DCMD_HDRSPEC(flags)) { - mdb_printf("%4s %7s %12s %6s %8s %15s %s\n", - "", "", "", "have", "", "", ""); - mdb_printf("%4s %7s %12s %6s %8s %15s %s\n", - "ctlr", - "RSMaddr", - "availability", "route?", "session", "route state", - "hostname"); - } - - if (mdb_vread(&node, sizeof (node), addr) != sizeof (node)) { - mdb_warn("failed to read wrsm_node_t at %p", addr); - return (DCMD_OK); - } - - if (mdb_vread(&config, sizeof (config), (uintptr_t)node.config) != - sizeof (config)) { - mdb_warn("failed to read wrsm_net_member_t at %p", node.config); - return (DCMD_OK); - } - - if (mdb_vread(&net, sizeof (net), (uintptr_t)node.network) != - sizeof (net)) { - mdb_warn("failed to read wrsm_network_t at %p", node.network); - return (DCMD_OK); - } - - if (mdb_vread(&sess, sizeof (sess), (uintptr_t)net.session) != - sizeof (sess)) { - mdb_warn("failed to read wrsm_session_t at %p", net.session); - return (DCMD_OK); - } - - if (mdb_vread(&routeinfo, sizeof (routeinfo), - (uintptr_t)node.routeinfo) != sizeof (routeinfo)) { - mdb_warn("failed to read wrsm_node_routeinfo_t at %p", - node.routeinfo); - return (DCMD_OK); - } - - - /* - * print interesting information - */ - mdb_printf("%4d %7d %12s %6s %8s %15s %s\n", - net.rsm_ctlr_id, - config.cnodeid, - AVAIL_STATE_STR(node.availability), - node.state ? "yes" : "no", - SESS_STATE_STR(sess.node[config.cnodeid].state), - ROUTE_STATE_STR(routeinfo.route_state), - config.hostname); - - return (DCMD_OK); -} - - - - - -/* - * setup info - */ - -/* - * MDB module linkage information: - * - * We declare a list of structures describing our dcmds, a list of structures - * describing our walkers, and a function named _mdb_init to return a pointer - * to our module information. - */ - -static const mdb_dcmd_t dcmds[] = { - { "wrsm_ctlr", NULL, "wrsm controller structure information", - wrsm_ctlr }, - { "wrsm_node", NULL, "wrsm node structure information", - wrsm_node }, - { "wrsm_expseg", NULL, "wrsm expseg structure information", - wrsm_expseg }, - { "wrsm_impseg", NULL, "wrsm impseg structure information", - wrsm_impseg }, - { "wrsm_wci", NULL, "wrsm WCI structure information", - wrsm_wci }, - { NULL } -}; - -static const mdb_walker_t walkers[] = { - { "wrsm_ctlr", "walk list of wrsm controller structures", - wrsm_ctlr_walk_init, wrsm_ctlr_walk_step, NULL }, - { "wrsm_node", "walk wrsm node structures in controller", - wrsm_node_walk_init, wrsm_node_walk_step, wrsm_node_walk_fini }, - { "wrsm_expseg", "walk wrsm expseg structures in controller", - wrsm_expseg_walk_init, wrsm_expseg_walk_step, - wrsm_expseg_walk_fini }, - { "wrsm_impseg", "walk wrsm impseg structures in controller", - wrsm_impseg_walk_init, wrsm_impseg_walk_step, - wrsm_impseg_walk_fini }, - { "wrsm_wci", "walk wrsm WCI structures in controller", - wrsm_wci_walk_init, wrsm_wci_walk_step, wrsm_wci_walk_fini }, - { NULL } -}; - -static const mdb_modinfo_t modinfo = { - MDB_API_VERSION, dcmds, walkers -}; - -const mdb_modinfo_t * -_mdb_init(void) -{ - return (&modinfo); -} diff --git a/usr/src/cmd/mdb/sun4u/modules/wrsmd/Makefile b/usr/src/cmd/mdb/sun4u/modules/wrsmd/Makefile deleted file mode 100644 index 9e96a9e470..0000000000 --- a/usr/src/cmd/mdb/sun4u/modules/wrsmd/Makefile +++ /dev/null @@ -1,29 +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 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" - -SUBDIRS = v9 -include $(SRC)/cmd/mdb/Makefile.subdirs diff --git a/usr/src/cmd/mdb/sun4u/modules/wrsmd/v9/Makefile b/usr/src/cmd/mdb/sun4u/modules/wrsmd/v9/Makefile deleted file mode 100644 index 649aeb25dd..0000000000 --- a/usr/src/cmd/mdb/sun4u/modules/wrsmd/v9/Makefile +++ /dev/null @@ -1,45 +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 2007 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" - -MODULE = wrsmd.so -MDBTGT = kvm - -MODSRCS = wrsmd.c - -include $(SRC)/cmd/Makefile.cmd -include $(SRC)/cmd/Makefile.cmd.64 -include $(SRC)/cmd/mdb/sparc/Makefile.sparcv9 -include $(SRC)/cmd/mdb/sun4u/Makefile.sun4u -include $(SRC)/cmd/mdb/Makefile.module - -CPPFLAGS += -DMP -D_MACHDEP -CPPFLAGS += -D_KERNEL -CPPFLAGS += -I../../../../../../../src/cmd/mdb/common -CPPFLAGS += -I$(SRC)/uts/sun4u -CPPFLAGS += -I$(SRC)/uts/sun4 -CPPFLAGS += -I$(SRC)/uts/sfmmu -CPPFLAGS += -I$(SRC)/uts/sparc/v9 diff --git a/usr/src/cmd/mdb/sun4u/modules/wrsmd/wrsmd.c b/usr/src/cmd/mdb/sun4u/modules/wrsmd/wrsmd.c deleted file mode 100644 index 687eafc808..0000000000 --- a/usr/src/cmd/mdb/sun4u/modules/wrsmd/wrsmd.c +++ /dev/null @@ -1,294 +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 2001 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/mdb_modapi.h> -#include <sys/stream.h> -#include <sys/note.h> -#include <sys/wrsmd.h> - -#define WRSMDSTATE_TO_SHORTSTR(x) ( \ - (x == WRSMD_STATE_NEW) ? "NEW" : \ - (x == WRSMD_STATE_INPROGRESS) ? "INPROGRESS" : \ - (x == WRSMD_STATE_DELETING) ? "DELETING" : \ - (x == WRSMD_STATE_W_SCONNTMO) ? "W_SCONNTMO" : \ - (x == WRSMD_STATE_W_ACCEPT) ? "W_ACCEPT" : \ - (x == WRSMD_STATE_W_ACK) ? "W_ACK" : \ - (x == WRSMD_STATE_W_READY) ? "W_READY" : \ - (x == WRSMD_STATE_W_FQE) ? "W_FQE" : \ - (x == WRSMD_STATE_S_REQ_CONNECT) ? "S_REQ_CONNECT" : \ - (x == WRSMD_STATE_S_NEWCONN) ? "S_NEWCONN" : \ - (x == WRSMD_STATE_S_CONNXFER_ACCEPT) ? "S_CONNXFER_ACCEPT" : \ - (x == WRSMD_STATE_S_CONNXFER_ACK) ? "S_CONNXFER_ACK" : \ - (x == WRSMD_STATE_S_XFER) ? "S_XFER" : \ - (x == WRSMD_STATE_S_DELETE) ? "S_DELETE" : \ - (x == WRSMD_STATE_S_SCONN) ? "S_SCONN" : "unknown") - - - - -/* - * wrsmd_dev - */ - - -/* - * Initialize the wrsmd_dev walker by either using the given starting - * address, or reading the value of the kernel's wrsmddev pointer. - */ -static int -wrsmd_dev_walk_init(mdb_walk_state_t *wsp) -{ - if (wsp->walk_addr == NULL && - mdb_readvar(&wsp->walk_addr, "wrsmddev") == -1) { - mdb_warn("failed to read 'wrsmddev'"); - return (WALK_ERR); - } - - wsp->walk_data = NULL; - return (WALK_NEXT); -} - -/* - * At each step, read a wrsmd_t into our private storage, and then - * invoke the callback function. We terminate when we reach a NULL next - * pointer. - */ -static int -wrsmd_dev_walk_step(mdb_walk_state_t *wsp) -{ - int status; - wrsmd_t wrsmd; - - if (wsp->walk_addr == NULL) - return (WALK_DONE); - - if (mdb_vread(&wrsmd, sizeof (wrsmd), wsp->walk_addr) != - sizeof (wrsmd)) { - mdb_warn("failed to read wrsmd_t at %p", wsp->walk_addr); - return (WALK_DONE); - } - - status = wsp->walk_callback(wsp->walk_addr, &wrsmd, wsp->walk_cbdata); - - wsp->walk_addr = (uintptr_t)wrsmd.wrsmd_nextp; - - return (status); -} - - -/* - * print list of valid nodes in wrsmd - */ -void -wrsmd_print_nodes(wrsmd_t *wrsmd) -{ - int i; - wrsmd_dest_t dest; - wrsmd_dqe_t dqe; - wrsmd_fqe_t fqe; - - mdb_printf("Remote Destinations:\n"); - mdb_printf("%7s %34s %6s %6s %8s\n", - "rsmaddr", - "____________state/estate___________", - "dstate", - "refcnt", - "pkts-q'd?"); - - for (i = 0; i < RSM_MAX_DESTADDR; i++) { - if (wrsmd->wrsmd_desttbl[i]) { - if (mdb_vread(&dest, sizeof (dest), - (uintptr_t)wrsmd->wrsmd_desttbl[i]) != - sizeof (dest)) { - mdb_warn("failed to read wrsmd_dest_t at %p", - wrsmd->wrsmd_desttbl[i]); - return; - } - - mdb_printf("%7d %17s/%17s %6d %6d %8s\n", - dest.rd_rsm_addr, - WRSMDSTATE_TO_SHORTSTR(dest.rd_state), - WRSMDSTATE_TO_SHORTSTR(dest.rd_estate), - dest.rd_dstate, - dest.rd_refcnt, - dest.rd_queue_h ? "yes" : "no"); - mdb_printf(" exportseg " - "handle & segid: 0x%16p %8d\n", - dest.rd_lxferhand, - dest.rd_lxfersegid); - mdb_printf(" importseg " - "handle & segid: 0x%16p %8d\n", - dest.rd_rxferhand, - dest.rd_rxfersegid); - mdb_printf(" loaned-bufs %u\n", - dest.rd_nlb); - - if (mdb_vread(&fqe, sizeof (wrsmd_fqe_t), - (uintptr_t)dest.rd_fqr_n) != sizeof (wrsmd_fqe_t)) { - mdb_warn("failed to read fqe at %p", - dest.rd_fqr_n); - } else { - mdb_printf(" available fqes? %s\n", - (dest.rd_cached_fqr_cnt || - (fqe.s.fq_seqnum == (dest.rd_fqr_seq & - WRSMD_FQE_SEQ_MASK))) ? "yes" : "no"); - } - - if (mdb_vread(&dqe, sizeof (wrsmd_dqe_t), - (uintptr_t)dest.rd_dqr_n) != sizeof (wrsmd_dqe_t)) { - mdb_warn("failed to read dqe at %p", - dest.rd_dqr_n); - } else { - mdb_printf(" available dqes? %s\n", - (dqe.s.dq_seqnum == (dest.rd_dqr_seq & - WRSMD_DQE_SEQ_MASK)) ? "yes" : "no"); - } - } - } - - mdb_printf("\n"); -} - - - -/* - * dcmd for printing out information about a Wildcat RSM controller - * (wrsmd_t). - */ -static int -wrsmd_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) -{ - wrsmd_t wrsmd; - - if (argc != 0) - return (DCMD_USAGE); - - /* - * If no wrsmd_t address was specified on the command line, - * we can print out all wrsmd wrsmd (controllers) by invoking the - * walker, using this dcmd itself as the callback. - */ - if (!(flags & DCMD_ADDRSPEC)) { - if (mdb_walk_dcmd("wrsmd_dev", "wrsmd_dev", - argc, argv) == -1) { - mdb_warn("failed to walk 'wrsmd_dev_walk'"); - return (DCMD_ERR); - } - return (DCMD_OK); - } - - - if (mdb_vread(&wrsmd, sizeof (wrsmd), addr) != sizeof (wrsmd)) { - mdb_warn("failed to read wrsmd_t at %p", addr); - return (DCMD_OK); - } - - /* - * print interesting information - */ - mdb_printf("\nDevice Instance (Controller Id): %3d\n", - wrsmd.wrsmd_ctlr_id); - mdb_printf("--------------------------------------\n"); - mdb_printf("RSM address: %d\n", - wrsmd.wrsmd_rsm_addr); - mdb_printf("attached streams: %d\n", - wrsmd.wrsmd_attached_streams); - - mdb_printf("ipackets %lu ierrors %u opackets %lu oerrors %u\n", - wrsmd.wrsmd_ipackets, - wrsmd.wrsmd_ierrors, - wrsmd.wrsmd_opackets, - wrsmd.wrsmd_oerrors); - - mdb_printf("collisions %u xfers %u xfer_pkts %u syncdqes %u\n", - wrsmd.wrsmd_collisions, - wrsmd.wrsmd_xfers, - wrsmd.wrsmd_xfer_pkts, - wrsmd.wrsmd_syncdqes); - - mdb_printf("lbufs %u nlbufs %u pullup %u pullup_fail %u\n", - wrsmd.wrsmd_lbufs, - wrsmd.wrsmd_nlbufs, - wrsmd.wrsmd_pullup, - wrsmd.wrsmd_pullup_fail); - - mdb_printf("starts %u start_xfers %u fqetmo_hint %u fqetmo_drops %u " - "maxq_drops %u\n", - wrsmd.wrsmd_starts, - wrsmd.wrsmd_start_xfers, - wrsmd.wrsmd_fqetmo_hint, - wrsmd.wrsmd_fqetmo_drops, - wrsmd.wrsmd_maxq_drops); - - mdb_printf("errs %u in_bytes %lu out_bytes %lu\n", - wrsmd.wrsmd_errs, - wrsmd.wrsmd_in_bytes, - wrsmd.wrsmd_out_bytes); - - wrsmd_print_nodes(&wrsmd); - - mdb_printf("\n"); - return (DCMD_OK); -} - - - - -/* - * setup info - */ - -/* - * MDB module linkage information: - * - * We declare a list of structures describing our dcmds, a list of structures - * describing our walkers, and a function named _mdb_init to return a pointer - * to our module information. - */ - -static const mdb_dcmd_t dcmds[] = { - { "wrsmd_dev", NULL, "wrsmd device information", - wrsmd_dev }, - { NULL } -}; - -static const mdb_walker_t walkers[] = { - { "wrsmd_dev", "walk list of wrsmd device structures", - wrsmd_dev_walk_init, wrsmd_dev_walk_step, NULL }, - { NULL } -}; - -static const mdb_modinfo_t modinfo = { - MDB_API_VERSION, dcmds, walkers -}; - -const mdb_modinfo_t * -_mdb_init(void) -{ - return (&modinfo); -} diff --git a/usr/src/cmd/wrsmconf/Makefile b/usr/src/cmd/wrsmconf/Makefile deleted file mode 100644 index b032be302b..0000000000 --- a/usr/src/cmd/wrsmconf/Makefile +++ /dev/null @@ -1,112 +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 2001-2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -SCRIPT = wrsmcfg -INIT_D = $(ROOTETC)/init.d -INIT_PROG = $(INIT_D)/$(SCRIPT) -RCS_SSCRIPT = S29wrsmcfg -RCS_KSCRIPT = K44wrsmcfg -ROOTRCS_D = $(ROOTETC)/rcS.d -ROOTRCS_SLINK = $(ROOTRCS_D)/$(RCS_SSCRIPT) -ROOTRCS_KLINK = $(ROOTRCS_D)/$(RCS_KSCRIPT) -DATA_D = $(ROOTETC)/wrsm - -PROG = wrsmconf -ROOTFS_PROG = $(PROG) -PLATFORM = sun4u -OBJS = wrsmconf.o mkconfig.o -SRCS = $(OBJS:%.o=%.c) - - -include ../Makefile.cmd -include ../../Makefile.psm - -ROOTBIN= $(ROOT)/platform/sun4u/sbin -ROOTPROG= $(ROOTBIN)/$(PROG) -POFILE= wrsmconf_cmd.po -POFILES= wrsmconf.po mkconfig.po - -INS.root.sys = install -s -m 755 -f -$(CH)INS.root.sys = install -s -m 755 -u root -g sys -f -INSLINKTARGET= $(INIT_PROG) - - -CPPFLAGS += -I$(USR_PSM_INCL_DIR) -LDFLAGS += -L$(ROOT)/platform/sun4u/lib -R/platform/sun4u/lib -LDLIBS += -lwrsmconf - -.KEEP_STATE: - -all: $(ROOTFS_PROG) - -install: all $(ROOTPROG) $(INIT_PROG) $(ROOTRCS_SLINK) $(ROOTRCS_KLINK) $(DATA_D) - - -$(PROG): $(OBJS) - $(LINK.c) $(OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -$(DATA_D): - $(INS.dir.root.sys) - -$(ROOTBIN): - $(INS.dir.root.sys) - -$(INIT_D): - $(INS.dir.root.sys) - -$(ROOTRCS_D): - $(INS.dir.root.sys) - -$(ROOTRCS_SLINK): $(INIT_PROG) $(ROOTRCS_D) - $(INS.link) - -$(ROOTRCS_KLINK): $(INIT_PROG) $(ROOTRCS_D) - $(INS.link) - -$(INIT_PROG): $(INIT_D) $(SCRIPT) - $(INS.root.sys) $(INIT_D) $(SCRIPT) - -$(ROOTPROG): $(ROOTBIN) $(PROG) - $(INS.root.sys) $(ROOTBIN) $(PROG) - -clean: - $(RM) $(OBJS) - -lint: $(MACH)_lint - -i386_lint: - -sparc_lint: - $(LINT.c) -u $(SRCS) $(LDLIBS.cmd) - -$(POFILE): $(POFILES) - $(RM) $@ - cat $(POFILES) > $@ - -include ../Makefile.targ diff --git a/usr/src/cmd/wrsmconf/mkconfig.c b/usr/src/cmd/wrsmconf/mkconfig.c deleted file mode 100644 index 58ac3233d4..0000000000 --- a/usr/src/cmd/wrsmconf/mkconfig.c +++ /dev/null @@ -1,891 +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 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This program converts a 'netlist' file into a config file, suitable - * for configuring the Wildcat RSM driver. - * - * Caveats: - * Handles 2-way wci striping, but not 4-way. - * Assumes you want to do as much striping as possible. - */ - -#include <sys/types.h> -#include <netdb.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <libintl.h> -#include <errno.h> -#include <sys/wrsm_types.h> -#include <sys/wrsm_config.h> -#include "wrsmconf_msgs.h" - -#ifdef DEBUG -#define TRACE(f) printf(f) -#define DPRINTF(s) printf s -#else -#define TRACE(f) -#define DPRINTF(s) -#endif - -#define MAXHOSTS 256 -#define MAXWCIS (3 * 18) -#define MAXLINKS 8 -#define MAXOPTLEN 80 -#define MAXULONGSTR 11 /* E.g., 0xffffffff or 4294967295 */ - - -#define NCSLICE_BASE 0xA1 /* Works for Serengeti and Starcat */ -#define NCSLICE_CTRL (multihop_allowed ? 10 : 4) /* Nodes per ctrl */ -#define COMM_BASE 2 /* Start with page 2 */ -#define PAGE_SIZE 0x2000 - -#define MAXCTRL ((WRSM_MAX_NCSLICES - 1) - ncslice_base)/NCSLICE_CTRL -#define WRSMCONF_CREATE "create" - -/* - * Macros to produce a quoted string containing the value of a - * preprocessor macro. For example, if SIZE is defined to be 256, - * VAL2STR(SIZE) is "256". This is used to construct format - * strings for scanf-family functions below. - */ -#define QUOTE(x) #x -#define VAL2STR(x) QUOTE(x) - -static int ncslice_base = NCSLICE_BASE; -static int controller = 0; /* Controller number to assign */ -static int gnid_offset = 0; -static boolean_t passthrough_allowed = B_FALSE; -static boolean_t multihop_allowed = B_FALSE; -static FILE *outf = stdout; - -typedef struct { - boolean_t in_use; - int remote_cnode; - int remote_wci; - int remote_link; -} link_info_t; - -typedef struct { - int wci_id; - link_info_t links[MAXLINKS]; -} wci_info_t; - -typedef struct { - boolean_t in_use; - char name[WRSM_HOSTNAMELEN]; - int num_wcis; - wci_info_t wcis[MAXWCIS]; - boolean_t wcswitch; -} host_info_t; - -typedef struct { - host_info_t hosts[MAXHOSTS]; - int num_hosts; - union { - struct { - uint32_t upper_word; - time_t clock_val; - } raw; - uint64_t val; - } version_stamp; -} config_info_t; - -typedef struct { - int wcia; - int wcib; -} stripe_group_t; - -typedef struct { - stripe_group_t sg[36]; - int nsg; -} stripe_list_t; - -typedef enum { - CAN_REACH_NO, - CAN_REACH_DIRECT, - CAN_REACH_MULTIHOP, - CAN_REACH_PASSTHROUGH -} can_reach_t; - -/* - * Finds the WCI associated with the given cnodeid, and if not found - * creates a new WCI for that cnode. - */ -static wci_info_t * -add_wci(config_info_t *config, int cnode, int wci_id) -{ - int i; - host_info_t *host = &(config->hosts[cnode]); - wci_info_t *wci; - - DPRINTF(("add_wci(cnode=%d, wci_id=%d)\n", cnode, wci_id)); - /* First search for a matching WCI */ - for (i = 0; i < host->num_wcis; i++) { - wci = &(host->wcis[i]); - if (wci->wci_id == wci_id) { - return (wci); - } - } - /* Otherwise, create the WCI */ - wci = &(host->wcis[host->num_wcis]); - wci->wci_id = wci_id; - host->num_wcis++; - return (wci); -} - -/* Adds link info to a host's wci */ -static void -add_link(config_info_t *config, int cnode, int wci_id, int link, - int rem_cnode, int rem_wci, int rem_link) -{ - host_info_t *host = &(config->hosts[cnode]); - wci_info_t *wci = add_wci(config, cnode, wci_id); - - DPRINTF(("add_link(cnode=%d, wci_id=%d, link=%d, rem_cnode=%d, " - "rem_wci=%d, rem_link=%d)\n", cnode, wci_id, link, rem_cnode, - rem_wci, rem_link)); - - /* Check for loopback links and ignore */ - if (cnode == rem_cnode && wci_id == rem_wci && link == rem_link) { - return; - } - - if (wci->links[link].in_use) { - (void) fprintf(stderr, MSG_LINK_IN_USE, - WRSMCONF_CREATE, host->name, wci->wci_id, link); - exit(1); - } - wci->links[link].in_use = B_TRUE; - wci->links[link].remote_cnode = rem_cnode; - wci->links[link].remote_wci = rem_wci; - wci->links[link].remote_link = rem_link; -} - -/* Creates a new host entry */ -static int -add_host(config_info_t *config, char *hostname, boolean_t wcswitch) -{ - int i; - int start = wcswitch ? 16 : 0; /* Bias switches to be > 16 */ - - DPRINTF(("add_host(hostname=%s, wcswitch=%d)\n", hostname, wcswitch)); - - for (i = start; i < MAXHOSTS; i++) { - if (!config->hosts[i].in_use) { - break; - } - } - if (i == MAXHOSTS) { - (void) fprintf(stderr, MSG_NUM_HOSTS, WRSMCONF_CREATE, - MAXHOSTS); - exit(1); - } - config->hosts[i].in_use = B_TRUE; - (void) strlcpy(config->hosts[i].name, hostname, WRSM_HOSTNAMELEN); - config->hosts[i].wcswitch = wcswitch; - - return (i); -} - -/* Given a host name, returns its cnode id, or creates a new one */ -static int -host2node(config_info_t *config, char *hostname) -{ - int i; - - /* First search for previous occurence */ - for (i = 0; i < MAXHOSTS; i++) { - if (config->hosts[i].in_use && - strcmp(hostname, config->hosts[i].name) == 0) { - return (i); - } - } - return (add_host(config, hostname, B_FALSE)); -} - -/* Parses the netlist file into the config structure */ -static void -parse_file(char *filename, config_info_t *config) -{ - char s[255]; - char t[255]; - FILE *f; - boolean_t show_usage; - - if (strcmp(filename, "-") == 0) { - f = stdin; - show_usage = isatty(0) ? B_TRUE : B_FALSE; - } else { - f = fopen(filename, "r"); - show_usage = B_TRUE; - } - - if (f == NULL) { - perror(filename); - exit(1); - } - if (show_usage) { - (void) fprintf(stderr, MSG_INPUT1); - (void) fprintf(stderr, MSG_INPUT2); - (void) fprintf(stderr, MSG_INPUT3); - } - while (fgets(t, sizeof (t), f)) { - int i; - int x; - char hosta[WRSM_HOSTNAMELEN+1]; - char hostb[WRSM_HOSTNAMELEN+1]; - char wciastr[MAXULONGSTR+1], wcibstr[MAXULONGSTR+1]; - int cnodea, wcia, linka, cnodeb, wcib, linkb; - - DPRINTF(("parsing line: %s\n", t)); - (void) fprintf(outf, "# %s", t); - for (i = 0; t[i]; i++) { - if (t[i] == '#') { - break; - } else if (t[i] == '.') { - s[i] = ' '; - } else if (t[i] == '=') { - s[i] = ' '; - } else { - s[i] = t[i]; - } - } - s[i] = 0; - - /* Check if this line is an "option" */ - if (s[0] == '-') { - char opt[MAXOPTLEN+1]; - char args[2][WRSM_HOSTNAMELEN+1]; - x = sscanf(&s[1], - "%" VAL2STR(MAXOPTLEN) "s " - "%" VAL2STR(WRSM_HOSTNAMELEN) "s " - "%" VAL2STR(WRSM_HOSTNAMELEN) "s", - opt, args[0], args[1]); - if (strcmp(opt, "multihop") == 0 && x == 1) { - multihop_allowed = B_TRUE; - } else if (strcmp(opt, "passthrough") == 0 && x == 1) { - passthrough_allowed = B_TRUE; - } else if (strcmp(opt, "host") == 0 && x == 2) { - (void) add_host(config, args[0], B_FALSE); - } else if (strcmp(opt, "switch") == 0 && x == 2) { - (void) add_host(config, args[0], B_TRUE); - multihop_allowed = B_TRUE; - } else if (strcmp(opt, "controller") == 0 && x == 2) { - controller = strtol(args[0], NULL, 0); - } else if (strcmp(opt, "ncslice") == 0 && x == 2) { - int n = strtol(args[0], NULL, 0); - if (n < 1 || n > 254) { - (void) fprintf(stderr, MSG_INVALID, - WRSMCONF_CREATE, "ncslice", n); - } else { - ncslice_base = n; - } - } else if (strcmp(opt, "gnid") == 0 && x == 2) { - gnid_offset = strtol(args[0], NULL, 0); - } else { - (void) fprintf(stderr, MSG_UNKNOWN, - WRSMCONF_CREATE, opt); - } - continue; - } - x = sscanf(s, - " %" VAL2STR(WRSM_HOSTNAMELEN) "s " - "%" VAL2STR(MAXULONGSTR) "s " - "%d " - "%" VAL2STR(WRSM_HOSTNAMELEN) "s " - "%" VAL2STR(MAXULONGSTR) "s " - "%d", - hosta, wciastr, &linka, hostb, wcibstr, &linkb); - if (x < 1) { - /* Blank line */ - continue; - } else if (x < 6) { - (void) fprintf(stderr, MSG_PARSE_ERR, - WRSMCONF_CREATE, t); - continue; - } - wcia = strtol(wciastr, NULL, 0); - wcib = strtol(wcibstr, NULL, 0); - if (linka > MAXLINKS || linkb > MAXLINKS) { - (void) fprintf(stderr, MSG_LINK_RANGE, - WRSMCONF_CREATE, s); - exit(1); - } - cnodea = host2node(config, hosta); - cnodeb = host2node(config, hostb); - /* Link goes it both directions, so add both directions */ - add_link(config, cnodea, wcia, linka, cnodeb, wcib, linkb); - add_link(config, cnodeb, wcib, linkb, cnodea, wcia, linka); - } -} - -/* - * The following functions generate the actual config file - */ - -/* Prints cnodeid section of config file */ -static void -print_cnodeids(config_info_t *config, int cnode) -{ - int i; - int comm_offset = (cnode + COMM_BASE) * PAGE_SIZE; - - for (i = 0; i < MAXHOSTS; i++) { - int ncslice = i + ncslice_base + controller * NCSLICE_CTRL; - int local_offset = (i + COMM_BASE) * PAGE_SIZE; - - if (!config->hosts[i].in_use || - config->hosts[i].wcswitch) { - continue; - } - - (void) fprintf(outf, "\tcnodeid %d {\n", i); - (void) fprintf(outf, "\t\tfmnodeid 0x%x %s\n", - i + gnid_offset, config->hosts[i].name); - (void) fprintf(outf, "\t\texported_ncslices { 0x%02x }\n", - ncslice); - (void) fprintf(outf, "\t\timported_ncslices { 0x%02x }\n", - cnode + ncslice_base + (controller * NCSLICE_CTRL)); - (void) fprintf(outf, "\t\tlocal_offset 0x%04x\n", - local_offset); - (void) fprintf(outf, "\t\tcomm_ncslice 0x%02x 0x%04x\n", - ncslice, comm_offset); - (void) fprintf(outf, "\t}\n"); - } -} - -/* Prints the link subsection of the wci section of the config file */ -static void -print_link(link_info_t *link) -{ - int remote_gnid; - - if (link->remote_cnode >= WRSM_MAX_WNODES) - remote_gnid = link->remote_cnode; - else - remote_gnid = link->remote_cnode + gnid_offset; - - (void) fprintf(outf, "\t\t\tremote_gnid %d\n", remote_gnid); - (void) fprintf(outf, "\t\t\tremote_link %d\n", link->remote_link); - (void) fprintf(outf, "\t\t\tremote_wci %d\n", link->remote_wci); -} - -/* Checks if a node is already reachable */ -static int -is_duplicate(int reachable_list[], int *num_reachable, int cnode) -{ - int i; - - for (i = 0; i < *num_reachable; i++) { - if (reachable_list[i] == cnode) { - return (B_TRUE); - } - } - reachable_list[*num_reachable] = cnode; - (*num_reachable)++; - return (B_FALSE); -} - -/* Prints the wci section of the config file */ -static void -print_wci(config_info_t *config, wci_info_t *wci, int cnode) -{ - int i; - int j; - boolean_t route_map_striping = B_FALSE; - - /* Check for route_map_striping */ - for (i = 0; i < MAXLINKS; i++) { - link_info_t *ilink = &(wci->links[i]); - if (!ilink->in_use) { - continue; - } - for (j = 0; j < i; j++) { - link_info_t *jlink = &(wci->links[j]); - if (!jlink->in_use) { - continue; - } - if (ilink->remote_cnode == jlink->remote_cnode && - ilink->remote_wci == jlink->remote_wci) { - route_map_striping = B_TRUE; - } - } - } - - (void) fprintf(outf, "\twci {\n"); - (void) fprintf(outf, "\t\tsafari_port_id %d\n", wci->wci_id); - (void) fprintf(outf, "\t\twnodeid %d\n", cnode); - (void) fprintf(outf, "\t\tgnid %d\n", cnode + gnid_offset); - (void) fprintf(outf, "\t\treachable (%d,%d,%d)", cnode, - cnode + gnid_offset, cnode); - - for (i = 0; i < MAXLINKS; i++) { - int reachable_list[MAXHOSTS]; - int num_reachable = 0; - link_info_t *link = &(wci->links[i]); - - /* Add ourselves to the reachable list */ - reachable_list[num_reachable++] = cnode; - - if (!link->in_use) { - continue; - } - /* Make sure it's not a dup */ - if (is_duplicate(reachable_list, &num_reachable, - link->remote_cnode)) { - continue; - } - - /* If not duplicate and remote node is a switch... */ - if (config->hosts[link->remote_cnode].wcswitch) { - /* Ignore switch, report on remote cnodes */ - wci_info_t *swwci = - &config->hosts[link->remote_cnode].wcis[0]; - - for (j = 0; j < MAXLINKS; j++) { - link_info_t *swlink = &(swwci->links[j]); - if (!swlink->in_use) { - continue; - } - if (is_duplicate(reachable_list, - &num_reachable, swlink->remote_cnode)) { - continue; - } - (void) fprintf(outf, " (%d,%d,%d)", - swlink->remote_cnode, - swlink->remote_cnode + gnid_offset, - swlink->remote_cnode); - } - } else { - (void) fprintf(outf, " (%d,%d,%d)", - link->remote_cnode, - link->remote_cnode + gnid_offset, - link->remote_cnode); - } - } - (void) fprintf(outf, "\n"); - (void) fprintf(outf, "\t\troute_map_striping %s\n", - (route_map_striping)?"true":"false"); - (void) fprintf(outf, "\t\ttopology_type distributed_switch\n"); - for (i = 0; i < MAXLINKS; i++) { - link_info_t *link = &(wci->links[i]); - if (link->in_use) { - (void) fprintf(outf, "\t\tlink %d {\n", i); - print_link(link); - (void) fprintf(outf, "\t\t}\n"); - } - } - (void) fprintf(outf, "\t}\n"); -} - -static wci_info_t * -wci_from_cnode(config_info_t *config, int cnode, int wci_id) -{ - int i; - DPRINTF(("wci_from_cnode(cnode=%d, wci=%d)\n", cnode, wci_id)); - for (i = 0; i < config->hosts[cnode].num_wcis; i++) { - if (config->hosts[cnode].wcis[i].wci_id == wci_id) { - return (&config->hosts[cnode].wcis[i]); - } - } - return (NULL); -} - -static boolean_t -wci_can_reach_direct(wci_info_t *wci, int dest_cnode) -{ - int link; - DPRINTF(("wci_can_reach_direct(wci=%d, dest_cnode=%d)\n", - wci->wci_id, dest_cnode)); - - /* Look for direct connect */ - for (link = 0; link < MAXLINKS; link++) { - if (wci->links[link].in_use && - wci->links[link].remote_cnode == dest_cnode) { - DPRINTF((" wci_can_reach_direct: TRUE\n")); - return (B_TRUE); - } - } - DPRINTF((" wci_can_reach_direct: FALSE\n")); - return (B_FALSE); -} - -static boolean_t -wci_can_reach_multihop(config_info_t *config, wci_info_t *wci, - int dest_cnode) -{ - int link; - - DPRINTF(("wci_can_reach_multihop(wci=%d, dest_cnode=%d)\n", - wci->wci_id, dest_cnode)); - - for (link = 0; link < MAXLINKS; link++) { - if (wci->links[link].in_use) { - /* Find the WCI at the other end of the link */ - wci_info_t *mh_wci = - wci_from_cnode(config, - wci->links[link].remote_cnode, - wci->links[link].remote_wci); - if (mh_wci == NULL) { - exit(1); - } - /* See if that WCI can get us where we're going */ - if (wci_can_reach_direct(mh_wci, dest_cnode)) { - DPRINTF((" wci_can_reach_multihop: TRUE\n")); - return (B_TRUE); - } - } - } - DPRINTF((" wci_can_reach_multihop: FALSE\n")); - return (B_FALSE); -} - -static boolean_t -cnode_can_reach_direct(config_info_t *config, int cnode, int dest_cnode) -{ - int i; - DPRINTF(("cnode_can_reach_direct(cnode=%d, dest_cnode=%d)\n", - cnode, dest_cnode)); - for (i = 0; i < config->hosts[cnode].num_wcis; i++) { - if (wci_can_reach_direct( - &config->hosts[cnode].wcis[i], - dest_cnode)) { - DPRINTF((" cnode_can_reach_direct: TRUE\n")); - return (B_TRUE); - } - } - DPRINTF((" cnode_can_reach_direct: FALSE\n")); - return (B_FALSE); -} - -static boolean_t -wci_can_reach_passthrough(config_info_t *config, wci_info_t *wci, - int dest_cnode, int *pt_cnode, int *num_switches) -{ - int link; - DPRINTF(("wci_can_reach_passthrough(wci=%d, dest_cnode=%d)\n", - wci->wci_id, dest_cnode)); - - *num_switches = 0; - /* Try all links, until we've found two switches */ - for (link = 0; link < MAXLINKS && *num_switches < 2; link++) { - /* - * If this link is in use, and the cnode at the other - * end of the link can reach the destination cnode, - * then we have a passthrough route. - */ - if (wci->links[link].in_use && - cnode_can_reach_direct(config, - wci->links[link].remote_cnode, - dest_cnode)) { - /* Remember the passthrough node */ - pt_cnode[*num_switches] = - wci->links[link].remote_cnode; - (*num_switches)++; - DPRINTF((" wci_can_reach_passthrough: TRUE\n")); - } - } - DPRINTF((" wci_can_reach_passthrough: %d\n", *num_switches)); - return (*num_switches > 0); -} - -/* Checks if this wci can reach the dest_cnode on one of its links */ -static can_reach_t -wci_can_reach(config_info_t *config, wci_info_t *wci, int dest_cnode, - int *pt_cnodes, int *num_switches) -{ - DPRINTF(("wci_can_reach(wci=%d, dest_cnode=%d)\n", - wci->wci_id, dest_cnode)); - - *pt_cnodes = -1; - *num_switches = 0; - - /* First try direct connect */ - if (wci_can_reach_direct(wci, dest_cnode)) { - return (CAN_REACH_DIRECT); - } - /* Look for multihop */ - if (multihop_allowed && - wci_can_reach_multihop(config, wci, dest_cnode)) { - return (CAN_REACH_MULTIHOP); - } - /* Finally, try passthrough */ - if (pt_cnodes != NULL && passthrough_allowed && - wci_can_reach_passthrough(config, wci, dest_cnode, - pt_cnodes, num_switches)) { - return (CAN_REACH_PASSTHROUGH); - } - return (CAN_REACH_NO); -} - -/* Given two wcis, returns their stripe group (or creates a new one) */ -static int -get_stripe_group(stripe_list_t *sl, int wcia, int wcib) { - int i; - - for (i = 0; i < sl->nsg; i++) { - if ((sl->sg[i].wcia == wcia && sl->sg[i].wcib == wcib) || - (sl->sg[i].wcia == wcib && sl->sg[i].wcib == wcia)) - return (i); - } - sl->sg[i].wcia = wcia; - sl->sg[i].wcib = wcib; - sl->nsg++; - return (i); -} - -/* Prints the stripe_group section of the config file */ -static void -print_stripe_groups(stripe_list_t *sl) -{ - int i; - for (i = 0; i < sl->nsg; i++) { - (void) fprintf(outf, "\tstripe_group %d { \n", i); - (void) fprintf(outf, "\t\twcis 0x%x 0x%x\n", - sl->sg[i].wcia, sl->sg[i].wcib); - (void) fprintf(outf, "\t}\n"); - } -} - -/* Prints the routing sections of the config file */ -static void -print_routing(config_info_t *config, int cnode) -{ - int i; - int j; - int k; - stripe_list_t sl; - host_info_t *host = &(config->hosts[cnode]); - int ptswitches[4]; - int num_switches = 0; - - sl.nsg = 0; - - for (i = 0; i < MAXHOSTS; i++) { - boolean_t same_node = (i == cnode); - boolean_t found_a_route = B_FALSE; - - if (!config->hosts[i].in_use || - config->hosts[i].wcswitch) { - continue; - } - - (void) fprintf(outf, "\trouting_policy %d { # %s\n", - i, same_node ? "loopback" : config->hosts[i].name); - /* First check for WCI striping */ - for (j = 0; j < host->num_wcis && !same_node; j++) { - wci_info_t *jwci = &(host->wcis[j]); - can_reach_t can_reach_j = wci_can_reach(config, - jwci, i, ptswitches, &num_switches); - if (can_reach_j == CAN_REACH_NO) { - continue; - } - for (k = 0; k < j; k++) { - wci_info_t *kwci = &(host->wcis[k]); - int sg; - int new_ptswitches[2]; - int new_switches = 0; - can_reach_t can_reach_k = - wci_can_reach(config, kwci, i, - new_ptswitches, - &new_switches); - if (can_reach_k != can_reach_j) { - continue; - } - found_a_route = B_TRUE; - - /* Make sure pt striping is balanced */ - if (num_switches == new_switches) { - int k; - for (k = 0; k < new_switches; k++) { - ptswitches[num_switches + k] = - new_ptswitches[k]; - } - num_switches += new_switches; - } else if (num_switches > 0) { - ptswitches[1] = new_ptswitches[0]; - num_switches = 2; - } - sg = get_stripe_group(&sl, jwci->wci_id, - kwci->wci_id); - (void) fprintf(outf, - "\t\tpreferred_route {\n"); - (void) fprintf(outf, - "\t\t\tstriping_level %d\n", - (can_reach_j == CAN_REACH_PASSTHROUGH) ? - num_switches : 2); - (void) fprintf(outf, - "\t\t\trouting_method %s\n", - (can_reach_j == CAN_REACH_PASSTHROUGH) ? - "passthrough" : "multihop"); - (void) fprintf(outf, - "\t\t\tstripe_group %d\n", sg); - if (can_reach_j == CAN_REACH_PASSTHROUGH) { - int k; - (void) fprintf(outf, - "\t\t\tswitches"); - for (k = 0; k < num_switches; k++) { - (void) fprintf(outf, " %d", - ptswitches[k]); - } - (void) fprintf(outf, "\n"); - } - (void) fprintf(outf, "\t\t}\n"); - } - } - - /* Next, find out how many WCIs go there */ - for (j = 0; j < host->num_wcis; j++) { - wci_info_t *wci = &(host->wcis[j]); - /* Note: We can always reach ourselves */ - can_reach_t can_reach; - if (same_node) { - can_reach = CAN_REACH_MULTIHOP; - } else { - can_reach = wci_can_reach(config, - wci, i, &ptswitches[0], &num_switches); - } - - if (can_reach == CAN_REACH_NO && i != cnode) { - continue; - } - found_a_route = B_TRUE; - (void) fprintf(outf, "\t\tpreferred_route {\n"); - (void) fprintf(outf, "\t\t\tstriping_level %d\n", - (can_reach == CAN_REACH_PASSTHROUGH) ? - num_switches : 1); - (void) fprintf(outf, "\t\t\trouting_method %s\n", - (can_reach == CAN_REACH_PASSTHROUGH) ? - "passthrough" : "multihop"); - (void) fprintf(outf, "\t\t\tuse_wci %d\n", - wci->wci_id); - if (can_reach == CAN_REACH_PASSTHROUGH) { - int k; - (void) fprintf(outf, "\t\t\tswitches"); - for (k = 0; k < num_switches; k++) { - (void) fprintf(outf, " %d", - ptswitches[k]); - } - (void) fprintf(outf, "\n"); - } - (void) fprintf(outf, "\t\t}\n"); - } - if (!found_a_route) { - (void) fprintf(stderr, MSG_NO_ROUTE, WRSMCONF_CREATE, - config->hosts[i].name, config->hosts[j].name); - (void) fprintf(outf, "\t\t/* NO ROUTE */\n"); - } - (void) fprintf(outf, "\t\twcis_balanced false\n"); - (void) fprintf(outf, "\t\tstriping_important true\n"); - if (passthrough_allowed && !same_node) { - (void) fprintf(outf, - "\t\tforwarding_ncslices 0x%x\n", - i + ncslice_base + (controller * NCSLICE_CTRL)); - } - (void) fprintf(outf, "\t}\n"); - } - print_stripe_groups(&sl); -} - -/* Prints a specific host configuration */ -static void -print_host(config_info_t *config, int cnode) -{ - int i; - host_info_t *host = &(config->hosts[cnode]); - - (void) fprintf(outf, "\n"); - (void) fprintf(outf, "#\n"); - (void) fprintf(outf, "# Config for host %s\n", host->name); - (void) fprintf(outf, "#\n"); - (void) fprintf(outf, "fmnodeid 0x%x %s\n", cnode + gnid_offset, - host->name); - (void) fprintf(outf, "controller %d {\n", controller); - (void) fprintf(outf, "\tconfig_protocol_version %u\n", - 2); - (void) fprintf(outf, "\tversion %llu\n", config->version_stamp.val); - (void) fprintf(outf, "\tlocal_cnodeid %d\n", cnode); - print_cnodeids(config, cnode); - for (i = 0; i < host->num_wcis; i++) { - print_wci(config, &(host->wcis[i]), cnode); - } - print_routing(config, cnode); - (void) fprintf(outf, "}\n"); -} - -/* Prints config file for all hosts */ -static void -print_config_file(config_info_t *config) -{ - int i; - for (i = 0; i < MAXHOSTS; i++) { - if (config->hosts[i].in_use && - !config->hosts[i].wcswitch) { - print_host(config, i); - } - } -} - -/* Main */ -int -mkconfig(char *input_file, char *output_file, int controller_id) -{ - config_info_t the_config; - - (void) memset(&the_config, 0, sizeof (the_config)); - (void) time(&the_config.version_stamp.raw.clock_val); - /* Set MSB to differentiate from FM-generated version stamps */ - the_config.version_stamp.raw.upper_word = 0x80000000; - - if (controller_id > MAXCTRL || controller_id < 0) { - errno = EINVAL; - perror(WRSMCONF_CREATE); - return (1); - } - controller = controller_id; - - if (input_file == NULL) - input_file = "-"; - if (output_file != NULL) { - outf = fopen(output_file, "w"); - if (outf == NULL) { - perror(WRSMCONF_CREATE); - return (1); - } - } - parse_file(input_file, &the_config); - if (the_config.num_hosts > NCSLICE_CTRL) { - (void) fprintf(stderr, MSG_NUM_HOSTS, - WRSMCONF_CREATE, NCSLICE_CTRL); - return (1); - } - print_config_file(&the_config); - return (0); -} diff --git a/usr/src/cmd/wrsmconf/wrsmcfg b/usr/src/cmd/wrsmconf/wrsmcfg deleted file mode 100644 index c6fefe7950..0000000000 --- a/usr/src/cmd/wrsmconf/wrsmcfg +++ /dev/null @@ -1,53 +0,0 @@ -#!/sbin/sh -# -# 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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#ident "%Z%%M% %I% %E% SMI" - -CMD="/platform/sun4u/sbin/wrsmconf" - -platform=${_INIT_UTS_PLATFORM:-`/sbin/uname -i`} -serengeti="SUNW,Sun-Fire" -starcat="SUNW,Sun-Fire-15000" - -case "$1" in -'start') - if [ ${platform} = "${serengeti}" -o ${platform} = "${starcat}" ]; then - $CMD start - fi - ;; - -'stop') - if [ ${platform} = "${serengeti}" -o ${platform} = "${starcat}" ]; then - $CMD stop - fi - ;; - -*) - echo "Usage: $0 { start | stop }" - exit 1 - ;; -esac -exit 0 diff --git a/usr/src/cmd/wrsmconf/wrsmconf.c b/usr/src/cmd/wrsmconf/wrsmconf.c deleted file mode 100644 index a579e9b947..0000000000 --- a/usr/src/cmd/wrsmconf/wrsmconf.c +++ /dev/null @@ -1,817 +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 2001-2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file implments the RSM Proxy. - * - * The program is controlled by its command line arguments. - * The first argument is always the name of the command to be - * executed followed by some number of options with the - * appropriate parameter values. - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <libintl.h> -#include <locale.h> -#include <sys/int_fmtio.h> -#include <sys/systeminfo.h> -#include <sys/wrsmconf.h> -#include <stddef.h> -#include <errno.h> -#include "wrsmconf_msgs.h" - -#define DEVNAME "/devices/wrsm@ffff,0:admin" -#define CTLRDEVNAME "/dev/wrsm%d" -#define MAX_WCI_IDS 54 - -extern int ErrorCount; - -struct dump_info { - wrsm_fmnodeid_t fmnode_id; - char host_name[WRSM_HOSTNAMELEN]; - uint32_t controller_id; - unsigned char cnode_id; -}; - -static void init_usage(void); -static void print_usage(boolean_t private); -static void print_command_usage(char *command); -static int dump_config(char *fn, int controller_id); -static int getinfo(int controller_id); -static void free_controller_info(struct dump_info ***controller_info); -static int compare(const void *left, const void *right); -static void print_column_headers(FILE *fp); -static void print_member_info(FILE *fp, struct dump_info **info, - int num_members); -static int topology(int cid); -static int check(int cid, char *hostname); -int mkconfig(char *input_file, char *output_file, int controller_id); - -/* Private function in libwrsmconf */ -extern void wrsm_print_controller(FILE *fp, wrsm_controller_t *cont); - -static struct { - char *name; - char *usage; -} commands[6], private_commands[] = { - { "usage", "[<command>]" }, - { "replace", "-f <in-filename> [-c <controller-id>] [-h <hostname>]" }, - { "install", "[-c <controller-id>] [-w <wci-id>]" }, - { "enable", "[-c <controller-id>] [-w <wci-id>]" }, - { "info", "[-c <controller-id>]" }, - { "read", "[-c <controller-id>] -f <in-filename> [-h <hostname>]" }, - { "start", "[-c <controller-id>]" }, - { "stop", "[-c <controller-id>]" }, - { "link_disable", "-w <wci-id> -l <linkno>" }, - { "link_enable", "-w <wci-id> -l <linkno>" }, - { "check", "[-c <controller-id>] [-h <hostname>]" }, - { "msgtest", "" }, - { NULL, NULL }, -}; - -static char *command_name; -extern char *optarg; -extern int optind; -extern int opterr; -extern int optopt; - -int -main(int argc, char **argv) -{ - char *file = NULL; - int controller_id = -1; - wrsm_safari_port_t wci_ids[MAX_WCI_IDS]; - size_t num_wcis = 0; - boolean_t got_controller_id = B_FALSE; - boolean_t got_hostname = B_FALSE; - char hostname[WRSM_HOSTNAMELEN] = ""; - char c; - char *command; - wrsm_controller_t *cont = NULL; - int wci_index = 0; - int rc; - int linkno = -1; - - (void) setlocale(LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - command_name = argv[0]; - - if (argc < 2) { - print_usage(B_FALSE); - return (2); - } - - command = argv[1]; - - while ((c = getopt(argc-1, &argv[1], "c:f:h:l:w:")) - != EOF) { - switch (c) { - case 'c': - controller_id = atoi(optarg); - got_controller_id = B_TRUE; - break; - case 'f': - file = optarg; - break; - case 'w': - wci_ids[wci_index++] = - (wrsm_safari_port_t) - strtol(optarg, NULL, 0); - num_wcis++; - break; - case 'h': - (void) strcpy(hostname, optarg); - got_hostname = B_TRUE; - break; - case 'l': - linkno = (int)atoi(optarg); - break; - default: - print_command_usage(command); - return (1); - } - } - - if (strcmp(command, "create") == 0) { - if (!got_controller_id) { - errno = EINVAL; - perror(command); - print_command_usage(command); - return (1); - } - if (file == NULL) { - errno = EINVAL; - perror(command); - print_command_usage(command); - return (1); - } - rc = mkconfig(NULL, file, controller_id); - - } else if (strcmp(command, "initial") == 0) { - if (file == NULL) { - errno = EINVAL; - perror(command); - print_command_usage(command); - return (1); - } - - if (got_hostname) - rc = wrsm_read_config_for_host(file, &cont, hostname); - else - rc = wrsm_read_config(file, &cont); - if (rc != 0) { - (void) fprintf(stderr, MSG_FILE, command, file); - return (1); - } - if (got_controller_id && - controller_id != cont->controller_id) { - (void) fprintf(stderr, MSG_NOT_FOUND, - command, controller_id, file); - return (1); - } - - if ((rc = wrsm_initial_config(cont)) != 0) { - perror(command); - return (1); - } - - } else if (strcmp(command, "start") == 0) { - if (!got_controller_id) { - rc = wrsm_start_all_configs(); - return (rc ? 1 : 0); - } else if ((rc = wrsm_start_config(controller_id)) != 0) { - perror(command); - return (1); - } - - } else if (strcmp(command, "stop") == 0) { - if (!got_controller_id) { - rc = wrsm_stop_all_configs(); - return (rc ? 1 : 0); - } else if ((rc = wrsm_stop_config(controller_id)) != 0) { - perror(command); - return (1); - } - - } else if (strcmp(command, "remove") == 0) { - if (!got_controller_id) { - rc = wrsm_remove_all_configs(); - return (rc ? 1 : 0); - } else if ((rc = wrsm_remove_config(controller_id)) != 0) { - perror(command); - return (1); - } - - } else if (strcmp(command, "replace") == 0) { - if (file == NULL) { - errno = EINVAL; - perror(command); - print_command_usage(command); - return (1); - } - - if (got_hostname) - rc = wrsm_read_config_for_host(file, &cont, hostname); - else - rc = wrsm_read_config(file, &cont); - - if (rc != 0) { - (void) fprintf(stderr, MSG_FILE, command, file); - return (1); - } - if (got_controller_id && - controller_id != cont->controller_id) { - (void) fprintf(stderr, MSG_NOT_FOUND, - command, controller_id, file); - return (1); - } - if ((rc = wrsm_replace_config(cont)) != 0) { - perror(command); - return (1); - } - - } else if (strcmp(command, "install") == 0) { - if (!got_controller_id) { - controller_id = 0; - } - if ((rc = wrsm_install_config(controller_id, num_wcis, - wci_ids)) != 0) { - perror(command); - return (1); - } - - } else if (strcmp(command, "enable") == 0) { - if (!got_controller_id) { - controller_id = 0; - } - if ((rc = wrsm_enable_config(controller_id, num_wcis, - wci_ids)) != 0) { - perror(command); - return (1); - } - - } else if (strcmp(command, "dump") == 0) { - if (!got_controller_id) { - errno = EINVAL; - perror(command); - print_command_usage(command); - return (1); - } - if (file == NULL) { - errno = EINVAL; - perror(command); - print_command_usage(command); - return (1); - } - return (dump_config(file, controller_id)); - - } else if (strcmp(command, "info") == 0) { - return (getinfo(controller_id)); - - } else if (strcmp(command, "topology") == 0) { - return (topology(controller_id)); - - } else if (strcmp(command, "check") == 0) { - return (check(controller_id, got_hostname ? hostname : NULL)); - - } else if (strcmp(command, "usage") == 0) { - if (argc == 3) { - char *cmd = argv[2]; - if (strcmp(cmd, "private") == 0) { - print_usage(B_TRUE); - } else { - print_command_usage(cmd); - } - } else { - print_usage(B_FALSE); - } - - } else if (strcmp(command, "read") == 0) { - if (file == NULL) { - errno = EINVAL; - perror(command); - print_command_usage(command); - return (1); - } - - if (got_hostname) - rc = wrsm_read_config_for_host(file, &cont, hostname); - else - rc = wrsm_read_config(file, &cont); - if (rc != 0) { - (void) fprintf(stderr, MSG_FILE, command, file); - return (1); - } - if (got_controller_id && - controller_id != cont->controller_id) { - (void) fprintf(stderr, MSG_NOT_FOUND, - command, controller_id, file); - return (1); - } - wrsm_print_controller(stdout, cont); - - } else if (strcmp(command, "link_enable") == 0) { - - if ((num_wcis != 1) || (linkno == -1)) { - errno = EINVAL; - perror(command); - print_command_usage(command); - return (1); - } - rc = wrsm_link_enable(wci_ids[0], linkno); - if (rc != 0) { - perror(command); - return (1); - } - - } else if (strcmp(command, "link_disable") == 0) { - - if ((num_wcis != 1) || (linkno == -1)) { - errno = EINVAL; - perror(command); - print_command_usage(command); - return (1); - } - rc = wrsm_link_disable(wci_ids[0], linkno); - if (rc != 0) { - perror(command); - return (1); - } - - } else if (strcmp(command, "msgtest") == 0) { - (void) printf(MSG_FILE, command, "filename"); - (void) printf(MSG_NOT_FOUND, command, 32, "filename"); - (void) printf(MSG_INPUT1); - (void) printf(MSG_INPUT2); - (void) printf(MSG_INPUT3); - (void) printf(MSG_LINK_IN_USE, "create", "hostname", 1023, 2); - (void) printf(MSG_INVALID, "create", "ncslice", 255); - (void) printf(MSG_UNKNOWN, "create", "option"); - (void) printf(MSG_PARSE_ERR, "create", "unparsable line\n"); - (void) printf(MSG_LINK_RANGE, "create", "hostname.1023.3"); - (void) printf(MSG_NUM_HOSTS, "create", 10); - (void) printf(MSG_NO_ROUTE, "create", "hostname1", - "hostname2"); - } else { - errno = EINVAL; - perror(command_name); - print_usage(B_FALSE); - return (1); - } - - return (0); -} - -void -init_usage() -{ - commands[0].name = "create"; - commands[0].usage = - gettext("-c <controller id> -f <output file name>"); - commands[1].name = "initial"; - commands[1].usage = - gettext("[-c <controller id>] -f <input file name>"); - commands[2].name = "remove"; - commands[2].usage = gettext("[-c <controller id>]"); - commands[3].name = "topology"; - commands[3].usage = gettext("[-c <controller id>]"); - commands[4].name = "dump"; - commands[4].usage = - gettext("-c <controller id> -f <output file name>"); - commands[5].name = NULL; - commands[5].usage = NULL; -} - -void -print_usage(boolean_t private) -{ - int i; - - init_usage(); - (void) fprintf(stderr, gettext("usage: %s\n"), command_name); - for (i = 0; commands[i].name; ++i) - (void) printf("\t%s %s\n", commands[i].name, - commands[i].usage); - if (private) { - (void) printf("private commands:\n"); - for (i = 0; private_commands[i].name; i++) { - (void) printf("\t%s %s\n", private_commands[i].name, - private_commands[i].usage); - } - } -} - -static void -print_command_usage(char *command) -{ - int i; - - init_usage(); - (void) fprintf(stderr, gettext("usage: %s "), command_name); - for (i = 0; commands[i].name; ++i) { - if (strcmp(commands[i].name, command) == 0) { - (void) printf("%s %s\n", commands[i].name, - commands[i].usage); - break; - } - } - if (commands[i].name == NULL) { - print_usage(B_FALSE); - } -} - - - -/* - * If dump_config is called with a controller id that is less than 0, - * it scans all available controllers and prints the number of - * those which are active. If there is a valid controller-id - * argument, it gets the config data from the kernel, unparses - * it, and prints its contents. - */ -int -dump_config(char *file_name, int controller_id) -{ - wrsm_controller_t *config; - FILE *fd; - - if (file_name) { - fd = fopen(file_name, "w"); - } else { - fd = stdout; - } - if (fd == NULL) { - perror("dump"); - } - if (wrsm_get_config(controller_id, &config) != 0) { - return (1); - } - wrsm_print_controller(fd, config); - wrsm_free_config(config); - return (0); -} - -/* - * If getinfo is called with a controller id that is less than 0, - * it prints info on all available controllers. - */ -int -getinfo(int controller_id) -{ - wrsm_controller_t *config; - int i; - - if (controller_id < 0) { - int n; - - if ((n = wrsm_get_num_controllers()) < 0) { - perror("info"); - return (1); - } - for (i = 0; i < n; ++i) - if (wrsm_get_config(i, &config) == 0) { - (void) getinfo(i); - } - return (0); - } - - if (wrsm_get_config(controller_id, &config) != 0) { - perror("info"); - return (1); - } - (void) printf("controller %d cnodeid %d\n", config->controller_id, - config->cnodeid); - for (i = 0; i < config->nmembers; i++) { - int cnodeid = config->u_members.val.members[i]->cnodeid; - (void) printf(" cnodeid %d %s\n", cnodeid, - config->u_members.val.members[i]->hostname); - } - free(config); - return (0); -} - - -void -free_controller_info(struct dump_info ***controller_info) -{ - int controller_index = 0; - int member_index; - - if (controller_info == NULL) { - return; - } - - while (controller_info[controller_index] != NULL) { - member_index = 0; - while (controller_info[controller_index][member_index] - != NULL) { - free(controller_info[controller_index][member_index]); - member_index++; - } - free(controller_info[controller_index]); - controller_index++; - } - free(controller_info); -} - -int -compare(const void *left, const void *right) -{ - struct dump_info *lt = *((struct dump_info **)left); - struct dump_info *rt = *((struct dump_info **)right); - - if (lt->fmnode_id < rt->fmnode_id) { - return (-1); - } else if (lt->fmnode_id > rt->fmnode_id) { - return (1); - } else { - if (lt->controller_id < rt->controller_id) { - return (-1); - } else if (lt->controller_id > rt->controller_id) { - return (1); - } else { - return (0); - } - } -} - -void -print_column_headers(FILE *fp) -{ - (void) fprintf(fp, "%-25s", "FM Node ID"); - (void) fprintf(fp, "%-25s", "Node Name"); - (void) fprintf(fp, "%-25s", "Wildcat Cont Instance"); - (void) fprintf(fp, "%-25s\n", "Wildcat Cont HW Addr"); -} - -void -print_member_info(FILE *fp, struct dump_info **info, int num_members) -{ - int i; - - print_column_headers(fp); - for (i = 0; i < num_members; i++) { - (void) fprintf(fp, "%-25llu", info[i]->fmnode_id); - (void) fprintf(fp, "%-25s", info[i]->host_name); - (void) fprintf(fp, "%-25u", info[i]->controller_id); - (void) fprintf(fp, "%-25x\n", info[i]->cnode_id); - } -} - - - -int -topology(int cid) -{ - int num_conts; - int controller_id; - int i; - struct dump_info ***controller_info; - int cont_index = 0; - int member_index; - int total_num_members = 0; - struct dump_info **member_info; - int member_count; - - if (cid == -1) { - - /* get the number of controllers */ - if ((num_conts = wrsm_get_num_controllers()) < 0) { - perror("topology"); - return (1); - } - - } else { - - /* print the specific controller */ - num_conts = 1; - } - - /* allocate num_controllers info records to hold the needed data */ - if ((controller_info = (struct dump_info ***)calloc(num_conts + 1, - sizeof (struct dump_info **))) == NULL) { - perror("topology"); - return (1); - } - /* Set last pointer to NULL for easy structure traversal, redundant */ - controller_info[num_conts] = NULL; - - for (i = 0; i < num_conts; ++i) { - - wrsm_controller_t *unpacked; - if (cid == -1) - controller_id = i; - else - controller_id = cid; - - if (wrsm_get_config(controller_id, &unpacked) != 0) { - continue; - } - /* - * allocate memory for the number of members in this - * controller - */ - if ((controller_info[cont_index] = (struct dump_info **) - calloc(unpacked->nmembers + 1, - sizeof (struct dump_info *))) == NULL) { - perror("toplogy"); - free_controller_info(controller_info); - free(unpacked); - return (1); - } - /* - * Set last pointer to NULL for easy structure - * traversal - */ - controller_info[cont_index][unpacked->nmembers] = NULL; - - /* - * Allocate each member record used to hold the info - * we are after and place the appropriate controller - * info in the new dump_info structs - */ - for (member_index = 0; - member_index < unpacked->nmembers; - member_index++) { - if ((controller_info[cont_index][member_index] = - (struct dump_info *) - calloc(1, sizeof (struct dump_info))) - == NULL) { - perror("toplogy"); - free_controller_info(controller_info); - free(unpacked); - return (1); - } - controller_info[cont_index][member_index]->fmnode_id = - unpacked->u_members.val.members[member_index] - ->fmnodeid; - (void) strcpy(controller_info[cont_index] - [member_index]->host_name, - unpacked->u_members.val.members[member_index]-> - hostname); - controller_info[cont_index][member_index]-> - controller_id = unpacked->controller_id; - controller_info[cont_index][member_index]-> - cnode_id = unpacked-> - u_members.val.members[member_index]-> - cnodeid; - } - - total_num_members += unpacked->nmembers; - cont_index++; - free(unpacked); - } - - /* - * All the member info is retrieved so now we allocate space for - * a flat array for sorting - */ - if ((member_info = (struct dump_info **)calloc(total_num_members, - sizeof (struct dump_info *))) == NULL) { - perror("toplogy"); - free_controller_info(controller_info); - return (1); - } - - /* copy the struct dump_info *'s to the one-dimensional array */ - cont_index = 0; - member_count = 0; - while (controller_info[cont_index] != NULL) { - member_index = 0; - while (controller_info[cont_index][member_index] != NULL) { - member_info[member_count++] = - controller_info[cont_index][member_index]; - member_index++; - } - cont_index++; - } - - qsort(member_info, total_num_members, - sizeof (struct dump_info *), compare); - - print_member_info(stdout, member_info, total_num_members); - - free(member_info); - free_controller_info(controller_info); - return (0); -} - -static int -check_cnode(int controller_id, wrsm_cnodeid_t cnode, int *time_nsec) -{ - int fd; - int rc; - wrsm_ping_arg_t arg; - char devname[BUFSIZ]; - const int count = 100; - - (void) sprintf(devname, CTLRDEVNAME, controller_id); - fd = open(devname, O_RDONLY); - if (fd == -1) { - perror("open"); - return (1); - } - - arg.ioctl_version = WRSM_CF_IOCTL_VERSION; - arg.target = cnode; - arg.count = count; - rc = ioctl(fd, WRSM_CTLR_PING, &arg); - (void) close(fd); - *time_nsec = arg.time / count; - - return (rc); -} - -static int -check(int controller_id, char *hostname) -{ - wrsm_controller_t *config; - int retval = 0; - boolean_t host_found = B_FALSE; - int i; - - if (controller_id < 0) { - int n; - - if ((n = wrsm_get_num_controllers()) < 0) { - perror("info"); - return (1); - } - for (i = 0; i < n; ++i) { - if (wrsm_get_config(i, &config) == 0) { - if (check(i, hostname)) { - retval = 1; - } - } - } - return (retval); - } - - if (wrsm_get_config(controller_id, &config) != 0) { - perror("check"); - return (1); - } - - (void) printf("controller %d:\n", controller_id); - - for (i = 0; i < config->nmembers; i++) { - wrsm_net_member_t *member = config->u_members.val.members[i]; - if (hostname == NULL || - strcmp(member->hostname, hostname) == 0) { - int ave_time; - int rc; - - host_found = B_TRUE; - rc = check_cnode(controller_id, member->cnodeid, - &ave_time); - if (rc == 0) { - (void) printf(" check of %s successful, " - "time = %d ns\n", member->hostname, - ave_time); - } else { - (void) printf(" check of %s failed\n", - member->hostname); - retval = 1; - } - } - } - if (!host_found) { - retval = 1; - } - return (retval); -} diff --git a/usr/src/cmd/wrsmconf/wrsmconf_msgs.h b/usr/src/cmd/wrsmconf/wrsmconf_msgs.h deleted file mode 100644 index 2738cb3a39..0000000000 --- a/usr/src/cmd/wrsmconf/wrsmconf_msgs.h +++ /dev/null @@ -1,53 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSMCONF_MSGS_H -#define _WRSMCONF_MSGS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#define MSG_FILE gettext("%s: failed reading file %s\n") -#define MSG_NOT_FOUND gettext("%s: controller %d not found in file %s\n") -#define MSG_INPUT1 gettext("Enter netlist in the form:\n") -#define MSG_INPUT2 gettext(" hostname.wci.link=hostname.wci.link\n") -#define MSG_INPUT3 gettext("Hit CTRL-D when done.\n") -#define MSG_LINK_IN_USE gettext("%s: %s.%d.%d already in use\n") -#define MSG_INVALID gettext("%s: invalid value for %s: %d\n") -#define MSG_UNKNOWN gettext("%s: unknown option '%s'\n") -#define MSG_PARSE_ERR gettext("%s: could not parse line: %s") -#define MSG_LINK_RANGE gettext("%s: link number out of range: %s\n") -#define MSG_NUM_HOSTS gettext("%s: number of hosts exceeds limit of %d\n") -#define MSG_NO_ROUTE gettext("%s: no route from %s to %s\n") - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSMCONF_MSGS_H */ diff --git a/usr/src/cmd/wrsmstat/Makefile b/usr/src/cmd/wrsmstat/Makefile deleted file mode 100644 index b91bdc2273..0000000000 --- a/usr/src/cmd/wrsmstat/Makefile +++ /dev/null @@ -1,95 +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 -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# - -PLATFORM = sun4u -SCRIPT = wrsm_lastwci -RCM_SCRIPT = SUNW,wrsm_lastwci -ROOTRCM_D = $(ROOT)/usr/platform/sun4u/lib/rcm -ROOTRCM_SCR_D = $(ROOTRCM_D)/scripts -ROOTRCM_PROG = $(ROOTRCM_SCR_D)/$(RCM_SCRIPT) -PROG = wrsmstat -OBJS = wrsmstat.o - -include ../Makefile.cmd -include ../../Makefile.psm - -ROOTBIN= $(ROOT)/usr/platform/sun4u/sbin -INS.root.sys = install -s -m 755 -f -$(CH)INS.root.sys = install -s -m 755 -u root -g sys -f - -CLOBBERFILES += $(RCM_SCRIPT) - -# -# Include path for rsm header files -# -CPPFLAGS += -I$(ROOT)/usr/platform/sun4u/include -CCFLAGS = -xarch=v9 -I$(INCLUDE) -LDLIBS += -lkstat -FILEMODE= 0555 -GROUP= bin - -.KEEP_STATE: - -all: $(PROG) - -install: all $(ROOTPROG) $(ROOTRCM_PROG) - -$(ROOTRCM_D): - $(INS.dir.root.sys) - -$(ROOTRCM_SCR_D): $(ROOTRCM_D) - $(INS.dir.root.sys) - -$(RCM_SCRIPT): $(SCRIPT) - $(CP) $(SCRIPT) $(RCM_SCRIPT) - $(CHMOD) 0755 $(RCM_SCRIPT) - -$(ROOTRCM_PROG): $(RCM_SCRIPT) $(ROOTRCM_SCR_D) - $(INS.root.sys) $(ROOTRCM_SCR_D) $(RCM_SCRIPT) - -$(ROOTBIN): - $(INS.dir.root.sys) - -$(ROOTPROG): $(ROOTBIN) $(PROG) - $(INS.root.sys) $(ROOTBIN) $(PROG) - -$(PROG): $(OBJS) - $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS) - $(POST_PROCESS) - -clean: - -$(RM) $(OBJS) - -lint: $(MACH)_lint - -i386_lint: - -sparc_lint: - $(LINT.c) -u $(PROG).c $(LDLIBS) - -include ../Makefile.targ diff --git a/usr/src/cmd/wrsmstat/wrsm_lastwci b/usr/src/cmd/wrsmstat/wrsm_lastwci deleted file mode 100644 index f0bd1a536c..0000000000 --- a/usr/src/cmd/wrsmstat/wrsm_lastwci +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/ksh -# -# 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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#ident "%Z%%M% %I% %E% SMI" - -WRSMSTAT="/usr/platform/sun4u/sbin/wrsmstat" -# -# This script tells the user that the removal of a WCI is not allowed -# when it is the last WCI in a wrsm controller. -# - -function do_scriptinfo -{ - echo "rcm_script_version=1" - echo "rcm_script_func_info=script for wrsm wci DR" - exit 0 -} - -function do_register -{ - ls /dev/wci* 2>/dev/null | while read devname - do - echo "rcm_resource_name=$devname" - done - exit 0 -} - -function do_resourceinfo -{ - id=`expr $1 : '/dev/wci\(.*\)'` - ctlr=`$WRSMSTAT wrsm -w 0x$id -p 2>/dev/null` - if [ "X$ctlr" = "X" ] - then - echo "rcm_resource_usage_info=not owned by a wrsm controller" - exit 0 - fi - echo "rcm_resource_usage_info=owned by wrsm controller $ctlr" - exit 0 -} - -function do_preremove -{ - id=`expr $1 : '/dev/wci\(.*\)'` - - ctlr=`$WRSMSTAT wrsm -w 0x$id -p 2>/dev/null` - if [ "X$ctlr" = "X" ] - then - exit 0 - fi - - wcis=`$WRSMSTAT controller -c $ctlr -p 2>/dev/null` - if [ "X$wcis" = "X" ] - then - exit 0 - fi - - if [ "$wcis" -eq 1 ] - then - echo "rcm_failure_reason=last wci device in wrsm controller" - exit 3 - else - exit 0 - fi -} - - - -# Main - -cmd=$1 -shift - -case $cmd in - "scriptinfo") - do_scriptinfo $* - ;; - "register") - do_register $* - ;; - "resourceinfo") - do_resourceinfo $* - ;; - "queryremove") - do_preremove $* - ;; - "preremove") - do_preremove $* - ;; - *) - exit 2 - ;; -esac diff --git a/usr/src/cmd/wrsmstat/wrsmstat.c b/usr/src/cmd/wrsmstat/wrsmstat.c deleted file mode 100644 index d190ffd03e..0000000000 --- a/usr/src/cmd/wrsmstat/wrsmstat.c +++ /dev/null @@ -1,1070 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Display WRSM kstat data. - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <kstat.h> -#include <libintl.h> -#include <values.h> -#include <locale.h> -#include <sys/rsm/rsmpi.h> -#include <sys/wrsm.h> -#include <sys/wci_common.h> -#ifndef lint -#include <sys/wci_cmmu.h> -#else -typedef union { - struct { - uint64_t count_enable; - } bit; - uint64_t val; -} wci_sram_array_as_cmmu_0_u; -#endif /* lint */ - -#define ERR_NO_ERR 0 -#define ERR_UNKNOWN 1 -#define ERR_USAGE 2 -#define ERR_KSOPEN 3 -#define ERR_KSLOOKUP 4 -#define ERR_KSREAD 5 - -#define MAX_CMMU_ENTRIES (0x200000) /* 2 million entries max */ - -/* Error messages */ -#define MSG_WRONG_ARGUMENT gettext("wrsmstat: wrong argument\n") -#define MSG_ERROR_ARGUMENTS gettext("wrsmatat: error reading arguments\n") -#define MSG_KSTAT_OPEN_FAIL gettext("wrsmstat: kstat not found\n") -#define MSG_KSTAT_NO_DATA gettext("wrsmstat: no data in kstat\n") -#define MSG_WRSM_FAIL gettext("wrsmstat: wrsm instance not found\n") -#define MSG_ROUTE_FAIL gettext("wrsmstat: route not found\n") -#define MSG_CONTROLLER_FAIL gettext("wrsmstat: controller not found\n") -#define MSG_SUB_NOT_IMPL gettext("wrsmstat: subcommand not implemented\n") -#define MSG_BAD_SUB gettext("wrsmstat: bad subcommand: %s\n") -/* WCI kstat messages */ -#define MSG_WCI_INSTANCE gettext("WCI instance: %d\n") -#define MSG_PORT_ID gettext("Port ID: %d\n") -#define MSG_CTLR_ID gettext("Controller ID: %d") -#define MSG_WCI_NOT_BELONG gettext(" (WCI does not belong to a controller)\n") -#define MSG_WCI_IN_LOOPBACK gettext(" (WCI is in loopback test mode)\n") -#define MSG_CONFIG_VERSION gettext("Config Version: %llu\n") -#define MSG_ERROR_LIMIT gettext("Link Error Shutdown Trigger: %d\n") -#define MSG_LINK_NOT_PRES gettext("Link %d is not present.\n") -#define MSG_LINK_ID gettext("Link %d\n") -#define MSG_LINK_STATE gettext("\tLink State: ") -#define MSG_STATE_UP gettext("up\n") -#define MSG_STATE_DOWN gettext("down\n") -#define MSG_STATE_NO_PAROLI gettext("no PAROLI\n") -#define MSG_STATE_WAIT_DOWN gettext("wait (down)\n") -#define MSG_STATE_WAIT_UP gettext("wait (up)\n") -#define MSG_STATE_ERR_DOWN gettext("wait (error down)\n") -#define MSG_UNKNOWN gettext("unknown\n") -#define MSG_PHYS_STATE gettext("\tPhysical Link State: ") -#define MSG_STATE_OFF gettext("off\n") -#define MSG_STATE_FAILOVER gettext("failover\n") -#define MSG_STATE_SEEK gettext("seek\n") -#define MSG_STATE_IN_USE gettext("in use\n") -#define MSG_LASER_ENABLED gettext("\tLaser Enabled: %s\n") -#define MSG_TX_ENABLED gettext("\tTransmit Enabled: %s\n") -#define MSG_REMOTE_CNODE gettext("\tRemote RSM HW addr: %d\n") -#define MSG_REMOTE_WNODE gettext("\tRemote wnode ID: %d\n") -#define MSG_REMOTE_LINK gettext("\tRemote link num: %d\n") -#define MSG_REMOTE_WCI gettext("\tRemote WCI port ID: %d\n") -#define MSG_DIS_TAKEDOWNS gettext("\tDisconnected takedowns: %d\n") -#define MSG_ERR_TAKEDOWNS gettext("\tError takedowns: %d\n") -#define MSG_CFG_TAKEDOWNS gettext("\tBad Config takedowns: %d\n") -#define MSG_FAILED_BRINGUPS gettext("\tFailed bringups: %d\n") -#define MSG_LINK_ENABLED gettext("\tLink enabled: %s\n") -#define MSG_TOT_LINK_ERRS gettext("\tTotal link errors: %d\n") -#define MSG_MAX_LINK_ERRS gettext("\tMaximum link errors: %d\n") -#define MSG_AVE_LINK_ERRS gettext("\tAverage link errors: %d\n") -#define MSG_AUTO_SHUT_EN gettext("\tAuto shutdown enabled: %s\n") -#define MSG_CLUSTER_ERR gettext("Cluster Error Count: %lld\n") -#define MSG_SRAM_ECC gettext("Uncorrectable SRAM ECC error: %s\n") -#define MSG_MAX_ECC gettext("Maximum SRAM ECC errors: %ld\n") -#define MSG_AVE_ECC gettext("Average SRAM ECC errors: %ld\n") -/* Route kstat messages */ -#define MSG_ROUTE_CTLR gettext("\nController %d - Route to %s\n") -#define MSG_FM_NODE_ID gettext("FM node id: 0x%x\n") -#define MSG_ROUTE_CNODE gettext("RSM hardware addr: %d\n") -#define MSG_ROUTE_CHANGES gettext("Route Changes: %d\n") -#define MSG_ROUTE_MH gettext("Route Type: Multihop\n") -#define MSG_ROUTE_PT gettext("Route Type: Passthrough\n") -#define MSG_NUM_WCIS gettext("Number of WCIs: %d\n") -#define MSG_STRIPES gettext("Stripes: %d\n") -#define MSG_PORTID gettext("\tPort ID: %d\n") -#define MSG_INSTANCE gettext("\tInstance : %d\n") -#define MSG_NUM_HOPS gettext("\tNumber of hops: %d\n") -#define MSG_NUM_LINKS gettext("\tNumber of links: %d\n") -#define MSG_ROUTE_LINKID gettext("\t\tLink #%d, ") -#define MSG_ROUTE_NODEID gettext("first hop RSM HW addr: 0x%x\n") -#define MSG_ROUTE_SWITCH gettext("is a switch, leading to RSM HW addr: 0x%x\n") -/* Controller kstat messages */ -#define MSG_CONTROLLER gettext("\nController %d\n") -#define MSG_CTLR_STATE gettext("Controller state: ") -#define MSG_CTLR_NOT_AVAIL gettext("not available\n") -#define MSG_CTLR_UP gettext("up\n") -#define MSG_CTLR_DOWN gettext("down\n") -#define MSG_CTLR_ADDR gettext("Local RSM Hardware Address: 0x%llx\n") -#define MSG_EX_MEMSEGS gettext("Exported segments: %d\n") -#define MSG_EX_MEMSEGS_PUB gettext("\tNum published: %d\n") -#define MSG_EX_MEMSEG_CON gettext("\tNum connections: %d\n") -#define MSG_BYTES_BOUND gettext("\tTotal bound memory: %lld\n") -#define MSG_IM_MEMSEGS_CON gettext("Imported segments: %d\n") -#define MSG_SENDQS gettext("Send Queues: %lld\n") -#define MSG_HANDLERS gettext("Registered Handlers: %ld\n") -#define MSG_RSM_NUM_WCIS gettext("Assigned WCIs: %d\n") -#define MSG_RSM_AVAIL_WCIS gettext("Available WCIs: %d\n") -#define MSG_NUM_RECONFIGS gettext("Number of reconfigs: %d\n") -#define MSG_FREE_CMMUS gettext("Number of free CMMU entries: %d\n") - -static boolean_t msg_test = B_FALSE; - -#define NOT_FOUND 0xffffffff -#define NOT_FOUND64 0xffffffffffffffffULL -static uint32_t find_named(kstat_t *ksp, char *name); -static uint64_t find_named64(kstat_t *ksp, char *name); -static char *find_named_char(kstat_t *ksp, char *name); - -static void show_usage(); - -static int find_wrsm(int wci_id, boolean_t v, boolean_t private, - kstat_ctl_t *kc); -static int fetch_wrsm(int instance, boolean_t v, kstat_ctl_t *kc); -static int fetch_route(int contid, char *fm_node_name, kstat_ctl_t *kc); -static int fetch_controller(int contid, boolean_t private, kstat_ctl_t *kc); -static int trace_cmmu(int wrsm_instance, int s, int e, kstat_ctl_t *kc); - -#define YESORNO(b) ((b) ? (gettext("yes")) : (gettext("no"))) - -int -main(int argc, char **argv) -{ - kstat_ctl_t *kc; - kstat_t *chain; - int c; - int controller_id = -1; - int wrsm_instance = -1; - int wrsm_id = -1; - int start; - boolean_t got_start = B_FALSE; - int end; - boolean_t got_end = B_FALSE; - char *set_argument = NULL; - char *disp_kstat; - char *nodename = NULL; - int retval; - boolean_t print_errors = B_FALSE; - boolean_t private = B_FALSE; - char *endptr; - boolean_t check_endptr = B_FALSE; - - (void) setlocale(LC_ALL, ""); - -#if !defined(TEXT_DOMAIN) -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - if (argc < 2) { - /* Not enough arguments */ - show_usage(); - return (ERR_USAGE); - } - - /* which kstat we are displaying */ - disp_kstat = argv[1]; - - while ((c = getopt(argc-1, &argv[1], "c:i:h:ps:e:vw:x:")) - != EOF) { - check_endptr = B_FALSE; - switch (c) { - case 'c': - if ((strcmp(disp_kstat, "controller") == 0) || - (strcmp(disp_kstat, "route") == 0)) { - controller_id = strtol(optarg, &endptr, 0); - check_endptr = B_TRUE; - } else { - set_argument = optarg; - } - break; - case 'i': - wrsm_instance = strtol(optarg, &endptr, 0); - check_endptr = B_TRUE; - break; - case 'h': - nodename = optarg; - break; - case 'v': - print_errors = B_TRUE; - break; - case 's': - start = strtol(optarg, &endptr, 0); - got_start = B_TRUE; - check_endptr = B_TRUE; - break; - case 'e': - end = strtol(optarg, &endptr, 0); - got_end = B_TRUE; - check_endptr = B_TRUE; - break; - case 'w': - wrsm_id = strtol(optarg, &endptr, 0); - break; - case 'p': - private = B_TRUE; - break; - case 'x': - if (optarg && strcmp(optarg, "msgtest") == 0) { - msg_test = B_TRUE; - } - break; - default: - (void) fprintf(stderr, MSG_WRONG_ARGUMENT); - show_usage(); - return (ERR_USAGE); - } - - if (check_endptr) { - if (strcmp(endptr, "\0")) { - (void) fprintf(stderr, MSG_ERROR_ARGUMENTS); - show_usage(); - return (ERR_USAGE); - } - } - } - - /* initialize kstat control structure */ - if ((kc = kstat_open()) == NULL) { - (void) fprintf(stderr, MSG_KSTAT_OPEN_FAIL); - return (ERR_KSOPEN); - } - - if (strcmp(disp_kstat, "controller") == 0) { - if (controller_id != -1 || msg_test) { - retval = fetch_controller(controller_id, private, kc); - } else { - chain = kc->kc_chain; - /* unless we find something, return error */ - retval = ERR_KSLOOKUP; - while (chain != NULL) { - if ((strcmp(chain->ks_module, WRSM_KSTAT_WRSM) - == 0) && (strcmp(chain->ks_name, - RSM_KS_NAME) == 0)) { - retval = fetch_controller( - chain->ks_instance, private, kc); - } - chain = chain->ks_next; - } - } - } else if (strcmp(disp_kstat, "route") == 0) { - boolean_t controller_found = B_FALSE; - boolean_t route_found = B_FALSE; - - chain = kc->kc_chain; - /* unless we find something, return error */ - retval = ERR_KSLOOKUP; - if (msg_test) { - controller_found = B_TRUE; - route_found = B_TRUE; - if (nodename == NULL) { - nodename = "?"; - } - retval = fetch_route(controller_id, nodename, kc); - } else while (chain != NULL) { - if (strcmp(chain->ks_module, WRSM_KSTAT_WRSM_ROUTE) - == 0) { - if ((controller_id == -1) || (controller_id == - chain->ks_instance)) { - controller_found = B_TRUE; - if ((nodename == NULL) || (strcmp( - nodename, chain->ks_name) == 0)) { - route_found = B_TRUE; - retval = fetch_route( - chain->ks_instance, - chain->ks_name, - kc); - } - } - } - chain = chain->ks_next; - } - if (controller_id != -1 && !controller_found) { - (void) printf(MSG_CONTROLLER_FAIL); - } else if (nodename != NULL && !route_found) { - (void) printf(MSG_ROUTE_FAIL); - } - } else if (strcmp(disp_kstat, "wrsm") == 0) { - if (wrsm_instance != -1 || msg_test) { - retval = fetch_wrsm(wrsm_instance, print_errors, kc); - } else if (wrsm_id != -1) { - retval = find_wrsm(wrsm_id, print_errors, private, kc); - } else { - chain = kc->kc_chain; - /* unless we find something, return error */ - retval = ERR_KSLOOKUP; - while (chain != NULL) { - if ((strcmp(chain->ks_module, WRSM_KSTAT_WRSM) - == 0) && (strcmp(chain->ks_name, - WRSM_KSTAT_STATUS) == 0)) { - retval = fetch_wrsm(chain->ks_instance, - print_errors, kc); - } - chain = chain->ks_next; - } - } - } else if (strcmp(disp_kstat, "set") == 0) { - if (set_argument == NULL || - strcmp(set_argument, "cmmu") != 0 || - (!got_start) || (!got_end)) { - show_usage(); - return (ERR_USAGE); - } - if (wrsm_instance != -1) { - retval = trace_cmmu(wrsm_instance, start, end, kc); - } else { - chain = kc->kc_chain; - /* unless we find something, return error */ - retval = ERR_KSLOOKUP; - while (chain != NULL) { - if ((strcmp(chain->ks_module, WRSM_KSTAT_WRSM) - == 0) && (strcmp(chain->ks_name, - WRSM_KSTAT_STATUS) == 0)) { - retval = trace_cmmu(chain->ks_instance, - start, end, kc); - } - chain = chain->ks_next; - } - } - } else if (strcmp(disp_kstat, "msgtest") == 0) { - (void) printf(MSG_WRONG_ARGUMENT); - (void) printf(MSG_ERROR_ARGUMENTS); - (void) printf(MSG_KSTAT_OPEN_FAIL); - (void) printf(MSG_KSTAT_NO_DATA); - (void) printf(MSG_WRSM_FAIL); - (void) printf(MSG_ROUTE_FAIL); - (void) printf(MSG_CONTROLLER_FAIL); - (void) printf(MSG_SUB_NOT_IMPL); - (void) printf(MSG_BAD_SUB); - return (0); - } else { - (void) fprintf(stderr, MSG_BAD_SUB, disp_kstat); - show_usage(); - return (ERR_USAGE); - } - - (void) kstat_close(kc); - - return (retval); -} - - -int -find_wrsm(int wci_id, boolean_t print_errors, boolean_t private, - kstat_ctl_t *kc) -{ - kstat_t *chain; - kstat_t *kstats; - uint32_t value; - - chain = kc->kc_chain; - - while (chain != NULL) { - if ((strcmp(chain->ks_module, WRSM_KSTAT_WRSM) == 0) && - (strcmp(chain->ks_name, WRSM_KSTAT_STATUS) == 0)) { - if ((kstats = kstat_lookup(kc, WRSM_KSTAT_WRSM, - chain->ks_instance, WRSM_KSTAT_STATUS)) == NULL) { - chain = chain->ks_next; - continue; - } - - if (kstat_read(kc, kstats, NULL) == -1) { - chain = chain->ks_next; - continue; - } - - value = find_named(kstats, WRSMKS_PORTID); - if (value == wci_id) { - if (private) { - value = find_named(kstats, - WRSMKS_CONTROLLER_ID_NAMED); - if (value != NOT_FOUND) { - (void) printf("%d\n", value); - } - return (ERR_NO_ERR); - } else { - return (fetch_wrsm(chain->ks_instance, - print_errors, kc)); - } - } - } - chain = chain->ks_next; - } - - return (ERR_KSLOOKUP); -} - -int -fetch_wrsm(int instance, boolean_t v, kstat_ctl_t *kc) -{ - int i; - - kstat_t *kstats; - - char ks_name[25]; - uint32_t value; - uint64_t value64; - boolean_t check_links = B_TRUE; - - if (msg_test) { - (void) printf("\n"); - (void) printf(MSG_WCI_INSTANCE, 1023); - (void) printf("-------------\n"); - (void) printf(MSG_PORT_ID, 1023); - (void) printf(MSG_CTLR_ID, -1); - (void) printf(MSG_WCI_NOT_BELONG); - (void) printf(MSG_CTLR_ID, -2); - (void) printf(MSG_WCI_IN_LOOPBACK); - (void) printf(MSG_CTLR_ID, 32); - (void) printf("\n"); - (void) printf(MSG_CONFIG_VERSION, MAXLONG); - (void) printf(MSG_ERROR_LIMIT, MAXINT); - (void) printf(MSG_LINK_NOT_PRES, 0); - (void) printf(MSG_LINK_ID, 1); - (void) printf(MSG_LINK_STATE); - (void) printf(MSG_STATE_UP); - (void) printf(MSG_LINK_STATE); - (void) printf(MSG_STATE_DOWN); - (void) printf(MSG_LINK_STATE); - (void) printf(MSG_STATE_NO_PAROLI); - (void) printf(MSG_LINK_STATE); - (void) printf(MSG_STATE_WAIT_DOWN); - (void) printf(MSG_LINK_STATE); - (void) printf(MSG_STATE_WAIT_UP); - (void) printf(MSG_LINK_STATE); - (void) printf(MSG_STATE_ERR_DOWN); - (void) printf(MSG_LINK_STATE); - (void) printf(MSG_UNKNOWN); - (void) printf(MSG_LINK_ENABLED, YESORNO(0)); - (void) printf(MSG_LINK_ENABLED, YESORNO(1)); - (void) printf(MSG_PHYS_STATE); - (void) printf(MSG_STATE_OFF); - (void) printf(MSG_PHYS_STATE); - (void) printf(MSG_STATE_FAILOVER); - (void) printf(MSG_PHYS_STATE); - (void) printf(MSG_STATE_SEEK); - (void) printf(MSG_PHYS_STATE); - (void) printf(MSG_STATE_IN_USE); - (void) printf(MSG_PHYS_STATE); - (void) printf(MSG_UNKNOWN); - (void) printf(MSG_LASER_ENABLED, YESORNO(0)); - (void) printf(MSG_TX_ENABLED, YESORNO(1)); - (void) printf(MSG_REMOTE_CNODE, 255); - (void) printf(MSG_REMOTE_WNODE, 15); - (void) printf(MSG_REMOTE_LINK, 2); - (void) printf(MSG_REMOTE_WCI, 1023); - (void) printf(MSG_ERR_TAKEDOWNS, MAXINT); - (void) printf(MSG_DIS_TAKEDOWNS, MAXINT); - (void) printf(MSG_CFG_TAKEDOWNS, MAXINT); - (void) printf(MSG_FAILED_BRINGUPS, MAXINT); - (void) printf(MSG_TOT_LINK_ERRS, MAXINT); - (void) printf(MSG_MAX_LINK_ERRS, MAXINT); - (void) printf(MSG_AVE_LINK_ERRS, MAXINT); - (void) printf(MSG_AUTO_SHUT_EN, YESORNO(0)); - (void) printf(MSG_LINK_NOT_PRES, 2); - (void) printf(MSG_CLUSTER_ERR, MAXLONG); - (void) printf(MSG_SRAM_ECC, YESORNO(1)); - (void) printf(MSG_MAX_ECC, MAXLONG); - (void) printf(MSG_AVE_ECC, MAXLONG); - (void) printf("\n"); - - return (0); - } - if ((kstats = kstat_lookup(kc, WRSM_KSTAT_WRSM, instance, - WRSM_KSTAT_STATUS)) == NULL) { - (void) fprintf(stderr, MSG_WRSM_FAIL); - return (ERR_KSLOOKUP); - } - - if (kstat_read(kc, kstats, NULL) == -1) { - (void) fprintf(stderr, MSG_WRSM_FAIL); - return (ERR_KSREAD); - } - - (void) printf("\n"); - (void) printf(MSG_WCI_INSTANCE, instance); - (void) printf("-------------\n"); - - value = find_named(kstats, WRSMKS_PORTID); - (void) printf(MSG_PORT_ID, value); - - value = find_named(kstats, WRSMKS_CONTROLLER_ID_NAMED); - (void) printf(MSG_CTLR_ID, value); - if (value == (uint32_t)WRSM_KSTAT_NO_CTRLR) { - (void) printf(MSG_WCI_NOT_BELONG); - check_links = B_FALSE; - } else if (value == (uint32_t)-2) { - (void) printf(MSG_WCI_IN_LOOPBACK); - check_links = B_FALSE; - } else { - (void) printf("\n"); - } - - if (check_links) { - - value64 = find_named64(kstats, WRSMKS_WCI_VERSION_NAMED); - (void) printf(MSG_CONFIG_VERSION, value64); - - value = find_named(kstats, WRSMKS_ERROR_LIMIT); - (void) printf(MSG_ERROR_LIMIT, value); - - for (i = 0; i < WCI_NUM_LINKS; i++) { - - (void) sprintf(ks_name, WRSMKS_VALID_LINK, i); - value = find_named(kstats, ks_name); - if (value == WRSMKS_LINK_NOT_PRESENT) { - (void) printf(MSG_LINK_NOT_PRES, i); - continue; - } - - (void) printf(MSG_LINK_ID, i); - - (void) sprintf(ks_name, WRSMKS_LINK_ENABLED, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_LINK_ENABLED, YESORNO(value)); - - (void) sprintf(ks_name, WRSMKS_LC_LINK_STATE, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_LINK_STATE); - if (value == lc_up) - (void) printf(MSG_STATE_UP); - else if (value == lc_down) - (void) printf(MSG_STATE_DOWN); - else if (value == lc_not_there) - (void) printf(MSG_STATE_NO_PAROLI); - else if (value == sc_wait_down) - (void) printf(MSG_STATE_WAIT_DOWN); - else if (value == sc_wait_up) - (void) printf(MSG_STATE_WAIT_UP); - else if (value == sc_wait_errdown) - (void) printf(MSG_STATE_ERR_DOWN); - else - (void) printf(MSG_UNKNOWN); - - (void) sprintf(ks_name, WRSMKS_PHYS_LINK_STATE, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_PHYS_STATE); - if (value == phys_off) - (void) printf(MSG_STATE_OFF); - else if (value == phys_failover) - (void) printf(MSG_STATE_FAILOVER); - else if (value == phys_seek) - (void) printf(MSG_STATE_SEEK); - else if (value == phys_in_use) - (void) printf(MSG_STATE_IN_USE); - else - (void) printf(MSG_UNKNOWN); - - (void) sprintf(ks_name, WRSMKS_PHYS_LASER_ENABLE, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_LASER_ENABLED, YESORNO(value)); - - (void) sprintf(ks_name, WRSMKS_PHYS_XMIT_ENABLE, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_TX_ENABLED, YESORNO(value)); - - (void) sprintf(ks_name, WRSMKS_REMOTE_CNODE_ID, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_REMOTE_CNODE, value); - - (void) sprintf(ks_name, WRSMKS_REMOTE_WNODE, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_REMOTE_WNODE, value); - - (void) sprintf(ks_name, WRSMKS_REMOTE_LINKNUM, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_REMOTE_LINK, value); - - (void) sprintf(ks_name, WRSMKS_REMOTE_WCI_PORTID, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_REMOTE_WCI, value); - - (void) sprintf(ks_name, WRSMKS_LINK_ERR_TAKEDOWNS, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_ERR_TAKEDOWNS, value); - - (void) sprintf(ks_name, WRSMKS_LINK_DISCON_TAKEDOWNS, - i); - value = find_named(kstats, ks_name); - (void) printf(MSG_DIS_TAKEDOWNS, value); - - (void) sprintf(ks_name, WRSMKS_LINK_CFG_TAKEDOWNS, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_CFG_TAKEDOWNS, value); - - (void) sprintf(ks_name, WRSMKS_LINK_FAILED_BRINGUPS, - i); - value = find_named(kstats, ks_name); - (void) printf(MSG_FAILED_BRINGUPS, value); - - (void) sprintf(ks_name, WRSMKS_LINK_ERRORS, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_TOT_LINK_ERRS, value); - - (void) sprintf(ks_name, WRSMKS_MAX_LINK_ERRORS, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_MAX_LINK_ERRS, value); - - (void) sprintf(ks_name, WRSMKS_AVG_LINK_ERRORS, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_AVE_LINK_ERRS, value); - - (void) sprintf(ks_name, WRSMKS_AUTO_SHUTDOWN_EN, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_AUTO_SHUT_EN, YESORNO(value)); - } - } - - if (v) { - - value64 = find_named64(kstats, WRSMKS_CLUSTER_ERROR_COUNT); - (void) printf(MSG_CLUSTER_ERR, value64); - - value = find_named(kstats, WRSMKS_UC_SRAM_ECC_ERROR); - (void) printf(MSG_SRAM_ECC, YESORNO(value)); - - value = find_named(kstats, WRSMKS_MAX_SRAM_ECC_ERRORS); - (void) printf(MSG_MAX_ECC, value); - - value = find_named(kstats, WRSMKS_AVG_SRAM_ECC_ERRORS); - (void) printf(MSG_AVE_ECC, value); - } - - (void) printf("\n"); - return (ERR_NO_ERR); -} - -int -fetch_route(int contid, char *fm_node_name, kstat_ctl_t *kc) -{ - int i, j; - - kstat_t *kstats; - - char ks_name[25]; - uint32_t value, value1, value2, numwcis, numlinks; - uint64_t value64; - - if (msg_test) { - (void) printf(MSG_ROUTE_CTLR, 32, fm_node_name); - (void) printf("------------------------\n"); - (void) printf(MSG_CONFIG_VERSION, MAXLONG); - (void) printf(MSG_FM_NODE_ID, MAXINT); - (void) printf(MSG_ROUTE_CNODE, 255); - (void) printf(MSG_ROUTE_CHANGES, MAXINT); - (void) printf(MSG_ROUTE_MH); - (void) printf(MSG_ROUTE_PT); - (void) printf(MSG_NUM_WCIS, MAXINT); - (void) printf(MSG_STRIPES, 16); - (void) printf("WCI #%d\n", 36); - (void) printf(MSG_PORTID, 1023); - (void) printf(MSG_INSTANCE, MAXINT); - (void) printf(MSG_NUM_HOPS, MAXINT); - (void) printf(MSG_NUM_LINKS, MAXINT); - (void) printf(MSG_ROUTE_LINKID, 0); - (void) printf(MSG_ROUTE_NODEID, 255); - (void) printf(MSG_ROUTE_LINKID, 1); - (void) printf(MSG_ROUTE_SWITCH, 255); - (void) printf("\n"); - - return (0); - } - if ((kstats = - kstat_lookup(kc, WRSM_KSTAT_WRSM_ROUTE, contid, - fm_node_name)) == NULL) { - (void) fprintf(stderr, MSG_ROUTE_FAIL); - return (ERR_KSLOOKUP); - } - - if (kstat_read(kc, kstats, NULL) == -1) { - (void) fprintf(stderr, MSG_ROUTE_FAIL); - return (ERR_KSREAD); - } - - (void) printf(MSG_ROUTE_CTLR, contid, fm_node_name); - (void) printf("------------------------\n"); - - value64 = find_named64(kstats, WRSMKS_CONFIG_VERSION_NAMED); - (void) printf(MSG_CONFIG_VERSION, value64); - - value = find_named(kstats, WRSMKS_FMNODEID); - (void) printf(MSG_FM_NODE_ID, value); - - value = find_named(kstats, WRSMKS_CNODEID); - (void) printf(MSG_ROUTE_CNODE, value); - - value = find_named(kstats, WRSMKS_NUMCHANGES); - (void) printf(MSG_ROUTE_CHANGES, value); - - value = find_named(kstats, WRSMKS_ROUTE_TYPE_NAMED); - if (value == 0) { - (void) printf(MSG_ROUTE_MH); - } else { - (void) printf(MSG_ROUTE_PT); - } - - value = find_named(kstats, WRSMKS_NUM_WCIS); - numwcis = (value == NOT_FOUND) ? 0 : value; - (void) printf(MSG_NUM_WCIS, value); - - value = find_named(kstats, WRSMKS_NUM_STRIPES); - (void) printf(MSG_STRIPES, value); - - for (i = 0; i < numwcis; i++) { - (void) printf("WCI #%d\n", i); - - (void) sprintf(ks_name, WRSMKS_ROUTE_PORTID, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_PORTID, value); - - (void) sprintf(ks_name, WRSMKS_ROUTE_INSTANCE, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_INSTANCE, value); - - (void) sprintf(ks_name, WRSMKS_ROUTE_NUMHOPS, i); - value = find_named(kstats, ks_name); - (void) printf(MSG_NUM_HOPS, value); - - (void) sprintf(ks_name, WRSMKS_ROUTE_NUMLINKS, i); - value = find_named(kstats, ks_name); - numlinks = (value == NOT_FOUND) ? 0 : value; - (void) printf(MSG_NUM_LINKS, numlinks); - - for (j = 0; j < numlinks; j++) { - - (void) sprintf(ks_name, WRSMKS_ROUTE_LINKID, i, j); - value = find_named(kstats, ks_name); - - (void) sprintf(ks_name, WRSMKS_ROUTE_NODEID, i, j); - value1 = find_named(kstats, ks_name); - - (void) sprintf(ks_name, WRSMKS_ROUTE_GNID, i, j); - value2 = find_named(kstats, ks_name); - - (void) printf(MSG_ROUTE_LINKID, value); - if (value2 < 16) { - (void) printf(MSG_ROUTE_NODEID, value1); - } else { - (void) printf(MSG_ROUTE_SWITCH, value1); - } - } - } - (void) printf("\n"); - return (ERR_NO_ERR); -} - -int -fetch_controller(int contid, boolean_t private, kstat_ctl_t *kc) -{ - kstat_t *kstats; - - uint32_t value; - uint64_t value64; - char *value_char; - - if (msg_test) { - (void) printf(MSG_CONTROLLER, contid); - (void) printf("----------\n"); - (void) printf(MSG_CTLR_STATE); - (void) printf(MSG_CTLR_NOT_AVAIL); - (void) printf(MSG_CTLR_STATE); - (void) printf(MSG_CTLR_UP); - (void) printf(MSG_CTLR_STATE); - (void) printf(MSG_CTLR_DOWN); - (void) printf(MSG_CTLR_ADDR, MAXLONG); - (void) printf(MSG_EX_MEMSEGS, MAXINT); - (void) printf(MSG_EX_MEMSEGS_PUB, MAXINT); - (void) printf(MSG_EX_MEMSEG_CON, MAXINT); - (void) printf(MSG_BYTES_BOUND, MAXLONG); - (void) printf(MSG_IM_MEMSEGS_CON, MAXINT); - (void) printf(MSG_SENDQS, MAXLONG); - (void) printf(MSG_HANDLERS, MAXLONG); - (void) printf(MSG_RSM_NUM_WCIS, MAXINT); - (void) printf(MSG_RSM_AVAIL_WCIS, MAXINT); - (void) printf(MSG_NUM_RECONFIGS, MAXINT); - (void) printf(MSG_FREE_CMMUS, MAXINT); - (void) printf("\n"); - - return (0); - } - - if ((kstats = - kstat_lookup(kc, WRSM_KSTAT_WRSM, contid, RSM_KS_NAME)) - == NULL) { - (void) fprintf(stderr, MSG_CONTROLLER_FAIL); - return (ERR_KSLOOKUP); - } - - if (kstat_read(kc, kstats, NULL) == -1) { - (void) fprintf(stderr, MSG_CONTROLLER_FAIL); - return (ERR_KSREAD); - } - - if (private) { - value = find_named(kstats, WRSMKS_RSM_AVAIL_WCIS); - (void) printf("%d\n", value); - return (ERR_NO_ERR); - } - - (void) printf(MSG_CONTROLLER, contid); - (void) printf("----------\n"); - - /* rsmpi components */ - - /* not printing kstat, to ease translation for language localization */ - value_char = find_named_char(kstats, RSM_KS_CTLR_STATE); - (void) printf(MSG_CTLR_STATE); - if (value_char == NULL) { - (void) printf(MSG_CTLR_NOT_AVAIL); - } else if (strcmp(value_char, RSM_AE_CTLR_UP) == 0) { - (void) printf(MSG_CTLR_UP); - } else { - (void) printf(MSG_CTLR_DOWN); - } - - value64 = find_named64(kstats, RSM_KS_ADDR); - (void) printf(MSG_CTLR_ADDR, value64); - - value = find_named(kstats, RSM_KS_EX_MEMSEGS); - (void) printf(MSG_EX_MEMSEGS, value); - - value = find_named(kstats, RSM_KS_EX_MEMSEGS_PUB); - (void) printf(MSG_EX_MEMSEGS_PUB, value); - - value = find_named(kstats, RSM_KS_EX_MEMSEGS_CON); - (void) printf(MSG_EX_MEMSEG_CON, value); - - value64 = find_named64(kstats, RSM_KS_BYTES_BOUND); - (void) printf(MSG_BYTES_BOUND, value64); - - value = find_named(kstats, RSM_KS_IM_MEMSEGS_CON); - (void) printf(MSG_IM_MEMSEGS_CON, value); - - value64 = find_named64(kstats, RSM_KS_SENDQS); - (void) printf(MSG_SENDQS, value64); - - value64 = find_named(kstats, RSM_KS_HANDLERS); - (void) printf(MSG_HANDLERS, value64); - - /* wrsm specific components */ - value = find_named(kstats, WRSMKS_RSM_NUM_WCIS); - (void) printf(MSG_RSM_NUM_WCIS, value); - - value = find_named(kstats, WRSMKS_RSM_AVAIL_WCIS); - (void) printf(MSG_RSM_AVAIL_WCIS, value); - - value = find_named(kstats, WRSMKS_NUM_RECONFIGS); - (void) printf(MSG_NUM_RECONFIGS, value); - - value = find_named(kstats, WRSMKS_FREE_CMMU_ENTRIES); - (void) printf(MSG_FREE_CMMUS, value); - - (void) printf("\n"); - return (ERR_NO_ERR); -} - -static uint32_t -find_named(kstat_t *ksp, char *name) -{ - kstat_named_t *kna; - int counter; - - kna = (kstat_named_t *)ksp->ks_data; - if (kna == NULL) { - (void) fprintf(stderr, MSG_KSTAT_NO_DATA); - return (NOT_FOUND); - } - - for (counter = 0; counter < ksp->ks_ndata; counter++) { - if (strcmp(kna->name, name) == 0) - return (kna->value.ui32); - kna++; - } - return (NOT_FOUND); -} - -static uint64_t -find_named64(kstat_t *ksp, char *name) -{ - kstat_named_t *kna; - int counter; - - kna = (kstat_named_t *)ksp->ks_data; - if (kna == NULL) { - (void) fprintf(stderr, MSG_KSTAT_NO_DATA); - return (NOT_FOUND64); - } - - for (counter = 0; counter < ksp->ks_ndata; counter++) { - if (strcmp(kna->name, name) == 0) - return (kna->value.ui64); - kna++; - } - return (NOT_FOUND64); -} - -static char * -find_named_char(kstat_t *ksp, char *name) -{ - kstat_named_t *kna; - int counter; - - kna = (kstat_named_t *)ksp->ks_data; - if (kna == NULL) { - (void) fprintf(stderr, MSG_KSTAT_NO_DATA); - return (NULL); - } - - for (counter = 0; counter < ksp->ks_ndata; counter++) { - if (strcmp(kna->name, name) == 0) - return (kna->value.c); - kna++; - } - return (NULL); -} - -static void show_usage() -{ - char *controller_id = gettext("controller id"); - char *wrsm_instance_num = gettext("wrsm instance num"); - char *nodename = gettext("nodename"); - char *start = gettext("start"); - char *end = gettext("end"); - - (void) fprintf(stderr, gettext("Usage:\n")); - (void) fprintf(stderr, "\twrsmstat controller [ -c <%s> ]\n", - controller_id); - (void) fprintf(stderr, "\twrsmstat wrsm [ -i <%s> ] [-v]\n", - wrsm_instance_num); - (void) fprintf(stderr, "\twrsmstat route [ -c <%s> ] [ -h <%s> ]\n", - controller_id, nodename); - (void) fprintf(stderr, - "\twrsmstat set [ -i <%s> ] -c cmmu -s <%s> -e <%s>\n", - wrsm_instance_num, start, end); -} - -int -trace_cmmu(int instance, int start, int end, kstat_ctl_t *kc) -{ - int i; - kstat_t *kstats; - uint64_t args[4]; - wci_sram_array_as_cmmu_0_u word0; - int retval; - int fd; - int port; - char devname[32]; - - if ((kstats = kstat_lookup(kc, WRSM_KSTAT_WRSM, instance, - WRSM_KSTAT_STATUS)) == NULL) { - (void) fprintf(stderr, MSG_WRSM_FAIL); - return (ERR_KSLOOKUP); - } - - if (kstat_read(kc, kstats, NULL) == -1) { - (void) fprintf(stderr, MSG_WRSM_FAIL); - return (ERR_KSREAD); - } - - port = find_named(kstats, WRSMKS_PORTID); - if (port == NOT_FOUND) { - return (ERR_KSREAD); - } - - (void) sprintf(devname, "/dev/wci%x", port); - - fd = open(devname, O_RDONLY); - if (fd < 0) { - perror("set"); - return (-1); - } - word0.val = 0; - - if (start == 0 && end == 0) { - /* Enable all */ - word0.bit.count_enable = 1; - start = 1; - end = MAX_CMMU_ENTRIES; - } else if (start == 0 && end == -1) { - /* Disable all */ - word0.bit.count_enable = 0; - start = 1; - end = MAX_CMMU_ENTRIES; - } else { - /* Enable the specified range */ - if (end > MAX_CMMU_ENTRIES) { - end = MAX_CMMU_ENTRIES; - } - if (start == 0) { - /* Entry 0 is read-only */ - start = 1; - } - word0.bit.count_enable = 1; - } - - args[0] = word0.val; - args[1] = 0; - args[3] = 0x100; /* Flag to change perf counter only */ - - for (i = start; i <= end; i++) { - args[2] = i; - retval = ioctl(fd, WRSM_LC_UPDATECMMU, args); - if (retval) { - if (errno == EINVAL) { - /* - * Walked off end of memory, CMMU might not be - * fully populated, and that's OK. - */ - return (ERR_NO_ERR); - } - perror("set"); - (void) close(fd); - return (errno); - } - } - (void) close(fd); - return (ERR_NO_ERR); -} diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index 3d0bcc05dd..4a8c33ac76 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -242,9 +242,7 @@ sparc_SUBDIRS= .WAIT \ librsc \ libfruutils .WAIT \ libfru \ - libwrsmconf \ storage \ - wrsm \ libpcp FM_sparc_DEPLIBS= libpri @@ -414,8 +412,7 @@ $(CLOSED_BUILD)HDRSUBDIRS += \ sparc_HDRSUBDIRS= \ libdscp \ - libpri \ - libwrsmconf + libpri all := TARGET= all check := TARGET= check diff --git a/usr/src/lib/libwrsmconf/Makefile b/usr/src/lib/libwrsmconf/Makefile deleted file mode 100644 index a8f81cccf1..0000000000 --- a/usr/src/lib/libwrsmconf/Makefile +++ /dev/null @@ -1,57 +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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.lib - -HDRS= wrsmconf.h -ROOTHDRDIR= $(ROOT)/usr/platform/sun4u/include/sys -HDRDIR= . -SUBDIRS= sparc sparcv9 - -all := TARGET= all -clean := TARGET= clean -clobber := TARGET= clobber -install := TARGET= install -lint := TARGET= lint - -.KEEP_STATE: - -all clean clobber lint: $(SUBDIRS) - -install: install_h $(SUBDIRS) - -install_h: $(ROOTHDRS) - -check: $(CHECKHDRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include ../Makefile.targ diff --git a/usr/src/lib/libwrsmconf/Makefile.com b/usr/src/lib/libwrsmconf/Makefile.com deleted file mode 100644 index 7efd97660c..0000000000 --- a/usr/src/lib/libwrsmconf/Makefile.com +++ /dev/null @@ -1,95 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -LIBRARY= libwrsmconf.a -VERS= .1 - -CSRCS = confpack.c confprint.c wrsm_confpack.c libwrsmconf.c util.c -LINTSRCS = $(CSRCS:%=../%) -OBJECTS = $(CSRCS:%.c=%.o) confparse.tab.o confparse.yy.o - -include ../../Makefile.lib - -# -# This Makefile makes using CTF very tricky, so we just disable it -# -CTFCONVERT_POST = : -CTFMERGE_LIB = : - -# -# Note: We install this library in the root filesystem -# because it is needed by the /platform/sun4u/sbin/wrsmconf -# command, which is executed before /usr is mounted. -# -ROOTLIBDIR= $(ROOT)/platform/sun4u/lib -ROOTLIBDIR64= $(ROOT)/platform/sun4u/lib/sparcv9 - -LIBS = $(DYNLIB) - -# There should be a mapfile here -MAPFILES = - -BUILD.SO= $(CC) $(CFLAGS) -o $@ $(GSHARED) $(DYNFLAGS) $(OBJECTS) $(LDLIBS) - -CLEANFILES= $(OBJECTS) confparse.yy.c confparse.tab.c confparse.tab.h -CLOBBERFILES= $(DYNLIB) $(LIBRARY) $(LINTLIB) - -FILEMODE = 755 - -CPPFLAGS += -I$(ROOT)/usr/platform/sun4u/include -I.. -I. -DPIC -CFLAGS += $(C_PICFLAGS) -CFLAGS64 += $(C_PICFLAGS64) -LDLIBS += -lc - -$(DYNLIB): $(OBJECTS) - $(BUILD.SO) - $(POST_PROCESS_SO) - -.KEEP_STATE: - -%.o: ../%.c - $(COMPILE.c) -o $@ $< - $(POST_PROCESS_O) - -confparse.tab.c: ../confparse.y - $(YACC) -b confparse -d ../confparse.y - -confparse.yy.c: ../confparse.l - $(LEX) -t ../confparse.l > confparse.yy.c - -clean: - -$(RM) $(CLEANFILES) - -clobber: clean - -$(RM) $(CLOBBERFILES) - -lint: $(MACH)_lint - -i386_lint: - -sparc_lint: - $(LINT.c) -m $(LINTSRCS) $(LDLIBS) diff --git a/usr/src/lib/libwrsmconf/confpack.c b/usr/src/lib/libwrsmconf/confpack.c deleted file mode 100644 index 5b149a5b40..0000000000 --- a/usr/src/lib/libwrsmconf/confpack.c +++ /dev/null @@ -1,146 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file contains functions used to serialize rsm controller - * data structures in preperation for injecting into the kernel. - */ - -#include <stdlib.h> -#include <string.h> -#include <sys/wrsm_config.h> - -#define PACK_SIZE 1 -#define PACK_DATA 2 - -#define ROUNDUP(x) (((x) + 0x07) & ~0x07) - - -static void * -cf_pack_cont(wrsm_controller_t *cont, int flag, int *sizep) -{ - char *data; - int size; - int i, j; - wrsm_routing_data_t *routing; - - if (flag == PACK_DATA) { - data = (void *)calloc(1, *sizep); - if (!data) - return (NULL); - } - size = 0; - - /* wrsm_controller */ - if (flag == PACK_DATA) - (void) memcpy((data+size), cont, sizeof (wrsm_controller_t)); - size += ROUNDUP(sizeof (wrsm_controller_t)); - - /* wrsm_routing_data */ - if (flag == PACK_DATA) - (void) memcpy((data+size), cont->WRSM_ALIGN_PTR(routing), - sizeof (wrsm_routing_data_t)); - size += ROUNDUP(sizeof (wrsm_routing_data_t)); - routing = cont->WRSM_ALIGN_PTR(routing); - - - for (i = 0; i < routing->nwcis; ++i) { - wrsm_wci_data_t *wci; - wci = routing->WRSM_ALIGN_PTR(wcis)[i]; - if (flag == PACK_DATA) - (void) memcpy((data+size), wci, - sizeof (wrsm_wci_data_t)); - size += ROUNDUP(sizeof (wrsm_wci_data_t)); - } - - for (i = 0; i < routing->ngroups; ++i) { - wrsm_stripe_group_t *group; - group = routing->WRSM_ALIGN_PTR(stripe_groups)[i]; - if (flag == PACK_DATA) - (void) memcpy((data+size), group, - sizeof (wrsm_stripe_group_t)); - size += ROUNDUP(sizeof (wrsm_stripe_group_t)); - } - - for (i = 0; i < routing->npolicy; ++i) { - wrsm_routing_policy_t *policy; - wrsm_preferred_route_t *route; - - policy = routing->WRSM_ALIGN_PTR(policy)[i]; - if (flag == PACK_DATA) - (void) memcpy((data+size), policy, - sizeof (wrsm_routing_policy_t)); - size += ROUNDUP(sizeof (wrsm_routing_policy_t)); - - for (j = 0; j < policy->nroutes; ++j) { - route = policy-> - WRSM_ALIGN_PTR(preferred_routes)[j]; - if (flag == PACK_DATA) - (void) memcpy((data+size), route, - sizeof (wrsm_preferred_route_t)); - size += ROUNDUP(sizeof (wrsm_preferred_route_t)); - } - - } - - /* wrsm_net_member */ - for (i = 0; i < cont->nmembers; ++i) { - wrsm_net_member_t *member; - member = cont->WRSM_ALIGN_PTR(members)[i]; - if (flag == PACK_DATA) - (void) memcpy((data+size), member, - sizeof (wrsm_net_member_t)); - size += ROUNDUP(sizeof (wrsm_net_member_t)); - } - - if (flag == PACK_SIZE) { - *sizep = size; - return (NULL); - } - return (data); -} - -void * -wrsm_cf_pack(wrsm_controller_t *cont, int *sizep) -{ - int block_size; - void *data; - - (void) cf_pack_cont(cont, PACK_SIZE, &block_size); - data = cf_pack_cont(cont, PACK_DATA, &block_size); - if (sizep) - *sizep = block_size; - return (data); -} - -void -wrsm_free_packed_cont(wrsm_controller_t *cont) -{ - if (cont) - free(cont); -} diff --git a/usr/src/lib/libwrsmconf/confparse.l b/usr/src/lib/libwrsmconf/confparse.l deleted file mode 100644 index f3444476cb..0000000000 --- a/usr/src/lib/libwrsmconf/confparse.l +++ /dev/null @@ -1,220 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - * - * Lexical analyzer used for parsing wrsm cluster configuration files - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <strings.h> -#include <ctype.h> -#include <sys/wrsm_config.h> -#include "confparse.tab.h" - -int ErrorCount = 0; -int lineNumber = 1; -int lexdebug = 0; - -YYSTYPE yylval; - -typedef struct reserved { - char *name; - int id; -} reserved_t; - -static int lookup_reserved(char *name); - -/* - * For debugging purposes, ECHO can be defined to print tokens - * as they are reduced. - */ -#ifdef ECHO -#undef ECHO -#define ECHO -#endif - -/* - * If lexdebug it turned on, print each token value and string - * before they are returned. - */ -#define Return(x) if (lexdebug) fprintf(stderr,"\"%s\":%d\n", yytext, x); return x; - -%} - -DIGIT [0-9] -EXTDIGIT [0-9a-fA-F] -LETTER [a-zA-Z] -ID {LETTER}("_"|"-"|{LETTER}|{DIGIT})* -INTEGER [-]?{DIGIT}+ -HEX 0x{EXTDIGIT}+ -WS [\t ] - -%% - -"//".* { ECHO; } -"#".* { ECHO; } -{WS}* { ECHO; } -"\n" { ECHO; ++lineNumber; } - -{INTEGER} { - ECHO; - yylval.ival = strtoull(yytext, 0, NULL); - Return(INT); -} - -{HEX} { - ECHO; - yylval.ival = strtoull(yytext, 0, NULL); - Return(INT); -} - -"true" { ECHO; yylval.bool = B_TRUE; Return(BOOL); } -"false" { ECHO; yylval.bool = B_FALSE; Return(BOOL); } -"central_switch" { - ECHO; yylval.tt = topology_central_switch; - Return(TT); -} -"distributed_switch" { - ECHO; - yylval.tt = topology_distributed_switch; - Return(TT); -} -"san_switch" { ECHO; yylval.tt = topology_san_switch; Return(TT); } -"multihop" { ECHO; yylval.rm = routing_multihop; Return(RM); } -"passthrough" { ECHO; yylval.rm = routing_passthrough; Return(RM); } - -{ID} { - int id; - ECHO; - if (id = lookup_reserved(yytext)) { - Return(id); - } - yylval.name = malloc(strlen(yytext) + 1); - strcpy(yylval.name, yytext); - Return(NAME); -} - - -"{" { ECHO; Return(LB); } -"}" { ECHO; Return(RB); } -"(" { ECHO; Return(LP); } -")" { ECHO; Return(RP); } -"," { ECHO; Return(COMMA); } - -. { - /* - * If none of the rules above matched there must be an - * unrecognized character, so fall through to here. - */ - ECHO; - if (isprint(*yytext)) - fprintf(stderr,"Illegal character: %c\n",*yytext); - else - fprintf(stderr,"Illegal character: %d\n",*yytext); - ++ErrorCount; -} - -%% - -reserved_t res_words[] = { -{"fmnodeid", FMNODEID}, -{"controller", CONTROLLER}, -{"version", VERSION}, -{"config_protocol_version", CONF_PROTOCOL_VERSION}, -{"local_cnodeid", LOCAL_CNODEID}, -{"imported_ncslices", IMPORTED_NCSLICES}, -{"exported_ncslices", EXPORTED_NCSLICES}, -{"cnodeid", CNODEID}, -{"comm_ncslice", COMM_NCSLICE}, -{"local_offset", LOCAL_OFFSET}, -{"small", SMALL}, -{"large", LARGE}, -{"wci", WCI}, -{"safari_port_id", SAFARI_PORT_ID}, -{"wnodeid", WNODEID}, -{"gnid", GNID}, -{"reachable", REACHABLE}, -{"route_map_striping", ROUTE_MAP_STRIPING}, -{"topology_type", TOPOLOGY_TYPE}, -{"link", LINK}, -{"remote_gnid", REMOTE_GNID}, -{"remote_link", REMOTE_LINK}, -{"remote_wci", REMOTE_WCI}, -{"routing_policy", ROUTING_POLICY}, -{"preferred_routes", PREFERRED_ROUTES}, -{"wcis_balanced", WCIS_BALANCED}, -{"striping_important", STRIPING_IMPORTANT}, -{"forwarding_ncslices", FORWARDING_NCSLICES}, -{"preferred_route", PREFERRED_ROUTE}, -{"striping_level", STRIPING_LEVEL}, -{"routing_method", ROUTING_METHOD}, -{"use_wci", USE_WCI}, -{"stripe_group", STRIPE_GROUP}, -{"wcis", WCIS}, -{"switches", SWITCHES}, -{(char *)0,0} -}; - -/* - * lookup_reserved is called when an identifier is found (letter - * followed by letters, digits or _) to scan the above list of - * keywords. If a match is found, return the associated token - * value, otherwise return 0. - */ -static int lookup_reserved(char *name) -{ - int i = 0; - while (res_words[i].name) { - if (strcmp(name, res_words[i].name) == 0) - return res_words[i].id; - ++i; - } - return 0; -} - -/* - * Called from yyparse if it finds an error. s is a string - * describing the type of error found. - */ -void yyerror(char *s) -{ - extern char yytext[1024]; - fprintf(stderr,"Error line %d: %s at \"%s\"\n", lineNumber,s, yytext); - ErrorCount++; -} - -int yywrap() -{ - return 1; -} - -void -wrsm_lexx_reset() -{ - ErrorCount = 0; - lineNumber = 1; - lexdebug = 0; -} diff --git a/usr/src/lib/libwrsmconf/confparse.y b/usr/src/lib/libwrsmconf/confparse.y deleted file mode 100644 index 0b076e9408..0000000000 --- a/usr/src/lib/libwrsmconf/confparse.y +++ /dev/null @@ -1,668 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <strings.h> -#include <stdlib.h> -#include <sys/wrsm_config.h> -#include "util.h" -#include "wrsmconf.h" -#include "wrsmconf_impl.h" - -int yyerror(const char *); - -static wrsm_controller_t controller[WRSM_MAX_CNODES] = {0}; -static int num_ctlrs = 0; -static int nmembers = 0; -static int nwcis = 0; -static int ngroups = 0; -static int npolicy = 0; -static int nroutes = 0; -static wrsm_link_data_t cur_links[WRSM_MAX_LINKS_PER_WCI]; -static wrsm_wci_data_t **cur_wci_list; -static wrsm_wci_data_t *cur_wci; - -struct intlist { - int length; - int *list; -}; - -#ifdef DEBUG -#define TRACE(s) (void) fprintf(stderr, "%s\n", s); -#else -#define TRACE(s) -#endif /* DEBUG */ - -%} - -%union { - uint64_t ival; - char *name; - int value; - boolean_t bool; - struct intlist *intlist; - wrsm_topology_t tt; - wrsm_controller_t *controller; - wrsm_net_member_t *member; - wrsm_net_member_t **members; - wrsm_wci_data_t **wcis; - wrsm_wci_data_t *wci; - wrsm_routing_data_t *routing; - wrsm_routing_policy_t **policies; - wrsm_routing_policy_t *policy; - wrsm_routing_method_t rm; - wrsm_stripe_group_t *stripe_group; - wrsm_stripe_group_t **stripe_groups; - wrsm_preferred_route_t **routes; - wrsm_preferred_route_t *route; - wrsm_ncslice_info_t *slice_info; -} - -%type <controller> controller -%type <member> net_member -%type <members> net_members -%type <wcis> wcis -%type <wci> wci -%type <tt> topology_type -%type <bool> route_map_striping -%type <routing> routing -%type <ival> remote_gnid remote_link remote_wci -%type <value> reachable -%type <policies> routing_policies -%type <policy> routing_policy -%type <routes> preferred_routes -%type <route> preferred_route -%type <bool> wcis_balanced striping_important -%type <ival> striping_level use_wci use_stripe -%type <rm> routing_method -%type <intlist> int_list switches forwarding_ncslices -%type <stripe_group> stripe_group -%type <stripe_groups> stripe_groups - -%token <ival> INT -%token <name> NAME -%token <bool> BOOL -%token <tt> TT -%token <rm> RM - -%token <value> LB RB COMMA LP RP -%token <value> FMNODEID CONTROLLER VERSION LOCAL_CNODEID -%token <value> IMPORTED_NCSLICES EXPORTED_NCSLICES CONF_PROTOCOL_VERSION -%token <value> CNODEID COMM_NCSLICE LOCAL_OFFSET SMALL LARGE GNID -%token <value> SAFARI_PORT_ID WNODEID ROUTE_MAP_STRIPING TOPOLOGY_TYPE -%token <value> REACHABLE WCI LINK REMOTE_GNID REMOTE_LINK REMOTE_WCI -%token <value> PREFERRED_ROUTES WCIS_BALANCED STRIPING_IMPORTANT -%token <value> FORWARDING_NCSLICES ROUTING_POLICY -%token <value> PREFERRED_ROUTE STRIPING_LEVEL ROUTING_METHOD USE_WCI -%token <value> STRIPE_GROUP WCIS SWITCHES - -%% - -controllers: controllers controller | controller; - -controller: - FMNODEID INT NAME CONTROLLER INT LB - CONF_PROTOCOL_VERSION INT VERSION INT LOCAL_CNODEID INT - { nmembers=0; } net_members - { nwcis=0; ngroups=0; } routing RB { - int i; - TRACE("controller"); - controller[num_ctlrs].fmnodeid = $2; - strcpy(controller[num_ctlrs].hostname, $3); - controller[num_ctlrs].controller_id = $5; - controller[num_ctlrs].config_protocol_version = $8; - controller[num_ctlrs].version_stamp = $10; - controller[num_ctlrs].cnodeid = $12; - controller[num_ctlrs].nmembers = nmembers; - controller[num_ctlrs].WRSM_ALIGN_PTR(members) = $14; - controller[num_ctlrs].WRSM_ALIGN_PTR(routing) = $16; - postprocess_controller(&controller[num_ctlrs]); - - num_ctlrs++; - } -; - - -net_members: - net_member net_members { - TRACE("net_members 1"); - ++nmembers; - $$ = (wrsm_net_member_t **)realloc($2, - sizeof(wrsm_net_member_t *) * nmembers); - $$[nmembers-1] = $1; - } -| net_member { - TRACE("net_members 2"); - ++nmembers; - $$ = (wrsm_net_member_t **)malloc( - sizeof(wrsm_net_member_t *) * nmembers); - $$[nmembers-1] = $1; - } -; - -net_member: - CNODEID INT LB - FMNODEID INT NAME - EXPORTED_NCSLICES LB int_list RB - IMPORTED_NCSLICES LB int_list RB - LOCAL_OFFSET INT - COMM_NCSLICE INT INT RB { - int i; - TRACE("net_member"); - $$ = (wrsm_net_member_t *)malloc(sizeof(wrsm_net_member_t)); - $$->cnodeid = $2; - $$->fmnodeid = $5; - strcpy($$->hostname,$6); - /* - * The first ncslice listed in the file becomes the last - * ncslice in the int list. So pick off the last one as - * the small page ncslice, and sort the rest based on - * large page index (lower 3 bits). - */ - memset(&($$->exported_ncslices), 0, - sizeof($$->exported_ncslices)); - $$->exported_ncslices.id[0] = $9->list[$9->length - 1]; - for (i = 0; i < $9->length - 1; i++) { - int index = $9->list[i] & 0x3; - if ($$->exported_ncslices.id[index] != 0) { - char errmsg[128]; - sprintf(errmsg, "exported_ncslices for " - "cnode %d: Large ncslice 0x%x attempts " - "to use position %d which is already " - "used by ncslice 0x%x", - $$->cnodeid, $9->list[i], index, - $$->exported_ncslices.id[index]); - yyerror(errmsg); - } - $$->exported_ncslices.id[index] = $9->list[i]; - } - memset(&($$->imported_ncslices), 0, - sizeof($$->imported_ncslices)); - $$->imported_ncslices.id[0] = $13->list[$13->length - 1]; - for (i = 0; i < $13->length - 1; i++) { - int index = $13->list[i] & 0x3; - if ($$->imported_ncslices.id[index] != 0) { - char errmsg[128]; - sprintf(errmsg, "imported_ncslices for " - "cnode %d: Large ncslice 0x%x attempts " - "to use position %d which is already " - "used by ncslice 0x%x", - $$->cnodeid, $13->list[i], index, - $$->imported_ncslices.id[index]); - yyerror(errmsg); - } - $$->imported_ncslices.id[index] = $13->list[i]; - } - $$->local_offset = $16; - $$->comm_ncslice = $18; - $$->comm_offset = $19; - } -; - -routing: - wcis { cur_wci_list=$1; npolicy=0;} - routing_policies stripe_groups { - TRACE("routing"); - $$ = (wrsm_routing_data_t *)malloc - (sizeof(wrsm_routing_data_t)); - $$->WRSM_ALIGN_PTR(wcis) = $1; - $$->nwcis = nwcis; - $$->WRSM_ALIGN_PTR(policy) = $3; - $$->npolicy = npolicy; - $$->WRSM_ALIGN_PTR(stripe_groups) = $4; - $$->ngroups = ngroups; - } - -wcis: - wci wcis { - TRACE("wcis 1"); - ++nwcis; - $$ = (wrsm_wci_data_t **)realloc($2, - sizeof(wrsm_wci_data_t *) * nwcis); - $$[nwcis-1] = $1; - } -| wci { - TRACE("wcis 2"); - ++nwcis; - $$ = (wrsm_wci_data_t **)malloc( - sizeof(wrsm_wci_data_t *) * nwcis); - $$[nwcis-1] = $1; - } -; - -wci: - WCI { - wrsm_gnid_t gnid; - cur_wci = _calloc(wrsm_wci_data_t,1); - for (gnid = 0; gnid < WRSM_MAX_WNODES; gnid++) { - cur_wci->gnid_to_wnode[gnid] = 0xff; - } - } - LB SAFARI_PORT_ID INT - WNODEID INT GNID INT reachable route_map_striping topology_type - { memset(cur_links, 0, sizeof(cur_links)); } links RB { - TRACE("wci"); - $$ = cur_wci; - $$->port = $5; - $$->local_wnode = $7; - $$->local_gnid = $9; - $$->route_map_striping = $11; - $$->topology_type = $12; - memcpy($$->links, cur_links, sizeof(wrsm_link_data_t) * - WRSM_MAX_LINKS_PER_WCI); - } -; - -reachable: - REACHABLE triplet_list -; - -triplet_list: - int_triplet triplet_list -| int_triplet -; - -int_triplet: - LP INT COMMA INT COMMA INT RP { - TRACE("triplet"); - if ($2 < 0 || $2 >= WRSM_MAX_WNODES) - Error("Illegal wnodeid %d", $2); - if ($4 < 0 || $4 >= WRSM_MAX_WNODES) - Error("Illegal gnid %d", $4); - cur_wci->reachable[$2] = $6; - cur_wci->gnid_to_wnode[$4] = $2; - cur_wci->wnode_reachable[$2] = B_TRUE; - } -; - -route_map_striping: - ROUTE_MAP_STRIPING BOOL { $$ = $2; } -; - -topology_type: - TOPOLOGY_TYPE TT { $$ = $2; } -; - -links: - link links -| -; - -link: - LINK INT LB remote_gnid remote_link remote_wci RB { - TRACE("link"); - if ($2 < 0 || $2 >= WRSM_MAX_LINKS_PER_WCI) - yyerror("Illegal link number"); - cur_links[$2].present = B_TRUE; - cur_links[$2].remote_gnid = $4; - cur_links[$2].remote_link_num = $5; - cur_links[$2].remote_port = $6; - } - -remote_gnid: - REMOTE_GNID INT { $$ = $2; } -; - -remote_link: - REMOTE_LINK INT { $$ = $2; } -; - -remote_wci: - REMOTE_WCI INT { $$ = $2; } -; - -routing_policies: - routing_policy routing_policies { - TRACE("routing_policies 1"); - ++npolicy; - $$ = (wrsm_routing_policy_t **)realloc - ($2, sizeof(wrsm_routing_policy_t *) * npolicy); - $$[npolicy-1] = $1; - } -| routing_policy { - TRACE("routing_policies 2"); - ++npolicy; - $$ = (wrsm_routing_policy_t **)malloc - (sizeof(wrsm_routing_policy_t *) * npolicy); - $$[npolicy-1] = $1; - } -; - -routing_policy: - ROUTING_POLICY INT LB { nroutes=0; } preferred_routes wcis_balanced - striping_important forwarding_ncslices RB { - int i; - TRACE("routing_policy"); - $$ = (wrsm_routing_policy_t *)malloc - (sizeof(wrsm_routing_policy_t)); - $$->cnodeid = $2; - $$->nroutes = nroutes; - $$->WRSM_ALIGN_PTR(preferred_routes) = $5; - $$->wcis_balanced = $6; - $$->striping_important = $7; - $$->forwarding_allowed = ($8 != NULL) && ($8->length > 0); - WRSMSET_ZERO($$->forwarding_ncslices); - for (i = 0; $8 && i < $8->length; i++) { - WRSMSET_ADD($$->forwarding_ncslices, $8->list[i]); - } - } -; - -wcis_balanced: - WCIS_BALANCED BOOL { $$ = $2; } -; - -striping_important: - STRIPING_IMPORTANT BOOL { $$ = $2; } -; - -preferred_routes: - preferred_route preferred_routes { - TRACE("preferred_routes 1"); - ++nroutes; - $$ = _realloc($2, wrsm_preferred_route_t *, nroutes); - $$[nroutes-1] = $1; - } -| preferred_route { - TRACE("preferred_routes 2"); - ++nroutes; - $$ = _malloc(wrsm_preferred_route_t *, nroutes); - $$[nroutes-1] = $1; - } -; - -preferred_route: - PREFERRED_ROUTE LB striping_level routing_method use_wci switches RB { - int i; - TRACE("preferred_route 1"); - $$ = _calloc(wrsm_preferred_route_t,1); - $$->striping_level = $3; - $$->method = $4; - $$->route_type = route_wci; - $$->route.wci_id = $5; - if ($6) { - $$->nswitches = $6->length; - for (i = 0; i < $6->length; ++i) - $$->switches[i] = $6->list[$6->length - i - 1]; - } - } -| PREFERRED_ROUTE LB striping_level routing_method use_stripe switches - RB { - int i; - TRACE("preferred_route 2"); - $$ = _calloc(wrsm_preferred_route_t,1); - $$->striping_level = $3; - $$->method = $4; - $$->route_type = route_stripe_group; - $$->route.stripe_group_id = $5; - if ($6) { - $$->nswitches = $6->length; - for (i = 0; i < $6->length; ++i) - $$->switches[i] = $6->list[$6->length - i - 1]; - } - } -; - -striping_level: - STRIPING_LEVEL INT { - TRACE("striping_level"); - $$ = $2; - } -; - -routing_method: - ROUTING_METHOD RM { - TRACE("routing_method"); - $$ = $2; - } -; - -use_wci: - USE_WCI INT { - TRACE("use_wci"); - $$ = $2; - } -; - -use_stripe: - STRIPE_GROUP INT { - TRACE("use_stripe"); - $$ = $2; - } -; - -switches: - SWITCHES int_list { $$ = $2; } -| { $$ = NULL; } -; - -forwarding_ncslices: - FORWARDING_NCSLICES int_list { $$ = $2; } -| { $$ = NULL; } -; - -stripe_groups: - stripe_group stripe_groups { - TRACE("stripe_groups"); - ++ngroups; - $$ = _realloc($2, wrsm_stripe_group_t *, ngroups); - $$[ngroups-1] = $1; - } -| { $$ = NULL; } -; - -stripe_group: - STRIPE_GROUP INT LB WCIS int_list RB { - int i; - TRACE("stripe_group"); - $$ = _calloc(wrsm_stripe_group_t,1); - $$->group_id = $2; - if ($5->length > WRSM_MAX_WCIS_PER_STRIPE) - Error("Too many wcis in stripe group"); - else { - $$->nwcis = $5->length; - for (i = 0; i < $$->nwcis; ++i) - $$->wcis[i] = $5->list[i]; - free($5->list); - free($5); - } - } -; - -int_list: - INT int_list { - TRACE("int_list 1"); - $$ = $2; - $$->length++; - $$->list = _realloc($$->list,int,$$->length); - $$->list[$$->length-1] = $1; - } -| INT { - TRACE("int_list 2"); - $$ = _malloc(struct intlist,1); - $$->length = 1; - $$->list = _malloc(int,$$->length); - $$->list[$$->length-1] = $1; - } -; - -%% - - -static int -compare_member(const void *a, const void *b) -{ - wrsm_cnodeid_t id_a, id_b; - TRACE("compare_member"); - id_a = (*(wrsm_net_member_t **)a)->cnodeid; - id_b = (*(wrsm_net_member_t **)b)->cnodeid; - return (id_a - id_b); -} - -static int -compare_policy(const void *a, const void *b) -{ - wrsm_cnodeid_t id_a, id_b; - TRACE("compare_policy"); - id_a = (*(wrsm_routing_policy_t **)a)->cnodeid; - id_b = (*(wrsm_routing_policy_t **)b)->cnodeid; - return (id_a - id_b); -} - -static int -compare_stripe_group(const void *a, const void *b) -{ - uint32_t id_a, id_b; - TRACE("compare_stripe_group"); - id_a = (*(wrsm_stripe_group_t **)a)->group_id; - id_b = (*(wrsm_stripe_group_t **)b)->group_id; - return (id_a - id_b); -} - -static int -compare_wci(const void *a, const void *b) -{ - uint32_t id_a, id_b; - TRACE("compare_wci"); - id_a = (*(wrsm_wci_data_t **)a)->port; - id_b = (*(wrsm_wci_data_t **)b)->port; - return (id_a - id_b); -} - - -static void -postprocess_controller(wrsm_controller_t *cont) -{ - int i, j; - TRACE("postprocess_controller"); - - /* sort network members by cnodeid */ - qsort(cont->WRSM_ALIGN_PTR(members), cont->nmembers, - sizeof (wrsm_net_member_t *), - &compare_member); - - if (cont->WRSM_ALIGN_PTR(routing)) { - wrsm_routing_data_t *routing; - routing = cont->WRSM_ALIGN_PTR(routing); - - /* sort routing policies by cnodeid */ - qsort(routing->WRSM_ALIGN_PTR(policy), routing->npolicy, - sizeof (wrsm_routing_policy_t *), &compare_policy); - - /* sort stripe groupd by group id */ - qsort(routing->WRSM_ALIGN_PTR(stripe_groups), - routing->ngroups, - sizeof (wrsm_stripe_group_t *), - &compare_stripe_group); - - /* sort wcis by safari port id */ - qsort(routing->WRSM_ALIGN_PTR(wcis), routing->nwcis, - sizeof (wrsm_wci_data_t *), &compare_wci); - - /* Reverse the order of the preferred routes list */ - for (i = 0; i < routing->npolicy; ++i) { - wrsm_preferred_route_t **routes = - routing->WRSM_ALIGN_PTR(policy)[i]-> - WRSM_ALIGN_PTR(preferred_routes); - int nroutes = - routing->WRSM_ALIGN_PTR(policy)[i]->nroutes; - for (j = 0; j < (nroutes/2); ++j) { - wrsm_preferred_route_t *tmp; - tmp = routes[j]; - routes[j] = routes[nroutes - j - 1]; - routes[nroutes - j - 1] = tmp; - } - } - /* Reverse the order of the stripe groups */ - for (i = 0; i < routing->ngroups; ++i) { - wrsm_stripe_group_t *group = - routing->WRSM_ALIGN_PTR(stripe_groups)[i]; - int nwcis = group->nwcis; - for (j = 0; j < (nwcis / 2); ++j) { - wrsm_safari_port_t tmp; - tmp = group->wcis[j]; - group->wcis[j] = group->wcis[nwcis - j - 1]; - group->wcis[nwcis - j - 1] = tmp; - } - } - } -} - -wrsm_controller_t * -wrsm_find_controller(char *host, int id) -{ - int i; - int j; - TRACE("wrsm_find_controller"); - - for (i = 0; i < num_ctlrs; i++) { - if (host == NULL || - strcmp(host, controller[i].hostname) == 0) { - if (controller[i].controller_id == id) { - return (&controller[i]); - } - } - } - return (NULL); -} - -wrsm_controller_t * -wrsm_find_controller_by_hostname(char *host) -{ - int i; - int j; - TRACE("wrsm_find_controller_by_hostname"); - - if (!host) - return (NULL); - - for (i = 0; i < num_ctlrs; i++) { - if (strcmp(host, controller[i].hostname) == 0) { - return (&controller[i]); - } - } - return (NULL); -} - -void -wrsm_yacc_reset() -{ - int i; - TRACE("wrsm_yacc_reset"); - - for (i = 0; i < num_ctlrs; i++) { - wrsm_cf_free(&controller[i], 0); - } - memset(controller, 0, sizeof(wrsm_controller_t) * WRSM_MAX_CNODES); - num_ctlrs = 0; - nmembers = 0; - nwcis = 0; - ngroups = 0; - npolicy = 0; - nroutes = 0; -} diff --git a/usr/src/lib/libwrsmconf/confprint.c b/usr/src/lib/libwrsmconf/confprint.c deleted file mode 100644 index d10cee3172..0000000000 --- a/usr/src/lib/libwrsmconf/confprint.c +++ /dev/null @@ -1,214 +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 2001-2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Convert an RSM configuration to plain text - */ - -#include <stdio.h> -#include <sys/wrsm_config.h> - -#define bool_string(x) (x == B_TRUE ? "true" : "false") - -static void -print_stripe_group(FILE *fp, wrsm_stripe_group_t *group) -{ - int i; - (void) fprintf(fp, "\tstripe_group %d {\n", group->group_id); - (void) fprintf(fp, "\t\twcis"); - for (i = 0; i < group->nwcis; ++i) - (void) fprintf(fp, " %d", group->wcis[i]); - (void) fprintf(fp, "\n\t}\n"); -} - -static void -print_route(FILE *fp, wrsm_preferred_route_t *route) -{ - (void) fprintf(fp, "\t\tpreferred_route {\n"); - (void) fprintf(fp, "\t\t\tstriping_level %d\n", route->striping_level); - (void) fprintf(fp, "\t\t\trouting_method %s\n", - (route->method == routing_multihop) ? "multihop": - (route->method == routing_passthrough) ? "passthrough":"ERROR"); - if (route->route_type == route_stripe_group) - (void) fprintf(fp, "\t\t\tstripe_group %d\n", - route->route.stripe_group_id); - else if (route->route_type == route_wci) - (void) fprintf(fp, "\t\t\tuse_wci %d\n", route->route.wci_id); - if (route->nswitches) { - int i; - (void) fprintf(fp, "\t\t\tswitches"); - for (i = 0; i < route->nswitches; ++i) - (void) fprintf(fp, " %d", route->switches[i]); - (void) fprintf(fp, "\n"); - } - (void) fprintf(fp, "\t\t}\n"); -} - -static void -print_policy(FILE *fp, wrsm_routing_policy_t *policy) -{ - int i; - (void) fprintf(fp, "\trouting_policy %d {\n", policy->cnodeid); - for (i = 0; i < policy->nroutes; ++i) - print_route(fp, - policy->WRSM_ALIGN_PTR(preferred_routes)[i]); - (void) fprintf(fp, "\t\twcis_balanced %s\n", - bool_string(policy->wcis_balanced)); - (void) fprintf(fp, "\t\tstriping_important %s\n", - bool_string(policy->striping_important)); - if (policy->forwarding_allowed) { - (void) fprintf(fp, "\t\tforwarding_ncslices"); - for (i = 0; i < WRSM_MAX_NCSLICES; i++) { - if (WRSM_IN_SET(policy->forwarding_ncslices, i)) { - (void) fprintf(fp, " 0x%x", i); - } - } - (void) fprintf(fp, "\n"); - } - (void) fprintf(fp, "\t}\n"); -} - -static void -print_link(FILE *fp, wrsm_link_data_t *link, int n) -{ - if (!link->present) - return; - (void) fprintf(fp, "\t\tlink %d {\n", n); - (void) fprintf(fp, "\t\t\tremote_gnid %d\n", link->remote_gnid); - (void) fprintf(fp, "\t\t\tremote_link %d\n", link->remote_link_num); - (void) fprintf(fp, "\t\t\tremote_wci %d\n", link->remote_port); - (void) fprintf(fp, "\t\t}\n"); -} - -static void -print_wci(FILE *fp, wrsm_wci_data_t *wci) -{ - int wnid; - int gnid; - int link; - - (void) fprintf(fp, "\twci {\n"); - (void) fprintf(fp, "\t\tsafari_port_id %d\n", wci->port); - (void) fprintf(fp, "\t\twnodeid %d\n", wci->local_wnode); - (void) fprintf(fp, "\t\tgnid %d\n", wci->local_gnid); - (void) fprintf(fp, "\t\treachable"); - for (wnid = 0; wnid < WRSM_MAX_WNODES; ++wnid) { - if (wci->wnode_reachable[wnid]) { - (void) fprintf(fp, " (%d,", wnid); - for (gnid = 0; gnid < WRSM_MAX_WNODES; gnid++) { - if (wci->gnid_to_wnode[gnid] == wnid) { - break; - } - } - (void) fprintf(fp, "%d,", gnid); - (void) fprintf(fp, "%d)", wci->reachable[wnid]); - } - } - (void) fprintf(fp, "\n"); - (void) fprintf(fp, "\t\troute_map_striping %s\n", - bool_string(wci->route_map_striping)); - (void) fprintf(fp, "\t\ttopology_type %s\n", - (wci->topology_type == topology_central_switch ? - "central_switch": - (wci->topology_type == topology_distributed_switch ? - "distributed_switch": - (wci->topology_type == topology_san_switch ? - "san_switch":"none")))); - for (link = 0; link < WRSM_MAX_LINKS_PER_WCI; ++link) - if (&wci->links[link]) { - print_link(fp, &wci->links[link], link); - } - (void) fprintf(fp, "\t}\n"); -} - -static void -print_routing(FILE *fp, wrsm_routing_data_t *routing) -{ - int i; - for (i = 0; i < routing->nwcis; ++i) - print_wci(fp, routing->WRSM_ALIGN_PTR(wcis)[i]); - for (i = 0; i < routing->npolicy; ++i) - print_policy(fp, routing->WRSM_ALIGN_PTR(policy)[i]); - for (i = 0; i < routing->ngroups; ++i) - print_stripe_group - (fp, routing->WRSM_ALIGN_PTR(stripe_groups)[i]); -} - -static void -print_member(FILE *fp, wrsm_net_member_t *member) -{ - int i; - (void) fprintf(fp, "\tcnodeid %d {\n", member->cnodeid); - (void) fprintf(fp, "\t\tfmnodeid 0x%llx ", - (longlong_t)member->fmnodeid); - (void) fprintf(fp, "%s\n", member->hostname); - - (void) fprintf(fp, "\t\texported_ncslices {"); - for (i = 0; i < WRSM_NODE_NCSLICES; ++i) { - if (member->exported_ncslices.id[i]) { - (void) fprintf(fp, " 0x%x", - member->exported_ncslices.id[i]); - } - } - (void) fprintf(fp, " }\n"); - - (void) fprintf(fp, "\t\timported_ncslices {"); - for (i = 0; i < WRSM_NODE_NCSLICES; ++i) { - if (member->imported_ncslices.id[i]) { - (void) fprintf(fp, " 0x%x", - member->imported_ncslices.id[i]); - } - } - (void) fprintf(fp, " }\n"); - - (void) fprintf(fp, "\t\tlocal_offset 0x%llx\n", - (longlong_t)member->local_offset); - (void) fprintf(fp, "\t\tcomm_ncslice 0x%x 0x%llx\n", - member->comm_ncslice, - (longlong_t)member->comm_offset); - (void) fprintf(fp, "\t}\n"); -} - -void -wrsm_print_controller(FILE *fp, wrsm_controller_t *cont) -{ - int i; - (void) fprintf(fp, "fmnodeid 0x%llx ", - (longlong_t)cont->fmnodeid); - (void) fprintf(fp, "%s\n", cont->hostname); - (void) fprintf(fp, "controller %d {\n", cont->controller_id); - (void) fprintf(fp, "\tconfig_protocol_version %u\n", - cont->config_protocol_version); - (void) fprintf(fp, "\tversion %llu\n", - (longlong_t)cont->version_stamp); - (void) fprintf(fp, "\tlocal_cnodeid %d\n", cont->cnodeid); - for (i = 0; i < cont->nmembers; ++i) - print_member(fp, cont->WRSM_ALIGN_PTR(members)[i]); - print_routing(fp, cont->WRSM_ALIGN_PTR(routing)); - (void) fprintf(fp, "}\n"); -} diff --git a/usr/src/lib/libwrsmconf/libwrsmconf.c b/usr/src/lib/libwrsmconf/libwrsmconf.c deleted file mode 100644 index e688342a28..0000000000 --- a/usr/src/lib/libwrsmconf/libwrsmconf.c +++ /dev/null @@ -1,915 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <strings.h> -#include <stropts.h> -#include <errno.h> -#include <sys/systeminfo.h> -#include <sys/types.h> -#include <sys/stat.h> -#include "wrsmconf.h" -#include "wrsmconf_impl.h" - -#define ADMINDEVNAME "/dev/wrsmadmin" /* Admin */ -#define CTLRDEVNAME "/dev/wrsm%d" /* Controller */ -#define WCIDEVNAME "/dev/wci%x" /* WCI */ - -#define DIRNAMEFMT "/etc/wrsm/c%d" -#define FILENAMEFMT "/etc/wrsm/c%d/config" -#define HOSTNAMEFMT "/etc/wrsm/c%d/hostname" - -/* - * Macros to produce a quoted string containing the value of a - * preprocessor macro. For example, if SIZE is defined to be 256, - * VAL2STR(SIZE) is "256". This is used to construct format - * strings for scanf-family functions below. - */ -#define QUOTE(x) #x -#define VAL2STR(x) QUOTE(x) - -/* Private function in libwrsmconf */ -extern void wrsm_print_controller(FILE *fp, wrsm_controller_t *cont); - -extern int ErrorCount; - -/* Saves cont config in a file to be read at next reboot */ -static void -store_config(wrsm_controller_t *cont) -{ - char filename[MAXPATHLEN]; - FILE *fp; - - (void) sprintf(filename, DIRNAMEFMT, cont->controller_id); - (void) mkdir(filename, 0755); - (void) sprintf(filename, HOSTNAMEFMT, cont->controller_id); - if ((fp = fopen(filename, "w")) != NULL) { - (void) fprintf(fp, "hostname=%s", cont->hostname); - (void) fclose(fp); - } - /* Save to file for rc2 script to read at boot */ - (void) sprintf(filename, FILENAMEFMT, cont->controller_id); - (void) wrsm_save_config(filename, cont); -} - -#define DPRINTF(x) if (libwrsmconf_debug) (void) printf x -int -wrsm_check_config(wrsm_controller_t *cont) -{ - int i; - wrsm_routing_data_t *routing; - wrsm_wnodeid_t wnode; - wrsm_gnid_t gnid; - boolean_t libwrsmconf_debug = B_FALSE; - wrsm_cnode_bitmask_t cnode_bitmask; - - if (getenv("LIBWRSMCONF_DEBUG") != NULL) { - libwrsmconf_debug = B_TRUE; - } - - /* Check for NULL pointers */ - if (cont == NULL) { - DPRINTF(("ERROR: Controller is null\n")); - return (EINVAL); - } - if (cont->WRSM_ALIGN_PTR(routing) == NULL) { - DPRINTF(("ERROR: routing is null\n")); - return (EINVAL); - } - if (cont->WRSM_ALIGN_PTR(members) == NULL) { - DPRINTF(("ERROR: members is null\n")); - return (EINVAL); - } - if (cont->config_protocol_version != CONFIG_PROTOCOL_VERSION) { - DPRINTF(("ERROR: config protocol version mismatch: got %d " - "expecting %d\n", cont->config_protocol_version, - CONFIG_PROTOCOL_VERSION)); - return (ENOTSUP); - } - - /* For each member in the cluster... */ - WRSMSET_ZERO(cnode_bitmask); - for (i = 0; i < cont->nmembers; i++) { - int j; - wrsm_net_member_t *member = cont->WRSM_ALIGN_PTR(members)[i]; - if (member == NULL) { - DPRINTF(("ERROR: members[%d] is null\n", i)); - return (EINVAL); - } - if (WRSM_IN_SET(cnode_bitmask, member->cnodeid)) { - DPRINTF(("ERROR: cnode id %d appears twice\n", - member->cnodeid)); - return (EINVAL); - } - WRSMSET_ADD(cnode_bitmask, member->cnodeid); - if (member->exported_ncslices.id[0] == 0) { - DPRINTF(("ERROR: cnode id %d exports no small-page " - "ncslice\n", member->cnodeid)); - return (EINVAL); - } - if (member->imported_ncslices.id[0] == 0) { - DPRINTF(("ERROR: cnode id %d imports no small-page " - "ncslice\n", member->cnodeid)); - return (EINVAL); - } - for (j = 1; j < WRSM_NODE_NCSLICES; j++) { - int index = member->exported_ncslices.id[j] & 0x3; - if (member->exported_ncslices.id[j] && index != j) { - DPRINTF(("ERROR: cnode id %d exported ncslice " - "0x%x in wrong index %d\n", - member->cnodeid, - member->exported_ncslices.id[j], j)); - return (EINVAL); - } - index = member->imported_ncslices.id[j] & 0x3; - if (member->imported_ncslices.id[j] && index != j) { - DPRINTF(("ERROR: cnode id %d imported ncslice " - "0x%x in wrong index %d\n", - member->cnodeid, - member->exported_ncslices.id[j], j)); - return (EINVAL); - } - } - } - - /* For each wci in the routing table... */ - routing = cont->WRSM_ALIGN_PTR(routing); - for (i = 0; i < routing->nwcis; i++) { - wrsm_wci_data_t *this_wci = routing->WRSM_ALIGN_PTR(wcis)[i]; - - /* Verify wcis are listed in increasing order based on port */ - if ((i > 0) && (this_wci->port <= - routing->WRSM_ALIGN_PTR(wcis)[i - 1]->port)) { - DPRINTF(("ERROR: wci %d is not in port order", - this_wci->port)); - return (EINVAL); - } - - /* Verify reachable and gnid_to_wnode tables are consistent */ - for (wnode = 0; wnode < WRSM_MAX_WNODES; wnode++) { - int count = 0; - - /* - * Count the number of times this wnode appears in - * gnid_to_wnode table -- Should be one for reachable - * nodes, zero of unreachable nodes. - */ - for (gnid = 0; gnid < WRSM_MAX_WNODES; gnid++) { - if (this_wci->gnid_to_wnode[gnid] == wnode) { - count++; - } - } - if (this_wci->wnode_reachable[wnode] && count != 1) { - DPRINTF(("ERROR: reachable wnode %d has %d " - "gnid_to_wnode entries for wci %d\n", - wnode, count, this_wci->port)); - return (EINVAL); - } else if ((!this_wci->wnode_reachable[wnode]) && - count != 0) { - DPRINTF(("ERROR: unreachable wnode %d has %d " - "gnid_to_wnode entries for wci %d\n", - wnode, count, this_wci->port)); - return (EINVAL); - } - } - - } - - /* Verify that stripe groups are listed in order based on group_id */ - for (i = 1; i < routing->ngroups; i++) { - if (routing->WRSM_ALIGN_PTR(stripe_groups)[i]->group_id < - routing->WRSM_ALIGN_PTR(stripe_groups)[i - 1]->group_id) { - DPRINTF(("ERROR: stripe group %d not in group_id " - "order\n", routing-> - WRSM_ALIGN_PTR(stripe_groups)[i]->group_id)); - return (EINVAL); - } - } - return (0); -} - -int -wrsm_initial_config(wrsm_controller_t *cont) -{ - int fd; - int rc; - int block_size; - int tmp_errno; - void *packed; - wrsm_admin_arg_config_t initial = {0}; - - if (!cont) { - errno = EFAULT; - return (-1); - } - - if ((errno = wrsm_check_config(cont)) != 0) { - return (-1); - } - - if ((packed = wrsm_cf_pack(cont, &block_size)) == NULL) { - errno = ENOMEM; - return (-1); - } - - initial.ioctl_version = WRSM_CF_IOCTL_VERSION; - initial.controller_id = cont->controller_id; - initial.controller_data_size = block_size; - initial.WRSM_ALIGN_PTR(controller) = (wrsm_controller_t *)packed; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - wrsm_free_packed_cont(packed); - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_INITIALCFG, initial); - tmp_errno = errno; - if (rc == 0) { - store_config(cont); - } - - (void) close(fd); - wrsm_free_packed_cont(packed); - - errno = tmp_errno; - return (rc); -} - -/* - * Start config in /etc/wrsm for this controller. - */ -int -wrsm_start_config(int controller_id) -{ - FILE *fp; - int fd; - int rc; - int block_size; - int tmp_errno; - void *packed; - wrsm_admin_arg_config_t start = {0}; - char filename[MAXPATHLEN]; - char hostname[WRSM_HOSTNAMELEN+1]; - wrsm_controller_t *cont; - - (void) sprintf(filename, HOSTNAMEFMT, controller_id); - if ((fp = fopen(filename, "r")) == NULL) { - return (1); - } - if (fscanf(fp, "hostname=%" VAL2STR(WRSM_HOSTNAMELEN) "s", - hostname) == 0) { - (void) fclose(fp); - return (1); - } - (void) fclose(fp); - - (void) sprintf(filename, FILENAMEFMT, controller_id); - rc = wrsm_read_config_for_host(filename, &cont, hostname); - if (rc != 0) { - return (rc); - } - - if (controller_id != cont->controller_id) { - (void) wrsm_free_config(cont); - return (rc); - } - - if ((errno = wrsm_check_config(cont)) != 0) { - return (-1); - } - - if ((packed = wrsm_cf_pack(cont, &block_size)) == NULL) { - (void) wrsm_free_config(cont); - errno = ENOMEM; - return (-1); - } - - start.ioctl_version = WRSM_CF_IOCTL_VERSION; - start.controller_id = cont->controller_id; - start.controller_data_size = block_size; - start.WRSM_ALIGN_PTR(controller) = (wrsm_controller_t *)packed; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - wrsm_free_packed_cont(packed); - (void) wrsm_free_config(cont); - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_INITIALCFG, start); - tmp_errno = errno; - if ((rc == -1) && (errno == EEXIST)) { - /* - * if controller config is already installed, - * make sure sessions are enabled. - */ - rc = ioctl(fd, WRSM_STARTCFG, cont->controller_id); - tmp_errno = errno; - } - - (void) close(fd); - wrsm_free_packed_cont(packed); - (void) wrsm_free_config(cont); - - errno = tmp_errno; - return (rc); -} - -int -wrsm_start_all_configs(void) -{ - int rc; - int retval = 0; - int fd; - int i; - int maxcont; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - (void) close(fd); - - if ((maxcont = wrsm_get_num_controllers()) == -1) { - return (-1); - } - - for (i = 0; i < maxcont; i++) { - rc = wrsm_start_config(i); - if (rc == -1) { - retval = rc; - } - } - - return (retval); -} - -int -wrsm_replace_config(wrsm_controller_t *cont) -{ - int fd; - int rc; - int tmp_errno; - int block_size; - void *packed; - wrsm_admin_arg_config_t replace = {0}; - - if (!cont) { - errno = EFAULT; - return (-1); - } - - if ((errno = wrsm_check_config(cont)) != 0) { - return (-1); - } - - if ((packed = wrsm_cf_pack(cont, &block_size)) == NULL) { - errno = ENOMEM; - return (-1); - } - - replace.ioctl_version = WRSM_CF_IOCTL_VERSION; - replace.controller_id = cont->controller_id; - replace.controller_data_size = block_size; - replace.WRSM_ALIGN_PTR(controller) = (wrsm_controller_t *)packed; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - wrsm_free_packed_cont(packed); - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_REPLACECFG, &replace); - tmp_errno = errno; - if (rc == 0) { - store_config(cont); - } - - (void) close(fd); - wrsm_free_packed_cont(packed); - - errno = tmp_errno; - return (rc); -} - -int -wrsm_enable_config(int controller_id, size_t num_wcis, - wrsm_safari_port_t *wci_ids_in) -{ - int fd; - int rc; - int tmp_errno; - wrsm_admin_arg_wci_t enable = {0}; - - if (!wci_ids_in) { - errno = EFAULT; - return (-1); - } - - enable.ioctl_version = WRSM_CF_IOCTL_VERSION; - enable.controller_id = controller_id; - enable.nwcis = num_wcis; - enable.WRSM_ALIGN_PTR(wci_ids) = wci_ids_in; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_ENABLECFG, &enable); - tmp_errno = errno; - - (void) close(fd); - - errno = tmp_errno; - return (rc); -} - -int -wrsm_install_config(int controller_id, size_t num_wcis, - wrsm_safari_port_t *wci_ids_in) -{ - int fd; - int rc; - int tmp_errno; - wrsm_admin_arg_wci_t install = {0}; - - if (!wci_ids_in) { - errno = EFAULT; - return (-1); - } - - install.ioctl_version = WRSM_CF_IOCTL_VERSION; - install.controller_id = controller_id; - install.nwcis = num_wcis; - install.WRSM_ALIGN_PTR(wci_ids) = wci_ids_in; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_INSTALLCFG, &install); - tmp_errno = errno; - - (void) close(fd); - - errno = tmp_errno; - return (rc); -} - -int -wrsm_remove_config(int controller_id) -{ - int rc; - int fd; - int tmp_errno; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_REMOVECFG, controller_id); - tmp_errno = errno; - if (rc == 0) { - char filename[MAXPATHLEN]; - /* Delete file read by rc2 script at boot */ - (void) sprintf(filename, FILENAMEFMT, controller_id); - (void) unlink(filename); - (void) sprintf(filename, HOSTNAMEFMT, controller_id); - (void) unlink(filename); - (void) sprintf(filename, DIRNAMEFMT, controller_id); - (void) rmdir(filename); - } - - - (void) close(fd); - - errno = tmp_errno; - return (rc); -} - -int -wrsm_remove_all_configs(void) -{ - int rc; - int retval = 0; - int fd; - int i; - int maxcont; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - (void) close(fd); - - if ((maxcont = wrsm_get_num_controllers()) == -1) { - return (-1); - } - - for (i = 0; i < maxcont; i++) { - rc = wrsm_remove_config(i); - if (rc == -1) { - retval = rc; - } - } - - return (retval); -} - - -/* - * Stop config. don't remove from /etc/wrsm. - */ -int -wrsm_stop_config(int controller_id) -{ - int rc; - int fd; - int tmp_errno; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_REMOVECFG, controller_id); - tmp_errno = errno; - if ((rc == -1) && (errno == EBUSY)) { - /* - * controller config can't be removed; - * make sure sessions are disabled. - */ - rc = ioctl(fd, WRSM_STOPCFG, controller_id); - tmp_errno = errno; - } - - (void) close(fd); - - errno = tmp_errno; - return (rc); -} - -int -wrsm_stop_all_configs(void) -{ - int rc; - int retval = 0; - int fd; - int i; - int maxcont; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - (void) close(fd); - - if ((maxcont = wrsm_get_num_controllers()) == -1) { - return (-1); - } - - for (i = 0; i < maxcont; i++) { - rc = wrsm_stop_config(i); - if (rc == -1) { - retval = rc; - } - } - - return (retval); -} - -int -wrsm_get_config(int controller_id, wrsm_controller_t **cont) -{ - int fd; - int tmp_errno; - wrsm_admin_arg_config_t getarg = {0}; - wrsm_controller_t *unpacked; - - if (!cont) { - errno = EFAULT; - return (-1); - } - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - - getarg.ioctl_version = WRSM_CF_IOCTL_VERSION; - getarg.controller_id = controller_id; - getarg.controller_data_size = 0; - if (ioctl(fd, WRSM_GETCFG, &getarg) != 0) { - tmp_errno = errno; - - (void) close(fd); - errno = tmp_errno; - return (-1); - } - - getarg.WRSM_ALIGN_PTR(controller) = - malloc(getarg.controller_data_size); - if (!getarg.WRSM_ALIGN_PTR(controller)) { - (void) close(fd); - errno = ENOMEM; - return (-1); - } - - if (ioctl(fd, WRSM_GETCFG, &getarg) != 0) { - tmp_errno = errno; - free(getarg.WRSM_ALIGN_PTR(controller)); - - (void) close(fd); - - errno = tmp_errno; - return (-1); - } - - unpacked = wrsm_cf_unpack((char *)getarg.WRSM_ALIGN_PTR(controller)); - *cont = unpacked; - (void) close(fd); - return (0); -} - -int -wrsm_get_num_controllers(void) -{ - int num_conts; - int fd; - int tmp_errno; - - fd = open(ADMINDEVNAME, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - - num_conts = ioctl(fd, WRSM_CONTROLLERS, 0); - tmp_errno = errno; - - (void) close(fd); - - errno = tmp_errno; - return (num_conts); -} - -int -wrsm_save_config(char *path, wrsm_controller_t *config) -{ - FILE *fp; - - if (!config) { - errno = EFAULT; - return (-1); - } - - if ((fp = fopen(path, "w")) == NULL) { - return (-1); - } - - wrsm_print_controller(fp, config); - (void) fclose(fp); - return (0); -} - -int -wrsm_read_config(char *path, wrsm_controller_t **config) -{ - return (wrsm_read_config_for_host(path, config, NULL)); -} - -int -wrsm_read_config_for_host(char *path, wrsm_controller_t **config, - char *hostname) -{ - char localhost[WRSM_HOSTNAMELEN] = ""; - extern FILE *yyin; - wrsm_controller_t *cfg; - - if (!path || !config) { - errno = EFAULT; - return (-1); - } - - if ((yyin = fopen(path, "r")) == NULL) { - errno = EACCES; - return (-1); - } - - wrsm_lexx_reset(); - wrsm_yacc_reset(); - yyparse(); - (void) fclose(yyin); - - if (ErrorCount > 0) { - errno = EINVAL; - return (-1); - } - - if (hostname) - cfg = wrsm_find_controller_by_hostname(hostname); - else { - (void) sysinfo(SI_HOSTNAME, localhost, WRSM_HOSTNAMELEN); - cfg = wrsm_find_controller_by_hostname(localhost); - } - if (cfg == NULL) { - errno = EINVAL; - return (-1); - } - /* Allocate memory for the caller's data structure */ - *config = (wrsm_controller_t *)malloc(sizeof (wrsm_controller_t)); - /* Copy controller from static structure to caller's structure */ - (void) memcpy(*config, cfg, sizeof (wrsm_controller_t)); - /* Zero the static structure, so we don't free any of the pointers */ - (void) memset(cfg, 0, sizeof (wrsm_controller_t)); - /* Free the other unused controllers read from the file */ - wrsm_yacc_reset(); - wrsm_lexx_reset(); - - return (0); -} - -int -wrsm_free_config(wrsm_controller_t *config) -{ - wrsm_cf_free(config, sizeof (wrsm_controller_t)); - return (0); -} - -int -wrsm_link_disable(wrsm_safari_port_t wci_id, int linkno) -{ - int rc; - int fd; - int tmp_errno; - char devname[MAXPATHLEN]; - - (void) sprintf(devname, WCIDEVNAME, wci_id); - fd = open(devname, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_WCI_LINKDOWN, &linkno); - tmp_errno = errno; - - (void) close(fd); - - errno = tmp_errno; - return (rc); -} - -int -wrsm_link_enable(wrsm_safari_port_t wci_id, int linkno) -{ - int rc; - int fd; - int tmp_errno; - char devname[MAXPATHLEN]; - - (void) sprintf(devname, WCIDEVNAME, wci_id); - fd = open(devname, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_WCI_LINKUP, &linkno); - tmp_errno = errno; - - (void) close(fd); - errno = tmp_errno; - return (rc); -} - -int -wrsm_memory_test(int controller_id, wrsm_memloopback_arg_t *memoryinfo) -{ - char devname[MAXPATHLEN]; - int fd; - int rc; - int tmp_errno; - - (void) sprintf(devname, CTLRDEVNAME, controller_id); - fd = open(devname, O_RDONLY); - if (fd == -1) { - errno = EACCES; - return (-1); - } - - rc = ioctl(fd, WRSM_CTLR_MEM_LOOPBACK, memoryinfo); - tmp_errno = errno; - - (void) close(fd); - errno = tmp_errno; - return (rc); -} - - -int -wrsm_link_test_setup(int wci_instance, int link_number) -{ - int fd; - int rc; - int tmp_errno; - char devname[MAXPATHLEN]; - - (void) sprintf(devname, WCIDEVNAME, wci_instance); - if ((fd = open(devname, O_RDONLY)) == -1) { - errno = EACCES; - return (-1); - } - rc = ioctl(fd, WRSM_WCI_LOOPBACK_ON, link_number); - tmp_errno = errno; - - (void) close(fd); - errno = tmp_errno; - return (rc); -} - -int -wrsm_link_test(int wci_instance, wrsm_linktest_arg_t *linkinfo) -{ - int fd; - int rc; - int tmp_errno; - char devname[MAXPATHLEN]; - - (void) sprintf(devname, WCIDEVNAME, wci_instance); - if ((fd = open(devname, O_RDONLY)) == -1) { - errno = EACCES; - return (-1); - } - rc = ioctl(fd, WRSM_WCI_LINKTEST, linkinfo); - tmp_errno = errno; - - (void) close(fd); - errno = tmp_errno; - return (rc); -} - -int -wrsm_link_test_teardown(int wci_instance, int link_number) -{ - int fd; - int rc; - int tmp_errno; - char devname[MAXPATHLEN]; - - (void) sprintf(devname, WCIDEVNAME, wci_instance); - if ((fd = open(devname, O_RDONLY)) == -1) { - errno = EACCES; - return (-1); - } - rc = ioctl(fd, WRSM_WCI_LOOPBACK_OFF, link_number); - tmp_errno = errno; - - (void) close(fd); - errno = tmp_errno; - return (rc); -} diff --git a/usr/src/lib/libwrsmconf/sparc/Makefile b/usr/src/lib/libwrsmconf/sparc/Makefile deleted file mode 100644 index 8a61d0329e..0000000000 --- a/usr/src/lib/libwrsmconf/sparc/Makefile +++ /dev/null @@ -1,41 +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 2001-2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -$(ROOTLIBDIR): - mkdir -p $(ROOTLIBDIR) - -$(ROOTLIBDIR)/%: % - $(INS.file) -$(ROOTLIBDIR)/$(LIBLINKS): $(ROOTLIBDIR)/$(LIBLINKS)$(VERS) - $(INS.liblink) - -all: $(LIBS) - -install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/libwrsmconf/sparcv9/Makefile b/usr/src/lib/libwrsmconf/sparcv9/Makefile deleted file mode 100644 index ff94bcffdc..0000000000 --- a/usr/src/lib/libwrsmconf/sparcv9/Makefile +++ /dev/null @@ -1,49 +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 2001-2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com -include ../../Makefile.lib.64 - -CFLAGS64 += -erroff=E_STATEMENT_NOT_REACHED - -BUILD.SO= $(CC) $(CFLAGS64) -o $@ -G $(DYNFLAGS) $(OBJECTS) $(LDLIBS) - -$(ROOTLIBDIR64): - mkdir -p $(ROOTLIBDIR64) - -$(ROOTLIBDIR64)/%: % - $(INS.file) - -$(ROOTLIBDIR64)/$(LIBLINKS): $(ROOTLIBDIR64)/$(LIBLINKS)$(VERS) - $(INS.liblink64) - -LINTFLAGS64 += -Xarch=v9 - -all: $(LIBS) - -install: all $(ROOTLIBDIR64) $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/libwrsmconf/util.c b/usr/src/lib/libwrsmconf/util.c deleted file mode 100644 index 8de0715a74..0000000000 --- a/usr/src/lib/libwrsmconf/util.c +++ /dev/null @@ -1,172 +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 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Utility functions to support the config file parser. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include "util.h" - -static void print_source_line(char *file_name, int line, int ch); -static void clean_exit(int code); -static int print_line(char *file_name, int line); - -static char *file_name = NULL; -static int charNumber = 0, last_token_len = 0; - -#define print_error(args, fmt, type, line) \ - va_start(args, fmt); \ - if (file_name == NULL) \ - (void) fprintf(stderr, "(%d): \t ", line); \ - else \ - (void) fprintf(stderr, "%s(%d): \t ", file_name, line); \ - (void) fprintf(stderr, "%s: ", type); \ - (void) vfprintf(stderr, fmt, args); \ - (void) fprintf(stderr, "\n"); \ - va_end(args); \ - if (file_name != NULL) \ - print_source_line(file_name, line, charNumber-last_token_len); - -/*PRINTFLIKE1*/ -void -Error(char *fmt, ...) -{ - va_list args; - - print_error(args, fmt, "Error", lineNumber); - ErrorCount++; -} - -static void -_Internal(char *sourcefile, int sourceline, char *fmt) -{ - - (void) fprintf(stderr, "\n%s: \tInternal Compiler Error --\n\t\tFile:" - "%s\n\t\tLine: %d;\n\t\tMessage: %s\n", - file_name, sourcefile, sourceline, fmt); - clean_exit(-1); -} - -static void -print_source_line(char *file_name, int line, int ch) -{ - int i; - - if (print_line(file_name, line) == FAILURE) - return; - - if (ch > 4) { - for (i = 0; i < ch-4; ++i) - (void) printf(" "); - (void) printf("....^\n"); - } else { - for (i = 0; i < ch; ++i) - (void) printf(" "); - (void) printf("^....\n"); - } -} - -static int -print_line(char *file_name, int line) -{ - FILE *fp; - char buf[BUFSIZ]; - int i; - - fp = fopen(file_name, "r"); - if (fp == NULL) { - Error("Can't read source file `%s'\n", file_name); - return (FAILURE); - } - for (i = 0; i < line; ++ i) { - if (fgets(buf, BUFSIZ, fp) == NULL) - return (FAILURE); - } - (void) printf("%s", buf); - return (SUCCESS); -} - -void * -my_malloc(unsigned size, char *file, int line) -{ - void * tmp; - - if (size == 0) - _Internal(file, line, "Zero allocate error"); - tmp = malloc(size); - if (tmp == NULL) { - _Internal(file, line, "Out of memory"); - return (NULL); - } - return (tmp); -} - -void * -my_calloc(unsigned n, unsigned size, char *file, int line) -{ - void * tmp; - - if ((size*n) == 0) - _Internal(file, line, "Zero allocate error"); - tmp = calloc(n, size); - if (tmp == NULL) { - _Internal(file, line, "Out of memory"); - return (NULL); - } - return (tmp); -} - -void * -my_realloc(void *ptr, unsigned size, char *file, int line) -{ - void *tmp; - - if (size == 0) - _Internal(file, line, "Zero allocate error"); - - if (ptr) - tmp = realloc(ptr, size); - else - tmp = malloc(size); - - if (tmp == NULL) { - _Internal(file, line, "Out of memory"); - return (NULL); - } - return (tmp); -} - - -static void -clean_exit(int code) -{ - exit(code); -} diff --git a/usr/src/lib/libwrsmconf/util.h b/usr/src/lib/libwrsmconf/util.h deleted file mode 100644 index 41ee285f54..0000000000 --- a/usr/src/lib/libwrsmconf/util.h +++ /dev/null @@ -1,76 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _UTIL_H -#define _UTIL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> - -#define SUCCESS 1 -#define FAILURE 0 - -/* Error class flags */ -#define Err_general 0 -#define Err_Syntax 1 -#define Err_Static 2 -#define Err_Semantic 3 -#define Err_Intern 4 -#define Err_Usage 5 - - -#define _malloc(type, n) \ -(type *)my_malloc(sizeof (type)*(n), __FILE__, __LINE__) - -#define _calloc(type, n) \ -(type *)my_calloc((n), sizeof (type), __FILE__, __LINE__) - -#define _realloc(ptr, type, n) \ -(type *)my_realloc(ptr, sizeof (type)*(n), __FILE__, __LINE__) - - -#define max(a, b) ((a) > (b) ? (a) : (b)) - -void *my_malloc(unsigned size, char *file, int line); -void *my_calloc(unsigned n, unsigned size, char *file, int line); -void *my_realloc(void *ptr, unsigned size, char *file, int line); -void Error(char *fmt, ...); -static void _Internal(char *sourcefile, int sourceline, char *fmt); - -extern int lineNumber; -extern int lexdebug; -extern int ErrorCount; - -#ifdef __cplusplus -} -#endif - -#endif /* _UTIL_H */ diff --git a/usr/src/lib/libwrsmconf/wrsm_confpack.c b/usr/src/lib/libwrsmconf/wrsm_confpack.c deleted file mode 100644 index d4124866b0..0000000000 --- a/usr/src/lib/libwrsmconf/wrsm_confpack.c +++ /dev/null @@ -1,195 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdlib.h> -#include <string.h> - -#include <sys/cmn_err.h> -#include <sys/wrsm_config.h> - -#include "wrsmconf_impl.h" - -#define ROUNDUP(x) (((x) + 0x07) & ~0x07) - -/* - * wrsm_controller - * wrsm_routing_data (1) - * ncslice (nslices) - * wrsm_ncslice_mode (nsclices) - * wrsm_wci_data (nwcis) - * wrsm_stripe_group (ngroups) - * wrsm_routing_policy (npolicy) - * wrsm_preferred_route (nroutes) - * wrsm_net_member (nmembers) - * ncslice_info.incoming_slices - * ncslice_info.slice_modes - */ -wrsm_controller_t * -wrsm_cf_unpack(char *data) -{ - wrsm_controller_t *cont; - wrsm_routing_data_t *routing; - int size; - int i, j; - - size = 0; - - /* wrsm_controller */ - /* LINTED */ - cont = (wrsm_controller_t *)data; - size += ROUNDUP(sizeof (wrsm_controller_t)); - - /* wrsm_routing_data */ - /* LINTED */ - cont->WRSM_ALIGN_PTR(routing) = (wrsm_routing_data_t *)(data+size); - size += ROUNDUP(sizeof (wrsm_routing_data_t)); - - routing = cont->WRSM_ALIGN_PTR(routing); - routing->WRSM_ALIGN_PTR(wcis) = malloc(sizeof (wrsm_wci_data_t *) * - routing->nwcis); - if (!routing->WRSM_ALIGN_PTR(wcis)) - goto err_finish; - - for (i = 0; i < routing->nwcis; ++i) { - /* LINTED */ - routing->WRSM_ALIGN_PTR(wcis)[i] = (wrsm_wci_data_t *) - (data+size); - size += ROUNDUP(sizeof (wrsm_wci_data_t)); - } - - if (routing->ngroups) { - routing->WRSM_ALIGN_PTR(stripe_groups) = - malloc(sizeof (wrsm_stripe_group_t *) * routing->ngroups); - if (!routing->WRSM_ALIGN_PTR(stripe_groups)) - goto err_finish; - - for (i = 0; i < routing->ngroups; ++i) { - routing->WRSM_ALIGN_PTR(stripe_groups)[i] = - /* LINTED */ - (wrsm_stripe_group_t *)(data+size); - size += ROUNDUP(sizeof (wrsm_stripe_group_t)); - } - } - - routing->WRSM_ALIGN_PTR(policy) = malloc - (sizeof (wrsm_routing_policy_t *) *routing->npolicy); - if (!routing->WRSM_ALIGN_PTR(policy)) - goto err_finish; - - for (i = 0; i < routing->npolicy; ++i) { - wrsm_routing_policy_t *policy; - - routing->WRSM_ALIGN_PTR(policy)[i] = - /* LINTED */ - (wrsm_routing_policy_t *)(data+size); - size += ROUNDUP(sizeof (wrsm_routing_policy_t)); - - policy = routing->WRSM_ALIGN_PTR(policy)[i]; - - policy->WRSM_ALIGN_PTR(preferred_routes) = - malloc(sizeof (wrsm_preferred_route_t *) * - policy->nroutes); - if (!policy->WRSM_ALIGN_PTR(preferred_routes)) - goto err_finish; - - for (j = 0; j < policy->nroutes; ++j) { - policy->WRSM_ALIGN_PTR(preferred_routes)[j] = - /* LINTED */ - (wrsm_preferred_route_t *)(data+size); - size += ROUNDUP(sizeof (wrsm_preferred_route_t)); - } - } - - cont->WRSM_ALIGN_PTR(members) = - malloc(sizeof (wrsm_net_member_t *) * cont->nmembers); - if (!cont->WRSM_ALIGN_PTR(members)) - goto err_finish; - - for (i = 0; i < cont->nmembers; ++i) { - /* LINTED */ - cont->WRSM_ALIGN_PTR(members)[i] = (wrsm_net_member_t *) - (data+size); - size += ROUNDUP(sizeof (wrsm_net_member_t)); - } - - return (cont); - -err_finish: - /* - * Playing a little game here. The top controller structure - * "cont" is allocated before this function is called, so we - * shouldn't free it. Passing a "size" of 0 to wrsm_cf_free() - * does what we want be freeing the pointer lists and leaving - * the controller struct alone. - */ - wrsm_cf_free(cont, 0); - return (NULL); -} - -/* - * Free all the components of an wrsm_controller_t struct - */ -void -wrsm_cf_free(wrsm_controller_t *cont, size_t size) -{ - wrsm_routing_data_t *routing; - int i; - - if (!cont) - return; - - routing = cont->WRSM_ALIGN_PTR(routing); - if (!routing) { - /* Already freed, don't bother doing anything else */ - return; - } - - if (routing->nwcis && routing->WRSM_ALIGN_PTR(wcis)) - free(routing->WRSM_ALIGN_PTR(wcis)); - - if (routing->ngroups && routing->WRSM_ALIGN_PTR(stripe_groups)) - free(routing->WRSM_ALIGN_PTR(stripe_groups)); - - if (routing->npolicy && routing->WRSM_ALIGN_PTR(policy)) { - wrsm_routing_policy_t *policy; - for (i = 0; i < routing->npolicy; ++i) { - policy = routing->WRSM_ALIGN_PTR(policy)[i]; - if (policy->nroutes && - policy->WRSM_ALIGN_PTR(preferred_routes)) - free(policy->WRSM_ALIGN_PTR(preferred_routes)); - } - - free(routing->WRSM_ALIGN_PTR(policy)); - } - - if (cont->nmembers && cont->WRSM_ALIGN_PTR(members)) - free(cont->WRSM_ALIGN_PTR(members)); - - if (size) - free(cont); -} diff --git a/usr/src/lib/libwrsmconf/wrsmconf.h b/usr/src/lib/libwrsmconf/wrsmconf.h deleted file mode 100644 index 27a8c055e2..0000000000 --- a/usr/src/lib/libwrsmconf/wrsmconf.h +++ /dev/null @@ -1,69 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSMCONF_H -#define _WRSMCONF_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/wrsm.h> -#include <sys/wrsm_config.h> - -int wrsm_initial_config(wrsm_controller_t *cont); -int wrsm_start_config(int controller_id); -int wrsm_start_all_configs(void); -int wrsm_replace_config(wrsm_controller_t *cont); -int wrsm_enable_config(int controller_id, size_t num_wcis, - wrsm_safari_port_t *wci_ids_in); -int wrsm_install_config(int controller_id, size_t num_wcis, - wrsm_safari_port_t *wci_ids_in); -int wrsm_remove_config(int controller_id); -int wrsm_remove_all_configs(void); -int wrsm_stop_config(int controller_id); -int wrsm_stop_all_configs(void); -int wrsm_get_config(int controller_id, wrsm_controller_t **cont); -int wrsm_get_num_controllers(void); -int wrsm_save_config(char *path, wrsm_controller_t *config); -int wrsm_read_config(char *path, wrsm_controller_t **config); -int wrsm_read_config_for_host(char *path, wrsm_controller_t **config, - char *hostname); -int wrsm_free_config(wrsm_controller_t *config); -int wrsm_memory_test(int controller_id, wrsm_memloopback_arg_t *memoryinfo); -int wrsm_link_test_setup(int wci_instance, int link_number); -int wrsm_link_test(int wci_instance, wrsm_linktest_arg_t *linkinfo); -int wrsm_link_test_teardown(int wci_instance, int link_number); -int wrsm_link_disable(wrsm_safari_port_t wci_id, int linkno); -int wrsm_link_enable(wrsm_safari_port_t wci_id, int linkno); - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSMCONF_H */ diff --git a/usr/src/lib/libwrsmconf/wrsmconf_impl.h b/usr/src/lib/libwrsmconf/wrsmconf_impl.h deleted file mode 100644 index 8ceb9f9ef8..0000000000 --- a/usr/src/lib/libwrsmconf/wrsmconf_impl.h +++ /dev/null @@ -1,48 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSMCONF_IMPL_H -#define _WRSMCONF_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -wrsm_controller_t *wrsm_cf_unpack(char *data); -wrsm_controller_t *wrsm_find_controller_by_hostname(char *host); -void wrsm_free_packed_cont(wrsm_controller_t *cont); -void wrsm_yacc_reset(void); -void wrsm_lexx_reset(void); -void wrsm_cf_free(wrsm_controller_t *, size_t); -int yyparse(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSMCONF_IMPL_H */ diff --git a/usr/src/lib/wrsm/Makefile b/usr/src/lib/wrsm/Makefile deleted file mode 100644 index 1e44e01a90..0000000000 --- a/usr/src/lib/wrsm/Makefile +++ /dev/null @@ -1,46 +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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.lib - -SUBDIRS= sparc sparcv9 - -all := TARGET= all -clean := TARGET= clean -clobber := TARGET= clobber -install := TARGET= install -lint := TARGET= lint - -.KEEP_STATE: - -all install clean clobber lint: $(SUBDIRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: diff --git a/usr/src/lib/wrsm/Makefile.com b/usr/src/lib/wrsm/Makefile.com deleted file mode 100644 index e926e87505..0000000000 --- a/usr/src/lib/wrsm/Makefile.com +++ /dev/null @@ -1,93 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -LIBRARY = wrsm.a -VERS = .1 -OBJECTS = librsmwrsm.o wrsmlib.o - -include ../../Makefile.lib - -# librsm searches for plug-in libraries in the directory -# /usr/platform/`uname -i`/lib/rsmlib[/sparcv9] -ROOTLIBDIR = $(ROOT)/usr/platform/SUNW,Sun-Fire/lib/rsmlib -ROOTLIBDIR64 = $(ROOTLIBDIR)/$(MACH64) - -# wrsm supports both Sun-Fire and Sun-Fire-15K, so create a -# symlink from Sun-Fire-15K to Sun-Fire. - -# sparc links -RSMLIBSUNFIRE15K = $(ROOT)/usr/platform/SUNW,Sun-Fire-15000/lib/rsmlib -RSMLINKSUNFIRE15K = $(RSMLIBSUNFIRE15K)/$(LIBLINKS) -RSMLINKREL = ../../../SUNW,Sun-Fire/lib/rsmlib/$(LIBLINKS)$(VERS) -RSMLINKS= $(RSMLINKSUNFIRE15K) -# sparcv9 links -RSMLIBSUNFIRE15K64 = $(RSMLIBSUNFIRE15K)/$(MACH64) -RSMLINKSUNFIRE15K64 = $(RSMLIBSUNFIRE15K64)/$(LIBLINKS) -RSMLINKREL64 = ../../../../SUNW,Sun-Fire/lib/rsmlib/$(MACH64)/$(LIBLINKS)$(VERS) -RSMLINKS64= $(RSMLINKSUNFIRE15K64) - -# There should be a mapfile here -MAPFILES = - -LIBS = $(DYNLIB) -SRCS = $(SRCDIR)/librsmwrsm.c $(SRCDIR)/wrsmlib.s -LDLIBS += -lc - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(ROOT)/usr/platform/sun4u/include -D_REENTRANT -AS_CPPFLAGS += -I$(ROOT)/usr/platform/sun4u/include -ASFLAGS += -D_ASM -P -xarch=v8plusa -K pic -sparcv9_XARCH = -xarch=v9a - -.KEEP_STATE: - -all: $(LIBS) - -# Only do lint for sparc platform -lint: $(MACH)_lint - -i386_lint: - -sparc_lint: lintcheck - -# Rule for compiling .s file -pics/wrsmlib.o: $(SRCDIR)/wrsmlib.s - $(COMPILE.s) -o $@ $(SRCDIR)/wrsmlib.s - $(POST_PROCESS_O) - -# Rules for creating RSMAPI-defined sym links -$(ROOTLIBDIR) $(ROOTLIBDIR64) $(RSMLIBSUNFIRE15K) $(RSMLIBSUNFIRE15K64): - $(INS.dir.root.bin) - -$(RSMLINKSUNFIRE15K): $(RSMLIBSUNFIRE15K) $(LIBS) - $(RM) $@; $(SYMLINK) $(RSMLINKREL) $@ - -$(RSMLINKSUNFIRE15K64): $(RSMLIBSUNFIRE15K) $(RSMLIBSUNFIRE15K64) $(LIBS) - $(RM) $@; $(SYMLINK) $(RSMLINKREL64) $@ - -include ../../Makefile.targ -include ../../../Makefile.psm diff --git a/usr/src/lib/wrsm/librsmwrsm.c b/usr/src/lib/wrsm/librsmwrsm.c deleted file mode 100644 index 5b1863699a..0000000000 --- a/usr/src/lib/wrsm/librsmwrsm.c +++ /dev/null @@ -1,1531 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * this library is the plugin module used by RSMAPI to communicate - * with the Wildcat RSM driver. The library offers functions to - * setup a connection with the driver, to enable users of RSMAPI to perform - * put, get and barrier operations. - */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <synch.h> -#include <assert.h> -#include <strings.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <sys/uio.h> - -#include <sys/rsm/rsmapi_common.h> -#include <sys/rsm/rsm_common.h> -#include <sys/rsm/rsmndi.h> -#include <sys/wrsm.h> -#include <sys/wrsm_plugin.h> -#include "librsmwrsm.h" - -#ifdef DEBUG - -#define PLUGIN_DEBUG 0x0001 -#define PLUGIN_WARN 0x0002 -#define PLUGIN_PUT 0x0004 -#define PLUGIN_GET 0x0008 -#define PLUGIN_BARRIER 0x0010 - -/* - * for debuging: - * - compile with DEBUG and set environment variable PLUGIN_VERBOSITY. - * PLUGIN_VERBOSITY = 0x1F to turn all ALL debug options - * or an OR'ed combination of: - * PLUGIN_DEBUG 0x0001 -This option is used for messages in all - * initialization functions and local functions - * (errors/failures use PLUGIN_WARN) - * PLUGIN_WARN 0x0002 - This option spans all areas, when ever error, - * or failure of any sort occurs. Minimally Set THIS ONE! - * PLUGIN_PUT 0x0004 - This option for all put related request. - * (errors/failures use PLUGIN_WARN) - * PLUGIN_GET 0x0008 - This option for all get related request - * (errors/failures use PLUGIN_WARN) - * PLUGIN_BARRIER 0x0010- This option for ALL barrier operations (close, open - * init, destroy, etc) - * Note, not all possible errors have a corresponding message printed. - */ -static void -plugin_debug_print(char *format, ...) -{ - va_list arglist; - - va_start(arglist, format); - (void) vfprintf(stderr, format, arglist); - va_end(arglist); -} -static int plugin_debug = 0; /* initialize to 0 */ - -#define DEBUGP(a, b) if (plugin_debug & (a)) plugin_debug_print b -#else -#define DEBUGP(a, b) { } -#endif -/* - * the following is based on wci_cluster_error_status_array_u defined - * in wci_regs.h. The plugin is unable to include wci_regs.h. Not - * only is wci_regs.h for use by Kernel modules, wci_regs.h can not - * be used with 32 bit applications. - */ - -typedef union { - struct wci_CESR { - uint32_t rsvd_z : 32; - uint32_t rsvd_x : 26; - uint32_t disable_fail_fast : 1; /* 5 */ - uint32_t not_valid : 1; /* 4 */ - uint32_t value : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_CESR_u; - - - -#define ASSERT assert -#define STRIPE_BIT(stripe, i) (((stripe) >> (i)) & (STRIPE_MASK)) - -/* Internal functions */ -static int wrsm_memseg_import_connect(rsmapi_controller_handle_t controller, - rsm_node_id_t node_id, rsm_memseg_id_t segment_id, - rsm_permission_t perm, rsm_memseg_import_handle_t *im_memseg); -static int wrsm_memseg_import_disconnect(rsm_memseg_import_handle_t im_memseg); -static int wrsm_memseg_import_get8(rsm_memseg_import_handle_t im_memseg, - off_t offset, uint8_t *datap, ulong_t rep_cnt, boolean_t swap); -static int wrsm_memseg_import_get16(rsm_memseg_import_handle_t im_memseg, - off_t offset, uint16_t *datap, ulong_t rep_cnt, boolean_t swap); -static int wrsm_memseg_import_get32(rsm_memseg_import_handle_t im_memseg, - off_t offset, uint32_t *datap, ulong_t rep_cnt, boolean_t swap); -static int wrsm_memseg_import_get64(rsm_memseg_import_handle_t im_memseg, - off_t offset, uint64_t *datap, ulong_t rep_cnt, boolean_t swap); -static int wrsm_memseg_import_get(rsm_memseg_import_handle_t im_memseg, - off_t offset, void *dst_addr, size_t length); -static int wrsm_memseg_import_put8(rsm_memseg_import_handle_t im_memseg, - off_t offset, uint8_t *data, ulong_t rep_cnt, boolean_t swap); -static int wrsm_memseg_import_put16(rsm_memseg_import_handle_t im_memseg, - off_t offset, uint16_t *data, ulong_t rep_cnt, boolean_t swap); -static int wrsm_memseg_import_put32(rsm_memseg_import_handle_t im_memseg, - off_t offset, uint32_t *data, ulong_t rep_cnt, boolean_t swap); -static int wrsm_memseg_import_put64(rsm_memseg_import_handle_t im_memseg, - off_t offset, uint64_t *data, ulong_t rep_cnt, boolean_t swap); -static int wrsm_memseg_import_put(rsm_memseg_import_handle_t im_memseg, - off_t offset, void *src_addr, size_t length); -static int wrsm_memseg_import_init_barrier(rsm_memseg_import_handle_t - im_memseg, rsm_barrier_type_t type, rsm_barrier_handle_t barrier); -static int wrsm_memseg_import_open_barrier(rsm_barrier_handle_t barrier); -static int wrsm_memseg_import_order_barrier(rsm_barrier_handle_t barrier); -static int wrsm_memseg_import_close_barrier(rsm_barrier_handle_t barrier); -static int wrsm_memseg_import_destroy_barrier(rsm_barrier_handle_t barrier); -static int wrsm_memseg_import_get_mode(rsm_memseg_import_handle_t im_memseg, - rsm_barrier_mode_t *mode); -static int wrsm_memseg_import_set_mode(rsm_memseg_import_handle_t im_memseg, - rsm_barrier_mode_t mode); -static int wrsm_memseg_import_putv(rsm_scat_gath_t *sg_io); -static int wrsm_memseg_import_getv(rsm_scat_gath_t *sg_io); -static int wrsm_create_localmemory_handle(rsmapi_controller_handle_t controller, - rsm_localmemory_handle_t *local_handle_p, caddr_t local_vaddr, size_t len); -static int wrsm_free_localmemory_handle(rsm_localmemory_handle_t local_handle); -static int wrsm_register_lib_funcs(rsm_lib_funcs_t *libfuncs); -static int wrsm_get_lib_attr(rsm_ndlib_attr_t **libattr); -static int wrsm_closedevice(rsmapi_controller_handle_t controller); - -static rsm_ndlib_attr_t wrsm_rsm_ndlib_attr = { - B_TRUE, - B_TRUE -}; -static rsm_segops_t wrsm_ops = { - RSM_LIB_VERSION, - wrsm_memseg_import_connect, - wrsm_memseg_import_disconnect, - wrsm_memseg_import_get8, - wrsm_memseg_import_get16, - wrsm_memseg_import_get32, - wrsm_memseg_import_get64, - wrsm_memseg_import_get, - wrsm_memseg_import_put8, - wrsm_memseg_import_put16, - wrsm_memseg_import_put32, - wrsm_memseg_import_put64, - wrsm_memseg_import_put, - wrsm_memseg_import_init_barrier, - wrsm_memseg_import_open_barrier, - wrsm_memseg_import_order_barrier, - wrsm_memseg_import_close_barrier, - wrsm_memseg_import_destroy_barrier, - wrsm_memseg_import_get_mode, - wrsm_memseg_import_set_mode, - wrsm_memseg_import_putv, - wrsm_memseg_import_getv, - wrsm_create_localmemory_handle, - wrsm_free_localmemory_handle, - wrsm_register_lib_funcs, - wrsm_get_lib_attr, - wrsm_closedevice -}; - -static rsm_lib_funcs_t *rsm_lib_funcs; - -/* list of file descriptors */ -static opened_controllers_t opened_ctrls_fd[MAXCONTROLLERS] = -{{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}, -{0, -1, -1}, {0, -1, -1}, {0, -1, -1}, {0, -1, -1}}; - -static wrsmlib_raw_message_t cachelinebufscratch; /* write/read barrier use */ - - -/* - * local function used to return a page aligned aligned structure - */ -static void * -wrsmlib_align(wrsmlib_raw_message_t *raw_msg) -{ - void *addr; - - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: wrsmlib_align\n")); - - addr = (void *)(((uintptr_t)raw_msg + (uintptr_t)WRSMLIB_ALIGN) & - ~(uintptr_t)WRSMLIB_CACHELINE_MASK); - - return (addr); - -} - - -/* - * writes and then reads to barrier scractchpage up to two way link striping - * and 4 way wci striping during the close_barrier that is called for - * a put routine. It is needed to flush out the buffer - * to assure that the transaction has made it to the remote node. - */ -static void -write_read_scratchpage(plugin_barrier_t *bar) -{ - int i; - caddr_t scratch_addr; - caddr_t aligned_cacheline; - - /* - * wrsmlib_blkcopy does a membar sync before, during and after - * writes/reads. - */ - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: write_read_scratchpage\n ")); - ASSERT(bar); - - /* No need to check data, since we check wci_error_cluster_count */ - - aligned_cacheline = (caddr_t)wrsmlib_align(&cachelinebufscratch); - - /* write all request */ - for (i = 0; i < (MAXWCISTRIPING * 2); i++) { - if (STRIPE_BIT(*bar->importsegp->stripingp, i)) { - scratch_addr = bar->importsegp->barrier_scratch_addr + - STRIPE_STRIDE * i; - DEBUGP(PLUGIN_BARRIER, (" librsmwrsm: " - "write_read_scratchpage write for %dth stripe " - "offset,addr is 0x%lx \n", i, scratch_addr)); - wrsmlib_blkcopy(aligned_cacheline, scratch_addr, 1); - } - } - - /* read all request */ - for (i = 0; i < (MAXWCISTRIPING * 2); i++) { - if (STRIPE_BIT(*bar->importsegp->stripingp, i)) { - scratch_addr = bar->importsegp->barrier_scratch_addr + - STRIPE_STRIDE * i; - DEBUGP(PLUGIN_BARRIER, (" librsmwrsm: " - "write_read_scratchpag read for %dth stripe " - "offset, addr is 0x%lx \n", i, scratch_addr)); - wrsmlib_blkcopy(scratch_addr, aligned_cacheline, 1); - } - } -} - -/* - * sum's up all the wci_cluster_error_count at the first four - * offsets in barrier_ncslice page (mapped in, in the connect call) - * if the striping bit is set for that offset - * The relation between which bit is set and at what offset to read is as - * follows: - * starting at barriermap->ncslice_addr - * If Bit 0 is set, stripe offset 0 - * If Bit 1 is set, stripe offset 128 - * IF Bit 2 is set, stripe offset 256 (+ 128 from the previous) - * If Bit 3 is set, stripe offset 384 (128 chunks) - */ -static void -sum_cluster_error_count(plugin_barrier_t *bar, uint64_t *total) -{ - int i; - - /* - * the location of the wci_cluster_error_count in ncslice page 0 - * is (based on wci -2 prm) byte offset 64. - */ - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: sum_cluster_error_count" - " barrier_ncslice addr start is %p \n", - bar->importsegp->barrier_ncslice_addr)); - - *total = 0; - for (i = 0; i < MAXWCISTRIPING; i++) { - /* - * STRIPE_STRIDE * i - is the start pointer between - * striping, and SAFARI_OFFSET is the offset into the - * location that the wci_cluster_error_count can be found - */ - if (STRIPE_BIT(*bar->importsegp->stripingp, i)) { - /* LINTED */ - *total += *((uint64_t *) - (bar->importsegp->barrier_ncslice_addr - + (STRIPE_STRIDE * i) + SAFARI_OFFSET)); - } - } - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: sum_cluster_error_count" - " total is %ld\n", *total)); -} - -/* gets at most 64 bytes of len from a single cacheline */ -static int -small_get(rsm_memseg_import_handle_t im_memseg, off_t offset, uint_t len, - caddr_t buf) -{ - wrsmlib_raw_message_t cachelinebuf; - caddr_t aligned_cacheline = (caddr_t)wrsmlib_align(&cachelinebuf); - off_t read_offset; - off_t cacheline_offset; - caddr_t seg; - plugin_importseg_t *importsegp; - - importsegp = RSMNDI_SEG_GETPRIV(im_memseg); - ASSERT(importsegp); - DEBUGP(PLUGIN_GET, ("librsmwrsm: small_get controller num %d," - " segment_id %d\n", RSMNDI_SEG_GETUNIT(im_memseg), - importsegp->segment_id)); - - if (!importsegp->isloopback) { - /* offset into aligned cacheline */ - cacheline_offset = offset & WRSMLIB_CACHELINE_MASK; - ASSERT((cacheline_offset + len) <= WRSMLIB_CACHELINE_SIZE); - - /* - * aligned offset relevant to which cacheline to copy from - * segment so mask out the lower 14 bits - */ - read_offset = offset & ~WRSMLIB_CACHELINE_MASK; - - seg = RSMNDI_GET_MAPADDR(im_memseg, read_offset); - ASSERT(seg); - - /* get entire cacheline starting at seg */ - wrsmlib_blkcopy(seg, aligned_cacheline, 1); - - /* - * copy requested len of bytes at cacheline_offset - * into buf - */ - bcopy(aligned_cacheline + cacheline_offset, buf, len); - } else { - /* If we're in loopback, just copy */ - seg = RSMNDI_GET_MAPADDR(im_memseg, offset); - bcopy(seg, buf, len); - } - - return (RSM_SUCCESS); -} - -/* - * local function that performs the meat of the close_barrier routine - * using the plugin's barrier structure. the use of this function is - * needed because when the IMPLICIT barriers are done, there is - * no way to pass the RSMAPI defined barrier structure of which is - * considered to be an opaque type according to the plugin. - * When flag is set to TRUE, close_barrier request is due to a put - * request, hence write_read_scratchpage is required, or the call request - * is due to an EXPLICIT barrier and we do not know wether or not the - * data request was a read or a write. - */ -static int -close_barrier(plugin_barrier_t *bar, boolean_t flag) -{ - uint64_t wci_cluster_error_count_final; - - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: close_barrier\n")); - - ASSERT(bar && bar->importsegp); - - if (bar->importsegp->isloopback) { - /* export_cnode = local cnode, loopback mode */ - return (RSM_SUCCESS); - } - /* - * If set to FAILED, return RSMERR_BARRIER_FAILURE - * rerouting occured on open_barrier - */ - if (bar->state == BARRIER_FAILED) { - return (RSMERR_BARRIER_FAILURE); - } - /* If set to OPENED, then open_barrier was not previously called */ - if (bar->state != BARRIER_OPENED) { - return (RSMERR_BARRIER_NOT_OPENED); - } - - bar->state = BARRIER_CLOSED; - - /* only write/read scratch page on puts done with implicit barriers */ - if (flag) { - write_read_scratchpage(bar); - } - sum_cluster_error_count(bar, &wci_cluster_error_count_final); - if (bar->wci_cluster_error_count_initial != - wci_cluster_error_count_final) { - /* span of time errors occured - fail */ - DEBUGP(PLUGIN_WARN, ("librsmwrsm: WARNING close barrier " - "cluster errors detected (initial != final) FAIL\n")); - return (RSMERR_BARRIER_FAILURE); - - } - - if (*bar->importsegp->reroutingp || (bar->route_counter != - *bar->importsegp->route_counterp)) { - DEBUGP(PLUGIN_WARN, ("librsmwrsm: WARNING close barrier" - "failure: either routing is changing %d (should be 0)\n" - "\t or route has changed: initial route = %d and should " - " be equal to final route = %d\n", - *bar->importsegp->reroutingp, bar->route_counter, - *bar->importsegp->route_counterp)); - return (RSMERR_BARRIER_FAILURE); - } - - return (RSM_SUCCESS); - - -} - -/* - * local function that performs the meat of the open_barrier routine - * using the plugin's barrier structure. the use of this function is - * needed because when the IMPLICIT barriers are done, there is - * no way to pass the RSMAPI defined barrier structure of which is - * considered to be an opaque type according to the plugin. - */ -static int -open_barrier(plugin_barrier_t *bar) -{ - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: open_barrier \n")); - ASSERT(bar && bar->importsegp); - - if (bar->importsegp->isloopback) { - /* export_cnode = local cnode, loopback mode */ - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: open_barrier - " - "LOOPBACK\n")); - return (RSM_SUCCESS); - } - - /* if reroutingp is set, driver is in process of route change */ - ASSERT(bar->importsegp->reroutingp); - if (*bar->importsegp->reroutingp) { - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: open_barrier - " - "FAILURE occuring - rerouting in progress" - "this will cause close barriers to FAIL\n")); - bar->state = BARRIER_FAILED; - return (RSM_SUCCESS); - } - - bar->state = BARRIER_OPENED; - bar->route_counter = bar->importsegp->init_route_counter; - - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: open_barrier\n")); - - /* - * by using the bar->importsegp->init_route_counter initialzied - * in the connect call, we avoid taking the lock for every - * call to open_barrier. instead, we only take the barrier lock - * when there is a route change. - */ - if (bar->route_counter != *bar->importsegp->route_counterp) { - /* - * if these don't match then there has been a route change - * we must now update the importseg->init_route_counter - * and the local bar->route_counter (used for comparison in - * close) recall importseg->route_counterp, is actually the - * read only pointer to the drivers address space. - */ - (void) mutex_lock(&bar->importsegp->segmutex); - - /* - * bar->route_counter will be used later for comparison - * in close_barrier which will check it against the drivers - * counter - *bar->importseg->route_counterp. - */ - - bar->route_counter = bar->importsegp->init_route_counter = - *bar->importsegp->route_counterp; - (void) mutex_unlock(&bar->importsegp->segmutex); - } - - sum_cluster_error_count(bar, &bar->wci_cluster_error_count_initial); - return (RSM_SUCCESS); -} - -/* - * Initialization routine called from rsm library framework - */ -int -wrsm_opendevice(int unit, rsm_segops_t **ops) -{ - int tmpfd; - char devicename[12]; - rsm_addr_t args; - -#ifdef DEBUG - char *env; - - /* set debug variables */ - if (env = getenv("PLUGIN_VERBOSITY")) { - /* LINTED cast from 64-bit integer to 32-bit integer */ - plugin_debug = (int) - strtol(env, (char **)NULL, 0); - } else { - plugin_debug = 0; - } - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: plugin_debug is 0x%x \n", - plugin_debug)); -#endif - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: wrsm_opendevice controller " - "%d\n", unit)); - - (void) sprintf(devicename, "/dev/wrsm%d", unit); - - if (opened_ctrls_fd[unit].fd == -1) { - /* first opendevice called, initialize count */ - opened_ctrls_fd[unit].open_controller_count = 1; - tmpfd = open(devicename, O_RDWR); - } else { - /* - * device already opened - keep count of number of times - * requested so that we only call the device's close - * routine once. This will save us the hassle of keeping - * track of additional fd's. - */ - ASSERT(opened_ctrls_fd[unit].fd >= 0); - opened_ctrls_fd[unit].open_controller_count++; - return (RSM_SUCCESS); - } - - if (tmpfd == -1) { - if (errno == ENOENT) { - /* no config exist for this controller */ - return (RSMERR_BAD_CTLR_HNDL); - } else { - return (RSMERR_CTLR_NOT_PRESENT); - } - } - - /* - * libc can only handle fd < 256 - * because of this, other libraries need to request fd >= 256 - */ - if ((opened_ctrls_fd[unit].fd = fcntl(tmpfd, F_DUPFD, 256)) == -1) { - /* than keep tmpfd */ - opened_ctrls_fd[unit].fd = tmpfd; - } else { - /* close tmpfd since new fd was assigned */ - (void) close(tmpfd); - } - - /* get local cnode - for use with loopback */ - if (ioctl(opened_ctrls_fd[unit].fd, - WRSM_CTLR_PLUGIN_GETLOCALNODE, &args) == 0) { - opened_ctrls_fd[unit].local_cnode = args; - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: local cnode is %d \n", - opened_ctrls_fd[unit].local_cnode)); - } else { - /* - * If a local cnode is not returned, that is because - * the controller is not part of network. - */ - DEBUGP(PLUGIN_WARN, ("librsmwrsm: wrsm_opendevice -" - "controller %d not part of network \n", unit)); - return (RSMERR_CTLR_NOT_PRESENT); - } - *ops = &wrsm_ops; - - /* initialize for use in read_write_barrier_scratch routine */ - (void) - memset(cachelinebufscratch, 0xFF, sizeof (wrsmlib_raw_message_t)); - - return (RSM_SUCCESS); -} - -/* set RSMAPI approved error based on errno coming from the driver/mmap call */ -static int -seterr() -{ - int retval; - switch (errno) { - case ENXIO: - case EINVAL: - retval = RSMERR_BAD_CTLR_HNDL; - break; - case ENODEV: - retval = RSMERR_CTLR_NOT_PRESENT; - break; - case EACCES: - retval = RSMERR_PERM_DENIED; - break; - case ENOMEM: - retval = RSMERR_INSUFFICIENT_MEM; - break; - case EPROTO: - retval = RSMERR_SEG_NOT_PUBLISHED; - break; - case EHOSTUNREACH: - retval = RSMERR_REMOTE_NODE_UNREACHABLE; - break; - case ENOTSUP: - case EOVERFLOW: - case EAGAIN: - case EBADF: - retval = RSMERR_INTERRUPTED; - break; - default: - /* unknown return value from mmap */ - DEBUGP(PLUGIN_WARN, ("librsmwrsm: ERROR: mmap returned %d\n", - errno)); - retval = RSMERR_INTERRUPTED; - } - - return (retval); -} - -/* ARGSUSED */ -static int -wrsm_memseg_import_connect(rsmapi_controller_handle_t controller, - rsm_node_id_t node_id, rsm_memseg_id_t segment_id, rsm_permission_t perm, - rsm_memseg_import_handle_t *im_memseg) -{ - int prot; - int ctrl_num; - wrsm_plugin_offset_t pseudo_offset; - rsm_addr_t export_cnodeid; - plugin_importseg_t *importsegp; - int err = 0; - - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: wrsm_memseg_import_connect \n")); - - ctrl_num = (int)RSMNDI_CNTRLR_GETUNIT(controller); - - if ((err = rsm_lib_funcs->rsm_get_hwaddr(controller, node_id, - &export_cnodeid)) != RSM_SUCCESS) { - return (err); - } - importsegp = (plugin_importseg_t *)malloc(sizeof (plugin_importseg_t)); - - if (importsegp == NULL) { - return (RSMERR_INSUFFICIENT_MEM); - } - - /* iniitialize plugin specific importseg */ - importsegp->segment_id = segment_id; - importsegp->export_cnodeid = export_cnodeid; - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: wrsm_memseg_import_connect" - " controller number is %d, segid is %d cnodeid %lld\n", - ctrl_num, segment_id, export_cnodeid)); - - ASSERT(ctrl_num >= 0 && ctrl_num <= MAXCONTROLLERS); - - /* determine if we should be doing loopback ie, export_cnode = local */ - if (opened_ctrls_fd[ctrl_num].local_cnode == export_cnodeid) { - importsegp->isloopback = B_TRUE; - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: connect - LOOPBACK mode" - "\n")); - } else { - importsegp->isloopback = B_FALSE; - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm:*** connect NOT in Loopback " - " mode \n")); - } - - /* if not loopback test, set up driver mappings */ - if (!importsegp->isloopback) { - /* prepare generic part of pseudo offset */ - pseudo_offset.bit.segment_id = segment_id; - /* cnodeids are never > 255 that is why we can cast this */ - pseudo_offset.bit.export_cnodeid = (unsigned char) - export_cnodeid; - - /* - * Remote memory scratch page used by close barrier to ensure - * completion of previous writes - */ - pseudo_offset.bit.page_type = WRSM_MMAP_BARRIER_SCRATCH; - prot = PROT_READ | PROT_WRITE; - if ((importsegp->barrier_scratch_addr = - mmap64(NULL, WRSM_PAGESIZE, prot, MAP_SHARED, - opened_ctrls_fd[ctrl_num].fd, pseudo_offset.val)) - == MAP_FAILED) { - DEBUGP(PLUGIN_WARN, ("librsmwrsm: mmap Barrier" - " scratch failed on controller number %d export" - " cnode %d errno %d.\n", ctrl_num, - pseudo_offset.bit.export_cnodeid, errno)); - return (seterr()); - } - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: mmap of BARRIER Scratch " - " successfull addr = %p for importsegp %p \n", - importsegp->barrier_scratch_addr, importsegp)); - - /* - * Local WCI error registers to check during barrier close, in - * particular, the plugin is currently only interested in - * wci_cluster_error_count that is assesible via ncslice page 0 - */ - pseudo_offset.bit.page_type = WRSM_MMAP_BARRIER_REGS; - prot = PROT_READ | PROT_WRITE; - - if ((importsegp->barrier_ncslice_addr = - mmap64(NULL, WRSM_PAGESIZE, prot, MAP_SHARED, - opened_ctrls_fd[ctrl_num].fd, pseudo_offset.val)) - == MAP_FAILED) { - DEBUGP(PLUGIN_WARN, ("librsmwrsm: mmap Barrier" - " REGS failed on controller number %d export" - " cnode %ld.\n", ctrl_num, export_cnodeid)); - return (seterr()); - } - - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: mmap of BARRIER_REGS " - "succesfull addr = %p for importsegp %p\n", - importsegp->barrier_ncslice_addr, importsegp)); - /* - * the wci wrsm driver maps the rerouting and the route_counter - * and striping (refered to by the driver as link_stripesp) - * into one address space. the plugin mmaps that address space - * route_info_addr, and then, for clarity, reads them with more - * meaningful names. - */ - pseudo_offset.bit.page_type = WRSM_MMAP_RECONFIG; - prot = PROT_READ; - - if ((importsegp->route_info_addr = - mmap64(NULL, WRSM_PAGESIZE, prot, MAP_SHARED, - opened_ctrls_fd[ctrl_num].fd, pseudo_offset.val)) - == MAP_FAILED) { - DEBUGP(PLUGIN_WARN, ("LIBRSMWRSM: mmap reconfig cntr" - " failed on controller number %d export " - " cnode %ld.\n", ctrl_num, export_cnodeid)); - return (seterr()); - } - /* - * a counter of the number of times the route have changed - * plugin needs to confirm that the number hasn't changed - * between a barrier open and a barrier close - */ - ASSERT(importsegp->route_info_addr); - - /* LINTED */ - importsegp->route_counterp = (uint32_t *) - importsegp->route_info_addr; - /* - * if reroutingp is > 0, then a rerouting in progress, - * barier_open and barrier_close need to check this. - */ - /* LINTED */ - importsegp->reroutingp = (uint32_t *) - (importsegp->route_info_addr + sizeof (uint32_t)); - - /* needed to determine which stripe offsets to read */ - /* LINTED */ - importsegp->stripingp = (uint32_t *) - (importsegp->route_info_addr + (2 * sizeof (uint32_t))); - - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: Mapped ROUTE info initial " - "addr is %p *route_counterp %d\n\t and rerouting %d " - "(should be 0) and striping DATA 0x%x for importsegp %p\n", - importsegp->route_info_addr, *importsegp->route_counterp, - *importsegp->reroutingp, *importsegp->stripingp, - importsegp)); - - /* - * initialize init_route_counter. if init_route_counter doesn't - * ever differ from the drivers route_counter - * (*importsegp->route_counterp) we know that routing has - * not changed. - */ - - importsegp->init_route_counter = *importsegp->route_counterp; - } - importsegp->barrier_mode = RSM_BARRIER_MODE_IMPLICIT; /* default */ - - if (mutex_init(&importsegp->segmutex, USYNC_THREAD, NULL) != 0) { - DEBUGP(PLUGIN_WARN, ("librsmwrsm: ERROR unable to allocate " - "space for mutex\n")); - (void) munmap(importsegp->route_info_addr, WRSM_PAGESIZE); - (void) munmap(importsegp->barrier_scratch_addr, WRSM_PAGESIZE); - (void) munmap(importsegp->barrier_ncslice_addr, WRSM_PAGESIZE); - return (RSMERR_INSUFFICIENT_MEM); - } - - RSMNDI_SEG_SETPRIV(*im_memseg, importsegp); - return (RSM_SUCCESS); -} - - -static int -wrsm_memseg_import_disconnect(rsm_memseg_import_handle_t im_memseg) -{ - plugin_importseg_t *importsegp; - int error = RSM_SUCCESS; - - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: wrsm_memseg_import_disconnect\n")); - importsegp = (plugin_importseg_t *)RSMNDI_SEG_GETPRIV(im_memseg); - ASSERT(importsegp); - - (void) mutex_destroy(&importsegp->segmutex); - if (!importsegp->isloopback) { - if (importsegp->route_info_addr == NULL) { - DEBUGP(PLUGIN_WARN, ("librsmwrsm: WARNING:" - "route_info_addr is NULL\n")); - error = RSMERR_BAD_SEG_HNDL; - } else { - (void) munmap(importsegp->route_info_addr, - WRSM_PAGESIZE); - } - if (importsegp->barrier_scratch_addr == NULL) { - DEBUGP(PLUGIN_WARN, ("librsmwrsm: WARNING:" - "barrier_scratch_addr is NULL\n")); - error = RSMERR_BAD_SEG_HNDL; - } else { - (void) munmap(importsegp->barrier_scratch_addr, - WRSM_PAGESIZE); - } - if (importsegp->barrier_ncslice_addr == NULL) { - DEBUGP(PLUGIN_WARN, ("librsmwrsm: WARNING: " - "barrier_ncslice_addr is NULL\n")); - error = RSMERR_BAD_SEG_HNDL; - } else { - (void) munmap(importsegp->barrier_ncslice_addr, - WRSM_PAGESIZE); - } - } - free(importsegp); - - return (error); -} - -/* ARGSUSED */ -static int -wrsm_memseg_import_get8(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint8_t *datap, ulong_t rep_cnt, boolean_t swap) -{ - size_t len = (size_t)(sizeof (uint8_t) * rep_cnt); - - return (wrsm_memseg_import_get(im_memseg, offset, (void *)datap, len)); -} - -/* ARGSUSED */ -static int -wrsm_memseg_import_get16(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint16_t *datap, ulong_t rep_cnt, boolean_t swap) -{ - size_t len = (size_t)(sizeof (uint16_t) * rep_cnt); - - /* Check for valid alignment */ - if ((((uintptr_t)datap & 0x1) != 0) || - (((uint64_t)offset & 0x1) != 0)) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - return (wrsm_memseg_import_get(im_memseg, offset, (void *)datap, len)); -} - -/* ARGSUSED */ -static int -wrsm_memseg_import_get32(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint32_t *datap, ulong_t rep_cnt, boolean_t swap) -{ - size_t len = (size_t)(sizeof (uint32_t) * rep_cnt); - - /* Check for valid alignment */ - if ((((uintptr_t)datap & 0x3) != 0) || - (((uint64_t)offset & 0x3) != 0)) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - return (wrsm_memseg_import_get(im_memseg, offset, (void *)datap, len)); -} - -/* ARGSUSED */ -static int -wrsm_memseg_import_get64(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint64_t *datap, ulong_t rep_cnt, boolean_t swap) -{ - size_t len = (size_t)(sizeof (uint64_t) * rep_cnt); - - /* Check for valid alignment */ - if ((((uintptr_t)datap & 0x7) != 0) || - (((uint64_t)offset & 0x7) != 0)) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - return (wrsm_memseg_import_get(im_memseg, offset, (void *)datap, len)); -} - -/* - * from segment addr, get len bytes starting at offset returned in dst_addr - * caller must gauruntee that the offset + len doesn't exceed segment size. - */ -static int -wrsm_memseg_import_get(rsm_memseg_import_handle_t im_memseg, off_t offset, - void *dst_addr, size_t len) -{ - wrsmlib_raw_message_t cachelinebuf; - caddr_t aligned_cacheline = (caddr_t)wrsmlib_align(&cachelinebuf); - - uint_t partial_cacheline; - uint_t num_cachelines; - int err = 0; - caddr_t dp = dst_addr; - plugin_importseg_t *importsegp; - caddr_t seg; - plugin_barrier_t bar_implicit; - -#ifdef DEBUG - int ctrl_num = RSMNDI_SEG_GETUNIT(im_memseg); -#endif /* DEBUG */ - - DEBUGP(PLUGIN_GET, ("librsmwrsm: wrsm_memseg_import_get\n")); - ASSERT(dst_addr); - - if (len == 0) { - return (RSM_SUCCESS); - } - - importsegp = (plugin_importseg_t *)RSMNDI_SEG_GETPRIV(im_memseg); - ASSERT(importsegp); - -#ifdef DEBUG - DEBUGP(PLUGIN_GET, ("librsmwrsm: wrsm_memseg_import_get controller" - " num %d, segment_id %d\n", ctrl_num, importsegp->segment_id)); -#endif - - if (importsegp->barrier_mode == RSM_BARRIER_MODE_IMPLICIT) { - bar_implicit.importsegp = importsegp; - DEBUGP(PLUGIN_GET, ("librsmwrsm: wrsm_get BARRIER IMPLICIT " - " mode \n")); - if ((err = open_barrier(&bar_implicit)) != RSM_SUCCESS) { - return (err); - } - } - - /* handle partial cacheline read at start of buffer */ - - if (offset & WRSMLIB_CACHELINE_MASK) { - DEBUGP(PLUGIN_GET, ("librsmwrsm: wrsm_memseg_import_get " - "partial, start of buf at offset 0x%lx " - "length %ld \n", offset, len)); - /* get length within given cacheline */ - partial_cacheline = WRSMLIB_CACHELINE_SIZE - ((uint_t)offset & - WRSMLIB_CACHELINE_MASK); - if (partial_cacheline > (uint_t)len) - partial_cacheline = (uint_t)len; - - if ((err = small_get(im_memseg, offset, partial_cacheline, dp)) - != RSM_SUCCESS) { - if (importsegp->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - (void) close_barrier(&bar_implicit, B_FALSE); - return (err); - } - } - - if (len == 0) { - if (importsegp->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - return (close_barrier(&bar_implicit, B_FALSE)); - - } else { - return (RSM_SUCCESS); - } - } - /* increment to next unread part in buffer */ - len -= partial_cacheline; - dp += partial_cacheline; - offset += partial_cacheline; - } - - - /* handle cacheline size reads */ - num_cachelines = (uint_t)(len >> WRSMLIB_CACHELINE_SHIFT); - if (num_cachelines) { - uint_t total_cachelines_size; - total_cachelines_size = num_cachelines * WRSMLIB_CACHELINE_SIZE; - DEBUGP(PLUGIN_GET, ("librsmwrsm: wrsm_memseg_import_get " - "for %d num_cachelines at offset 0x%lx length %ld\n", - num_cachelines, offset, len)); - - /* get virtual address of offset in mapped segment */ - seg = RSMNDI_GET_MAPADDR(im_memseg, offset); - ASSERT(seg); - - if (((uintptr_t)dp & (uintptr_t)WRSMLIB_CACHELINE_MASK) - == 0) { - /* aligned cacheline - this is to be fixed */ - if (!importsegp->isloopback) { - wrsmlib_blkcopy(seg, dp, num_cachelines); - } else { - bcopy(seg, dp, total_cachelines_size); - } - dp += total_cachelines_size; - } else { - while (num_cachelines) { - if (!importsegp->isloopback) { - wrsmlib_blkcopy(seg, aligned_cacheline, - 1); - bcopy(aligned_cacheline, dp, - WRSMLIB_CACHELINE_SIZE); - } else { - bcopy(seg, dp, WRSMLIB_CACHELINE_SIZE); - } - dp += WRSMLIB_CACHELINE_SIZE; - seg += WRSMLIB_CACHELINE_SIZE; - num_cachelines--; - } - } - len -= total_cachelines_size; - offset += total_cachelines_size; - } - - /* get partial cacheline at end of buffer */ - if (len) { - DEBUGP(PLUGIN_GET, ("librsmwrsm: wrsm_memseg_import_get " - "end of buf at offset 0x%lx length %ld\n", - offset, len)); - if ((err = small_get(im_memseg, offset, (uint_t)len, dp)) - != RSM_SUCCESS) { - if (importsegp->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - (void) close_barrier(&bar_implicit, B_FALSE); - } - return (err); - } - } - if (importsegp->barrier_mode == RSM_BARRIER_MODE_IMPLICIT) { - err = close_barrier(&bar_implicit, B_FALSE); - } - return (err); -} - -/* ARGSUSED */ -static int -wrsm_memseg_import_put8(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint8_t *datap, ulong_t rep_cnt, boolean_t swap) -{ - size_t len = (size_t)(sizeof (uint8_t) * rep_cnt); - - return (wrsm_memseg_import_put(im_memseg, offset, (void *)datap, len)); -} - -/* ARGSUSED */ -static int -wrsm_memseg_import_put16(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint16_t *datap, ulong_t rep_cnt, boolean_t swap) -{ - size_t len = (size_t)(sizeof (uint16_t) * rep_cnt); - - /* Check for valid alignment */ - if ((((uintptr_t)datap & 0x1) != 0) || - (((uint64_t)offset & 0x1) != 0)) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - return (wrsm_memseg_import_put(im_memseg, offset, (void *)datap, len)); -} - -/* ARGSUSED */ -static int -wrsm_memseg_import_put32(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint32_t *datap, ulong_t rep_cnt, boolean_t swap) -{ - size_t len = (size_t)(sizeof (uint32_t) * rep_cnt); - - /* Check for valid alignment */ - if ((((uintptr_t)datap & 0x3) != 0) || - (((uint64_t)offset & 0x3) != 0)) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - return (wrsm_memseg_import_put(im_memseg, offset, (void *)datap, len)); -} - -/* ARGSUSED */ -static int -wrsm_memseg_import_put64(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint64_t *datap, ulong_t rep_cnt, boolean_t swap) -{ - size_t len = (size_t)(sizeof (uint64_t) * rep_cnt); - - /* Check for valid alignment */ - if ((((uintptr_t)datap & 0x7) != 0) || - (((uint64_t)offset & 0x7) != 0)) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - return (wrsm_memseg_import_put(im_memseg, offset, (void *)datap, len)); -} - -static int -wrsm_memseg_import_put(rsm_memseg_import_handle_t im_memseg, off_t offset, - void *src_addr, size_t length) -{ - uint_t partial_cacheline; - uint_t num_cachelines; - int err = 0; - plugin_importseg_t *importsegp; - caddr_t seg; - msg_pluginput_args_t args; /* to pass args to driver via ioctl */ - int ctrl_num; - plugin_barrier_t bar_implicit; - - DEBUGP(PLUGIN_PUT, ("librsmwrsm: wrsm_memseg_import_put \n")); - - importsegp = RSMNDI_SEG_GETPRIV(im_memseg); - ASSERT(importsegp); - ASSERT(src_addr); - - ctrl_num = RSMNDI_SEG_GETUNIT(im_memseg); - - if (length == 0) { - return (RSM_SUCCESS); - } - - /* set unchanging fields in msgargs */ - args.remote_cnodeid = importsegp->export_cnodeid; - args.segment_id = importsegp->segment_id; - - /* set msgargs.buf to src_addr - increment/decrement using buf */ - args.buf = src_addr; - - if (importsegp->barrier_mode == RSM_BARRIER_MODE_IMPLICIT) { - bar_implicit.importsegp = importsegp; - DEBUGP(PLUGIN_PUT, ("librsmwrsm: wrsm...put Implicit" - " Barriers\n")); - if ((err = open_barrier(&bar_implicit)) != - RSM_SUCCESS) { - return (err); - } - } - - /* - * WARNING - if thread-barriers are supported, small put errors must - * be recorded because these errors are currently recorded in the CESR - * register but they are cleared by the driver prior to return from - * the ioctl. - */ - - /* handle partial line write at start of buff */ - if (offset & WRSMLIB_CACHELINE_MASK) { - DEBUGP(PLUGIN_PUT, ("librsmwrsm: partial write, start " - " of buf for controller %d, and segid %d offset 0x%lx" - " length %ld buf addr %p export_cnode %d\n", - ctrl_num, args.segment_id, offset, length, - (void *)args.buf, importsegp->export_cnodeid)); - partial_cacheline = WRSMLIB_CACHELINE_SIZE - ((uint_t)offset & - WRSMLIB_CACHELINE_MASK); - if (partial_cacheline > (uint_t)length) - partial_cacheline = (uint_t)length; - - args.offset = offset; - args.len = partial_cacheline; - - if (!importsegp->isloopback) { - if ((err = ioctl(opened_ctrls_fd[ctrl_num].fd, - WRSM_CTLR_PLUGIN_SMALLPUT, &args)) != 0) { - if (importsegp->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - (void) close_barrier(&bar_implicit, - B_TRUE); - } - DEBUGP(PLUGIN_PUT, ("librsmwrsm: partial " - "write, start of buf for controller %d, " - "and segid %d IOCTL failed with err %d " - "errno is %d\n", - ctrl_num, args.segment_id, err, errno)); - return (RSMERR_BARRIER_FAILURE); - } - } else { - seg = RSMNDI_GET_MAPADDR(im_memseg, offset); - bcopy(args.buf, seg, partial_cacheline); - } - length -= partial_cacheline; - args.buf += partial_cacheline; - offset += partial_cacheline; - - if (length == 0) { - if (importsegp->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - return (close_barrier(&bar_implicit, B_TRUE)); - } else { - return (RSM_SUCCESS); - } - } - } - - - /* handle cacheline size writes */ - num_cachelines = (uint_t)(length >> WRSMLIB_CACHELINE_SHIFT); - - if (num_cachelines) { - uint_t total_cachelines_size; - total_cachelines_size = num_cachelines * WRSMLIB_CACHELINE_SIZE; - - seg = RSMNDI_GET_MAPADDR(im_memseg, offset); - ASSERT(seg); - DEBUGP(PLUGIN_PUT, ("librsmwrsm: full cachelines ctrl_num " - " %d offset 0x%lx length %ld \n", ctrl_num, offset, - length)); - if (importsegp->isloopback) { - bcopy(args.buf, seg, - num_cachelines * WRSMLIB_CACHELINE_SIZE); - } else { - /* - * args.buf (ie. src_addr) can be any alignment - * and dst is cacheline aligned so we can - * wrsmlib_blkwrite once to send all cachelines - */ - wrsmlib_blkwrite(args.buf, seg, num_cachelines); - } - args.buf += total_cachelines_size; - length -= total_cachelines_size; - offset += total_cachelines_size; - } - - /* handle partial cacheline write at end of buffer */ - - if (length) { - DEBUGP(PLUGIN_PUT, ("librsmwrsm: writes at end of buffer " - "for ctrl_num %d segment id %d offset 0x%lx length " - "%d export cnode %d\n", ctrl_num, args.segment_id, - offset, length, importsegp->export_cnodeid)); - args.offset = offset; - args.len = length; - if (!importsegp->isloopback) { - if ((err = ioctl(opened_ctrls_fd[ctrl_num].fd, - WRSM_CTLR_PLUGIN_SMALLPUT, &args)) != 0) { - if (importsegp->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - (void) close_barrier(&bar_implicit, - B_TRUE); - } - DEBUGP(PLUGIN_PUT, ("librsmwrsm: partial " - "write, end of buf for controller %d, " - "and segid %d IOCTL FAILED WITH ERR %d " - "errno is %d\n", - ctrl_num, args.segment_id, err, errno)); - return (RSMERR_BARRIER_FAILURE); - } - } else { - seg = RSMNDI_GET_MAPADDR(im_memseg, offset); - bcopy(args.buf, seg, length); - } - } - - if (importsegp->barrier_mode == RSM_BARRIER_MODE_IMPLICIT) { - return (close_barrier(&bar_implicit, B_TRUE)); - } else { - return (RSM_SUCCESS); - } - -} - -static int -wrsm_memseg_import_init_barrier(rsm_memseg_import_handle_t im_memseg, - rsm_barrier_type_t type, rsm_barrier_handle_t barrier) -{ - plugin_barrier_t *bar; - plugin_importseg_t *importsegp; - - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: wrsm...init_barrier \n")); - - importsegp = RSMNDI_SEG_GETPRIV(im_memseg); - ASSERT(importsegp); - - bar = (plugin_barrier_t *)malloc(sizeof (plugin_barrier_t)); - if (bar == NULL) { - return (RSMERR_INSUFFICIENT_RESOURCES); - } - bar->importsegp = importsegp; - bar->importsegp->barrier_type = type; - bar->state = BARRIER_CLOSED; - RSMNDI_BARRIER_SETPRIV(barrier, bar); - return (RSM_SUCCESS); -} - - -static int -wrsm_memseg_import_open_barrier(rsm_barrier_handle_t barrier) -{ - plugin_barrier_t *bar; - int err = 0; - - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: " - "wrsm_memseg_import_open_barrier\n")); - bar = (plugin_barrier_t *)RSMNDI_BARRIER_GETPRIV(barrier); - - err = open_barrier(bar); - - return (err); -} - -static int -wrsm_memseg_import_order_barrier(rsm_barrier_handle_t barrier) -{ - - plugin_barrier_t *bar; - int err = 0; - - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: " - "wrsm_memseg_import_order_barrier\n")); - bar = (plugin_barrier_t *)RSMNDI_BARRIER_GETPRIV(barrier); - err = close_barrier(bar, B_TRUE); - /* - * to allow code reuse, we call close_barrier here since order_barrier - * and close barrier perform the same function expect that - * order_barrier does not change the barrier_state to CLOSED. We set - * it back to opened here so that close_barrier doesn't need to - * perform and additional check - */ - bar->state = BARRIER_OPENED; - return (err); -} - -static int -wrsm_memseg_import_close_barrier(rsm_barrier_handle_t barrier) -{ - plugin_barrier_t *bar; - int err = 0; - - bar = (plugin_barrier_t *)RSMNDI_BARRIER_GETPRIV(barrier); - - err = close_barrier(bar, B_TRUE); - - return (err); - - -} - -static int -wrsm_memseg_import_destroy_barrier(rsm_barrier_handle_t barrier) -{ - plugin_barrier_t *bar; - - DEBUGP(PLUGIN_BARRIER, ("librsmwrsm: " - "wrsm_memseg_import_destroy_barrier\n")); - bar = (plugin_barrier_t *)RSMNDI_BARRIER_GETPRIV(barrier); - if (bar) - free(bar); - return (RSM_SUCCESS); -} - -static int -wrsm_memseg_import_get_mode(rsm_memseg_import_handle_t im_memseg, - rsm_barrier_mode_t *mode) -{ - plugin_importseg_t *importsegp; - - importsegp = (plugin_importseg_t *)RSMNDI_SEG_GETPRIV(im_memseg); - ASSERT(importsegp); - - (void) mutex_lock(&importsegp->segmutex); - *mode = importsegp->barrier_mode; - (void) mutex_unlock(&importsegp->segmutex); - - return (RSM_SUCCESS); -} - -static int -wrsm_memseg_import_set_mode(rsm_memseg_import_handle_t im_memseg, - rsm_barrier_mode_t mode) -{ - plugin_importseg_t *importsegp; - importsegp = (plugin_importseg_t *)RSMNDI_SEG_GETPRIV(im_memseg); - ASSERT(importsegp); - - (void) mutex_lock(&importsegp->segmutex); - importsegp->barrier_mode = mode; - (void) mutex_unlock(&importsegp->segmutex); - - return (RSM_SUCCESS); -} - -static int -wrsm_memseg_import_putv(rsm_scat_gath_t *sg_io) -{ - rsm_iovec_t *iovec; - int64_t i; - int err = 0; - - DEBUGP(PLUGIN_PUT, ("librsmwrsm: wrsm_memseg_import_putv \n")); - - /* - * iovec for Wildcat always just uses local.vaddr - */ - iovec = sg_io->iovec; - for (i = 0; i < sg_io->io_request_count; i++) { - DEBUGP(PLUGIN_PUT, ("librsmwrsm: wrsm_memseg_import_putv " - "offset %d, length %d \n", iovec->local_offset, - iovec->transfer_length)); - err = wrsm_memseg_import_put(sg_io->remote_handle, - iovec->remote_offset, - iovec->local.vaddr + iovec->local_offset, - iovec->transfer_length); - if (err != RSM_SUCCESS) { - DEBUGP(PLUGIN_WARN, ("librsmwrsm: WARNING" - " wrsm_memseg_import_putv err detected\n")); - /* - * set io_residual_count to the number of putv's that - * failed including this one. - */ - sg_io->io_residual_count = - sg_io->io_request_count - i + 1; - return (err); - } - iovec++; - } - sg_io->io_residual_count = 0; - return (err); -} - -static int -wrsm_memseg_import_getv(rsm_scat_gath_t *sg_io) -{ - rsm_iovec_t *iovec; - int64_t i; - int err = 0; - - DEBUGP(PLUGIN_GET, ("librsmwrsm: wrsm_memseg_import_getv \n")); - - /* - * iovec for Wildcat always just uses local.vaddr - */ - iovec = sg_io->iovec; - for (i = 0; i < sg_io->io_request_count; i++) { - DEBUGP(PLUGIN_GET, ("librsmwrsm: wrsm_memseg_import_getv " - "offset %d, length %d \n", iovec->local_offset, - iovec->transfer_length)); - err = wrsm_memseg_import_get(sg_io->remote_handle, - iovec->remote_offset, - iovec->local.vaddr + iovec->local_offset, - iovec->transfer_length); - if (err != RSM_SUCCESS) { - DEBUGP(PLUGIN_WARN, ("librsmwrsm: WARNING" - " wrsm_memseg_import_getv err detected\n")); - /* - * set io_residual_count to the number of getv's that - * failed including this one. - */ - sg_io->io_residual_count = - sg_io->io_request_count - i + 1; - return (err); - } - iovec++; - } - sg_io->io_residual_count = 0; - return (err); -} - - -/* ARGSUSED */ -static int -wrsm_create_localmemory_handle(rsmapi_controller_handle_t controller, - rsm_localmemory_handle_t *local_handle_p, - caddr_t local_vaddr, size_t len) -{ - *local_handle_p = (rsm_localmemory_handle_t)local_vaddr; - return (RSM_SUCCESS); -} - -/* ARGSUSED */ -static int -wrsm_free_localmemory_handle(rsm_localmemory_handle_t local_handle) -{ - return (RSM_SUCCESS); -} - - -static int -wrsm_register_lib_funcs(rsm_lib_funcs_t *libfuncs) -{ - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: wrsm_register_lib_funcs \n")); - rsm_lib_funcs = libfuncs; - return (RSM_SUCCESS); -} - - -static int -wrsm_get_lib_attr(rsm_ndlib_attr_t **libattr) -{ - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: wrsm_get_lib_attr\n")); - *libattr = &wrsm_rsm_ndlib_attr; - return (RSM_SUCCESS); -} - - - -/* - * the kernel will call the drivers close only on the last close of - * for all open instances. Hence, this close routines spares the kernel - * the added work, and only request a close on the last close. By doing - * this, we save ourselves the hassle of keeping track of additional - * fd. - */ -static int -wrsm_closedevice(rsmapi_controller_handle_t controller) -{ - int ctrl_num; - - ctrl_num = (int)RSMNDI_CNTRLR_GETUNIT(controller); - DEBUGP(PLUGIN_DEBUG, ("librsmwrsm: wrsm_closedevice controller " - "%d\n", ctrl_num)); - - if (opened_ctrls_fd[ctrl_num].open_controller_count > 0) { - if ((--opened_ctrls_fd[ctrl_num].open_controller_count) == 0) { - (void) close(opened_ctrls_fd[ctrl_num].fd); - opened_ctrls_fd[ctrl_num].fd = -1; - } - } - return (RSM_SUCCESS); - -} diff --git a/usr/src/lib/wrsm/librsmwrsm.h b/usr/src/lib/wrsm/librsmwrsm.h deleted file mode 100644 index 78a148fd24..0000000000 --- a/usr/src/lib/wrsm/librsmwrsm.h +++ /dev/null @@ -1,124 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _LIBRSMWRSM_H -#define _LIBRSMWRSM_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Private Header file for librsmwrsm.c */ - -#define WRSMLIB_CACHELINE_SIZE 64 -#define WRSMLIB_ALIGN 64 -#define WRSMLIB_CACHELINE_SHIFT 6 -#define WRSMLIB_CACHELINE_MASK (WRSMLIB_CACHELINE_SIZE - 1) -/* - * number of controllers is set by the wrsm.conf file. as there is no - * way to dynamically relay this information to the plugin library, - * maxcontrollers is set here to the maximum number of controllers a system - * could ever have. - */ -#define MAXCONTROLLERS 64 -#define STRIPE_STRIDE 128 -#define SAFARI_OFFSET 64 -#define MAXWCISTRIPING 4 -#define STRIPE_MASK 1 - - -typedef unsigned char wrsm_barrier_state_t; -#define BARRIER_CLOSED ((wrsm_barrier_state_t)0xff) -#define BARRIER_OPENED ((wrsm_barrier_state_t)0xfe) -#define BARRIER_FAILED ((wrsm_barrier_state_t)0xfd) - -/* - * The following type may be allocated on the stack, then using the function - * wrsmlib_align a properly aligned message buffer is extracted. - * once wrsmlib_blkcopy is fixed - alignment here won't be needed - */ -typedef uint8_t wrsmlib_raw_message_t[WRSMLIB_CACHELINE_SIZE + WRSMLIB_ALIGN]; - -/* plugin specific structures */ -typedef struct { - mutex_t segmutex; - boolean_t isloopback; /* when export cnode - local cnode */ - rsm_barrier_mode_t barrier_mode; /* implicit or explicit barrier */ - rsm_barrier_type_t barrier_type; - rsm_memseg_id_t segment_id; - caddr_t barrier_scratch_addr; /* barrier scratch page */ - caddr_t barrier_ncslice_addr; /* page 0 of ncslice */ - caddr_t route_info_addr; /* start of route change data */ - uint32_t init_route_counter; /* set on open = *reconfig_ctr_addr */ - uint32_t *route_counterp; /* route counter pointer - read only */ - uint32_t *reroutingp; /* in process of ncslice rerouting - read only */ - uint32_t *stripingp; - rsm_addr_t export_cnodeid; -} plugin_importseg_t; - - -/* - * this struct is a static array in the plugin. for each controller, - * it maintains the related opened (> 0) file descriptors and the count - * for the number of open request on that controller. the library will - * request the driver to close the controller on the last close request for - * that particular controller. - */ -typedef struct { - rsm_addr_t local_cnode; - int open_controller_count; - int fd; -} opened_controllers_t; - -typedef struct { - wrsm_barrier_state_t state; /* whether opened or closed */ - uint32_t route_counter; /* init in open and checked in close */ - uint64_t wci_cluster_error_count_initial; - plugin_importseg_t *importsegp; -} plugin_barrier_t; - - -/* - * Performs a 64-byte block copy, used for remote read/write/interrupts. - * Assumes both addresses are 64-byte aligned, and does no checking. - */ -void -wrsmlib_blkcopy(void *src, void *dst, uint_t num_blocks); - -/* - * Performs a 64-byte block store, used for remote writes. - * Assumes that the dst addr is 64-byte aligned, and does no checking. - */ -void -wrsmlib_blkwrite(void *src, void *dst, uint_t num_blocks); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBRSMWRSM_H */ diff --git a/usr/src/lib/wrsm/sparc/Makefile b/usr/src/lib/wrsm/sparc/Makefile deleted file mode 100644 index 885f1a865f..0000000000 --- a/usr/src/lib/wrsm/sparc/Makefile +++ /dev/null @@ -1,32 +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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#ident "%Z%%M% %I% %E% SMI" -# -# lib/librsmwrsm/sparc/Makefile - -include ../Makefile.com - -install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(RSMLINKS) diff --git a/usr/src/lib/wrsm/sparcv9/Makefile b/usr/src/lib/wrsm/sparcv9/Makefile deleted file mode 100644 index 5ec76dedb3..0000000000 --- a/usr/src/lib/wrsm/sparcv9/Makefile +++ /dev/null @@ -1,33 +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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#ident "%Z%%M% %I% %E% SMI" -# -# lib/librsmwrsm/sparcv9/Makefile - -include ../Makefile.com -include ../../Makefile.lib.64 - -install: all $(ROOTLIBDIR64) $(ROOTLIBS64) $(ROOTLINKS64) $(RSMLINKS64) diff --git a/usr/src/lib/wrsm/wrsmlib.s b/usr/src/lib/wrsm/wrsmlib.s deleted file mode 100644 index a5aeff9a0c..0000000000 --- a/usr/src/lib/wrsm/wrsmlib.s +++ /dev/null @@ -1,443 +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 2001,2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * TL1 trap handler for DMV interrupts generated by WCIs - * Note: You must build sun4u/genassym before assembling this file. - */ - -#if defined(lint) -#include <sys/types.h> -#else -#include <sys/asm_linkage.h> -#include <sys/fsr.h> -#include <sys/sun4asi.h> -#endif /* lint */ - -/* - * Zero the parts of the fpreg file that we actually use - * ( 1 or 3 sets of 8 registers ) - */ -#define FZERO1 \ - fzero %f0 ;\ - fzero %f2 ;\ - faddd %f0, %f2, %f4 ;\ - fmuld %f0, %f2, %f6 ;\ - faddd %f0, %f2, %f8 ;\ - fmuld %f0, %f2, %f10 ;\ - faddd %f0, %f2, %f12 ;\ - fmuld %f0, %f2, %f14 - -#define FZERO3 \ - fzero %f0 ;\ - fzero %f2 ;\ - faddd %f0, %f2, %f4 ;\ - fmuld %f0, %f2, %f6 ;\ - faddd %f0, %f2, %f8 ;\ - fmuld %f0, %f2, %f10 ;\ - faddd %f0, %f2, %f12 ;\ - fmuld %f0, %f2, %f14 ;\ - faddd %f0, %f2, %f16 ;\ - fmuld %f0, %f2, %f18 ;\ - faddd %f0, %f2, %f20 ;\ - fmuld %f0, %f2, %f22 ;\ - faddd %f0, %f2, %f24 ;\ - fmuld %f0, %f2, %f26 ;\ - faddd %f0, %f2, %f28 ;\ - fmuld %f0, %f2, %f30 ;\ - faddd %f0, %f2, %f32 ;\ - fmuld %f0, %f2, %f34 ;\ - faddd %f0, %f2, %f36 ;\ - fmuld %f0, %f2, %f38 ;\ - faddd %f0, %f2, %f40 ;\ - fmuld %f0, %f2, %f42 ;\ - faddd %f0, %f2, %f44 ;\ - fmuld %f0, %f2, %f46 - -/* - * Size of each block being stored - */ -#define VIS_BLOCKSIZE 64 - -/* - * Size of stack frame in order to accomodate 64-byte aligned - * floating-point register save area and a 64-bit temp locations. - */ -#define BLKCOPYFRAMESIZE ((VIS_BLOCKSIZE * 2) + 8) -#define BCOPY_FPREGS_OFFSET (VIS_BLOCKSIZE * 2) -#define BCOPY_FPREGS_ADJUST (VIS_BLOCKSIZE - 1) -#define BCOPY_FPRS_OFFSET (BCOPY_FPREGS_OFFSET + 8) - -#define BLKWRITEFRAMESIZE ((VIS_BLOCKSIZE * 4) + 8) -#define BWRITE_FPREGS_OFFSET (VIS_BLOCKSIZE * 4) -#define BWRITE_FPREGS_ADJUST ((VIS_BLOCKSIZE * 3) - 1) -#define BWRITE_FPRS_OFFSET (BWRITE_FPREGS_OFFSET + 8) - - -#if defined(lint) -/* ARGSUSED */ -void -wrsmlib_blkcopy(void *src, void *dst, uint_t num_blocks) -{} -#else /* !lint */ -! -! Move a single cache line of data. Survive UE and CE on the read. -! The source and destination must both be 64-byte aligned. -! -! %i0 = src va -! %i1 = dst va -! %i2 = num_blocks -! %i4 = cache of fpu state -! -! XXX redo to allow for case of misaligned data - ENTRY(wrsmlib_blkcopy) - - save %sp, -SA(MINFRAME + BLKCOPYFRAMESIZE), %sp - -#ifndef BCOPY_BUG_FIXED - membar #Sync ! protect against bcopy bug -#endif - rd %fprs, %i4 - st %i4, [%fp + STACK_BIAS - BCOPY_FPRS_OFFSET] ! save orig %fprs - btst FPRS_FEF, %i4 - bz,a 1f - wr %g0, FPRS_FEF, %fprs - - ! save in-use fpregs on stack - membar #Sync - add %fp, STACK_BIAS - BCOPY_FPREGS_ADJUST, %o2 - and %o2, -VIS_BLOCKSIZE, %o2 - stda %d0, [%o2]ASI_BLK_P - membar #Sync - - tst %i2 ! set CC -1: - ! Perform block move - bz,pn %icc, 2f ! (always 32-bit) while (%i2 > 0) { - nop - ldda [%i0] ASI_BLK_P, %d0 ! tmp = *src; -#ifdef WRSM_NOCHEETAH - membar #Sync ! not needed by Cheetah -#endif - stda %d0, [%i1] ASI_BLK_P ! *dst = tmp; - membar #Sync - add %i0, VIS_BLOCKSIZE, %i0 ! src++; - add %i1, VIS_BLOCKSIZE, %i1 ! dst++; - ba 1b ! branch back to 1: - deccc %i2 ! %i2-- ;} -2: - ! restore fp to the way we got it - ld [%fp + STACK_BIAS - BCOPY_FPRS_OFFSET], %i4 - btst FPRS_FEF, %i4 - bz,a 3f ! branch forward to label 3: - nop - - ! restore fpregs from stack - add %fp, STACK_BIAS - BCOPY_FPREGS_ADJUST, %o2 - and %o2, -VIS_BLOCKSIZE, %o2 - ldda [%o2] ASI_BLK_P, %d0 - membar #Sync - - ba 4f - wr %i4, 0, %fprs -3: - FZERO1 - wr %i4, 0, %fprs ! fpu back to the way it was -4: - ret - restore - SET_SIZE(wrsmlib_blkcopy) -#endif /* lint */ - -/* - * Number of bytes needed to "break even" using VIS-accelerated - * memory operations. - */ -#define HW_THRESHOLD 256 - -/* - * Number of outstanding prefetches. - */ -#define CHEETAH_PREFETCH 7 - -#if defined(lint) -/* ARGSUSED */ -void -wrsmlib_blkwrite(void *src, void *dst, uint_t num_blocks) -{} -#else /* !lint */ -! -! Copy multiple cache lines of data by prefetching into P$. -! The destination address must be 64-byte aligned. -! -! %i0 = src va -! %i1 = dst va -! %i2 = num_blocks -! %i4 = cache of fpu state - - ENTRY(wrsmlib_blkwrite) - - save %sp, -SA(MINFRAME + BLKWRITEFRAMESIZE), %sp - -#ifndef BCOPY_BUG_FIXED - membar #Sync ! protect against bcopy bug -#endif - - sllx %i2, 6, %i2 ! convert blocks to bytes - - rd %fprs, %i4 - st %i4, [%fp + STACK_BIAS - BWRITE_FPRS_OFFSET] - btst FPRS_FEF, %i4 - bz,a .do_blkcopy - wr %g0, FPRS_FEF, %fprs ! always enable FPU - -.fpregs_inuse: - - ! save in-use fpregs on stack - membar #Sync - add %fp, STACK_BIAS - BWRITE_FPREGS_ADJUST, %o2 - and %o2, -VIS_BLOCKSIZE, %o2 - stda %d0, [%o2]ASI_BLK_P - add %o2, VIS_BLOCKSIZE, %o2 - stda %d16, [%o2]ASI_BLK_P - add %o2, VIS_BLOCKSIZE, %o2 - stda %d32, [%o2]ASI_BLK_P - membar #Sync - -.do_blkcopy: - -#define REALSRC %i0 -#define DST %i1 -#define CNT %i2 -#define SRC %i3 - - cmp CNT, HW_THRESHOLD ! for lesser than HW_THRESHOLD - blu %ncc, .slow_copy ! branch to slow_copy - .empty - -1: membar #StoreLoad - alignaddr REALSRC, %g0, SRC - - ! SRC - 8-byte aligned - ! DST - 64-byte aligned - prefetch [SRC], #one_read - prefetch [SRC + (1 * VIS_BLOCKSIZE)], #one_read - prefetch [SRC + (2 * VIS_BLOCKSIZE)], #one_read - prefetch [SRC + (3 * VIS_BLOCKSIZE)], #one_read - ldd [SRC], %f0 -#if CHEETAH_PREFETCH >= 4 - prefetch [SRC + (4 * VIS_BLOCKSIZE)], #one_read -#endif - ldd [SRC + 0x8], %f2 -#if CHEETAH_PREFETCH >= 5 - prefetch [SRC + (5 * VIS_BLOCKSIZE)], #one_read -#endif - ldd [SRC + 0x10], %f4 -#if CHEETAH_PREFETCH >= 6 - prefetch [SRC + (6 * VIS_BLOCKSIZE)], #one_read -#endif - faligndata %f0, %f2, %f32 - ldd [SRC + 0x18], %f6 -#if CHEETAH_PREFETCH >= 7 - prefetch [SRC + (7 * VIS_BLOCKSIZE)], #one_read -#endif - faligndata %f2, %f4, %f34 - ldd [SRC + 0x20], %f8 - faligndata %f4, %f6, %f36 - ldd [SRC + 0x28], %f10 - faligndata %f6, %f8, %f38 - ldd [SRC + 0x30], %f12 - faligndata %f8, %f10, %f40 - ldd [SRC + 0x38], %f14 - faligndata %f10, %f12, %f42 - ldd [SRC + VIS_BLOCKSIZE], %f0 - sub CNT, VIS_BLOCKSIZE, CNT - add SRC, VIS_BLOCKSIZE, SRC ! Inc src - add REALSRC, VIS_BLOCKSIZE, REALSRC ! Inc realsrc - ba,a,pt %ncc, 2f - .align 32 -2: - ldd [SRC + 0x8], %f2 - faligndata %f12, %f14, %f44 - ldd [SRC + 0x10], %f4 - faligndata %f14, %f0, %f46 - stda %f32, [DST] ASI_BLK_P ! Store cache line - ldd [SRC + 0x18], %f6 - faligndata %f0, %f2, %f32 - ldd [SRC +0x20], %f8 - faligndata %f2, %f4, %f34 - ldd [SRC+ 0x28], %f10 - faligndata %f4, %f6, %f36 - ldd [SRC + 0x30], %f12 - faligndata %f6, %f8, %f38 - ldd [SRC + 0x38], %f14 - faligndata %f8, %f10, %f40 - ldd [SRC + VIS_BLOCKSIZE], %f0 - prefetch [SRC + (CHEETAH_PREFETCH * VIS_BLOCKSIZE)], #one_read - faligndata %f10, %f12, %f42 - sub CNT, VIS_BLOCKSIZE, CNT ! Dec cnt - add DST, VIS_BLOCKSIZE, DST ! Inc dst - add REALSRC, VIS_BLOCKSIZE, REALSRC ! Inc dst - cmp CNT, VIS_BLOCKSIZE + 8 - bgu,pt %ncc, 2b - add SRC, VIS_BLOCKSIZE, SRC ! Inc src - - ! only if REALSRC & 0x7 is 0 - andcc REALSRC, 0x7, %g0 - bz %ncc, 4f - nop - -3: - ldd [SRC + 0x8], %f2 - faligndata %f12, %f14, %f44 - ldd [SRC + 0x10], %f4 - faligndata %f14, %f0, %f46 - stda %f32, [DST] ASI_BLK_P ! Store cache line - ldd [SRC + 0x18], %f6 - faligndata %f0, %f2, %f32 - ldd [SRC +0x20], %f8 - faligndata %f2, %f4, %f34 - ldd [SRC+ 0x28], %f10 - faligndata %f4, %f6, %f36 - ldd [SRC + 0x30], %f12 - faligndata %f6, %f8, %f38 - ldd [SRC + 0x38], %f14 - faligndata %f8, %f10, %f40 - ldd [SRC + VIS_BLOCKSIZE], %f0 - faligndata %f10, %f12, %f42 - add REALSRC, VIS_BLOCKSIZE, REALSRC ! Inc realsrc - sub CNT, VIS_BLOCKSIZE, CNT ! Dec cnt - add DST, VIS_BLOCKSIZE, DST ! Inc dst - faligndata %f12, %f14, %f44 - faligndata %f14, %f0, %f46 - stda %f32, [DST] ASI_BLK_P ! Store cache line - ba 5f - add SRC, VIS_BLOCKSIZE, SRC ! Inc src -4: - ldd [SRC + 0x08], %f2 - fsrc1 %f12, %f44 - ldd [SRC + 0x10], %f4 - fsrc1 %f14, %f46 - stda %f32, [DST]ASI_BLK_P - ldd [SRC + 0x18], %f6 - ldd [SRC + 0x20], %f8 - ldd [SRC + 0x28], %f10 - ldd [SRC + 0x30], %f12 - ldd [SRC + 0x38], %f14 - sub CNT, VIS_BLOCKSIZE, CNT - add DST, VIS_BLOCKSIZE, DST - add REALSRC, VIS_BLOCKSIZE, REALSRC - stda %f0, [DST]ASI_BLK_P - ba 5f - add SRC, VIS_BLOCKSIZE, SRC -5: -.copy_exit: - membar #StoreLoad|#StoreStore - - ! restore fp to the way we got it - ld [%fp + STACK_BIAS - BWRITE_FPRS_OFFSET], %i4 - btst FPRS_FEF, %i4 - bz,a 6f ! branch to label 5 - nop - - ! restore fpregs from stack - membar #Sync - add %fp, STACK_BIAS - BWRITE_FPREGS_ADJUST, %o2 - and %o2, -VIS_BLOCKSIZE, %o2 - ldda [%o2]ASI_BLK_P, %d0 - add %o2, VIS_BLOCKSIZE, %o2 - ldda [%o2]ASI_BLK_P, %d16 - add %o2, VIS_BLOCKSIZE, %o2 - ldda [%o2]ASI_BLK_P, %d32 - membar #Sync - - ba 7f - wr %i4, 0, %fprs ! restore fprs -6: - FZERO3 ! zero all of the fpregs - wr %i4, 0, %fprs ! change fpu way it was -7: - ret - restore - -.slow_copy: - - andcc REALSRC, 0x7, %g0 - bz %ncc, 9f - alignaddr REALSRC, %g0, SRC - -8: cmp CNT, %g0 - ble,pn %ncc, .copy_exit - nop - ldd [SRC], %f0 - ldd [SRC + 0x08], %f2 - ldd [SRC + 0x10], %f4 - faligndata %f0, %f2, %f32 - ldd [SRC + 0x18], %f6 - faligndata %f2, %f4, %f34 - ldd [SRC + 0x20], %f8 - faligndata %f4, %f6, %f36 - ldd [SRC + 0x28], %f10 - faligndata %f6, %f8, %f38 - ldd [SRC + 0x30], %f12 - faligndata %f8, %f10, %f40 - ldd [SRC + 0x38], %f14 - faligndata %f10, %f12, %f42 - ldd [SRC + VIS_BLOCKSIZE], %f0 - sub CNT, VIS_BLOCKSIZE, CNT - add SRC, VIS_BLOCKSIZE, SRC - add REALSRC, VIS_BLOCKSIZE, REALSRC - faligndata %f12, %f14, %f44 - faligndata %f14, %f0, %f46 - stda %f32, [DST]ASI_BLK_P - ba 8b - add DST, VIS_BLOCKSIZE, DST - - ! SRC - 8-byte aligned - ! DST - 64-byte aligned - -9: cmp CNT, %g0 - ble,pn %ncc, .copy_exit - nop - ldd [SRC], %f0 - ldd [SRC + 0x08], %f2 - ldd [SRC + 0x10], %f4 - ldd [SRC + 0x18], %f6 - ldd [SRC + 0x20], %f8 - ldd [SRC + 0x28], %f10 - ldd [SRC + 0x30], %f12 - ldd [SRC + 0x38], %f14 - sub CNT, VIS_BLOCKSIZE, CNT - add SRC, VIS_BLOCKSIZE, SRC - add REALSRC, VIS_BLOCKSIZE, REALSRC - stda %f0, [DST]ASI_BLK_P - ba 9b - add DST, VIS_BLOCKSIZE, DST - - SET_SIZE(wrsmlib_blkwrite) -#endif /* lint */ diff --git a/usr/src/pkgdefs/Makefile b/usr/src/pkgdefs/Makefile index 178ee54bc4..c0b25b4e1f 100644 --- a/usr/src/pkgdefs/Makefile +++ b/usr/src/pkgdefs/Makefile @@ -96,11 +96,7 @@ sparc_SUBDIRS= \ SUNWstc.u \ SUNWus.u \ SUNWust1.v \ - SUNWust2.v \ - SUNWwrsa.u \ - SUNWwrsd.u \ - SUNWwrsm.u \ - SUNWwrsu.u + SUNWust2.v sparc_XMODS= diff --git a/usr/src/pkgdefs/SUNWdrcr.u/prototype_com b/usr/src/pkgdefs/SUNWdrcr.u/prototype_com index 9a001a5a01..d3620885ec 100644 --- a/usr/src/pkgdefs/SUNWdrcr.u/prototype_com +++ b/usr/src/pkgdefs/SUNWdrcr.u/prototype_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. @@ -22,7 +21,7 @@ # # ident "%Z%%M% %I% %E% SMI" # -# Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This required package information file contains a list of package contents. @@ -56,5 +55,4 @@ d none platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9 755 root sys f none platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9/drmach 755 root sys f none platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9/fcgp2 755 root sys f none platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9/gptwo_pci 755 root sys -f none platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9/gptwo_wci 755 root sys f none platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9/sc_gptwocfg 755 root sys diff --git a/usr/src/pkgdefs/SUNWhea/prototype_sparc b/usr/src/pkgdefs/SUNWhea/prototype_sparc index a1846c7c40..c4b1b43779 100644 --- a/usr/src/pkgdefs/SUNWhea/prototype_sparc +++ b/usr/src/pkgdefs/SUNWhea/prototype_sparc @@ -256,17 +256,6 @@ f none usr/platform/sun4u/include/sys/xc_impl.h 644 root bin f none usr/platform/sun4u/include/sys/x_call.h 644 root bin f none usr/platform/sun4u/include/sys/zsmach.h 644 root bin f none usr/platform/sun4u/include/sys/cvc.h 644 root bin -f none usr/platform/sun4u/include/sys/wci_common.h 644 root bin -f none usr/platform/sun4u/include/sys/wci_regs.h 644 root bin -f none usr/platform/sun4u/include/sys/wci_offsets.h 644 root bin -f none usr/platform/sun4u/include/sys/wci_cmmu.h 644 root bin -f none usr/platform/sun4u/include/sys/wrsm.h 644 root bin -f none usr/platform/sun4u/include/sys/wrsm_common.h 644 root bin -f none usr/platform/sun4u/include/sys/wrsm_config.h 644 root bin -f none usr/platform/sun4u/include/sys/wrsm_types.h 644 root bin -f none usr/platform/sun4u/include/sys/wrsm_plat.h 644 root bin -f none usr/platform/sun4u/include/sys/wrsm_plugin.h 644 root bin -f none usr/platform/sun4u/include/sys/wrsmconf.h 644 root bin d none usr/platform/sun4u/include/vm 755 root bin f none usr/platform/sun4u/include/vm/hat_sfmmu.h 644 root bin f none usr/platform/sun4u/include/vm/mach_sfmmu.h 644 root bin diff --git a/usr/src/pkgdefs/SUNWmdb/prototype_sparc b/usr/src/pkgdefs/SUNWmdb/prototype_sparc index 091e59fd23..7e6878d47e 100644 --- a/usr/src/pkgdefs/SUNWmdb/prototype_sparc +++ b/usr/src/pkgdefs/SUNWmdb/prototype_sparc @@ -87,8 +87,6 @@ d none usr/platform/sun4u/lib/mdb/kvm/sparcv9 755 root sys f none usr/platform/sun4u/lib/mdb/kvm/sparcv9/unix.so 555 root sys f none usr/platform/sun4u/lib/mdb/kvm/sparcv9/sgenv.so 555 root sys f none usr/platform/sun4u/lib/mdb/kvm/sparcv9/sgsbbc.so 555 root sys -f none usr/platform/sun4u/lib/mdb/kvm/sparcv9/wrsm.so 555 root sys -f none usr/platform/sun4u/lib/mdb/kvm/sparcv9/wrsmd.so 555 root sys f none usr/platform/sun4u/lib/mdb/kvm/sparcv9/oplhwd.so 555 root sys # d none usr/platform/sun4v 755 root sys diff --git a/usr/src/pkgdefs/SUNWmdbr/prototype_sparc b/usr/src/pkgdefs/SUNWmdbr/prototype_sparc index 631b7d29d8..99bb424c63 100644 --- a/usr/src/pkgdefs/SUNWmdbr/prototype_sparc +++ b/usr/src/pkgdefs/SUNWmdbr/prototype_sparc @@ -71,8 +71,6 @@ d none platform/sun4u/kernel/kmdb/sparcv9 755 root sys f none platform/sun4u/kernel/kmdb/sparcv9/sgenv 555 root sys f none platform/sun4u/kernel/kmdb/sparcv9/sgsbbc 555 root sys f none platform/sun4u/kernel/kmdb/sparcv9/unix 555 root sys -f none platform/sun4u/kernel/kmdb/sparcv9/wrsm 555 root sys -f none platform/sun4u/kernel/kmdb/sparcv9/wrsmd 555 root sys f none platform/sun4u/kernel/kmdb/sparcv9/oplhwd 555 root sys # d none platform/sun4v 755 root sys diff --git a/usr/src/pkgdefs/SUNWwrsa.u/Makefile b/usr/src/pkgdefs/SUNWwrsa.u/Makefile deleted file mode 100644 index ed0e331ce3..0000000000 --- a/usr/src/pkgdefs/SUNWwrsa.u/Makefile +++ /dev/null @@ -1,36 +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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#pragma ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -DATAFILES += depend - -all: $(FILES) -install: all pkg - -include ../Makefile.targ diff --git a/usr/src/pkgdefs/SUNWwrsa.u/pkginfo.tmpl b/usr/src/pkgdefs/SUNWwrsa.u/pkginfo.tmpl deleted file mode 100644 index af22136f53..0000000000 --- a/usr/src/pkgdefs/SUNWwrsa.u/pkginfo.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -# -# This required package information file describes characteristics of the -# package, such as package abbreviation, full package name, package version, -# and package architecture. -# -PKG="SUNWwrsa" -NAME="WCI Remote Shared Memory API Library" -ARCH="sparc.sun4u" -VERSION="ONVERS,REV=0.0.0" -SUNW_PRODNAME="SunOS" -SUNW_PRODVERS="RELEASE/VERSION" -SUNW_PKGTYPE="kvm" -MAXINST="1000" -CATEGORY="system" -DESC="Library to enable Remote Shared Memory over WCI interface" -VENDOR="Sun Microsystems, Inc." -HOTLINE="Please contact your local service provider" -EMAIL="" -CLASSES="none" -BASEDIR=/ -SUNW_PKGVERS=1.0 -SUNW_PKG_ALLZONES="true" -SUNW_PKG_HOLLOW="false" -SUNW_PKG_THISZONE="false" diff --git a/usr/src/pkgdefs/SUNWwrsa.u/prototype_sparc b/usr/src/pkgdefs/SUNWwrsa.u/prototype_sparc deleted file mode 100644 index e67463470a..0000000000 --- a/usr/src/pkgdefs/SUNWwrsa.u/prototype_sparc +++ /dev/null @@ -1,66 +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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#ident "%Z%%M% %I% %E% SMI" -# -# This required package information file contains a list of package contents. -# The 'pkgmk' command uses this file to identify the contents of a package -# and their location on the development machine when building the package. -# Can be created via a text editor or through use of the 'pkgproto' command. - -#!search <pathname pathname ...> # where to find pkg objects -#!include <filename> # include another 'prototype' file -#!default <mode> <owner> <group> # default used if not specified on entry -#!<param>=<value> # puts parameter in pkg environment - -# -# List files which are SPARC specific here -# -# source locations relative to the prototype file -# -i pkginfo -i copyright -i depend - -# Create directories -d none usr 0755 root sys -d none usr/platform 0755 root sys -d none usr/platform/SUNW,Sun-Fire 0755 root sys -d none usr/platform/SUNW,Sun-Fire/lib 0755 root bin -d none usr/platform/SUNW,Sun-Fire/lib/rsmlib 0755 root bin -d none usr/platform/SUNW,Sun-Fire/lib/rsmlib/sparcv9 0755 root bin -d none usr/platform/SUNW,Sun-Fire-15000 0755 root sys -d none usr/platform/SUNW,Sun-Fire-15000/lib 0755 root bin -d none usr/platform/SUNW,Sun-Fire-15000/lib/rsmlib 0755 root bin -d none usr/platform/SUNW,Sun-Fire-15000/lib/rsmlib/sparcv9 0755 root bin - -# Plug-in Library -f none usr/platform/SUNW,Sun-Fire/lib/rsmlib/sparcv9/wrsm.so.1 0755 root bin -f none usr/platform/SUNW,Sun-Fire/lib/rsmlib/wrsm.so.1 0755 root bin - -s none usr/platform/SUNW,Sun-Fire/lib/rsmlib/sparcv9/wrsm.so=wrsm.so.1 0777 root other -s none usr/platform/SUNW,Sun-Fire/lib/rsmlib/wrsm.so=wrsm.so.1 0777 root other -s none usr/platform/SUNW,Sun-Fire-15000/lib/rsmlib/sparcv9/wrsm.so=../../../../SUNW,Sun-Fire/lib/rsmlib/sparcv9/wrsm.so.1 0777 root other -s none usr/platform/SUNW,Sun-Fire-15000/lib/rsmlib/wrsm.so=../../../SUNW,Sun-Fire/lib/rsmlib/wrsm.so.1 0777 root other diff --git a/usr/src/pkgdefs/SUNWwrsd.u/Makefile b/usr/src/pkgdefs/SUNWwrsd.u/Makefile deleted file mode 100644 index 110a74b904..0000000000 --- a/usr/src/pkgdefs/SUNWwrsd.u/Makefile +++ /dev/null @@ -1,36 +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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#pragma ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -.KEEP_STATE: - -all: $(FILES) -install: all pkg - -include ../Makefile.targ diff --git a/usr/src/pkgdefs/SUNWwrsd.u/depend b/usr/src/pkgdefs/SUNWwrsd.u/depend deleted file mode 100644 index 6abe6b8cdb..0000000000 --- a/usr/src/pkgdefs/SUNWwrsd.u/depend +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright 2005 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, 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 -# -# ident "%Z%%M% %I% %E% SMI" -# -# This package information file defines software dependencies associated -# with the pkg. You can define three types of pkg dependencies with this file: -# P indicates a prerequisite for installation -# I indicates an incompatible package -# R indicates a reverse dependency -# <pkg.abbr> see pkginfo(4), PKG parameter -# <name> see pkginfo(4), NAME parameter -# <version> see pkginfo(4), VERSION parameter -# <arch> see pkginfo(4), ARCH parameter -# <type> <pkg.abbr> <name> -# (<arch>)<version> -# (<arch>)<version> -# ... -# <type> <pkg.abbr> <name> -# ... -# - -P SUNWrsmo RSMPI Operations Registration Module -P SUNWwrsm WCI Remote Shared Memory Drivers -P SUNWcar Core Architecture, (Root) -P SUNWcakr Core Solaris Kernel Architecture (Root) -P SUNWkvm Core Architecture, (Kvm) -P SUNWcsr Core Solaris, (Root) -P SUNWckr Core Solaris Kernel (Root) -P SUNWcnetr Core Solaris Network Infrastructure (Root) -P SUNWcsu Core Solaris, (Usr) -P SUNWcsd Core Solaris Devices -P SUNWcsl Core Solaris, (Shared Libs) diff --git a/usr/src/pkgdefs/SUNWwrsd.u/pkginfo.tmpl b/usr/src/pkgdefs/SUNWwrsd.u/pkginfo.tmpl deleted file mode 100644 index da2e927e51..0000000000 --- a/usr/src/pkgdefs/SUNWwrsd.u/pkginfo.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -# -# This required package information file describes characteristics of the -# package, such as package abbreviation, full package name, package version, -# and package architecture. -# -PKG="SUNWwrsd" -NAME="WCI RSM DLPI driver" -ARCH="sparc.sun4u" -VERSION="ONVERS,REV=0.0.0" -SUNW_PRODNAME="SunOS" -SUNW_PRODVERS="RELEASE/VERSION" -SUNW_PKGVERS=1.0 -SUNW_PKGTYPE="root" -MAXINST="1000" -CATEGORY="system" -DESC="DLPI Driver for use with the WCI Remote Shared Memory Driver" -VENDOR="Sun Microsystems, Inc." -HOTLINE="Please contact your local service provider" -EMAIL="" -CLASSES="none" -BASEDIR=/ -SUNW_PKG_ALLZONES="true" -SUNW_PKG_HOLLOW="true" -SUNW_PKG_THISZONE="false" diff --git a/usr/src/pkgdefs/SUNWwrsd.u/postinstall b/usr/src/pkgdefs/SUNWwrsd.u/postinstall deleted file mode 100644 index 4301afe9d9..0000000000 --- a/usr/src/pkgdefs/SUNWwrsd.u/postinstall +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# 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 -# -# -#pragma ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# - -PATH="/usr/bin:/usr/sbin:$PATH" -export PATH - -ADD_DRV="add_drv -b ${BASEDIR}" - -not_installed() { - driver=$1 - grep "^${driver} " ${BASEDIR}/etc/name_to_major > /dev/null 2>&1 - return $? -} - -EXIT=0 - -not_installed wrsmd || $ADD_DRV -m '* 0666 root sys' wrsmd || -EXIT=1 - -exit $EXIT diff --git a/usr/src/pkgdefs/SUNWwrsd.u/preremove b/usr/src/pkgdefs/SUNWwrsd.u/preremove deleted file mode 100644 index db7bf0fe9c..0000000000 --- a/usr/src/pkgdefs/SUNWwrsd.u/preremove +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh -# -# 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 -# -# -#pragma ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -# -if [ "${BASEDIR:=/}" = "/" ] -then - REM_DRV="rem_drv" -else - REM_DRV="rem_drv -b ${BASEDIR}" -fi - -if [ "${PKG_INSTALL_ROOT:-/}" = "/" ]; then - - # Unplumb any existing interfaces - for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - do - ifconfig wrsmd$i down >/dev/null 2>&1 - ifconfig wrsmd$i unplumb >/dev/null 2>&1 - done -fi - -$REM_DRV wrsmd - -exit 0 diff --git a/usr/src/pkgdefs/SUNWwrsd.u/prototype_sparc b/usr/src/pkgdefs/SUNWwrsd.u/prototype_sparc deleted file mode 100644 index e2ed533d63..0000000000 --- a/usr/src/pkgdefs/SUNWwrsd.u/prototype_sparc +++ /dev/null @@ -1,60 +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 (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -#ident "%Z%%M% %I% %E% SMI" -# -# This required package information file contains a list of package contents. -# The 'pkgmk' command uses this file to identify the contents of a package -# and their location on the development machine when building the package. -# Can be created via a text editor or through use of the 'pkgproto' command. - -#!search <pathname pathname ...> # where to find pkg objects -#!include <filename> # include another 'prototype' file -#!default <mode> <owner> <group> # default used if not specified on entry -#!<param>=<value> # puts parameter in pkg environment - -# -# List files which are SPARC specific here -# -# source locations relative to the prototype file -# -# SUNWwrsmd -# -i pkginfo -i copyright -i postinstall -i preremove -i depend - -# directories -d none platform 0755 root sys -d none platform/sun4u 0755 root sys -d none platform/sun4u/kernel 0755 root sys -d none platform/sun4u/kernel/drv 0755 root sys -d none platform/sun4u/kernel/drv/sparcv9 0755 root sys - -# driver -f none platform/sun4u/kernel/drv/wrsmd.conf 0644 root sys -f none platform/sun4u/kernel/drv/sparcv9/wrsmd 0755 root sys diff --git a/usr/src/pkgdefs/SUNWwrsm.u/Makefile b/usr/src/pkgdefs/SUNWwrsm.u/Makefile deleted file mode 100644 index eee3382284..0000000000 --- a/usr/src/pkgdefs/SUNWwrsm.u/Makefile +++ /dev/null @@ -1,39 +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 2000-2002 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -DATAFILES += i.initd -CHKINSTALLSRC=checkinstall.initd - -.KEEP_STATE: - -all: $(FILES) -install: all pkg - -include ../Makefile.targ diff --git a/usr/src/pkgdefs/SUNWwrsm.u/depend b/usr/src/pkgdefs/SUNWwrsm.u/depend deleted file mode 100644 index c2b1866202..0000000000 --- a/usr/src/pkgdefs/SUNWwrsm.u/depend +++ /dev/null @@ -1,52 +0,0 @@ -# -# Copyright 2005 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, 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 -# -# ident "%Z%%M% %I% %E% SMI" -# -# This package information file defines software dependencies associated -# with the pkg. You can define three types of pkg dependencies with this file: -# P indicates a prerequisite for installation -# I indicates an incompatible package -# R indicates a reverse dependency -# <pkg.abbr> see pkginfo(4), PKG parameter -# <name> see pkginfo(4), NAME parameter -# <version> see pkginfo(4), VERSION parameter -# <arch> see pkginfo(4), ARCH parameter -# <type> <pkg.abbr> <name> -# (<arch>)<version> -# (<arch>)<version> -# ... -# <type> <pkg.abbr> <name> -# ... -# - -P SUNWrsmo RSMPI Operations Registration Module -P SUNWcar Core Architecture, (Root) -P SUNWcakr Core Solaris Kernel Architecture (Root) -P SUNWkvm Core Architecture, (Kvm) -P SUNWcsr Core Solaris, (Root) -P SUNWckr Core Solaris Kernel (Root) -P SUNWcnetr Core Solaris Network Infrastructure (Root) -P SUNWcsu Core Solaris, (Usr) -P SUNWcsd Core Solaris Devices diff --git a/usr/src/pkgdefs/SUNWwrsm.u/pkginfo.tmpl b/usr/src/pkgdefs/SUNWwrsm.u/pkginfo.tmpl deleted file mode 100644 index 58223c9616..0000000000 --- a/usr/src/pkgdefs/SUNWwrsm.u/pkginfo.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -# -# This required package information file describes characteristics of the -# package, such as package abbreviation, full package name, package version, -# and package architecture. -# -PKG="SUNWwrsm" -NAME="WCI Remote Shared Memory Drivers" -ARCH="sparc.sun4u" -VERSION="ONVERS,REV=0.0.0" -SUNW_PRODNAME="SunOS" -SUNW_PRODVERS="RELEASE/VERSION" -SUNW_PKGVERS=1.0 -SUNW_PKGTYPE="root" -MAXINST="1000" -CATEGORY="system" -DESC="WCI Remote Shared Memory Drivers" -VENDOR="Sun Microsystems, Inc." -HOTLINE="Please contact your local service provider" -EMAIL="" -CLASSES="none initd" -BASEDIR=/ -SUNW_PKG_ALLZONES="true" -SUNW_PKG_HOLLOW="true" -SUNW_PKG_THISZONE="false" diff --git a/usr/src/pkgdefs/SUNWwrsm.u/postinstall b/usr/src/pkgdefs/SUNWwrsm.u/postinstall deleted file mode 100644 index 15759f43b8..0000000000 --- a/usr/src/pkgdefs/SUNWwrsm.u/postinstall +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# 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 -# -# -#pragma ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# - -PATH="/usr/bin:/usr/sbin:$PATH" -export PATH - -ADD_DRV="add_drv -b ${BASEDIR}" - -not_installed() { - driver=$1 - grep "^${driver} " ${BASEDIR}/etc/name_to_major > /dev/null 2>&1 - return $? -} - -EXIT=0 - -not_installed wrsm || $ADD_DRV -i '"SUNW,wci-rsm"' -m '* 0666 root sys' wrsm || -EXIT=1 - -exit $EXIT diff --git a/usr/src/pkgdefs/SUNWwrsm.u/preremove b/usr/src/pkgdefs/SUNWwrsm.u/preremove deleted file mode 100644 index 521750b7ad..0000000000 --- a/usr/src/pkgdefs/SUNWwrsm.u/preremove +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# -# 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 -# -# -#pragma ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 2000-2001 by Sun Microsystems, Inc. -# All rights reserved. -# -WRSMCONF="/platform/sun4u/sbin/wrsmconf" - -if [ "${BASEDIR:=/}" = "/" ] -then - REM_DRV="rem_drv" -else - REM_DRV="rem_drv -b ${BASEDIR}" -fi - -if [ "${PKG_INSTALL_ROOT:-/}" = "/" ]; then - # Remove any controllers - if [ -f $WRSMCONF ]; then - $WRSMCONF remove - fi -fi - -$REM_DRV wrsm - -exit 0 diff --git a/usr/src/pkgdefs/SUNWwrsm.u/prototype_sparc b/usr/src/pkgdefs/SUNWwrsm.u/prototype_sparc deleted file mode 100644 index 62bdc8a396..0000000000 --- a/usr/src/pkgdefs/SUNWwrsm.u/prototype_sparc +++ /dev/null @@ -1,97 +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 2000-2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#pragma ident "%Z%%M% %I% %E% SMI" -# -# This required package information file contains a list of package contents. -# The 'pkgmk' command uses this file to identify the contents of a package -# and their location on the development machine when building the package. -# Can be created via a text editor or through use of the 'pkgproto' command. - -#!search <pathname pathname ...> # where to find pkg objects -#!include <filename> # include another 'prototype' file -#!default <mode> <owner> <group> # default used if not specified on entry -#!<param>=<value> # puts parameter in pkg environment - -# -# List files which are SPARC specific here -# -# source locations relative to the prototype file -# -i pkginfo -i copyright -i checkinstall -i postinstall -i preremove -i depend -i i.initd - -# Create directories -d none etc 0755 root sys -d none etc/init.d 0755 root sys -d none etc/rcS.d 0755 root sys -d none etc/wrsm 755 root sys - -d none platform 0755 root sys -d none platform/sun4u 0755 root sys -d none platform/sun4u/lib 0755 root bin -d none platform/sun4u/lib/sparcv9 0755 root bin -d none platform/sun4u/sbin 0755 root bin -d none platform/SUNW,Sun-Fire 0755 root sys -d none platform/SUNW,Sun-Fire/kernel 0755 root sys -d none platform/SUNW,Sun-Fire/kernel/drv 0755 root sys -d none platform/SUNW,Sun-Fire/kernel/drv/sparcv9 0755 root sys -d none platform/SUNW,Sun-Fire/kernel/misc 0755 root sys -d none platform/SUNW,Sun-Fire/kernel/misc/sparcv9 0755 root sys -d none platform/SUNW,Sun-Fire-15000 0755 root sys -d none platform/SUNW,Sun-Fire-15000/kernel 0755 root sys -d none platform/SUNW,Sun-Fire-15000/kernel/drv 0755 root sys -d none platform/SUNW,Sun-Fire-15000/kernel/drv/sparcv9 0755 root sys -d none platform/SUNW,Sun-Fire-15000/kernel/misc 0755 root sys -d none platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9 0755 root sys - -# Platform-specific command -f none platform/sun4u/sbin/wrsmconf 0755 root sys - -# Platform-specific libraries -f none platform/sun4u/lib/libwrsmconf.so.1 755 root bin -s none platform/sun4u/lib/libwrsmconf.so=libwrsmconf.so.1 -f none platform/sun4u/lib/sparcv9/libwrsmconf.so.1 755 root bin -s none platform/sun4u/lib/sparcv9/libwrsmconf.so=libwrsmconf.so.1 - -# Platform-specific modules -f none platform/SUNW,Sun-Fire/kernel/misc/sparcv9/wrsmplat 0755 root sys -f none platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9/wrsmplat 0755 root sys - -# Drivers -f none platform/SUNW,Sun-Fire/kernel/drv/wrsm.conf 0644 root sys -f none platform/SUNW,Sun-Fire/kernel/drv/sparcv9/wrsm 0755 root sys -f none platform/SUNW,Sun-Fire-15000/kernel/drv/wrsm.conf 0644 root sys -l none platform/SUNW,Sun-Fire-15000/kernel/drv/sparcv9/wrsm=../../../../SUNW,Sun-Fire/kernel/drv/sparcv9/wrsm - -# Startup script -e initd etc/init.d/wrsmcfg 0755 root sys -l initd etc/rcS.d/S29wrsmcfg=../../etc/init.d/wrsmcfg -l initd etc/rcS.d/K44wrsmcfg=../../etc/init.d/wrsmcfg diff --git a/usr/src/pkgdefs/SUNWwrsu.u/Makefile b/usr/src/pkgdefs/SUNWwrsu.u/Makefile deleted file mode 100644 index 8c689cfdac..0000000000 --- a/usr/src/pkgdefs/SUNWwrsu.u/Makefile +++ /dev/null @@ -1,36 +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 (c) 2001 Sun Microsystems, Inc. -# All rights reserved. -# -#pragma ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -DATAFILES += depend - -all: $(FILES) -install: all pkg - -include ../Makefile.targ diff --git a/usr/src/pkgdefs/SUNWwrsu.u/pkginfo.tmpl b/usr/src/pkgdefs/SUNWwrsu.u/pkginfo.tmpl deleted file mode 100644 index 6a517cd7ee..0000000000 --- a/usr/src/pkgdefs/SUNWwrsu.u/pkginfo.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -# -# This required package information file describes characteristics of the -# package, such as package abbreviation, full package name, package version, -# and package architecture. -# -PKG="SUNWwrsu" -NAME="WCI RSM Commands and Libraries" -ARCH="sparc.sun4u" -VERSION="ONVERS,REV=0.0.0" -SUNW_PRODNAME="SunOS" -SUNW_PRODVERS="RELEASE/VERSION" -SUNW_PKGVERS=1.0 -SUNW_PKGTYPE="kvm" -MAXINST="1000" -CATEGORY="system" -DESC="Commands and libraries for the wrsm and wrsmd drivers" -VENDOR="Sun Microsystems, Inc." -HOTLINE="Please contact your local service provider" -EMAIL="" -CLASSES="none" -BASEDIR=/ -SUNW_PKG_ALLZONES="true" -SUNW_PKG_HOLLOW="false" -SUNW_PKG_THISZONE="false" diff --git a/usr/src/pkgdefs/SUNWwrsu.u/prototype_sparc b/usr/src/pkgdefs/SUNWwrsu.u/prototype_sparc deleted file mode 100644 index 400082a129..0000000000 --- a/usr/src/pkgdefs/SUNWwrsu.u/prototype_sparc +++ /dev/null @@ -1,68 +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 2001-2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#pragma ident "%Z%%M% %I% %E% SMI" -# -# This required package information file contains a list of package contents. -# The 'pkgmk' command uses this file to identify the contents of a package -# and their location on the development machine when building the package. -# Can be created via a text editor or through use of the 'pkgproto' command. - -#!search <pathname pathname ...> # where to find pkg objects -#!include <filename> # include another 'prototype' file -#!default <mode> <owner> <group> # default used if not specified on entry -#!<param>=<value> # puts parameter in pkg environment - -# -# List files which are SPARC specific here -# -# source locations relative to the prototype file -# -i pkginfo -i copyright -i depend - -# Directories -d none usr 0755 root sys -d none usr/platform 0755 root sys -d none usr/platform/sun4u 0755 root sys -d none usr/platform/sun4u/lib 0755 root bin -d none usr/platform/sun4u/lib/rcm 0755 root sys -d none usr/platform/sun4u/lib/rcm/scripts 0755 root sys -d none usr/platform/sun4u/lib/sparcv9 0755 root bin -d none usr/platform/sun4u/sbin 0755 root bin - -# RCM script -f none usr/platform/sun4u/lib/rcm/scripts/SUNW,wrsm_lastwci 0755 root sys - -# Commands -s none usr/platform/sun4u/sbin/wrsmconf=../../../../platform/sun4u/sbin/wrsmconf -f none usr/platform/sun4u/sbin/wrsmstat 0755 root sys - -# Libraries -s none usr/platform/sun4u/lib/libwrsmconf.so.1=../../../../platform/sun4u/lib/libwrsmconf.so.1 -s none usr/platform/sun4u/lib/libwrsmconf.so=../../../../platform/sun4u/lib/libwrsmconf.so.1 -s none usr/platform/sun4u/lib/sparcv9/libwrsmconf.so.1=../../../../../platform/sun4u/lib/sparcv9/libwrsmconf.so.1 -s none usr/platform/sun4u/lib/sparcv9/libwrsmconf.so=../../../../../platform/sun4u/lib/sparcv9/libwrsmconf.so.1 diff --git a/usr/src/tools/abi/etc/exceptions b/usr/src/tools/abi/etc/exceptions index 2602d79c07..064fe49214 100644 --- a/usr/src/tools/abi/etc/exceptions +++ b/usr/src/tools/abi/etc/exceptions @@ -442,15 +442,12 @@ PSARC 2004/619: RULE W4: usr/lib/amd64/mpss.so.1 4480868: RULE W4: usr/platform/SUNW,Sun-Fire-280R/lib/libpsvcpolicy_psr.so.1 4480868: RULE W4: usr/platform/SUNW,Sun-Fire-480R/lib/libpsvcpolicy_psr.so.1 4480868: RULE W4: usr/platform/SUNW,Sun-Fire-880/lib/libpsvcpolicy_psr.so.1 -4480868: RULE W4: usr/platform/SUNW,Sun-Fire/lib/rsmlib/sparcv9/wrsm.so.1 -4480868: RULE W4: usr/platform/SUNW,Sun-Fire/lib/rsmlib/wrsm.so.1 4941466: RULE W4: usr/platform/SUNW,Netra-CP2300/lib/libfruaccess.so.1 4941466: RULE W4: usr/platform/SUNW,Netra-CP2300/lib/libctsmc.so.1 4480868: RULE W4: usr/platform/sun4u/lib/libfruaccess.so.1 4480868: RULE W4: usr/platform/sun4u/lib/libprtdiag.so.1 4480868: RULE W4: usr/platform/sun4u/lib/libpsvcobj.so.1 4480868: RULE W4: usr/platform/sun4u/lib/libpsvcpolicy.so.1 -4480868: RULE W4: usr/platform/sun4u/lib/libwrsmconf.so.1 4480868: RULE W4: usr/sadm/admin/dhcpmgr/dhcpmgr.so.1 4480868: RULE W4: usr/sadm/admin/printmgr/lib/libpmgr.so.1 4480868: RULE W4: usr/lib/fs/hsfs/ident_hsfs.so.1 @@ -485,8 +482,6 @@ PSARC 2004/619: RULE W4: usr/lib/amd64/madv.so.1 4480868: RULE W4: usr/platform/SUNW,Sun-Blade-1500/lib/picl/plugins/libpiclenvd.so.1 4480868: RULE W4: usr/platform/SUNW,Sun-Blade-2500/lib/picl/plugins/libpiclenvd.so.1 4480868: RULE W4: usr/platform/SUNW,A70/lib/picl/plugins/libpiclenvd.so.1 -4480868: RULE W4: platform/sun4u/lib/libwrsmconf.so.1 -4480868: RULE W4: platform/sun4u/lib/sparcv9/libwrsmconf.so.1 4897400: RULE W4: usr/lib/libcryptoutil.so.1 4897400: RULE W4: usr/lib/sparcv9/libcryptoutil.so.1 PSARC 2004/619: RULE W4: usr/lib/amd64/libcryptoutil.so.1 diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh index 53bbe8c928..aae3c760ff 100644 --- a/usr/src/tools/scripts/bfu.sh +++ b/usr/src/tools/scripts/bfu.sh @@ -2916,6 +2916,80 @@ remove_perl_500503() } # +# Remove Wildcat (aka Sun Fire Link) +# +remove_eof_wildcat() +{ + # Packages to remove + typeset -r wildcat_pkgs='SUNWwrsa SUNWwrsd SUNWwrsu SUNWwrsm' + typeset -r pkgroot=${rootprefix:+-R $rootprefix} + typeset pkg + + # + # First, attempt to remove the packages cleanly if possible. + # Use a custom "admin" file to specify that removal scripts + # in the packages being removed should be run even if they + # will run as root. + # + typeset -r admfile='/tmp/wcat_eof.$$' + echo "action=nocheck" > $admfile + + printf 'Removing Wildcat packages...' + for pkg in $wildcat_pkgs + do + if pkginfo $pkgroot -q $pkg; then + printf ' %s' $pkg + pkgrm $pkgroot -n -a $admfile $pkg >/dev/null 2>&1 + fi + done + printf '\n' + + # + # In case that didn't work, do it manually. + # + printf 'Removing Wildcat from %s/var/sadm/install/contents...' \ + $rootprefix + for pkg in $wildcat_pkgs + do + printf ' %s' $pkg + if [ -d $rootprefix/var/sadm/pkg/$pkg ]; then + rm -rf $rootprefix/var/sadm/pkg/$pkg + grep -vw $pkg $rootprefix/var/sadm/install/contents > \ + /tmp/contents.$$ + cp /tmp/contents.$$ \ + $rootprefix/var/sadm/install/contents + rm /tmp/contents.$$ + fi + done + printf '\n' + + # + # Cleanup any remaining Wildcat files, symlinks, and directories. + # + rm -f $usr/platform/sun4u/include/sys/wci_common.h + rm -f $usr/platform/sun4u/include/sys/wci_regs.h + rm -f $usr/platform/sun4u/include/sys/wci_offsets.h + rm -f $usr/platform/sun4u/include/sys/wci_cmmu.h + rm -f $usr/platform/sun4u/include/sys/wrsm.h + rm -f $usr/platform/sun4u/include/sys/wrsm_common.h + rm -f $usr/platform/sun4u/include/sys/wrsm_config.h + rm -f $usr/platform/sun4u/include/sys/wrsm_types.h + rm -f $usr/platform/sun4u/include/sys/wrsm_plat.h + rm -f $usr/platform/sun4u/include/sys/wrsm_plugin.h + rm -f $usr/platform/sun4u/include/sys/wrsmconf.h + + rm -f $usr/platform/sun4u/lib/mdb/kvm/sparcv9/wrsm.so + rm -f $usr/platform/sun4u/lib/mdb/kvm/sparcv9/wrsmd.so + + rm -f $rootprefix/platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9/gptwo_wci + + rm -f $rootprefix/platform/sun4u/kernel/kmdb/sparcv9/wrsm + rm -f $rootprefix/platform/sun4u/kernel/kmdb/sparcv9/wrsmd + + rm -f $admfile +} + +# # Remove ASET # remove_eof_aset() @@ -5672,6 +5746,17 @@ mondo_loop() { fi # + # Remove Wildcat + # + if [ -f $rootprefix/platform/SUNW,Sun-Fire-15000/kernel/misc/sparcv9/gptwo_wci -o \ + -f $usr/platform/SUNW,Sun-Fire/lib/rsmlib/wrsm.so.1 -o \ + -f $rootprefix/platform/sun4u/kernel/drv/wrsmd.conf -o \ + -d $rootprefix/etc/wrsm -o \ + -f $usr/platform/sun4u/sbin/wrsmstat ]; then + remove_eof_wildcat + fi + + # # Remove ASET # if [ -d $usr/aset ]; then diff --git a/usr/src/uts/sun4u/Makefile.files b/usr/src/uts/sun4u/Makefile.files index 88224612cc..79d91b9f90 100644 --- a/usr/src/uts/sun4u/Makefile.files +++ b/usr/src/uts/sun4u/Makefile.files @@ -92,7 +92,6 @@ PCI_COMMON_OBJS += pci.o pci_util.o pci_dma.o pci_devctl.o \ pci_space.o pci_counters.o pci_axq.o \ pci_fm.o pci_reloc.o pci_tools.o pci_asm.o RMCLOMV_OBJS += rmclomv.o -WRSMD_OBJS += wrsmd.o PSYCHO_PCI_OBJS += $(PCI_COMMON_OBJS) pcipsy.o SCHIZO_PCI_OBJS += $(PCI_COMMON_OBJS) pcisch_asm.o pcisch.o pcix.o @@ -136,27 +135,6 @@ TRAPSTAT_OBJS += trapstat.o I2BSC_OBJS += i2bsc.o GPTWOCFG_OBJS += gptwocfg.o GPTWO_CPU_OBJS += gptwo_cpu.o -WRSM_OBJS += wci_common.o \ - wrsm_barrier.o \ - wrsm_cf.o \ - wrsm_cmmu.o \ - wrsm_common.o \ - wrsm_confpack.o \ - wrsm_copy.o \ - wrsm_driver.o \ - wrsm_getput.o \ - wrsm_intr.o \ - wrsm_lc.o \ - wrsm_memseg.o \ - wrsm_memseg_export.o \ - wrsm_memseg_import.o \ - wrsm_mh.o \ - wrsm_nc.o \ - wrsm_nr.o \ - wrsm_rsmpi.o \ - wrsm_session.o \ - wrsm_tl.o \ - wrsm_trap.o ZULUVM_OBJS += zuluvm.o zulu_asm.o zulu_hat.o zulu_hat_asm.o JBUSPPM_OBJS += jbusppm.o diff --git a/usr/src/uts/sun4u/Makefile.rules b/usr/src/uts/sun4u/Makefile.rules index 2b49e2cfc8..a77d0a1cd1 100644 --- a/usr/src/uts/sun4u/Makefile.rules +++ b/usr/src/uts/sun4u/Makefile.rules @@ -91,13 +91,6 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/sun4u/io/px/%.c $(OBJS_DIR)/%.o: $(UTSBASE)/sun4u/io/px/%.s $(COMPILE.s) -o $@ $< -$(OBJS_DIR)/%.o: $(UTSBASE)/sun4u/io/wrsm/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - -$(OBJS_DIR)/%.o: $(UTSBASE)/sun4u/io/wrsm/%.s - $(COMPILE.s) -o $@ $< - $(OBJS_DIR)/%.o: $(UTSBASE)/sun4u/io/dmfe/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) @@ -215,12 +208,6 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/sun4u/io/px/%.c $(LINTS_DIR)/%.ln: $(UTSBASE)/sun4u/io/px/%.s @($(LHEAD) $(LINT.s) $< $(LTAIL)) -$(LINTS_DIR)/%.ln: $(UTSBASE)/sun4u/io/wrsm/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - -$(LINTS_DIR)/%.ln: $(UTSBASE)/sun4u/io/wrsm/%.s - @($(LHEAD) $(LINT.s) $< $(LTAIL)) - $(LINTS_DIR)/%.ln: $(UTSBASE)/sun4u/io/dmfe/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) diff --git a/usr/src/uts/sun4u/Makefile.sun4u.shared b/usr/src/uts/sun4u/Makefile.sun4u.shared index 1c48318211..b6ffd619d2 100644 --- a/usr/src/uts/sun4u/Makefile.sun4u.shared +++ b/usr/src/uts/sun4u/Makefile.sun4u.shared @@ -402,7 +402,6 @@ DRV_KMODS += dmfe DRV_KMODS += rmc_comm DRV_KMODS += rmcadm DRV_KMODS += rmclomv -DRV_KMODS += wrsmd DRV_KMODS += sf DRV_KMODS += nxge DRV_KMODS += i2bsc diff --git a/usr/src/uts/sun4u/io/wci_common.c b/usr/src/uts/sun4u/io/wci_common.c deleted file mode 100644 index af137d9630..0000000000 --- a/usr/src/uts/sun4u/io/wci_common.c +++ /dev/null @@ -1,1895 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/systm.h> -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/kmem.h> -#include <sys/debug.h> -#include <sys/cmn_err.h> -#include <sys/kstat.h> -#include <sys/async.h> -#include <sys/cheetahregs.h> - -#include <sys/wci_offsets.h> -#include <sys/wci_regs.h> -#include <sys/wci_common.h> - -/* busstat-style kstats support */ -/* Use predefined strings to name the kstats from this driver. */ -#define WCI_KSTAT_NAME "%s" -#define WCI_LPBK_KSTAT_NAME "%slpbk" -#define WCI_LINK_KSTAT_NAME "%slink" -#define WCI_SFI_KSTAT_NAME "%ssfi" - -#define EOSTR "\0" - -/* - * Function prototypes - */ -static void wci_add_misc_kstats(struct wci_common_soft_state *, char *); -static void wci_add_lpbk_kstats(struct wci_common_soft_state *, char *); -static void wci_add_link_kstats(struct wci_common_soft_state *, char *); -static void wci_add_sfi_kstats(struct wci_common_soft_state *, char *); - -static void wci_add_misc_pic_kstats(char *); -static void wci_add_lpbk_pic_kstats(char *); -static void wci_add_link_pic_kstats(char *); -static void wci_add_sfi_pic_kstats(char *); - -static int wci_misc_kstat_update(kstat_t *, int); -static int wci_lpbk_kstat_update(kstat_t *, int); -static int wci_link_kstat_update(kstat_t *, int); -static int wci_sfi_kstat_update(kstat_t *, int); - -/* this varible is used in wci_link_kstat_update() routine */ -static int wci_link_kstat_modlen; - -/* Wildcat ECC error handling support */ -void -wci_log_ce_error(struct async_flt *ecc, char *unum) -{ - uint64_t t_afsr; - uint64_t t_afar; - ushort_t id = ecc->flt_bus_id; - ushort_t inst = ecc->flt_inst; - - t_afsr = ecc->flt_stat; - t_afar = ecc->flt_addr; - - if (t_afsr == RA_ECC_MTAG_CE) { - cmn_err(CE_CONT, "WCI%d CE RA MTAG ERROR: " - "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " - "Id %d\n", - inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, - (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); - } - if (t_afsr == RA_ECC_DATA_CE) { - cmn_err(CE_CONT, "WCI%d CE RA DATA ERROR: " - "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " - "Id %d\n", - inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, - (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); - } - if (t_afsr == HA_ECC_MTAG_CE) { - cmn_err(CE_CONT, "WCI%d CE HA MTAG ERROR: " - "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " - "Id %d\n", - inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, - (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); - } - if (t_afsr == HA_ECC_DATA_CE) { - cmn_err(CE_CONT, "WCI%d CE HA DATA ERROR: " - "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " - "Id %d\n", - inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, - (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); - } - if (t_afsr == SA_ECC_MTAG_CE) { - cmn_err(CE_CONT, "WCI%d CE SA MTAG ERROR: " - "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " - "Id %d\n", - inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, - (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); - } - if (t_afsr == SA_ECC_DATA_CE) { - cmn_err(CE_CONT, "WCI%d CE SA DATA ERROR: " - "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " - "Id %d\n", - inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, - (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); - } - if (t_afsr == CA_ECC_MTAG_CE) { - cmn_err(CE_CONT, "WCI%d CE CA MTAG ERROR: " - "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " - "Id %d\n", - inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, - (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); - } - if (t_afsr == CA_ECC_DATA_CE) { - cmn_err(CE_CONT, "WCI%d CE CA DATA ERROR: " - "AFSR 0x%08x.%08x AFAR 0x%08x.%08x MemMod %s " - "Id %d\n", - inst, (uint32_t)(t_afsr>>32), (uint32_t)t_afsr, - (uint32_t)(t_afar>>32), (uint32_t)t_afar, unum, id); - } -} - - -/* - * WCI Performance Events. - * - * For each pic there is an array of event-names and event-masks. - * The num of events in this array is WCI_NUM_EVENTS + 1 - * (num of WCI events) + (clear_pic event) - * - */ - -/* Misc Counter */ -static wci_event_mask_t - wci_misc_events_arr[WCI_NUM_PICS][WCI_MISC_NUM_EVENTS] = { -/* pic 0 */ - { - /* SFI agent */ - {"sfi_sfi_histogram0", SFI_SFI_HISTOGRAM0}, - {"sfi_sfi_histogram1", SFI_SFI_HISTOGRAM1}, - {"sfi_atransid_alloc_1", SFI_ATRANSID_ALLOC_1}, - {"sfi_atransid_alloc_4", SFI_ATRANSID_ALLOC_4}, - {"sfi_atransid_alloc_8", SFI_ATRANSID_ALLOC_8}, - {"sfi_atransid_alloc_10", SFI_ATRANSID_ALLOC_10}, - {"sfi_atransid_alloc_12", SFI_ATRANSID_ALLOC_12}, - {"sfi_atransid_dealloc", SFI_ATRANSID_DEALLOC}, - {"sfi_targid_alloc_0", SFI_TARGID_ALLOC_0}, - {"sfi_targid_alloc_2", SFI_TARGID_ALLOC_2}, - {"sfi_targid_alloc_8", SFI_TARGID_ALLOC_8}, - {"sfi_targid_dealloc", SFI_TARGID_DEALLOC}, - {"sfi_p0_req_valid", SFI_P0_REQ_VALID}, - {"sfi_p1_req_valid", SFI_P1_REQ_VALID}, - {"sfi_p2_req_valid", SFI_P2_REQ_VALID}, - {"sfi_p3_req_valid", SFI_P3_REQ_VALID}, - {"sfi_p4_req_valid", SFI_P4_REQ_VALID}, - {"sfi_p5_req_valid", SFI_P5_REQ_VALID}, - {"sfi_p6_req_valid", SFI_P6_REQ_VALID}, - {"sfi_p7_req_valid", SFI_P7_REQ_VALID}, - {"sfi_p8_req_valid", SFI_P8_REQ_VALID}, - {"sfi_p9_req_valid", SFI_P9_REQ_VALID}, - {"sfi_p10_req_valid", SFI_P10_REQ_VALID}, - {"sfi_p11_req_valid", SFI_P11_REQ_VALID}, - {"sfi_p12_req_valid", SFI_P12_REQ_VALID}, - {"sfi_p0_grant", SFI_P0_GRANT}, - {"sfi_p1_grant", SFI_P1_GRANT}, - {"sfi_p2_grant", SFI_P2_GRANT}, - {"sfi_p3_grant", SFI_P3_GRANT}, - {"sfi_p4_grant", SFI_P4_GRANT}, - {"sfi_p5_grant", SFI_P5_GRANT}, - {"sfi_p6_grant", SFI_P6_GRANT}, - {"sfi_p7_grant", SFI_P7_GRANT}, - {"sfi_p8_grant", SFI_P8_GRANT}, - {"sfi_p9_grant", SFI_P9_GRANT}, - {"sfi_p10_grant", SFI_P10_GRANT}, - {"sfi_p11_grant", SFI_P11_GRANT}, - {"sfi_p12_grant", SFI_P12_GRANT}, - {"sfi_sfi_pull_req", SFI_SFI_PULL_REQ}, - {"sfi_sfi_pull_grant", SFI_SFI_PULL_GRANT}, - /* cnt0 duration */ - {"sfi_atransid_dealloc_duration", - SFI_ATRANSID_DEALLOC_DURATION}, - {"sfi_targid_dealloc_duration", SFI_TARGID_DEALLOC_DURATION}, - /* DC agent */ - {"dc_dif_output_valid", DC_DIF_OUTPUT_VALID}, - {"dc_sfi_data_grant", DC_SFI_DATA_GRANT}, - /* LC agent */ - {"lc_dif_push", LC_DIF_PUSH}, - {"lc_com_valid_links_dif_full", LC_COM_VALID_LINKS_DIF_FULL}, - {"lc_data_pkt_fr_node", LC_DATA_PKT_FR_NODE}, - {"lc_sfi_data_cancle", LC_SFI_DATA_CANCEL}, - /* SFQ agent */ - {"sfq_piq_push", SFQ_PIQ_PUSH}, - {"sfq_piq_pop", SFQ_PIQ_POP}, - {"sfq_niq_push", SFQ_NIQ_PUSH}, - {"sfq_niq_pop", SFQ_NIQ_POP}, - {"sfq_siq_push", SFQ_SIQ_PUSH}, - {"sfq_siq_pop", SFQ_SIQ_POP}, - /* HLI agent */ - {"hli_slq_push", HLI_SLQ_PUSH}, - {"hli_slq_pop", HLI_SLQ_POP}, - {"hli_chq_push", HLI_CHQ_PUSH}, - {"hli_chq_pop", HLI_CHQ_POP}, - {"hli_phq_push", HLI_PHQ_PUSH}, - {"hli_phq_pop", HLI_PHQ_POP}, - /* Cache Control agent */ - {"cachectl_clust0", CACHECTL_CLUST0}, - {"cachectl_clust1", CACHECTL_CLUST1}, - /* pic0, cluster event 0 */ - {"cachectl_clust0_cwr", CACHECTL_CLUST_CWR | CACHECTL_CLUST0}, - {"cachectl_clust0_crd", CACHECTL_CLUST_CRD | CACHECTL_CLUST0}, - {"cachectl_clust0_crd_cwr", - CACHECTL_CLUST_CRD_CWR | CACHECTL_CLUST0}, - {"cachectl_clust0_at", CACHECTL_CLUST_AT | CACHECTL_CLUST0}, - {"cachectl_clust0_at_cwr", - CACHECTL_CLUST_AT_CWR | CACHECTL_CLUST0}, - {"cachectl_clust0_at_crd", - CACHECTL_CLUST_AT_CRD | CACHECTL_CLUST0}, - {"cachectl_clust0_at_crd_cwr", - CACHECTL_CLUST_AT_CRD_CWR | CACHECTL_CLUST0}, - {"cachectl_clust0_int", - CACHECTL_CLUST_INT | CACHECTL_CLUST0}, - {"cachectl_clust0_int_cwr", - CACHECTL_CLUST_INT_CWR | CACHECTL_CLUST0}, - {"cachectl_clust0_int_crd", - CACHECTL_CLUST_INT_CRD | CACHECTL_CLUST0}, - {"cachectl_clust0_int_crd_cwr", - CACHECTL_CLUST_INT_CRD_CWR | CACHECTL_CLUST0}, - {"cachectl_clust0_int_at", - CACHECTL_CLUST_INT_AT | CACHECTL_CLUST0}, - {"cachectl_clust0_int_at_cwr", - CACHECTL_CLUST_INT_AT_CWR | CACHECTL_CLUST0}, - {"cachectl_clust0_int_at_crd", - CACHECTL_CLUST_INT_AT_CRD | CACHECTL_CLUST0}, - {"cachectl_clust0_int_at_crd_cwr", - CACHECTL_CLUST_INT_AT_CRD_CWR | CACHECTL_CLUST0}, - /* pic0, cluster event 1 */ - {"cachectl_clust1_cwr", CACHECTL_CLUST_CWR | CACHECTL_CLUST1}, - {"cachectl_clust1_crd", CACHECTL_CLUST_CRD | CACHECTL_CLUST1}, - {"cachectl_clust1_crd_cwr", - CACHECTL_CLUST_CRD_CWR | CACHECTL_CLUST1}, - {"cachectl_clust1_at", - CACHECTL_CLUST_AT | CACHECTL_CLUST1}, - {"cachectl_clust1_at_cwr", - CACHECTL_CLUST_AT_CWR | CACHECTL_CLUST1}, - {"cachectl_clust1_at_crd", - CACHECTL_CLUST_AT_CRD | CACHECTL_CLUST1}, - {"cachectl_clust1_at_crd_cwr", - CACHECTL_CLUST_AT_CRD_CWR | CACHECTL_CLUST1}, - {"cachectl_clust1_int", - CACHECTL_CLUST_INT | CACHECTL_CLUST1}, - {"cachectl_clust1_int_cwr", - CACHECTL_CLUST_INT_CWR | CACHECTL_CLUST1}, - {"cachectl_clust1_int_crd", - CACHECTL_CLUST_INT_CRD | CACHECTL_CLUST1}, - {"cachectl_clust1_int_crd_cwr", - CACHECTL_CLUST_INT_CRD_CWR | CACHECTL_CLUST1}, - {"cachectl_clust1_int_at", - CACHECTL_CLUST_INT_AT | CACHECTL_CLUST1}, - {"cachectl_clust1_int_at_cwr", - CACHECTL_CLUST_INT_AT_CWR | CACHECTL_CLUST1}, - {"cachectl_clust1_int_at_crd", - CACHECTL_CLUST_INT_AT_CRD | CACHECTL_CLUST1}, - {"cachectl_clust1_int_at_crd_cwr", - CACHECTL_CLUST_INT_AT_CRD_CWR | CACHECTL_CLUST1}, - {"cachectl_cache_cyl_used", CACHECTL_CACHE_CYL_USED}, - {"cachectl_lpa2ga_lookup", CACHECTL_LPA2GA_LOOKUP}, - {"cachectl_ga2lpa_access", CACHECTL_GA2LPA_ACCESS}, - {"cachectl_ga2lpa_lookup", CACHECTL_GA2LPA_LOOKUP}, - {"cachectl_ga2lpa_miss", CACHECTL_GA2LPA_MISS}, - {"cachectl_dir_lookup", CACHECTL_DIR_LOOKUP}, - {"cachectl_dir_miss", CACHECTL_DIR_MISS}, - {"cachectl_dir_wrtbk", CACHECTL_DIR_WRTBK}, - {"cachectl_cmmu_access", CACHECTL_CMMU_ACCESS}, - {"cachectl_cmmu_lookup", CACHECTL_CMMU_LOOKUP}, - {"cachectl_csr_lookup", CACHECTL_CSR_LOOKUP}, - {"cachectl_cnt_alwys", CACHECTL_CNT_ALWYS}, - {"cachectl_hag_req_valid", CACHECTL_HAG_REQ_VALID}, - {"cachectl_ciq_req_valid", CACHECTL_CIQ_REQ_VALID}, - {"cachectl_slq_req_valid", CACHECTL_SLQ_REQ_VALID}, - /* Cluster agent */ - {"clust_agent_alloc", CLUSTER_AGENT_ALLOC}, - {"clust_agent_retired", CLUSTER_AGENT_RETIRED}, - {"clust_sfi_grant_rd", CLUSTER_SFI_GRANT_RD}, - {"clust_sfi_grant_wr", CLUSTER_SFI_GRANT_WR}, - {"clust_pull_seen", CLUSTER_PULL_SEEN}, - {"clust_1dc_rcv_ack", CLUSTER_1DC_RCV_ACK}, - {"clust_2dc_snd_ack", CLUSTER_2DC_SND_ACK}, - {"clust_1_cpi_rcv_ack", CLUSTER_1_CPI_RCV_ACK}, - {"clust_2_cpi_rcv_ack", CLUSTER_2_CPI_RCV_ACK}, - {"clust_pkt_que_odd", CLUSTER_PKT_QUE_ODD}, - {"clust_pkt_que_even", CLUSTER_PKT_QUE_EVEN}, - {"clust_pkt_sent_odd", CLUSTER_PKT_SENT_ODD}, - {"clust_pkt_sent_even", CLUSTER_PKT_SENT_EVEN}, - {"clust_hli_req_0", CLUSTER_HLI_REQ_0}, - {"clust_hli_req_1", CLUSTER_HLI_REQ_1}, - {"clust_hli_req_2", CLUSTER_HLI_REQ_2}, - {"clust_hli_req_3", CLUSTER_HLI_REQ_3}, - {"clust_hli_req_4", CLUSTER_HLI_REQ_4}, - {"clust_hli_req_5", CLUSTER_HLI_REQ_5}, - {"clust_hli_grant_0", CLUSTER_HLI_GRANT_0}, - {"clust_hli_grant_1", CLUSTER_HLI_GRANT_1}, - {"clust_hli_grant_2", CLUSTER_HLI_GRANT_2}, - {"clust_hli_grant_3", CLUSTER_HLI_GRANT_3}, - {"clust_hli_grant_4", CLUSTER_HLI_GRANT_4}, - {"clust_hli_grant_5", CLUSTER_HLI_GRANT_5}, - - /* cnt 0 duration */ - {"clust_agent_retired_duration", - CLUSTER_AGENT_RETIRED | WCI_DURATION_BIT}, - {"clust_pull_seen_duration", - CLUSTER_PULL_SEEN | WCI_DURATION_BIT}, - {"clust_1dc_rcv_ack_duration", - CLUSTER_1DC_RCV_ACK | WCI_DURATION_BIT}, - {"clust_2dc_snd_ack_duration", - CLUSTER_2DC_SND_ACK | WCI_DURATION_BIT}, - {"clust_pkt_sent_odd_duration", - CLUSTER_PKT_SENT_ODD | WCI_DURATION_BIT}, - {"clust_pkt_sent_even_duration", - CLUSTER_PKT_SENT_EVEN | WCI_DURATION_BIT}, - {"clust_1_cpi_rcv_ack_duration", - CLUSTER_1_CPI_RCV_ACK | WCI_DURATION_BIT}, - {"clust_2_cpi_rcv_ack_duration", - CLUSTER_2_CPI_RCV_ACK | WCI_DURATION_BIT}, - /* Request agent */ - {"req_agent_alloc", REQ_AGENT_ALLOC}, - {"req_agent_retired", REQ_AGENT_RETIRED}, - {"req_sfi_grant_p2", REQ_SFI_GRANT_P2}, - {"req_1dc_rcv_ack", REQ_1DC_RCV_ACK}, - {"req_2dc_snd_ack", REQ_2DC_SND_ACK}, - {"req_1_cpi_rcv_ack", REQ_1_CPI_RCV_ACK}, - {"req_2_cpi_rcv_ack", REQ_2_CPI_RCV_ACK}, - {"req_pkt_que", REQ_PKT_QUE}, - {"req_pkt_sent", REQ_PKT_SENT}, - {"req_pkt_sent_clust_rd", REQ_PKT_SENT_CLUST_RD}, - {"req_pkt_sent_clust_wr", REQ_PKT_SENT_CLUST_WR}, - {"req_hli_req_0", REQ_HLI_REQ_0}, - {"req_hli_req_1", REQ_HLI_REQ_1}, - {"req_hli_req_2", REQ_HLI_REQ_2}, - {"req_hli_req_3", REQ_HLI_REQ_3}, - {"req_hli_req_4", REQ_HLI_REQ_4}, - {"req_hli_req_5", REQ_HLI_REQ_5}, - {"req_hli_grant_0", REQ_HLI_GRANT_0}, - {"req_hli_grant_1", REQ_HLI_GRANT_1}, - {"req_hli_grant_2", REQ_HLI_GRANT_2}, - {"req_hli_grant_3", REQ_HLI_GRANT_3}, - {"req_hli_grant_4", REQ_HLI_GRANT_4}, - {"req_hli_grant_5", REQ_HLI_GRANT_5}, - {"req_last_reply_rcvd", REQ_LAST_REPLY_RCVD}, - {"req_sent_clust_rd", REQ_SENT_CLUST_RD}, - {"req_sent_clust_wr", REQ_SENT_CLUST_WR}, - {"req_piq_valid", REQ_PIQ_VALID}, - {"req_piq_dispatch", REQ_PIQ_DISPATCH}, - {"req_ciq_valid", REQ_CIQ_VALID}, - {"req_ciq_dispatch", REQ_CIQ_DISPATCH}, - {"req_niq_valid", REQ_NIQ_VALID}, - {"req_niq_dispatch", REQ_NIQ_DISPATCH}, - {"req_numa_bypass_dispatch", REQ_NUMA_BYPASS_DISPATCH}, - /* cnt 0 duration */ - {"req_agent_retired_duration", - REQ_AGENT_RETIRED | WCI_DURATION_BIT}, - {"req_1dc_rcv_ack_duration", - REQ_1DC_RCV_ACK | WCI_DURATION_BIT}, - {"req_2dc_snd_ack_duration", - REQ_2DC_SND_ACK | WCI_DURATION_BIT}, - {"req_1_cpi_rcv_ack_duration", - REQ_1_CPI_RCV_ACK | WCI_DURATION_BIT}, - {"req_2_cpi_rcv_ack_duration", - REQ_2_CPI_RCV_ACK | WCI_DURATION_BIT}, - {"req_pkt_sent_duration", REQ_PKT_SENT | WCI_DURATION_BIT}, - {"req_last_reply_rcvd_duration", - REQ_LAST_REPLY_RCVD | WCI_DURATION_BIT}, - /* Home Agent */ - {"home_agent_alloc", HOME_AGENT_ALLOC}, - {"home_agent_retired", HOME_AGENT_RETIRED}, - {"home_sfi_p8_rd_aux", HOME_SFI_P8_RD_AUX}, - {"home_sfi_p8_rd_main", HOME_SFI_P8_RD_MAIN}, - {"home_sfi_p8_wr", HOME_SFI_P8_WR}, - {"home_sfi_p9_wr", HOME_SFI_P9_WR}, - {"home_sfi_p10_wr", HOME_SFI_P10_WR}, - {"home_1dc_rcv_ack_aux", HOME_1DC_RCV_ACK_AUX}, - {"home_1dc_rcv_ack_main", HOME_1DC_RCV_ACK_MAIN}, - {"home_2dc_snd_ack", HOME_2DC_SND_ACK}, - {"home_sfi_pull_seen", HOME_SFI_PULL_SEEN}, - {"home_last_demrep_sent", HOME_LAST_DEMREP_SENT}, - {"home_comp_pkt_seen", HOME_COMP_PKT_SEEN}, - {"home_hli_req_link_0_a", HOME_HLI_REQ_LINK_0_A}, - {"home_hli_req_link_0_b", HOME_HLI_REQ_LINK_0_B}, - {"home_hli_req_link_1_a", HOME_HLI_REQ_LINK_1_A}, - {"home_hli_req_link_1_b", HOME_HLI_REQ_LINK_1_B}, - {"home_hli_req_link_2_a", HOME_HLI_REQ_LINK_2_A}, - {"home_hli_req_link_2_b", HOME_HLI_REQ_LINK_2_B}, - {"home_hli_req_link_3_a", HOME_HLI_REQ_LINK_3_A}, - {"home_hli_req_link_3_b", HOME_HLI_REQ_LINK_3_B}, - {"home_hli_req_link_4_a", HOME_HLI_REQ_LINK_4_A}, - {"home_hli_req_link_4_b", HOME_HLI_REQ_LINK_4_B}, - {"home_hli_req_link_5_a", HOME_HLI_REQ_LINK_5_A}, - {"home_hli_req_link_5_b", HOME_HLI_REQ_LINK_5_B}, - {"home_hli_grant_link_0_a", HOME_HLI_GRANT_LINK_0_A}, - {"home_hli_grant_link_0_b", HOME_HLI_GRANT_LINK_0_B}, - {"home_hli_grant_link_1_a", HOME_HLI_GRANT_LINK_1_A}, - {"home_hli_grant_link_1_b", HOME_HLI_GRANT_LINK_1_B}, - {"home_hli_grant_link_2_a", HOME_HLI_GRANT_LINK_2_A}, - {"home_hli_grant_link_2_b", HOME_HLI_GRANT_LINK_2_B}, - {"home_hli_grant_link_3_a", HOME_HLI_GRANT_LINK_3_A}, - {"home_hli_grant_link_3_b", HOME_HLI_GRANT_LINK_3_B}, - {"home_hli_grant_link_4_a", HOME_HLI_GRANT_LINK_4_A}, - {"home_hli_grant_link_4_b", HOME_HLI_GRANT_LINK_4_B}, - {"home_hli_grant_link_5_a", HOME_HLI_GRANT_LINK_5_A}, - {"home_hli_grant_link_5_b", HOME_HLI_GRANT_LINK_5_B}, - {"home_blk_cam_hit", HOME_BLK_CAM_HIT}, - {"home_dir_rtned-before_rd_grant", - HOME_DIR_RTNED_BEFORE_RD_GRANT}, - {"home_dir_rtned_before_rd_order", - HOME_DIR_RTNED_BEFORE_RD_ORDER}, - {"home_dir_rtned_before_rd_data", - HOME_DIR_RTNED_BEFORE_RD_DATA}, - {"home_dir_rtned_after_rd_data", - HOME_DIR_RTNED_AFTER_RD_DATA}, - {"home_req_home", HOME_REQ_HOME}, - {"home_req_same_box", HOME_REQ_SAME_BOX}, - {"home_ref_data_back_home", HOME_REF_DATA_BACK_HOME}, - {"home_dir_miss_alloc", HOME_DIR_MISS_ALLOC}, - {"home_dir_hit_gi", HOME_DIR_HIT_GI}, - {"home_dir_hit_gs", HOME_DIR_HIT_GS}, - {"home_dir_hit_gm", HOME_DIR_HIT_GM}, - {"home_dir_hit_rto_gm", HOME_DIR_HIT_RTO_GM}, - {"home_dir_hit_rts_gms", HOME_DIR_HIT_RTS_GMS}, - {"home_dir_miss_rts_gi", HOME_DIR_MISS_RTS_GI}, - {"home_dir_miss_rts", HOME_DIR_MISS_RTS}, - {"home_dir_miss_rto_gs_gi", HOME_DIR_MISS_RTO_GS_GI}, - {"home_dir_miss_rto", HOME_DIR_MISS_RTO}, - /* cnt 0 duration */ - {"home_agent_retired_duration", - HOME_AGENT_RETIRED | WCI_DURATION_BIT}, - {"home_1dc_rcv_ack_aux_duration", - HOME_1DC_RCV_ACK_AUX | WCI_DURATION_BIT}, - {"home_1dc_rcv_ack_main_duration", - HOME_1DC_RCV_ACK_MAIN | WCI_DURATION_BIT}, - {"home_2dc_snd_ack_duration", - HOME_2DC_SND_ACK | WCI_DURATION_BIT}, - {"home_sfi_pull_seen_duration", - HOME_SFI_PULL_SEEN | WCI_DURATION_BIT}, - {"home_comp_pkt_seen_duration", - HOME_COMP_PKT_SEEN | WCI_DURATION_BIT}, - /* Slave agent */ - {"slave_agent_alloc", SLAVE_AGENT_ALLOC}, - {"slave_agent_alloc_lpa", SLAVE_AGENT_ALLOC_LPA}, - {"slave_agent_alloc_ga", SLAVE_AGENT_ALLOC_GA}, - {"slave_agent_alloc_h_lpa", SLAVE_AGENT_ALLOC_H_LPA}, - {"slave_agent_alloc_h_ga", SLAVE_AGENT_ALLOC_H_GA}, - {"slave_agent_alloc_h_mlpa", SLAVE_AGENT_ALLOC_H_MLPA}, - {"slave_agent_alloc_h_mga", SLAVE_AGENT_ALLOC_H_MGA}, - {"slave_agent_alloc_h_m", SLAVE_AGENT_ALLOC_H_M}, - {"slave_agent_alloc_h_inv_lpa", SLAVE_AGENT_ALLOC_H_INV_LPA}, - {"slave_agent_alloc_h_inv_ga", SLAVE_AGENT_ALLOC_H_INV_GA}, - {"slave_agent_retired", SLAVE_AGENT_RETIRED}, - {"slave_reply_sent", SLAVE_REPLY_SENT}, - {"slave_sfi_p6_grant_wr", SLAVE_SFI_P6_GRANT_WR}, - {"slave_sfi_p12gt_rlpa", SLAVE_SFI_P12GT_RLPA}, - {"slave_sfi_p12gt_rga", SLAVE_SFI_P12GT_RGA}, - {"slave_sfi_p12gt_rhlpa", - SLAVE_SFI_P12GT_RHLPA}, - {"slave_sfi_p12gt_rhga", SLAVE_SFI_P12GT_RHGA}, - {"slave_sfi_p12gt_rhmlpa", - SLAVE_SFI_P12GT_RHMLPA}, - {"slave_sfi_p12gt_rhmga", - SLAVE_SFI_P12GT_RHMGA}, - {"slave_sfi_p12gt_wr", SLAVE_SFI_P12GT_WR}, - {"slave_1dc_rcv_ack", SLAVE_1DC_RCV_ACK}, - {"slave_2dc_snd_ack", SLAVE_2DC_SND_ACK}, - {"slave_2dc_snd_ack_refl", SLAVE_2DC_SND_ACK_REFL}, - {"slave_4dc_snd_ack", SLAVE_4DC_SND_ACK}, - {"slave_pull_seen", SLAVE_PULL_SEEN}, - {"slave_h_m_ga_not_ownd", SLAVE_H_M_GA_NOT_OWND}, - {"slave_h_m_no_state_change", SLAVE_H_M_NO_STATE_CHANGE}, - {"slave_hli_req_0", SLAVE_HLI_REQ_0}, - {"slave_hli_req_1", SLAVE_HLI_REQ_1}, - {"slave_hli_req_2", SLAVE_HLI_REQ_2}, - {"slave_hli_req_3", SLAVE_HLI_REQ_3}, - {"slave_hli_req_4", SLAVE_HLI_REQ_4}, - {"slave_hli_req_5", SLAVE_HLI_REQ_5}, - {"slave_hli_grant_0", SLAVE_HLI_GRANT_0}, - {"slave_hli_grant_1", SLAVE_HLI_GRANT_1}, - {"slave_hli_grant_2", SLAVE_HLI_GRANT_2}, - {"slave_hli_grant_3", SLAVE_HLI_GRANT_3}, - {"slave_hli_grant_4", SLAVE_HLI_GRANT_4}, - {"slave_hli_grant_5", SLAVE_HLI_GRANT_5}, - /* cnt0 duration */ - {"slave_agent_retired_duration", - SLAVE_AGENT_RETIRED | WCI_DURATION_BIT}, - {"slave_1dc_rcv_ack_c0_duration", - SLAVE_1DC_RCV_ACK | WCI_DURATION_BIT}, - {"slave_2dc_snd_ack_duration", - SLAVE_2DC_SND_ACK | WCI_DURATION_BIT}, - {"slave_pull_seen_duration", - SLAVE_PULL_SEEN | WCI_DURATION_BIT}, - {"slave_reply_sent_duration", - SLAVE_REPLY_SENT | WCI_DURATION_BIT}, - {"slave_4dc_snd_ack_duration", - SLAVE_4DC_SND_ACK | WCI_DURATION_BIT}, - {"clear_pic", MISC_CLEAR_PIC0}, - {EOSTR, 0} - }, - -/* pic 1 */ - { - /* SFI agent */ - {"sfi_sfi_histogram0", SFI_SFI_HISTOGRAM0<<10}, - {"sfi_sfi_histogram1", SFI_SFI_HISTOGRAM1<<10}, - {"sfi_atransid_alloc_1", SFI_ATRANSID_ALLOC_1<<10}, - {"sfi_atransid_alloc_4", SFI_ATRANSID_ALLOC_4<<10}, - {"sfi_atransid_alloc_8", SFI_ATRANSID_ALLOC_8<<10}, - {"sfi_atransid_alloc_10", SFI_ATRANSID_ALLOC_10<<10}, - {"sfi_atransid_alloc_12", SFI_ATRANSID_ALLOC_12<<10}, - {"sfi_atransid_dealloc", SFI_ATRANSID_DEALLOC<<10}, - {"sfi_targid_alloc_0", SFI_TARGID_ALLOC_0<<10}, - {"sfi_targid_alloc_2", SFI_TARGID_ALLOC_2<<10}, - {"sfi_targid_alloc_8", SFI_TARGID_ALLOC_8<<10}, - {"sfi_targid_dealloc", SFI_TARGID_DEALLOC<<10}, - {"sfi_p0_req_valid", SFI_P0_REQ_VALID<<10}, - {"sfi_p1_req_valid", SFI_P1_REQ_VALID<<10}, - {"sfi_p2_req_valid", SFI_P2_REQ_VALID<<10}, - {"sfi_p3_req_valid", SFI_P3_REQ_VALID<<10}, - {"sfi_p4_req_valid", SFI_P4_REQ_VALID<<10}, - {"sfi_p5_req_valid", SFI_P5_REQ_VALID<<10}, - {"sfi_p6_req_valid", SFI_P6_REQ_VALID<<10}, - {"sfi_p7_req_valid", SFI_P7_REQ_VALID<<10}, - {"sfi_p8_req_valid", SFI_P8_REQ_VALID<<10}, - {"sfi_p9_req_valid", SFI_P9_REQ_VALID<<10}, - {"sfi_p10_req_valid", SFI_P10_REQ_VALID<<10}, - {"sfi_p11_req_valid", SFI_P11_REQ_VALID<<10}, - {"sfi_p12_req_valid", SFI_P12_REQ_VALID<<10}, - {"sfi_p0_grant", SFI_P0_GRANT<<10}, - {"sfi_p1_grant", SFI_P1_GRANT<<10}, - {"sfi_p2_grant", SFI_P2_GRANT<<10}, - {"sfi_p3_grant", SFI_P3_GRANT<<10}, - {"sfi_p4_grant", SFI_P4_GRANT<<10}, - {"sfi_p5_grant", SFI_P5_GRANT<<10}, - {"sfi_p6_grant", SFI_P6_GRANT<<10}, - {"sfi_p7_grant", SFI_P7_GRANT<<10}, - {"sfi_p8_grant", SFI_P8_GRANT<<10}, - {"sfi_p9_grant", SFI_P9_GRANT<<10}, - {"sfi_p10_grant", SFI_P10_GRANT<<10}, - {"sfi_p11_grant", SFI_P11_GRANT<<10}, - {"sfi_p12_grant", SFI_P12_GRANT<<10}, - {"sfi_sfi_pull_req", SFI_SFI_PULL_REQ<<10}, - {"sfi_sfi_pull_grant", SFI_SFI_PULL_GRANT<<10}, - /* cnt1 duration */ - {"sfi_atransid_alloc_1_duration", - SFI_ATRANSID_ALLOC_1_DURATION}, - {"sfi_atransid_alloc_4_duration", - SFI_ATRANSID_ALLOC_4_DURATION}, - {"sfi_atransid_alloc_8_duration", - SFI_ATRANSID_ALLOC_8_DURATION}, - {"sfi_atransid_alloc_10_duration", - SFI_ATRANSID_ALLOC_10_DURATION}, - {"sfi_atransid_alloc_12_duration", - SFI_ATRANSID_ALLOC_12_DURATION}, - {"sfi_targid_alloc_0_duration", - SFI_TARGID_ALLOC_0_DURATION}, - {"sfi_targid_alloc_2_duration", - SFI_TARGID_ALLOC_2_DURATION}, - {"sfi_targid_alloc_8_duration", - SFI_TARGID_ALLOC_8_DURATION}, - /* DC agent */ - {"dc_dif_output_valid", DC_DIF_OUTPUT_VALID<<10}, - {"dc_sfi_data_grant", DC_SFI_DATA_GRANT<<10}, - /* LC agent */ - {"lc_dif_push", LC_DIF_PUSH<<10}, - {"lc_com_valid_links_dif_full", - LC_COM_VALID_LINKS_DIF_FULL<<10}, - {"lc_data_pkt_fr_node", LC_DATA_PKT_FR_NODE<<10}, - {"lc_sfi_data_cancle", LC_SFI_DATA_CANCEL<<10}, - /* SFQ agent */ - {"sfq_piq_push", SFQ_PIQ_PUSH<<10}, - {"sfq_piq_pop", SFQ_PIQ_POP<<10}, - {"sfq_niq_push", SFQ_NIQ_PUSH<<10}, - {"sfq_niq_pop", SFQ_NIQ_POP<<10}, - {"sfq_siq_push", SFQ_SIQ_PUSH<<10}, - {"sfq_siq_pop", SFQ_SIQ_POP<<10}, - /* HLI agent */ - {"hli_slq_push", HLI_SLQ_PUSH<<10}, - {"hli_slq_pop", HLI_SLQ_POP<<10}, - {"hli_chq_push", HLI_CHQ_PUSH<<10}, - {"hli_chq_pop", HLI_CHQ_POP<<10}, - {"hli_phq_push", HLI_PHQ_PUSH<<10}, - {"hli_phq_pop", HLI_PHQ_POP<<10}, - /* Cache Control agent */ - {"cachectl_clust0", CACHECTL_CLUST0<<10}, - {"cachectl_clust1", CACHECTL_CLUST1<<10}, - /* pic1, cluster event 0 */ - {"cachectl_clust0_cwr", - (CACHECTL_CLUST_CWR<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_crd", - (CACHECTL_CLUST_CRD<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_crd_cwr", - (CACHECTL_CLUST_CRD_CWR<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_at", - (CACHECTL_CLUST_AT<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_at_cwr", - (CACHECTL_CLUST_AT_CWR<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_at_crd", - (CACHECTL_CLUST_AT_CRD<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_at_crd_cwr", - (CACHECTL_CLUST_AT_CRD_CWR<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_int", - (CACHECTL_CLUST_INT<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_int_cwr", - (CACHECTL_CLUST_INT_CWR<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_int_crd", - (CACHECTL_CLUST_INT_CRD<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_int_crd_cwr", - (CACHECTL_CLUST_INT_CRD_CWR<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_int_at", - (CACHECTL_CLUST_INT_AT<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_int_at_cwr", - (CACHECTL_CLUST_INT_AT_CWR<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_int_at_crd", - (CACHECTL_CLUST_INT_AT_CRD<<4) | (CACHECTL_CLUST0<<10)}, - {"cachectl_clust0_int_at_crd_cwr", - (CACHECTL_CLUST_INT_AT_CRD_CWR<<4) | - (CACHECTL_CLUST0<<10)}, - /* pic1, clust event 1 */ - {"cachectl_clust1_cwr", - (CACHECTL_CLUST_CWR<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_crd", - (CACHECTL_CLUST_CRD<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_crd_cwr", - (CACHECTL_CLUST_CRD_CWR<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_at", - (CACHECTL_CLUST_AT<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_at_cwr", - (CACHECTL_CLUST_AT_CWR<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_at_crd", - (CACHECTL_CLUST_AT_CRD<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_at_crd_cwr", - (CACHECTL_CLUST_AT_CRD_CWR<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_int", - (CACHECTL_CLUST_INT<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_int_cwr", - (CACHECTL_CLUST_INT_CWR<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_int_crd", - (CACHECTL_CLUST_INT_CRD<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_int_crd_cwr", - (CACHECTL_CLUST_INT_CRD_CWR<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_int_at", - (CACHECTL_CLUST_INT_AT<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_int_at_cwr", - (CACHECTL_CLUST_INT_AT_CWR<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_int_at_crd", - (CACHECTL_CLUST_INT_AT_CRD<<4) | (CACHECTL_CLUST1<<10)}, - {"cachectl_clust1_int_at_crd_cwr", - (CACHECTL_CLUST_INT_AT_CRD_CWR<<4) | - (CACHECTL_CLUST1<<10)}, - {"cachectl_cache_cyl_used", CACHECTL_CACHE_CYL_USED<<10}, - {"cachectl_lpa2ga_lookup", CACHECTL_LPA2GA_LOOKUP<<10}, - {"cachectl_ga2lpa_access", CACHECTL_GA2LPA_ACCESS<<10}, - {"cachectl_ga2lpa_lookup", CACHECTL_GA2LPA_LOOKUP<<10}, - {"cachectl_ga2lpa_miss", CACHECTL_GA2LPA_MISS<<10}, - {"cachectl_dir_lookup", CACHECTL_DIR_LOOKUP<<10}, - {"cachectl_dir_miss", CACHECTL_DIR_MISS<<10}, - {"cachectl_dir_wrtbk", CACHECTL_DIR_WRTBK<<10}, - {"cachectl_cmmu_access", CACHECTL_CMMU_ACCESS<<10}, - {"cachectl_cmmu_lookup", CACHECTL_CMMU_LOOKUP<<10}, - {"cachectl_csr_lookup", CACHECTL_CSR_LOOKUP<<10}, - {"cachectl_cnt_alwys", CACHECTL_CNT_ALWYS<<10}, - {"cachectl_hag_req_valid", CACHECTL_HAG_REQ_VALID<<10}, - {"cachectl_ciq_req_valid", CACHECTL_CIQ_REQ_VALID<<10}, - {"cachectl_slq_req_valid", CACHECTL_SLQ_REQ_VALID<<10}, - /* Cluster agent */ - {"clust_agent_alloc", CLUSTER_AGENT_ALLOC<<10}, - {"clust_agent_retired", CLUSTER_AGENT_RETIRED<<10}, - {"clust_sfi_grant_rd", CLUSTER_SFI_GRANT_RD<<10}, - {"clust_sfi_grant_wr", CLUSTER_SFI_GRANT_WR<<10}, - {"clust_pull_seen", CLUSTER_PULL_SEEN<<10}, - {"clust_1dc_rcv_ack", CLUSTER_1DC_RCV_ACK<<10}, - {"clust_2dc_snd_ack", CLUSTER_2DC_SND_ACK<<10}, - {"clust_1_cpi_rcv_ack", CLUSTER_1_CPI_RCV_ACK<<10}, - {"clust_2_cpi_rcv_ack", CLUSTER_2_CPI_RCV_ACK<<10}, - {"clust_pkt_que_odd", CLUSTER_PKT_QUE_ODD<<10}, - {"clust_pkt_que_even", CLUSTER_PKT_QUE_EVEN<<10}, - {"clust_pkt_sent_odd", CLUSTER_PKT_SENT_ODD<<10}, - {"clust_pkt_sent_even", CLUSTER_PKT_SENT_EVEN<<10}, - {"clust_hli_req_0", CLUSTER_HLI_REQ_0<<10}, - {"clust_hli_req_1", CLUSTER_HLI_REQ_1<<10}, - {"clust_hli_req_2", CLUSTER_HLI_REQ_2<<10}, - {"clust_hli_req_3", CLUSTER_HLI_REQ_3<<10}, - {"clust_hli_req_4", CLUSTER_HLI_REQ_4<<10}, - {"clust_hli_req_5", CLUSTER_HLI_REQ_5<<10}, - {"clust_hli_grant_0", CLUSTER_HLI_GRANT_0<<10}, - {"clust_hli_grant_1", CLUSTER_HLI_GRANT_1<<10}, - {"clust_hli_grant_2", CLUSTER_HLI_GRANT_2<<10}, - {"clust_hli_grant_3", CLUSTER_HLI_GRANT_3<<10}, - {"clust_hli_grant_4", CLUSTER_HLI_GRANT_4<<10}, - {"clust_hli_grant_5", CLUSTER_HLI_GRANT_5<<10}, - /* cnt1 duration */ - {"clust_agent_alloc_duration", - CLUSTER_AGENT_ALLOC<<10 | WCI_DURATION_BIT}, - {"clust_sfi_grant_wr_duration", - CLUSTER_SFI_GRANT_WR<<10 | WCI_DURATION_BIT}, - {"clust_sfi_grant_rd_duration", - CLUSTER_SFI_GRANT_RD<<10 | WCI_DURATION_BIT}, - {"clust_1dc_rcv_ack_duration", - CLUSTER_1DC_RCV_ACK<<10 | WCI_DURATION_BIT}, - {"clust_pkt_que_odd_duration", - CLUSTER_PKT_QUE_ODD<<10 | WCI_DURATION_BIT}, - {"clust_pkt_que_even_duration", - CLUSTER_PKT_QUE_EVEN<<10 | WCI_DURATION_BIT}, - {"clust_hli_grant_0_duration", - CLUSTER_HLI_GRANT_0<<10 | WCI_DURATION_BIT}, - {"clust_hli_grant_1_duration", - CLUSTER_HLI_GRANT_1<<10 | WCI_DURATION_BIT}, - {"clust_hli_grant_2_duration", - CLUSTER_HLI_GRANT_2<<10 | WCI_DURATION_BIT}, - {"clust_hli_grant_3_duration", - CLUSTER_HLI_GRANT_3<<10 | WCI_DURATION_BIT}, - {"clust_hli_grant_4_duration", - CLUSTER_HLI_GRANT_4<<10 | WCI_DURATION_BIT}, - {"clust_hli_grant_5_duration", - CLUSTER_HLI_GRANT_5<<10 | WCI_DURATION_BIT}, - {"clust_1_cpi_rcv_ack_duration", - CLUSTER_1_CPI_RCV_ACK<<10 | WCI_DURATION_BIT}, - /* Request agent */ - {"req_agent_alloc", REQ_AGENT_ALLOC<<10}, - {"req_agent_retired", REQ_AGENT_RETIRED<<10}, - {"req_sfi_grant_p2", REQ_SFI_GRANT_P2<<10}, - {"req_1dc_rcv_ack", REQ_1DC_RCV_ACK<<10}, - {"req_2dc_snd_ack", REQ_2DC_SND_ACK<<10}, - {"req_1_cpi_rcv_ack", REQ_1_CPI_RCV_ACK<<10}, - {"req_2_cpi_rcv_ack", REQ_2_CPI_RCV_ACK<<10}, - {"req_pkt_que", REQ_PKT_QUE<<10}, - {"req_pkt_sent", REQ_PKT_SENT<<10}, - {"req_pkt_sent_clust_rd", REQ_PKT_SENT_CLUST_RD<<10}, - {"req_pkt_sent_clust_wr", REQ_PKT_SENT_CLUST_WR<<10}, - {"req_hli_req_0", REQ_HLI_REQ_0<<10}, - {"req_hli_req_1", REQ_HLI_REQ_1<<10}, - {"req_hli_req_2", REQ_HLI_REQ_2<<10}, - {"req_hli_req_3", REQ_HLI_REQ_3<<10}, - {"req_hli_req_4", REQ_HLI_REQ_4<<10}, - {"req_hli_req_5", REQ_HLI_REQ_5<<10}, - {"req_hli_grant_0", REQ_HLI_GRANT_0<<10}, - {"req_hli_grant_1", REQ_HLI_GRANT_1<<10}, - {"req_hli_grant_2", REQ_HLI_GRANT_2<<10}, - {"req_hli_grant_3", REQ_HLI_GRANT_3<<10}, - {"req_hli_grant_4", REQ_HLI_GRANT_4<<10}, - {"req_hli_grant_5", REQ_HLI_GRANT_5<<10}, - {"req_last_reply_rcvd", REQ_LAST_REPLY_RCVD<<10}, - {"req_sent_clust_rd", REQ_SENT_CLUST_RD<<10}, - {"req_sent_clust_wr", REQ_SENT_CLUST_WR<<10}, - {"req_piq_valid", REQ_PIQ_VALID<<10}, - {"req_piq_dispatch", REQ_PIQ_DISPATCH<<10}, - {"req_ciq_valid", REQ_CIQ_VALID<<10}, - {"req_ciq_dispatch", REQ_CIQ_DISPATCH<<10}, - {"req_niq_valid", REQ_NIQ_VALID<<10}, - {"req_niq_dispatch", REQ_NIQ_DISPATCH<<10}, - {"req_numa_bypass_dispatch", REQ_NUMA_BYPASS_DISPATCH<<10}, - /* cnt1 duration */ - {"req_agent_alloc_duration", - REQ_AGENT_ALLOC<<10 | WCI_DURATION_BIT}, - {"req_sfi_grant_p2_duration", - REQ_SFI_GRANT_P2<<10 | WCI_DURATION_BIT}, - {"req_1dc_rcv_ack_duration", - REQ_1DC_RCV_ACK<<10 | WCI_DURATION_BIT}, - {"req_pkt_sent_clust_rd_duration", - REQ_PKT_SENT_CLUST_RD<<10 | WCI_DURATION_BIT}, - {"req_1_cpi_rcv_ack_duration", - REQ_1_CPI_RCV_ACK<<10 | WCI_DURATION_BIT}, - {"req_pkt_que_duration", REQ_PKT_QUE<<10 | WCI_DURATION_BIT}, - {"req_pkt_sent_duration", - REQ_PKT_SENT<<10 | WCI_DURATION_BIT}, - /* Home Agent */ - {"home_agent_alloc", HOME_AGENT_ALLOC<<10}, - {"home_agent_retired", HOME_AGENT_RETIRED<<10}, - {"home_sfi_p8_rd_aux", HOME_SFI_P8_RD_AUX<<10}, - {"home_sfi_p8_rd_main", HOME_SFI_P8_RD_MAIN<<10}, - {"home_sfi_p8_wr", HOME_SFI_P8_WR<<10}, - {"home_sfi_p9_wr", HOME_SFI_P9_WR<<10}, - {"home_sfi_p10_wr", HOME_SFI_P10_WR<<10}, - {"home_1dc_rcv_ack_aux", HOME_1DC_RCV_ACK_AUX<<10}, - {"home_1dc_rcv_ack_main", HOME_1DC_RCV_ACK_MAIN<<10}, - {"home_2dc_snd_ack", HOME_2DC_SND_ACK<<10}, - {"home_sfi_pull_seen", HOME_SFI_PULL_SEEN<<10}, - {"home_last_demrep_sent", HOME_LAST_DEMREP_SENT<<10}, - {"home_comp_pkt_seen", HOME_COMP_PKT_SEEN<<10}, - {"home_hli_req_link_0_a", HOME_HLI_REQ_LINK_0_A<<10}, - {"home_hli_req_link_0_b", HOME_HLI_REQ_LINK_0_B<<10}, - {"home_hli_req_link_1_a", HOME_HLI_REQ_LINK_1_A<<10}, - {"home_hli_req_link_1_b", HOME_HLI_REQ_LINK_1_B<<10}, - {"home_hli_req_link_2_a", HOME_HLI_REQ_LINK_2_A<<10}, - {"home_hli_req_link_2_b", HOME_HLI_REQ_LINK_2_B<<10}, - {"home_hli_req_link_3_a", HOME_HLI_REQ_LINK_3_A<<10}, - {"home_hli_req_link_3_b", HOME_HLI_REQ_LINK_3_B<<10}, - {"home_hli_req_link_4_a", HOME_HLI_REQ_LINK_4_A<<10}, - {"home_hli_req_link_4_b", HOME_HLI_REQ_LINK_4_B<<10}, - {"home_hli_req_link_5_a", HOME_HLI_REQ_LINK_5_A<<10}, - {"home_hli_req_link_5_b", HOME_HLI_REQ_LINK_5_B<<10}, - {"home_hli_grant_link_0_a", HOME_HLI_GRANT_LINK_0_A<<10}, - {"home_hli_grant_link_0_b", HOME_HLI_GRANT_LINK_0_B<<10}, - {"home_hli_grant_link_1_a", HOME_HLI_GRANT_LINK_1_A<<10}, - {"home_hli_grant_link_1_b", HOME_HLI_GRANT_LINK_1_B<<10}, - {"home_hli_grant_link_2_a", HOME_HLI_GRANT_LINK_2_A<<10}, - {"home_hli_grant_link_2_b", HOME_HLI_GRANT_LINK_2_B<<10}, - {"home_hli_grant_link_3_a", HOME_HLI_GRANT_LINK_3_A<<10}, - {"home_hli_grant_link_3_b", HOME_HLI_GRANT_LINK_3_B<<10}, - {"home_hli_grant_link_4_a", HOME_HLI_GRANT_LINK_4_A<<10}, - {"home_hli_grant_link_4_b", HOME_HLI_GRANT_LINK_4_B<<10}, - {"home_hli_grant_link_5_a", HOME_HLI_GRANT_LINK_5_A<<10}, - {"home_hli_grant_link_5_b", HOME_HLI_GRANT_LINK_5_B<<10}, - {"home_blk_cam_hit", HOME_BLK_CAM_HIT<<10}, - {"home_dir_rtned_before_rd_grant", - HOME_DIR_RTNED_BEFORE_RD_GRANT<<10}, - {"home_dir_rtned_before_rd_order", - HOME_DIR_RTNED_BEFORE_RD_ORDER<<10}, - {"home_dir_rtned_before_rd_data", - HOME_DIR_RTNED_BEFORE_RD_DATA<<10}, - {"home_dir_rtned_after_rd_data", - HOME_DIR_RTNED_AFTER_RD_DATA<<10}, - {"home_req_home", HOME_REQ_HOME<<10}, - {"home_req_same_box", HOME_REQ_SAME_BOX<<10}, - {"home_ref_data_back_home", HOME_REF_DATA_BACK_HOME<<10}, - {"home_dir_miss_alloc", HOME_DIR_MISS_ALLOC<<10}, - {"home_dir_hit_gi", HOME_DIR_HIT_GI<<10}, - {"home_dir_hit_gs", HOME_DIR_HIT_GS<<10}, - {"home_dir_hit_gm", HOME_DIR_HIT_GM<<10}, - {"home_dir_hit_rto_gm", HOME_DIR_HIT_RTO_GM<<10}, - {"home_dir_hit_rts_gms", HOME_DIR_HIT_RTS_GMS<<10}, - {"home_dir_miss_rts_gi", HOME_DIR_MISS_RTS_GI<<10}, - {"home_dir_miss_rts", HOME_DIR_MISS_RTS<<10}, - {"home_dir_miss_rto_gs_gi", HOME_DIR_MISS_RTO_GS_GI<<10}, - {"home_dir_miss_rto", HOME_DIR_MISS_RTO<<10}, - /* cnt1 duration */ - {"home_agent_alloc_duration", - HOME_AGENT_ALLOC<<10 | WCI_DURATION_BIT}, - {"home_sfi_p8_rd_aux_duration", - HOME_SFI_P8_RD_AUX<<10 | WCI_DURATION_BIT}, - {"home_sfi_p8_rd_main_duration", - HOME_SFI_P8_RD_MAIN<<10 | WCI_DURATION_BIT}, - {"home_1dc_rcv_ack_aux_duration", - HOME_1DC_RCV_ACK_AUX<<10 | WCI_DURATION_BIT}, - {"home_1dc_rcv_ack_main_duration", - HOME_1DC_RCV_ACK_MAIN<<10 | WCI_DURATION_BIT}, - {"home_sfi_p8_wr_duration", - HOME_SFI_P8_WR<<10 | WCI_DURATION_BIT}, - {"home_sfi_p9_wr_duration", - HOME_SFI_P9_WR<<10 | WCI_DURATION_BIT}, - {"home_sfi_p10_wr_duration", - HOME_SFI_P10_WR<<10 | WCI_DURATION_BIT}, - {"home_last_demrep_sent_duration", - HOME_LAST_DEMREP_SENT<<10 | WCI_DURATION_BIT}, - /* Slave agent */ - {"slave_agent_alloc", SLAVE_AGENT_ALLOC<<10}, - {"slave_agent_alloc_lpa", SLAVE_AGENT_ALLOC_LPA<<10}, - {"slave_agent_alloc_ga", SLAVE_AGENT_ALLOC_GA<<10}, - {"slave_agent_alloc_h_lpa", SLAVE_AGENT_ALLOC_H_LPA<<10}, - {"slave_agent_alloc_h_ga", SLAVE_AGENT_ALLOC_H_GA<<10}, - {"slave_agent_alloc_h_mlpa", SLAVE_AGENT_ALLOC_H_MLPA<<10}, - {"slave_agent_alloc_h_mga", SLAVE_AGENT_ALLOC_H_MGA<<10}, - {"slave_agent_alloc_h_m", SLAVE_AGENT_ALLOC_H_M<<10}, - {"slave_agent_alloc_h_inv_lpa", - SLAVE_AGENT_ALLOC_H_INV_LPA<<10}, - {"slave_agent_alloc_h_inv_ga", - SLAVE_AGENT_ALLOC_H_INV_GA<<10}, - {"slave_agent_retired", SLAVE_AGENT_RETIRED<<10}, - {"slave_reply_sent", SLAVE_REPLY_SENT<<10}, - {"slave_sfi_p6_grant_wr", SLAVE_SFI_P6_GRANT_WR<<10}, - {"slave_sfi_p12gt_rlpa", - SLAVE_SFI_P12GT_RLPA<<10}, - {"slave_sfi_p12gt_rga", - SLAVE_SFI_P12GT_RGA<<10}, - {"slave_sfi_p12gt_rhlpa", - SLAVE_SFI_P12GT_RHLPA<<10}, - {"slave_sfi_p12gt_rhga", - SLAVE_SFI_P12GT_RHGA<<10}, - {"slave_sfi_p12gt_rhmlpa", - SLAVE_SFI_P12GT_RHMLPA<<10}, - {"slave_sfi_p12gt_rhmga", - SLAVE_SFI_P12GT_RHMGA<<10}, - {"slave_sfi_p12gt_wr", SLAVE_SFI_P12GT_WR<<10}, - {"slave_1dc_rcv_ack", SLAVE_1DC_RCV_ACK<<10}, - {"slave_2dc_snd_ack", SLAVE_2DC_SND_ACK<<10}, - {"slave_2dc_snd_ack_refl", SLAVE_2DC_SND_ACK_REFL<<10}, - {"slave_4dc_snd_ack", SLAVE_4DC_SND_ACK<<10}, - {"slave_pull_seen", SLAVE_PULL_SEEN<<10}, - {"slave_h_m_ga_not_ownd", SLAVE_H_M_GA_NOT_OWND<<10}, - {"slave_h_m_no_state_change", SLAVE_H_M_NO_STATE_CHANGE<<10}, - {"slave_hli_req_0", SLAVE_HLI_REQ_0<<10}, - {"slave_hli_req_1", SLAVE_HLI_REQ_1<<10}, - {"slave_hli_req_2", SLAVE_HLI_REQ_2<<10}, - {"slave_hli_req_3", SLAVE_HLI_REQ_3<<10}, - {"slave_hli_req_4", SLAVE_HLI_REQ_4<<10}, - {"slave_hli_req_5", SLAVE_HLI_REQ_5<<10}, - {"slave_hli_grant_0", SLAVE_HLI_GRANT_0<<10}, - {"slave_hli_grant_1", SLAVE_HLI_GRANT_1<<10}, - {"slave_hli_grant_2", SLAVE_HLI_GRANT_2<<10}, - {"slave_hli_grant_3", SLAVE_HLI_GRANT_3<<10}, - {"slave_hli_grant_4", SLAVE_HLI_GRANT_4<<10}, - {"slave_hli_grant_5", SLAVE_HLI_GRANT_5<<10}, - /* cnt1 duration */ - {"slave_agent_alloc_duration", - SLAVE_AGENT_ALLOC<<10 | WCI_DURATION_BIT}, - {"slave_sfi_p12gt_rlpa_duration", - SLAVE_SFI_P12GT_RLPA<<10 | WCI_DURATION_BIT}, - {"slave_sfi_p12gt_rga_duration", - SLAVE_SFI_P12GT_RGA<<10 | WCI_DURATION_BIT}, - {"slave_sfi_p12gt_rhlpa_duration", - SLAVE_SFI_P12GT_RHLPA<<10 | WCI_DURATION_BIT}, - {"slave_sfi_p12gt_rhga_duration", - SLAVE_SFI_P12GT_RHGA<<10 | WCI_DURATION_BIT}, - {"slave_sfi_p12gtrhmlpa_duration", - SLAVE_SFI_P12GT_RHMLPA<<10 | WCI_DURATION_BIT}, - {"slave_sfi_p12gt_rhmga_duration", - SLAVE_SFI_P12GT_RHMGA<<10 | WCI_DURATION_BIT}, - {"slave_1dc_rcv_ack_c1_duration", - SLAVE_1DC_RCV_ACK<<10 | WCI_DURATION_BIT}, - {"slave_sfi_p6_grant_wr_duration", - SLAVE_SFI_P6_GRANT_WR<<10 | WCI_DURATION_BIT}, - {"slave_sfi_p12gt_wr_duration", - SLAVE_SFI_P12GT_WR<<10 | WCI_DURATION_BIT}, - {"slave_2dc_sndack_refl_duration", - SLAVE_2DC_SND_ACK_REFL<<10 | WCI_DURATION_BIT}, - {"clear_pic", MISC_CLEAR_PIC1}, - {EOSTR, 0} - } - -}; - - -/* Loopback Counter */ -static wci_event_mask_t - wci_lpbk_events_arr[WCI_NUM_PICS][WCI_LPBK_NUM_EVENTS+1] = { -/* pic 0 */ - { - {"lpbk_rcvd_data_pkt", LPBK_RCVD_DATA_PKT}, - {"lpbk_rcvd_addr_2_pkt", LPBK_RCVD_ADDR_2_PKT}, - {"lpbk_raddr2_rdata", LPBK_RADDR2_RDATA}, - {"lpbk_rcvd_addr_1_pkt", LPBK_RCVD_ADDR_1_PKT}, - {"lpbk_raddr1_rdata", LPBK_RADDR1_RDATA}, - {"lpbk_data_lpbk_full", LPBK_DATA_LPBK_FULL}, - {"lpbk_dfull_rdata", LPBK_DFULL_RDATA}, - {"lpbk_dfull_raddr2", LPBK_DFULL_RADDR2}, - {"lpbk_dfull_raddr2_rdata", LPBK_DFULL_RADDR2_RDATA}, - {"lpbk_dfull_raddr1", LPBK_DFULL_RADDR1}, - {"lpbk_dfull_raddr1_rdata", LPBK_DFULL_RADDR1_RDATA}, - {"lpbk_addr_lpbk_full", LPBK_ADDR_LPBK_FULL}, - {"lpbk_afull_rdata", LPBK_AFULL_RDATA}, - {"lpbk_afull_raddr2", LPBK_AFULL_RADDR2}, - {"lpbk_afull_raddr2_rdata", LPBK_AFULL_RADDR2_RDATA}, - {"lpbk_afull_raddr1", LPBK_AFULL_RADDR1}, - {"lpbk_afull_raddr1_rdata", LPBK_AFULL_RADDR1_RDATA}, - {"lpbk_afull_dfull", LPBK_AFULL_DFULL}, - {"lpbk_afull_dfull_rdata", LPBK_AFULL_DFULL_RDATA}, - {"lpbk_afull_dfull_raddr2", LPBK_AFULL_DFULL_RADDR2}, - {"lpbk_afull_dfull_raddr2_rdata", LPBK_AFULL_DFULL_RADDR2_RDATA}, - {"lpbk_afull_dfull_raddr1", LPBK_AFULL_DFULL_RADDR1}, - {"lpbk_afull_dfull_raddr1_rdata", LPBK_AFULL_DFULL_RADDR1_RDATA}, - {"clear_pic", LPBK_CLEAR_PIC0} - }, -/* pic 1 */ - { - {"lpbk_rcvd_data_pkt", LPBK_RCVD_DATA_PKT<<16}, - {"lpbk_rcvd_addr_2_pkt", LPBK_RCVD_ADDR_2_PKT<<16}, - {"lpbk_raddr2_rdata", LPBK_RADDR2_RDATA<<16}, - {"lpbk_rcvd_addr_1_pkt", LPBK_RCVD_ADDR_1_PKT<<16}, - {"lpbk_raddr1_rdata", LPBK_RADDR1_RDATA<<16}, - {"lpbk_data_lpbk_full", LPBK_DATA_LPBK_FULL<<16}, - {"lpbk_dfull_rdata", LPBK_DFULL_RDATA<<16}, - {"lpbk_dfull_raddr2", LPBK_DFULL_RADDR2<<16}, - {"lpbk_dfull_raddr2_rdata", LPBK_DFULL_RADDR2_RDATA<<16}, - {"lpbk_dfull_raddr1", LPBK_DFULL_RADDR1<<16}, - {"lpbk_dfull_raddr1_rdata", LPBK_DFULL_RADDR1_RDATA<<16}, - {"lpbk_addr_lpbk_full", LPBK_ADDR_LPBK_FULL<<16}, - {"lpbk_afull_rdata", LPBK_AFULL_RDATA<<16}, - {"lpbk_afull_raddr2", LPBK_AFULL_RADDR2<<16}, - {"lpbk_afull_raddr2_rdata", LPBK_AFULL_RADDR2_RDATA<<16}, - {"lpbk_afull_raddr1", LPBK_AFULL_RADDR1<<16}, - {"lpbk_afull_raddr1_rdata", LPBK_AFULL_RADDR1_RDATA<<16}, - {"lpbk_afull_dfull", LPBK_AFULL_DFULL<<16}, - {"lpbk_afull_dfull_rdata", LPBK_AFULL_DFULL_RDATA<<16}, - {"lpbk_afull_dfull_raddr2", LPBK_AFULL_DFULL_RADDR2<<16}, - {"lpbk_afull_dfull_raddr2_rdata", LPBK_AFULL_DFULL_RADDR2_RDATA<<16}, - {"lpbk_afull_dfull_raddr1", LPBK_AFULL_DFULL_RADDR1<<16}, - {"lpbk_afull_dfull_raddr1_rdata", LPBK_AFULL_DFULL_RADDR1_RDATA<<16}, - {"clear_pic", LPBK_CLEAR_PIC1} - } -}; - - - -/* Link Counter */ -/* one event list per counter, per link */ -static wci_event_mask_t - wci_link_events_arr[WCI_NUM_PICS][WCI_LINK_NUM_EVENTS+1] = { -/* pic 0 */ - { - {"link_sending_admin_pkts", LINK_SENDING_ADMIN_PKTS}, - {"link_rcvd_mh_data_pkt", LINK_RCVD_MH_DATA_PKT}, - {"link_sadm_rmhdp", LINK_RMHDP_SADM}, - {"link_rcvd_data_pkt", LINK_RCVD_DATA_PKT}, - {"link_sadm_rdp", LINK_RDP_SADM}, - {"link_rdp_rmhdp", LINK_RDP_RMHDP}, - {"link_rejected_flit", LINK_REJECTED_FLIT}, - {"link_rejflit_sadm", LINK_REJFLIT_SADM}, - {"link_rejflit_rmhdp", LINK_REJFLIT_RMHDP}, - {"link_rejflit_rmhdp_sadm", LINK_REJFLIT_RMHDP_SADM}, - {"link_rejflit_rdp", LINK_REJFLIT_RDP}, - {"link_rejflit_rdp_sadm", LINK_REJFLIT_RDP_SADM}, - {"link_rcvd_admin_pkt", LINK_RCVD_ADMIN_PKT}, - {"link_radmp_sadm", LINK_RADMP_SADM}, - {"link_radmp_rmhdp", LINK_RADMP_RMHDP}, - {"link_radmp_rmhdp_sadm", LINK_RADMP_RMHDP_SADM}, - {"link_radmp_rdp", LINK_RADMP_RDP}, - {"link_radmp_rdp_sadm", LINK_RADMP_RDP_SADM}, - {"link_radmp_rejflit", LINK_RADMP_REJFLIT}, - {"clear_pic", LINK_CLEAR_PIC0}, - }, -/* pic 1 */ - { - {"link_sending_admin_pkts", LINK_SENDING_ADMIN_PKTS<<16}, - {"link_rcvd_mh_data_pkt", LINK_RCVD_MH_DATA_PKT<<16}, - {"link_sadm_rmhdp", LINK_RMHDP_SADM<<16}, - {"link_rcvd_data_pkt", LINK_RCVD_DATA_PKT<<16}, - {"link_sadm_rdp", LINK_RDP_SADM<<16}, - {"link_rdp_rmhdp", LINK_RDP_RMHDP<<16}, - {"link_rejected_flit", LINK_REJECTED_FLIT<<16}, - {"link_rejflit_sadm", LINK_REJFLIT_SADM<<16}, - {"link_rejflit_rmhdp", LINK_REJFLIT_RMHDP<<16}, - {"link_rejflit_rmhdp_sadm", LINK_REJFLIT_RMHDP_SADM<<16}, - {"link_rejflit_rdp", LINK_REJFLIT_RDP<<16}, - {"link_rejflit_rdp_sadm", LINK_REJFLIT_RDP_SADM<<16}, - {"link_rcvd_admin_pkt", LINK_RCVD_ADMIN_PKT<<16}, - {"link_radmp_sadm", LINK_RADMP_SADM<<16}, - {"link_radmp_rmhdp", LINK_RADMP_RMHDP<<16}, - {"link_radmp_rmhdp_sadm", LINK_RADMP_RMHDP_SADM<<16}, - {"link_radmp_rdp", LINK_RADMP_RDP<<16}, - {"link_radmp_rdp_sadm", LINK_RADMP_RDP_SADM<<16}, - {"link_radmp_rejflit", LINK_RADMP_REJFLIT<<16}, - {"clear_pic", LINK_CLEAR_PIC1} - } -}; - -/* - * WCI Safari Histogramming Counter - * One event list per pic counter. - */ -static wci_event_mask_t - wci_sfi_events_arr[WCI_NUM_PICS][WCI_SFI_NUM_EVENTS + 1] = { -/* pic 0 */ - { - {"sfi_hstgrm_all_trans", - SFI_HSTGRM_ALL_TRANS | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_int", SFI_HSTGRM_INT | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_local_int", - SFI_HSTGRM_LOCAL_INT | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_rmt_clu_incm_int", - SFI_HSTGRM_RMT_CLU_INCM_INT | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_rmt_ssm_incm_int", - SFI_HSTGRM_RMT_SSM_INCM_INT | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_io", SFI_HSTGRM_IO | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_rmt_ssm_incm_io", - SFI_HSTGRM_RMT_SSM_INCM_IO | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_cohrnt", SFI_HSTGRM_COHRNT | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_rmt_clu_incm_cohrnt", - SFI_HSTGRM_RMT_CLU_INCM_COHRNT | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_rmt_ssm_otg_cohrnt", - SFI_HSTGRM_RMT_SSM_OTG_COHRNT | SFI_SFI_HISTOGRAM0}, - {"sfi_hstgrm_rmt_ssm_incm_cohrnt", - SFI_HSTGRM_RMT_SSM_INCM_COHRNT | SFI_SFI_HISTOGRAM0}, - {"clear_pic", WCI_SFI_CLEAR_PIC0} - }, -/* pic 1 */ - { - {"sfi_hstgrm_all_trans", - SFI_HSTGRM_ALL_TRANS<<4 | SFI_SFI_HISTOGRAM1<< 10}, - {"sfi_hstgrm_int", SFI_HSTGRM_INT<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"sfi_hstgrm_local_int", - SFI_HSTGRM_LOCAL_INT<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"sfi_hstgrm_rmt_clu_incm_int", - SFI_HSTGRM_RMT_CLU_INCM_INT<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"sfi_hstgrm_rmt_ssm_incm_int", - SFI_HSTGRM_RMT_SSM_INCM_INT<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"sfi_hstgrm_io", SFI_HSTGRM_IO<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"sfi_hstgrm_rmt_ssm_incm_io", - SFI_HSTGRM_RMT_SSM_INCM_IO<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"sfi_hstgrm_cohrnt", - SFI_HSTGRM_COHRNT<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"sfi_hstgrm_rmt_clu_incm_cohrnt", - SFI_HSTGRM_RMT_CLU_INCM_COHRNT<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"sfi_hstgrm_rmt_ssm_otg_cohrnt", - SFI_HSTGRM_RMT_SSM_OTG_COHRNT<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"sfi_hstgrm_rmt_ssm_incm_cohrnt", - SFI_HSTGRM_RMT_SSM_INCM_COHRNT<<4 | SFI_SFI_HISTOGRAM1<<10}, - {"clear_pic", WCI_SFI_CLEAR_PIC1} - } -}; - -static wci_sfi_regs_value_t wci_sfi_ctr_regs_tab[WCI_SFI_NUM_EVENTS] = { - { 0x0000000000000000ULL, 0x0000000000000000ULL, 0x000000000007FFFFULL }, - { 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000200ULL }, - { 0x00000000000F8000ULL, 0x00000000000F8000ULL, 0x0000000000000200ULL }, - { 0x0000F80000000000ULL, 0x0000F80000000000ULL, 0x0000000000000200ULL }, - { 0x0000F80000000000ULL, 0x0000F80000000000ULL, 0x0000000000000200ULL }, - { 0x0000000000000000ULL, 0x0000000000000000ULL, 0x000000000000000FULL }, - { 0x0000F80000000000ULL, 0x0000F80000000000ULL, 0x000000000000000FULL }, - { 0x0000000000000000ULL, 0x0000000000000000ULL, 0x000000000007FDF0ULL }, - { 0x0000F80000000000ULL, 0x0000F80000000000ULL, 0x0000000000018060ULL }, - { 0x0000000000000000ULL, 0x0000000000000000ULL, 0x00000000000001F0ULL }, - { 0x0000F80000000000ULL, 0x0000F80000000000ULL, 0x000000000007FC00ULL } -}; - - -/* - * Driver globals - */ -static kstat_t *wci_misc_pic_ksp[WCI_NUM_PICS]; /* Misc picN kstats */ -static kstat_t *wci_lpbk_pic_ksp[WCI_NUM_PICS]; /* Lpbk picN kstats */ -static kstat_t *wci_link_pic_ksp[WCI_NUM_LINKS][WCI_NUM_PICS]; /* link */ -static kstat_t *wci_sfi_pic_ksp[WCI_NUM_PICS]; /* SFI histogram picN kstats */ - -void -wci_add_counters_kstats(struct wci_common_soft_state *softsp, char *drvname) -{ - wci_add_misc_kstats(softsp, drvname); - wci_add_lpbk_kstats(softsp, drvname); - wci_add_link_kstats(softsp, drvname); - wci_add_sfi_kstats(softsp, drvname); -} - -void -wci_add_picN_kstats(char *drvname) -{ - wci_add_misc_pic_kstats(drvname); - wci_add_lpbk_pic_kstats(drvname); - wci_add_link_pic_kstats(drvname); - wci_add_sfi_pic_kstats(drvname); -} - - -static void -wci_add_misc_kstats(struct wci_common_soft_state *softsp, char *drvname) -{ - struct kstat *wci_misc_ksp; - struct wci_counters_kstat *wci_misc_named_ksp; - char drvmod[15]; - - /* - * A "counter" kstat is created for each WCI - * instance that provides access to the %pcr and %pic - * registers for that instance. - */ - (void) sprintf(drvmod, WCI_KSTAT_NAME, drvname); - if ((wci_misc_ksp = kstat_create(drvmod, softsp->instance, - "counters", "bus", KSTAT_TYPE_NAMED, - sizeof (struct wci_counters_kstat) / sizeof (kstat_named_t), - KSTAT_FLAG_WRITABLE)) == NULL) { - cmn_err(CE_WARN, "wci%d: kstat_create failed", - softsp->instance); - return; - } - - wci_misc_named_ksp = - (struct wci_counters_kstat *)(wci_misc_ksp->ks_data); - - /* initialize the named kstats */ - kstat_named_init(&wci_misc_named_ksp->wci_ctr_ctl, - WCI_CTRCTL_KSTAT_NAMED, - KSTAT_DATA_UINT64); - kstat_named_init(&wci_misc_named_ksp->wci_ctr0, - WCI_CTR0_KSTAT_NAMED, - KSTAT_DATA_UINT64); - kstat_named_init(&wci_misc_named_ksp->wci_ctr1, - WCI_CTR1_KSTAT_NAMED, - KSTAT_DATA_UINT64); - wci_misc_ksp->ks_update = wci_misc_kstat_update; - wci_misc_ksp->ks_private = (void *)softsp; - kstat_install(wci_misc_ksp); - /* update the common softstate */ - softsp->wci_misc_counters_ksp = wci_misc_ksp; -} - -/* - * called from wci_add_picN_kstats() to create a kstat for each %pic that - * the WCI Misc counter supports. These (read-only) kstats export the - * event names that each %pic supports. - * - * wci_misc_events_arr is an array of (event_name, pcr_mask) records - * for each (pic, event) pair. - */ -static void -wci_add_misc_pic_kstats(char *drvname) -{ - struct kstat_named *wci_misc_pic_named_data; - int event, pic; - char pic_name[30]; - int i = 0; - int num_events = 0; - char drvmod[15]; - - for (pic = 0; pic < WCI_NUM_PICS; pic++) { - (void) sprintf(pic_name, "pic%d", pic); - /* - * calculate the actual number of events for - * each misc picN, since they are different for each picN - * Note: make sure {NULL, 0 } is the last event - */ - for (i = 0; i < WCI_MISC_NUM_EVENTS; i++) { - if (strcmp(wci_misc_events_arr[pic][i].event_name, - EOSTR) == 0) - break; - } - num_events = i; - /* - * create the picN kstat. The size of this kstat is - * WCI_NUM_EVENTS + 1 for the clear_event_mask - */ - (void) sprintf(drvmod, WCI_KSTAT_NAME, drvname); - if ((wci_misc_pic_ksp[pic] = kstat_create(drvmod, 0, - pic_name, "bus", KSTAT_TYPE_NAMED, - num_events, NULL)) == NULL) { - cmn_err(CE_WARN, "wci misc %s: kstat_create failed", - pic_name); - /* - * remove all picN kstat from 0 to pic-1 - * if current picN kstat create fails - */ - for (i = 0; i < pic; i++) { - kstat_delete(wci_misc_pic_ksp[i]); - wci_misc_pic_ksp[i] = NULL; - } - return; - } - wci_misc_pic_named_data = - (struct kstat_named *)(wci_misc_pic_ksp[pic]->ks_data); - /* - * for each picN event we need to write a kstat record - * (name = EVENT, value.ui64 = PCR_MASK) - */ - for (event = 0; event < num_events; event ++) { - /* pcr_mask */ - wci_misc_pic_named_data[event].value.ui64 = - wci_misc_events_arr[pic][event].pcr_mask; - /* event-name */ - kstat_named_init(&wci_misc_pic_named_data[event], - wci_misc_events_arr[pic][event].event_name, - KSTAT_DATA_UINT64); - } - kstat_install(wci_misc_pic_ksp[pic]); - } -} - - -static int wci_misc_kstat_update(kstat_t *ksp, int rw) -{ - struct wci_counters_kstat *wci_misc_ksp; - struct wci_common_soft_state *softsp; - uint64_t wci_cluster_ctr; - - wci_misc_ksp = (struct wci_counters_kstat *)ksp->ks_data; - softsp = (struct wci_common_soft_state *)ksp->ks_private; - - if (rw == KSTAT_WRITE) { - /* - * can only write the wci_misc_ctr_ctl register - */ - *(softsp->wci_misc_ctr_ctl_vaddr) = - (uint64_t)wci_misc_ksp->wci_ctr_ctl.value.ui64; - /* - * The misc counters can be used to count cluster - * related events related to incoming transactions - * as they are processed by the CMMU. - * The wci_cluster_ctr_ctl register has bits <3:0> - * specifying 4 different events that are counted - * if a misc counter is programmed with event - * "cluster event 0", and bits <7:4> specifying 4 - * different events that are counted if a misc - * counter is programmed with event "cluster event 1". - * For counter 0, bits <27:24> of the - * wci_misc_ksp->wci_ctr_ctl represent the setting of - * the either the cnt0 or the cnt1 wci_cluster_ctr_ctl - * register fields. For counter 1, bits <31:28> of - * the wci_misc_ksp->wci_ctr_ctl represent the setting - * of the either the cnt0 or the cnt1 wci_cluster_ctr_ctl - * register fields. Selecting a pic0 or pic1 event type - * which specifies the CACHE-CTR agent and the event type - * of "cluster event 0" or "cluster event 1" causes the - * cnt0 or cnt1 events (respectively) in the - * wci_cluster_ctr_ctl register to be set as specified in - * bits <27:24> or <31:28>, respectively. If one or more - * of bits <31:24> of wci_misc_ksp->wci_ctr_ctl are - * non-zero, we need to write those bits in - * wci_cluster_ctr_ctl registers to set and enable - * the corresponding fields. - * Hence, the cluster counter fields are contained in the - * wci_misc_ksp->wci_ctr_ctl. We need to write these bits - * to the misc control register wci_misc_ctr_ctl_vaddr. - * Since for all the other misc counter event masks, - * the bits <31:24> are set to 0, these bits are never - * used by any events other than those with Cacthe-control - * agent and "cluster event 0" or "cluster event 1" set. - * Thus, It does not matter that we also write these bits - * to the misc control register. Also, for `busstat` support, - * we must keep consistent misc control register (pcr) values. - */ - wci_cluster_ctr = (uint64_t) - (wci_misc_ksp->wci_ctr_ctl.value.ui64 >> 24) & - WCI_CLUSTER_MASK; - - /* only need bits<7:0>, keep bits <63:8> original value */ - if (wci_cluster_ctr > 0) - *(softsp->wci_cluster_ctr_ctl_vaddr) = - (*(softsp->wci_cluster_ctr_ctl_vaddr) & - (~WCI_CLUSTER_MASK)) | wci_cluster_ctr; - - } else { - /* - * copy the current state of the hardware into the - * kstat structure. - */ - wci_misc_ksp->wci_ctr_ctl.value.ui64 = - (uint64_t)*(softsp->wci_misc_ctr_ctl_vaddr); - wci_misc_ksp->wci_ctr0.value.ui64 = - (*(softsp->wci_misc_ctr_vaddr)) & WCI_PIC0_MASK; - wci_misc_ksp->wci_ctr1.value.ui64 = - (*(softsp->wci_misc_ctr_vaddr)) >> 32; - } - return (0); -} - - - -static void -wci_add_lpbk_kstats(struct wci_common_soft_state *softsp, char *drvname) -{ - struct kstat *wci_lpbk_ksp; - struct wci_counters_kstat *wci_lpbk_named_ksp; - char drvmod[15]; - - (void) sprintf(drvmod, WCI_LPBK_KSTAT_NAME, drvname); - if ((wci_lpbk_ksp = kstat_create(drvmod, - softsp->instance, "counters", "bus", KSTAT_TYPE_NAMED, - sizeof (struct wci_counters_kstat) / sizeof (kstat_named_t), - KSTAT_FLAG_WRITABLE)) == NULL) { - cmn_err(CE_WARN, "wci%d: kstat_create failed", - softsp->instance); - return; - } - - wci_lpbk_named_ksp = (struct wci_counters_kstat *) - (wci_lpbk_ksp->ks_data); - /* initialize the named kstats */ - kstat_named_init(&wci_lpbk_named_ksp->wci_ctr_ctl, - WCI_CTRCTL_KSTAT_NAMED, KSTAT_DATA_UINT64); - kstat_named_init(&wci_lpbk_named_ksp->wci_ctr0, - WCI_CTR0_KSTAT_NAMED, KSTAT_DATA_UINT64); - kstat_named_init(&wci_lpbk_named_ksp->wci_ctr1, - WCI_CTR1_KSTAT_NAMED, KSTAT_DATA_UINT64); - - wci_lpbk_ksp->ks_update = wci_lpbk_kstat_update; - wci_lpbk_ksp->ks_private = (void *)softsp; - kstat_install(wci_lpbk_ksp); - /* update the common softstate */ - softsp->wci_lpbk_counters_ksp = wci_lpbk_ksp; -} - - -static void -wci_add_lpbk_pic_kstats(char *drvname) -{ - struct kstat_named *wci_lpbk_pic_named_data; - int event, pic; - char pic_name[30]; - char drvmod[15]; - - (void) sprintf(drvmod, WCI_LPBK_KSTAT_NAME, drvname); - for (pic = 0; pic < WCI_NUM_PICS; pic++) { - (void) sprintf(pic_name, "pic%d", pic); - /* - * create the picN kstat. The size of this kstat is - * WCI_LPBK_NUM_EVENTS + 1 for the clear_event_mask - */ - if ((wci_lpbk_pic_ksp[pic] = kstat_create(drvmod, - 0, pic_name, "bus", KSTAT_TYPE_NAMED, - WCI_LPBK_NUM_EVENTS + 1, NULL)) == NULL) { - cmn_err(CE_WARN, - "wci lpbk %s: kstat_create failed", pic_name); - /* remove pic0 kstat if pic1 create fails */ - if (pic == 1) { - kstat_delete(wci_lpbk_pic_ksp[0]); - wci_lpbk_pic_ksp[0] = NULL; - } - - return; - } - wci_lpbk_pic_named_data = - (struct kstat_named *)(wci_lpbk_pic_ksp[pic]->ks_data); - - /* - * for each picN event we need to write a kstat record - * (name = EVENT, value.ui64 = PCR_MASK) - */ - for (event = 0; event < WCI_LPBK_NUM_EVENTS + 1; event ++) { - /* pcr_mask */ - wci_lpbk_pic_named_data[event].value.ui64 = - wci_lpbk_events_arr[pic][event].pcr_mask; - /* event_name */ - kstat_named_init(&wci_lpbk_pic_named_data[event], - wci_lpbk_events_arr[pic][event].event_name, - KSTAT_DATA_UINT64); - } - kstat_install(wci_lpbk_pic_ksp[pic]); - } -} - - -static int wci_lpbk_kstat_update(kstat_t *ksp, int rw) { - struct wci_counters_kstat *wci_lpbk_ksp; - struct wci_common_soft_state *softsp; - - - wci_lpbk_ksp = (struct wci_counters_kstat *)ksp->ks_data; - softsp = (struct wci_common_soft_state *)ksp->ks_private; - - if (rw == KSTAT_WRITE) { - /* - * can only write the wci_misc_ctr_ctl register - */ - *(softsp->wci_lpbk_ctr_ctl_vaddr) = - (uint64_t)wci_lpbk_ksp->wci_ctr_ctl.value.ui64; - - - } else { - wci_lpbk_ksp->wci_ctr_ctl.value.ui64 = - (uint64_t)*(softsp->wci_lpbk_ctr_ctl_vaddr); - wci_lpbk_ksp->wci_ctr0.value.ui64 = - *(softsp->wci_lpbk_ctr_vaddr) & WCI_PIC0_MASK; - wci_lpbk_ksp->wci_ctr1.value.ui64 = - *(softsp->wci_lpbk_ctr_vaddr) >> 32; - - } - return (0); -} - - - - -static void -wci_add_link_kstats(struct wci_common_soft_state *softsp, char *drvname) -{ - struct kstat *wci_link_ksp[WCI_NUM_LINKS]; - struct wci_counters_kstat *wci_link_named_ksp[WCI_NUM_LINKS]; - int link_no; - char wci_link_kstat_name[30]; - char tmp[15]; - - /* - * Calculate the link kstat name length, i.e., length of "wssmlink". - * This is needed in the wci_link_kstat_update() routine - */ - (void) sprintf(tmp, WCI_LINK_KSTAT_NAME, drvname); - wci_link_kstat_modlen = strlen(tmp); - - for (link_no = 0; link_no < WCI_NUM_LINKS; link_no++) { - (void) sprintf(wci_link_kstat_name, "%slink%c", drvname, - link_no + 'a'); - if ((wci_link_ksp[link_no] = kstat_create( - wci_link_kstat_name, - softsp->instance, - "counters", "bus", KSTAT_TYPE_NAMED, - sizeof (struct wci_counters_kstat) / - sizeof (kstat_named_t), - KSTAT_FLAG_WRITABLE)) == NULL) { - cmn_err(CE_WARN, "wci%d: kstat_create failed", - softsp->instance); - return; - } - - wci_link_named_ksp[link_no] = (struct wci_counters_kstat *) - (wci_link_ksp[link_no]->ks_data); - - /* initialize the named kstats */ - - kstat_named_init(&wci_link_named_ksp[link_no]->wci_ctr_ctl, - WCI_CTRCTL_KSTAT_NAMED, - KSTAT_DATA_UINT64); - kstat_named_init(&wci_link_named_ksp[link_no]->wci_ctr0, - WCI_CTR0_KSTAT_NAMED, - KSTAT_DATA_UINT64); - kstat_named_init(&wci_link_named_ksp[link_no]->wci_ctr1, - WCI_CTR1_KSTAT_NAMED, - KSTAT_DATA_UINT64); - wci_link_ksp[link_no]->ks_update = wci_link_kstat_update; - wci_link_ksp[link_no]->ks_private = (void *)softsp; - kstat_install(wci_link_ksp[link_no]); - - /* update the common softstate */ - softsp->wci_link_counters_ksp[link_no] = - wci_link_ksp[link_no]; - } -} - - - -static void -wci_add_link_pic_kstats(char *drvname) -{ - - struct kstat_named *wci_link_pic_named_data; - - int event, pic, link_no; - char pic_name[30]; - char wci_link_kstat_name[30]; - - for (link_no = 0; link_no < WCI_NUM_LINKS; link_no++) { - (void) sprintf(wci_link_kstat_name, "%slink%c", drvname, - link_no + 'a'); - for (pic = 0; pic < WCI_NUM_PICS; pic++) { - (void) sprintf(pic_name, "pic%d", pic); - /* - * create the picN kstat. The size of this kstat is - * WCI_LINK_NUM_EVENTS + 1 for the clear_event_mask - */ - if ((wci_link_pic_ksp[link_no][pic] = kstat_create( - wci_link_kstat_name, 0, pic_name, "bus", - KSTAT_TYPE_NAMED, - WCI_LINK_NUM_EVENTS + 1, - NULL)) == NULL) { - cmn_err(CE_WARN, - "wci link%d %s: kstat_create failed", - link_no, pic_name); - - /* remove pic0 kstat if pic1 create fails */ - if (pic == 1) { - kstat_delete(wci_link_pic_ksp - [link_no][0]); - wci_link_pic_ksp[link_no][0] = NULL; - } - - return; - } - wci_link_pic_named_data = - (struct kstat_named *) - (wci_link_pic_ksp[link_no][pic]->ks_data); - - /* - * for each picN event we need to write a kstat - * record (name = EVENT, value.ui64 = PCR_MASK) - */ - for (event = 0; event < WCI_LINK_NUM_EVENTS + 1; - event++) { - /* pcr mask */ - wci_link_pic_named_data[event]. - value.ui64 = - wci_link_events_arr[pic][event].pcr_mask; - - /* event_name */ - kstat_named_init( - &wci_link_pic_named_data[event], - wci_link_events_arr[pic][event]. - event_name, - KSTAT_DATA_UINT64); - } - - kstat_install(wci_link_pic_ksp[link_no][pic]); - - } - } -} - - -static int wci_link_kstat_update(kstat_t *ksp, int rw) { - struct wci_counters_kstat *wci_link_ksp; - struct wci_common_soft_state *softsp; - int arr_index; - - wci_link_ksp = (struct wci_counters_kstat *)ksp->ks_data; - ASSERT(wci_link_ksp != NULL); - softsp = (struct wci_common_soft_state *)ksp->ks_private; - ASSERT(softsp != NULL); - arr_index = ksp->ks_module[wci_link_kstat_modlen] - 'a'; - ASSERT(arr_index >= 0); - - if (rw == KSTAT_WRITE) { - /* - * can only write the wci_link_ctr_ctl register array - */ - *(softsp->wci_link_ctr_ctl_vaddr[arr_index]) = - (uint64_t)wci_link_ksp->wci_ctr_ctl.value.ui64; - - } else { - ASSERT(softsp->wci_link_ctr_ctl_vaddr[arr_index] != NULL); - - wci_link_ksp->wci_ctr_ctl.value.ui64 = - (uint64_t)*(softsp->wci_link_ctr_ctl_vaddr[arr_index]); - wci_link_ksp->wci_ctr0.value.ui64 = (uint64_t) - *(softsp->wci_link_ctr_vaddr[arr_index]) & WCI_PIC0_MASK; - wci_link_ksp->wci_ctr1.value.ui64 = (uint64_t) - *(softsp->wci_link_ctr_vaddr[arr_index]) >> 32; - } - return (0); -} - -static void -wci_add_sfi_kstats(struct wci_common_soft_state *softsp, char *drvname) -{ - struct kstat *wci_sfi_ksp; - struct wci_counters_kstat *wci_sfi_named_ksp; - char drvmod[15]; - - (void) sprintf(drvmod, WCI_SFI_KSTAT_NAME, drvname); - if ((wci_sfi_ksp = kstat_create(drvmod, - softsp->instance, "counters", "bus", KSTAT_TYPE_NAMED, - sizeof (struct wci_counters_kstat) / sizeof (kstat_named_t), - KSTAT_FLAG_WRITABLE)) == NULL) { - cmn_err(CE_WARN, "wci%d: kstat_create failed for sfi histogram", - softsp->instance); - return; - } - - wci_sfi_named_ksp = (struct wci_counters_kstat *) - (wci_sfi_ksp->ks_data); - /* initialize the named kstats */ - kstat_named_init(&wci_sfi_named_ksp->wci_ctr_ctl, - WCI_CTRCTL_KSTAT_NAMED, KSTAT_DATA_UINT64); - kstat_named_init(&wci_sfi_named_ksp->wci_ctr0, - WCI_CTR0_KSTAT_NAMED, KSTAT_DATA_UINT64); - kstat_named_init(&wci_sfi_named_ksp->wci_ctr1, - WCI_CTR1_KSTAT_NAMED, KSTAT_DATA_UINT64); - - wci_sfi_ksp->ks_update = wci_sfi_kstat_update; - wci_sfi_ksp->ks_private = (void *)softsp; - kstat_install(wci_sfi_ksp); - /* update the common softstate */ - softsp->wci_sfi_counters_ksp = wci_sfi_ksp; -} - -static void -wci_add_sfi_pic_kstats(char *drvname) -{ - struct kstat_named *wci_sfi_pic_named_data; - int event, pic; - char pic_name[30]; - char drvmod[15]; - - (void) sprintf(drvmod, WCI_SFI_KSTAT_NAME, drvname); - for (pic = 0; pic < WCI_NUM_PICS; pic++) { - (void) sprintf(pic_name, "pic%d", pic); - /* - * create the picN kstat. The size of this kstat is - * WCI_SFI_NUM_EVENTS + 1 for the clear_event_mask - */ - if ((wci_sfi_pic_ksp[pic] = kstat_create(drvmod, - 0, pic_name, "bus", KSTAT_TYPE_NAMED, - WCI_SFI_NUM_EVENTS + 1, NULL)) == NULL) { - cmn_err(CE_WARN, - "wci sfi %s: kstat_create failed", pic_name); - /* remove pic0 kstat if pic1 create fails */ - if (pic == 1) { - kstat_delete(wci_sfi_pic_ksp[0]); - wci_sfi_pic_ksp[0] = NULL; - } - - return; - } - wci_sfi_pic_named_data = - (struct kstat_named *)(wci_sfi_pic_ksp[pic]->ks_data); - - /* - * for each picN event we need to write a kstat record - * (name = EVENT, value.ui64 = PCR_MASK) - */ - for (event = 0; event < WCI_SFI_NUM_EVENTS + 1; event ++) { - /* pcr_mask */ - wci_sfi_pic_named_data[event].value.ui64 = - wci_sfi_events_arr[pic][event].pcr_mask; - /* event_name */ - kstat_named_init(&wci_sfi_pic_named_data[event], - wci_sfi_events_arr[pic][event].event_name, - KSTAT_DATA_UINT64); - } - kstat_install(wci_sfi_pic_ksp[pic]); - } -} - -static int wci_sfi_kstat_update(kstat_t *ksp, int rw) -{ - struct wci_counters_kstat *wci_sfi_ksp; - struct wci_common_soft_state *softsp; - uint64_t evt0, evt1; - uint_t id0, id1; - - wci_sfi_ksp = (struct wci_counters_kstat *)ksp->ks_data; - softsp = (struct wci_common_soft_state *)ksp->ks_private; - - if (rw == KSTAT_WRITE) { - /* write to virtual sfi counter control */ - softsp->wci_sfi_sw_ctr_ctl = - wci_sfi_ksp->wci_ctr_ctl.value.ui64; - /* write to wci_misc_ctr_ctl register bit <19:0> */ - *softsp->wci_misc_ctr_ctl_vaddr = - wci_sfi_ksp->wci_ctr_ctl.value.ui64 & - WCI_SFI_SW_CTR_CTL_MASK; - - evt0 = (softsp->wci_sfi_sw_ctr_ctl & WCI_SFI_CTR0_EVENT_MASK); - id0 = (uint_t)(evt0 >> WCI_SFI_CTR0_EVENT_SHIFT); - if (evt0 > 0) { - /* safri histogramming counter 0 */ - *softsp->wci_sfi_ctr0_mask_vaddr = - wci_sfi_ctr_regs_tab[id0-1].wci_sfi_ctr_mask_val; - *softsp->wci_sfi_ctr0_match_transaction_vaddr = - wci_sfi_ctr_regs_tab[id0-1]. - wci_sfi_ctr_match_trans_val; - - switch (evt0) { - case SFI_HSTGRM_LOCAL_INT: - *softsp->wci_sfi_ctr0_match_vaddr = - (softsp->node_id << - WCI_SFI_ADDR_TNID_SHIFT) & - wci_sfi_ctr_regs_tab[id0-1]. - wci_sfi_ctr_match_val; - break; - case SFI_HSTGRM_RMT_CLU_INCM_INT: - case SFI_HSTGRM_RMT_SSM_INCM_INT: - case SFI_HSTGRM_RMT_SSM_INCM_IO: - case SFI_HSTGRM_RMT_CLU_INCM_COHRNT: - case SFI_HSTGRM_RMT_SSM_INCM_COHRNT: - *softsp->wci_sfi_ctr0_match_vaddr = - ((uint64_t)(softsp->node_id) - << WCI_SFI_ATRANS_DEVID_SHIFT) & - wci_sfi_ctr_regs_tab[id0-1]. - wci_sfi_ctr_match_val; - break; - default: - *softsp->wci_sfi_ctr0_match_vaddr = - wci_sfi_ctr_regs_tab[id0-1]. - wci_sfi_ctr_match_val; - break; - } - } - - evt1 = softsp->wci_sfi_sw_ctr_ctl & WCI_SFI_CTR1_EVENT_MASK; - id1 = (uint_t)(evt1 >> WCI_SFI_CTR1_EVENT_SHIFT); - if (evt1 > 0) { - /* safri histogramming counter 1 */ - *softsp->wci_sfi_ctr1_mask_vaddr = - wci_sfi_ctr_regs_tab[id1-1].wci_sfi_ctr_mask_val; - *softsp->wci_sfi_ctr1_match_transaction_vaddr = - wci_sfi_ctr_regs_tab[id1-1]. - wci_sfi_ctr_match_trans_val; - - switch (evt1 >> 4) { - case SFI_HSTGRM_LOCAL_INT: - *softsp->wci_sfi_ctr1_match_vaddr = - (softsp->node_id << - WCI_SFI_ADDR_TNID_SHIFT) & - wci_sfi_ctr_regs_tab[id1-1]. - wci_sfi_ctr_match_val; - break; - case SFI_HSTGRM_RMT_CLU_INCM_INT: - case SFI_HSTGRM_RMT_SSM_INCM_INT: - case SFI_HSTGRM_RMT_SSM_INCM_IO: - case SFI_HSTGRM_RMT_CLU_INCM_COHRNT: - case SFI_HSTGRM_RMT_SSM_INCM_COHRNT: - *softsp->wci_sfi_ctr1_match_vaddr = - ((uint64_t)(softsp->node_id) - << WCI_SFI_ATRANS_DEVID_SHIFT) & - wci_sfi_ctr_regs_tab[id1-1]. - wci_sfi_ctr_match_val; - break; - default: - *softsp->wci_sfi_ctr1_match_vaddr = - wci_sfi_ctr_regs_tab[id1-1]. - wci_sfi_ctr_match_val; - break; - } - } - } else { - /* - * Copy the current state of the hardware into the kstat - * structure. Here for safari histogram counter control, we - * need to copy the combination of wci_misc_ctr_ctl bits - * <19:0> and wci_sfi_sw_ctr_ctl bits <27:20> because the - * busstat needs a way to find out whether another process - * has changed wci_misc_ctr_ctl to count other events. When - * using safari histogramming counter, wci_misc_ctr_ctl must - * select agent 0, and event 0 or 1. If another process choose - * other agent or event by manipulating misc device, then the - * user who is monitoring sfi device should be notified. - */ - wci_sfi_ksp->wci_ctr_ctl.value.ui64 = - ((((uint64_t)*(softsp->wci_misc_ctr_ctl_vaddr)) & - WCI_SFI_SW_CTR_CTL_MASK) | - (softsp->wci_sfi_sw_ctr_ctl & - (~WCI_SFI_SW_CTR_CTL_MASK))); - wci_sfi_ksp->wci_ctr0.value.ui64 = - (*(softsp->wci_misc_ctr_vaddr)) & WCI_PIC0_MASK; - wci_sfi_ksp->wci_ctr1.value.ui64 = - (*(softsp->wci_misc_ctr_vaddr)) >> 32; - } - - return (0); -} - - -void wci_del_counters_kstats(struct wci_common_soft_state *softsp) { - - struct kstat *wci_ksp; - int link_no; - - /* remove "link" counters kstat */ - for (link_no = 0; link_no < WCI_NUM_LINKS; link_no++) { - wci_ksp = softsp->wci_link_counters_ksp[link_no]; - softsp->wci_link_counters_ksp[link_no] = NULL; - if (wci_ksp != NULL) { - ASSERT(wci_ksp->ks_private == (void *)softsp); - kstat_delete(wci_ksp); - } - } - - /* remove "lpbk" counters kstat */ - wci_ksp = softsp->wci_lpbk_counters_ksp; - softsp->wci_lpbk_counters_ksp = NULL; - if (wci_ksp != NULL) { - ASSERT(wci_ksp->ks_private == (void *)softsp); - kstat_delete(wci_ksp); - } - - /* remove "misc" counters kstat */ - wci_ksp = softsp->wci_misc_counters_ksp; - softsp->wci_misc_counters_ksp = NULL; - if (wci_ksp != NULL) { - ASSERT(wci_ksp->ks_private == (void *)softsp); - kstat_delete(wci_ksp); - } - - /* remove "sfi" counters kstat */ - wci_ksp = softsp->wci_sfi_counters_ksp; - softsp->wci_sfi_counters_ksp = NULL; - if (wci_ksp != NULL) { - ASSERT(wci_ksp->ks_private == (void *)softsp); - kstat_delete(wci_ksp); - } -} - -void wci_del_picN_kstats() { - - int pic, link_no; - - /* remove "link" picN kstat */ - for (link_no = 0; link_no < WCI_NUM_LINKS; link_no++) { - for (pic = 0; pic < WCI_NUM_PICS; pic++) { - if (wci_link_pic_ksp[link_no][pic] != - (kstat_t *)NULL) { - kstat_delete(wci_link_pic_ksp[link_no][pic]); - wci_link_pic_ksp[link_no][pic] = NULL; - } - } - } - - for (pic = 0; pic < WCI_NUM_PICS; pic++) { - /* remove "lpbk" picN kstat */ - if (wci_lpbk_pic_ksp[pic] != (kstat_t *)NULL) { - kstat_delete(wci_lpbk_pic_ksp[pic]); - wci_lpbk_pic_ksp[pic] = NULL; - } - /* remove "misc" picN kstat */ - if (wci_misc_pic_ksp[pic] != (kstat_t *)NULL) { - kstat_delete(wci_misc_pic_ksp[pic]); - wci_misc_pic_ksp[pic] = NULL; - } - /* remove "sfi" picN kstat */ - if (wci_sfi_pic_ksp[pic] != (kstat_t *)NULL) { - kstat_delete(wci_sfi_pic_ksp[pic]); - wci_sfi_pic_ksp[pic] = NULL; - } - } -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm.conf b/usr/src/uts/sun4u/io/wrsm/wrsm.conf deleted file mode 100644 index 1bf06fdad1..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm.conf +++ /dev/null @@ -1,324 +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 2001-2003 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" -# -# Ensure that devices are not taken offline by the auto-unloader. -ddi-no-autodetach=1; -# -# Force devices to be attached at boot time before /etc/init.d/wrsmcfg -# runs -ddi-forceattach=1; -# -# The wrsm driver manages 3 types of devices: WCIS, controllers -# (which are pseudo devices), and a wrsm admin device. -# -# Controllers are assigned high instance numbers so they don't conflict -# with WCIs, which are assigned instance numbers starting at 0 when they -# are attached. We will never get a WCI assigned an instance number this -# high because there aren't that many slots in a Sun-Fire. -# -name="wrsm" parent="pseudo" instance=100 rsm_controller=0; -name="wrsm" parent="pseudo" instance=101 rsm_controller=1; -name="wrsm" parent="pseudo" instance=102 rsm_controller=2; -name="wrsm" parent="pseudo" instance=103 rsm_controller=3; -name="wrsm" parent="pseudo" instance=104 rsm_controller=4; -name="wrsm" parent="pseudo" instance=105 rsm_controller=5; -name="wrsm" parent="pseudo" instance=106 rsm_controller=6; -name="wrsm" parent="pseudo" instance=107 rsm_controller=7; -name="wrsm" parent="pseudo" instance=108 rsm_controller=8; -name="wrsm" parent="pseudo" instance=109 rsm_controller=9; -name="wrsm" parent="pseudo" instance=110 rsm_controller=10; -name="wrsm" parent="pseudo" instance=111 rsm_controller=11; -name="wrsm" parent="pseudo" instance=112 rsm_controller=12; -name="wrsm" parent="pseudo" instance=113 rsm_controller=13; -name="wrsm" parent="pseudo" instance=114 rsm_controller=14; -name="wrsm" parent="pseudo" instance=115 rsm_controller=15; -# -# WARNING: DO NOT MODIFY ANYTHING BELOW HERE!!! -# The driver depends on these exact properties being defined for this -# device. The reg property for the admin device describes ncslice ranges. -# The portid property of the admin device is used to construct a unique -# name for the admin device special file. -# -name="wrsm" parent="rootnex" admin=1 portid=0xffff -reg= -0x400,0x00000000,0x0,0xffffffff, -0x404,0x00000000,0x0,0xffffffff, -0x408,0x00000000,0x0,0xffffffff, -0x40c,0x00000000,0x0,0xffffffff, -0x410,0x00000000,0x0,0xffffffff, -0x414,0x00000000,0x0,0xffffffff, -0x418,0x00000000,0x0,0xffffffff, -0x41c,0x00000000,0x0,0xffffffff, -0x420,0x00000000,0x0,0xffffffff, -0x424,0x00000000,0x0,0xffffffff, -0x428,0x00000000,0x0,0xffffffff, -0x42c,0x00000000,0x0,0xffffffff, -0x430,0x00000000,0x0,0xffffffff, -0x434,0x00000000,0x0,0xffffffff, -0x438,0x00000000,0x0,0xffffffff, -0x43c,0x00000000,0x0,0xffffffff, -0x440,0x00000000,0x0,0xffffffff, -0x444,0x00000000,0x0,0xffffffff, -0x448,0x00000000,0x0,0xffffffff, -0x44c,0x00000000,0x0,0xffffffff, -0x450,0x00000000,0x0,0xffffffff, -0x454,0x00000000,0x0,0xffffffff, -0x458,0x00000000,0x0,0xffffffff, -0x45c,0x00000000,0x0,0xffffffff, -0x460,0x00000000,0x0,0xffffffff, -0x464,0x00000000,0x0,0xffffffff, -0x468,0x00000000,0x0,0xffffffff, -0x46c,0x00000000,0x0,0xffffffff, -0x470,0x00000000,0x0,0xffffffff, -0x474,0x00000000,0x0,0xffffffff, -0x478,0x00000000,0x0,0xffffffff, -0x47c,0x00000000,0x0,0xffffffff, -0x480,0x00000000,0x0,0xffffffff, -0x484,0x00000000,0x0,0xffffffff, -0x488,0x00000000,0x0,0xffffffff, -0x48c,0x00000000,0x0,0xffffffff, -0x490,0x00000000,0x0,0xffffffff, -0x494,0x00000000,0x0,0xffffffff, -0x498,0x00000000,0x0,0xffffffff, -0x49c,0x00000000,0x0,0xffffffff, -0x4a0,0x00000000,0x0,0xffffffff, -0x4a4,0x00000000,0x0,0xffffffff, -0x4a8,0x00000000,0x0,0xffffffff, -0x4ac,0x00000000,0x0,0xffffffff, -0x4b0,0x00000000,0x0,0xffffffff, -0x4b4,0x00000000,0x0,0xffffffff, -0x4b8,0x00000000,0x0,0xffffffff, -0x4bc,0x00000000,0x0,0xffffffff, -0x4c0,0x00000000,0x0,0xffffffff, -0x4c4,0x00000000,0x0,0xffffffff, -0x4c8,0x00000000,0x0,0xffffffff, -0x4cc,0x00000000,0x0,0xffffffff, -0x4d0,0x00000000,0x0,0xffffffff, -0x4d4,0x00000000,0x0,0xffffffff, -0x4d8,0x00000000,0x0,0xffffffff, -0x4dc,0x00000000,0x0,0xffffffff, -0x4e0,0x00000000,0x0,0xffffffff, -0x4e4,0x00000000,0x0,0xffffffff, -0x4e8,0x00000000,0x0,0xffffffff, -0x4ec,0x00000000,0x0,0xffffffff, -0x4f0,0x00000000,0x0,0xffffffff, -0x4f4,0x00000000,0x0,0xffffffff, -0x4f8,0x00000000,0x0,0xffffffff, -0x4fc,0x00000000,0x0,0xffffffff, -0x500,0x00000000,0x0,0xffffffff, -0x504,0x00000000,0x0,0xffffffff, -0x508,0x00000000,0x0,0xffffffff, -0x50c,0x00000000,0x0,0xffffffff, -0x510,0x00000000,0x0,0xffffffff, -0x514,0x00000000,0x0,0xffffffff, -0x518,0x00000000,0x0,0xffffffff, -0x51c,0x00000000,0x0,0xffffffff, -0x520,0x00000000,0x0,0xffffffff, -0x524,0x00000000,0x0,0xffffffff, -0x528,0x00000000,0x0,0xffffffff, -0x52c,0x00000000,0x0,0xffffffff, -0x530,0x00000000,0x0,0xffffffff, -0x534,0x00000000,0x0,0xffffffff, -0x538,0x00000000,0x0,0xffffffff, -0x53c,0x00000000,0x0,0xffffffff, -0x540,0x00000000,0x0,0xffffffff, -0x544,0x00000000,0x0,0xffffffff, -0x548,0x00000000,0x0,0xffffffff, -0x54c,0x00000000,0x0,0xffffffff, -0x550,0x00000000,0x0,0xffffffff, -0x554,0x00000000,0x0,0xffffffff, -0x558,0x00000000,0x0,0xffffffff, -0x55c,0x00000000,0x0,0xffffffff, -0x560,0x00000000,0x0,0xffffffff, -0x564,0x00000000,0x0,0xffffffff, -0x568,0x00000000,0x0,0xffffffff, -0x56c,0x00000000,0x0,0xffffffff, -0x570,0x00000000,0x0,0xffffffff, -0x574,0x00000000,0x0,0xffffffff, -0x578,0x00000000,0x0,0xffffffff, -0x57c,0x00000000,0x0,0xffffffff, -0x580,0x00000000,0x0,0xffffffff, -0x584,0x00000000,0x0,0xffffffff, -0x588,0x00000000,0x0,0xffffffff, -0x58c,0x00000000,0x0,0xffffffff, -0x590,0x00000000,0x0,0xffffffff, -0x594,0x00000000,0x0,0xffffffff, -0x598,0x00000000,0x0,0xffffffff, -0x59c,0x00000000,0x0,0xffffffff, -0x5a0,0x00000000,0x0,0xffffffff, -0x5a4,0x00000000,0x0,0xffffffff, -0x5a8,0x00000000,0x0,0xffffffff, -0x5ac,0x00000000,0x0,0xffffffff, -0x5b0,0x00000000,0x0,0xffffffff, -0x5b4,0x00000000,0x0,0xffffffff, -0x5b8,0x00000000,0x0,0xffffffff, -0x5bc,0x00000000,0x0,0xffffffff, -0x5c0,0x00000000,0x0,0xffffffff, -0x5c4,0x00000000,0x0,0xffffffff, -0x5c8,0x00000000,0x0,0xffffffff, -0x5cc,0x00000000,0x0,0xffffffff, -0x5d0,0x00000000,0x0,0xffffffff, -0x5d4,0x00000000,0x0,0xffffffff, -0x5d8,0x00000000,0x0,0xffffffff, -0x5dc,0x00000000,0x0,0xffffffff, -0x5e0,0x00000000,0x0,0xffffffff, -0x5e4,0x00000000,0x0,0xffffffff, -0x5e8,0x00000000,0x0,0xffffffff, -0x5ec,0x00000000,0x0,0xffffffff, -0x5f0,0x00000000,0x0,0xffffffff, -0x5f4,0x00000000,0x0,0xffffffff, -0x5f8,0x00000000,0x0,0xffffffff, -0x5fc,0x00000000,0x0,0xffffffff, -0x600,0x00000000,0x0,0xffffffff, -0x604,0x00000000,0x0,0xffffffff, -0x608,0x00000000,0x0,0xffffffff, -0x60c,0x00000000,0x0,0xffffffff, -0x610,0x00000000,0x0,0xffffffff, -0x614,0x00000000,0x0,0xffffffff, -0x618,0x00000000,0x0,0xffffffff, -0x61c,0x00000000,0x0,0xffffffff, -0x620,0x00000000,0x0,0xffffffff, -0x624,0x00000000,0x0,0xffffffff, -0x628,0x00000000,0x0,0xffffffff, -0x62c,0x00000000,0x0,0xffffffff, -0x630,0x00000000,0x0,0xffffffff, -0x634,0x00000000,0x0,0xffffffff, -0x638,0x00000000,0x0,0xffffffff, -0x63c,0x00000000,0x0,0xffffffff, -0x640,0x00000000,0x0,0xffffffff, -0x644,0x00000000,0x0,0xffffffff, -0x648,0x00000000,0x0,0xffffffff, -0x64c,0x00000000,0x0,0xffffffff, -0x650,0x00000000,0x0,0xffffffff, -0x654,0x00000000,0x0,0xffffffff, -0x658,0x00000000,0x0,0xffffffff, -0x65c,0x00000000,0x0,0xffffffff, -0x660,0x00000000,0x0,0xffffffff, -0x664,0x00000000,0x0,0xffffffff, -0x668,0x00000000,0x0,0xffffffff, -0x66c,0x00000000,0x0,0xffffffff, -0x670,0x00000000,0x0,0xffffffff, -0x674,0x00000000,0x0,0xffffffff, -0x678,0x00000000,0x0,0xffffffff, -0x67c,0x00000000,0x0,0xffffffff, -0x680,0x00000000,0x0,0xffffffff, -0x684,0x00000000,0x0,0xffffffff, -0x688,0x00000000,0x0,0xffffffff, -0x68c,0x00000000,0x0,0xffffffff, -0x690,0x00000000,0x0,0xffffffff, -0x694,0x00000000,0x0,0xffffffff, -0x698,0x00000000,0x0,0xffffffff, -0x69c,0x00000000,0x0,0xffffffff, -0x6a0,0x00000000,0x0,0xffffffff, -0x6a4,0x00000000,0x0,0xffffffff, -0x6a8,0x00000000,0x0,0xffffffff, -0x6ac,0x00000000,0x0,0xffffffff, -0x6b0,0x00000000,0x0,0xffffffff, -0x6b4,0x00000000,0x0,0xffffffff, -0x6b8,0x00000000,0x0,0xffffffff, -0x6bc,0x00000000,0x0,0xffffffff, -0x6c0,0x00000000,0x0,0xffffffff, -0x6c4,0x00000000,0x0,0xffffffff, -0x6c8,0x00000000,0x0,0xffffffff, -0x6cc,0x00000000,0x0,0xffffffff, -0x6d0,0x00000000,0x0,0xffffffff, -0x6d4,0x00000000,0x0,0xffffffff, -0x6d8,0x00000000,0x0,0xffffffff, -0x6dc,0x00000000,0x0,0xffffffff, -0x6e0,0x00000000,0x0,0xffffffff, -0x6e4,0x00000000,0x0,0xffffffff, -0x6e8,0x00000000,0x0,0xffffffff, -0x6ec,0x00000000,0x0,0xffffffff, -0x6f0,0x00000000,0x0,0xffffffff, -0x6f4,0x00000000,0x0,0xffffffff, -0x6f8,0x00000000,0x0,0xffffffff, -0x6fc,0x00000000,0x0,0xffffffff, -0x700,0x00000000,0x0,0xffffffff, -0x704,0x00000000,0x0,0xffffffff, -0x708,0x00000000,0x0,0xffffffff, -0x70c,0x00000000,0x0,0xffffffff, -0x710,0x00000000,0x0,0xffffffff, -0x714,0x00000000,0x0,0xffffffff, -0x718,0x00000000,0x0,0xffffffff, -0x71c,0x00000000,0x0,0xffffffff, -0x720,0x00000000,0x0,0xffffffff, -0x724,0x00000000,0x0,0xffffffff, -0x728,0x00000000,0x0,0xffffffff, -0x72c,0x00000000,0x0,0xffffffff, -0x730,0x00000000,0x0,0xffffffff, -0x734,0x00000000,0x0,0xffffffff, -0x738,0x00000000,0x0,0xffffffff, -0x73c,0x00000000,0x0,0xffffffff, -0x740,0x00000000,0x0,0xffffffff, -0x744,0x00000000,0x0,0xffffffff, -0x748,0x00000000,0x0,0xffffffff, -0x74c,0x00000000,0x0,0xffffffff, -0x750,0x00000000,0x0,0xffffffff, -0x754,0x00000000,0x0,0xffffffff, -0x758,0x00000000,0x0,0xffffffff, -0x75c,0x00000000,0x0,0xffffffff, -0x760,0x00000000,0x0,0xffffffff, -0x764,0x00000000,0x0,0xffffffff, -0x768,0x00000000,0x0,0xffffffff, -0x76c,0x00000000,0x0,0xffffffff, -0x770,0x00000000,0x0,0xffffffff, -0x774,0x00000000,0x0,0xffffffff, -0x778,0x00000000,0x0,0xffffffff, -0x77c,0x00000000,0x0,0xffffffff, -0x780,0x00000000,0x0,0xffffffff, -0x784,0x00000000,0x0,0xffffffff, -0x788,0x00000000,0x0,0xffffffff, -0x78c,0x00000000,0x0,0xffffffff, -0x790,0x00000000,0x0,0xffffffff, -0x794,0x00000000,0x0,0xffffffff, -0x798,0x00000000,0x0,0xffffffff, -0x79c,0x00000000,0x0,0xffffffff, -0x7a0,0x00000000,0x0,0xffffffff, -0x7a4,0x00000000,0x0,0xffffffff, -0x7a8,0x00000000,0x0,0xffffffff, -0x7ac,0x00000000,0x0,0xffffffff, -0x7b0,0x00000000,0x0,0xffffffff, -0x7b4,0x00000000,0x0,0xffffffff, -0x7b8,0x00000000,0x0,0xffffffff, -0x7bc,0x00000000,0x0,0xffffffff, -0x7c0,0x00000000,0x0,0xffffffff, -0x7c4,0x00000000,0x0,0xffffffff, -0x7c8,0x00000000,0x0,0xffffffff, -0x7cc,0x00000000,0x0,0xffffffff, -0x7d0,0x00000000,0x0,0xffffffff, -0x7d4,0x00000000,0x0,0xffffffff, -0x7d8,0x00000000,0x0,0xffffffff, -0x7dc,0x00000000,0x0,0xffffffff, -0x7e0,0x00000000,0x0,0xffffffff, -0x7e4,0x00000000,0x0,0xffffffff, -0x7e8,0x00000000,0x0,0xffffffff, -0x7ec,0x00000000,0x0,0xffffffff, -0x7f0,0x00000000,0x0,0xffffffff, -0x7f4,0x00000000,0x0,0xffffffff, -0x7f8,0x00000000,0x0,0xffffffff, -0x7fc,0x00000000,0x0,0xffffffff -; diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c b/usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c deleted file mode 100644 index 40586b6556..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_barrier.c +++ /dev/null @@ -1,811 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file implements RSMPI barriers in the Wildcat RSM driver. - */ - -#include <sys/types.h> - -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/errno.h> -#include <sys/debug.h> -#include <sys/promif.h> - -#include <sys/wrsm_barrier.h> -#include <sys/wrsm_common.h> -#include <sys/wrsm_session.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_memseg_impl.h> -#include <sys/wci_regs.h> - -/* - * The following macros define a DPRINTF macro which can be used to enable - * or disable various levels of logging for this module. - */ -#ifdef DEBUG - -#define BARDBG 0x1 -#define BARWARN 0x2 -#define BARERR 0x4 -#define BARTRACE 0x8 -static uint_t wrsm_bar_debug = BARERR; - -#define DPRINTF(a, b) { if (wrsm_bar_debug & a) wrsmdprintf b; } -#define PRINT_BAR(a, b) { if (wrsm_bar_debug & a) wrsm_print_barrier(b); } - -#else /* DEBUG */ - -#define DPRINTF(a, b) { } -#define PRINT_BAR(a, b) { } - -#endif /* DEBUG */ - -#define DTRC(s) DPRINTF(BARTRACE, (CE_CONT, s)) -#define WARN(s) DPRINTF(BARWARN, (CE_WARN, s)) -#define NOTE(s) DPRINTF(BARDBG, (CE_NOTE, s)) -#define ERR(s) DPRINTF(BARERR, (CE_WARN, s)) - -/* - * Local types - */ -#define BARRIER_TIME_REGION 0 -#define BARRIER_TIME_REGIONS 1 -#define BARRIER_TIME_NODE 2 -#define BARRIER_TIME_CONTROLLER 3 -#define BARRIER_THREAD_REGION 4 -#define BARRIER_THREAD_REGIONS 5 -#define BARRIER_THREAD_NODE 6 -#define BARRIER_THREAD_CONTROLLER 7 -typedef unsigned char wrsm_barrier_scope_t; - -#ifdef DEBUG -/* The following array is used in wrsm_print_barrier, for debug only */ -static const char *scope_txt[] = { - "BARRIER_TIME_REGION", - "BARRIER_TIME_REGIONS", - "BARRIER_TIME_NODE", - "BARRIER_TIME_CONTROLLER", - "BARRIER_THREAD_REGION", - "BARRIER_THREAD_REGIONS", - "BARRIER_THREAD_NODE", - "BARRIER_THREAD_CONTROLLER"}; -#endif /* DEBUG */ - -/* Define state flags to help ensure that barrier is really initialized */ -typedef unsigned char wrsm_barrier_state_t; -#define BARRIER_CLOSED ((wrsm_barrier_state_t)0xff) -#define BARRIER_OPENED ((wrsm_barrier_state_t)0xfe) - -/* This struct is an overlay for rsm_barrier_t */ -typedef struct { - void *parent; /* network, importseg or array of importsegs */ - uint64_t init_err_count; - uint32_t reroute_counter; - uint32_t transfer_errors; - int num_regions; /* if multiple importsegs */ - wrsm_barrier_scope_t scope; - wrsm_barrier_state_t state; - cnodeid_t cnodeid; /* if node barrier */ -} wrsm_barrier_t; - -/* - * Local Functions - */ - -/* - * This function sums the wci_cluster_error_count register for all WCIs - * routing to the given ncslice (i.e., remote node). It does this by - * reading the wci_cluster_error_count mapped into the stripes of page 0 - * of the nslice. - */ -static uint64_t -sum_errors_node(caddr_t ncslice_base, int link_stripes) -{ - uint64_t total = 0; - int stripes; - caddr_t err_addr = ncslice_base + WCI_ERRPAGE_CLUSTER_ERROR_OFFSET; - - for (stripes = link_stripes; stripes; stripes = stripes >> 1) { - if (stripes & 1) { - /* Sum in errors for this stripe */ - total += *((uint64_t *)err_addr); - } - err_addr += WCI_CLUSTER_STRIPE_STRIDE; - } - return (total); -} - -/* Sums wci_cluster_error_counts for all nodes in nodes bitmask */ -static int -sum_errors_nodes(wrsm_network_t *net, wrsm_cnode_bitmask_t cnodes, - uint64_t *sum) -{ - wrsm_node_t *node; - int i; - - /* If we're in the process of rerouting, return MAX INT */ - if (*net->reroutingp) { - *sum = UINT64_MAX; - return (RSM_SUCCESS); - } - - *sum = 0; - mutex_enter(&net->lock); - /* Loop for each node in the set. Exit early once set is empty */ - for (i = 0; i < WRSM_MAX_CNODES && !WRSMSET_ISNULL(cnodes); i++) { - if (WRSM_IN_SET(cnodes, i)) { - node = net->nodes[i]; - if (node == NULL) { - mutex_exit(&net->lock); - return (RSMERR_CONN_ABORTED); - } - *sum += sum_errors_node(node->cesr_vaddr, - *node->link_stripesp); - } - /* Remove this node from the list, hoping for early exit */ - WRSMSET_DEL(cnodes, i); - } - mutex_exit(&net->lock); - return (RSM_SUCCESS); -} - -/* - * RSMPI Functions - */ -/* ARGSUSED */ -int -wrsm_open_barrier_ctrl(rsm_controller_handle_t ctrl, rsm_barrier_t *barrier) -{ - DTRC("wrsm_open_barrier_ctrl"); - /* LINTED: E_TRUE_LOGICAL_EXPR */ - ASSERT(sizeof (wrsm_barrier_t) <= sizeof (rsm_barrier_t)); - return (RSMERR_UNSUPPORTED_OPERATION); -} - -int -wrsm_open_barrier_node(rsm_controller_handle_t ctrl, rsm_addr_t addr, - rsm_barrier_t *barrier) -{ - wrsm_node_t *node; - wrsm_network_t *net = (wrsm_network_t *)ctrl; - wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; - - DPRINTF(BARTRACE, (CE_CONT, "wrsm_open_barrier_node(addr=%d)", addr)); - /* LINTED: E_TRUE_LOGICAL_EXPR */ - ASSERT(sizeof (wrsm_barrier_t) <= sizeof (rsm_barrier_t)); - - if (bar == NULL) { - return (RSMERR_BAD_BARRIER_PTR); - } - if (net == NULL) { - return (RSMERR_BAD_CTLR_HNDL); - } - if (addr >= WRSM_MAX_CNODES) { - return (RSMERR_UNKNOWN_RSM_ADDR); - } - bar->state = BARRIER_CLOSED; /* Mark as closed until we're done */ - bar->scope = BARRIER_TIME_NODE; - - mutex_enter(&net->lock); - node = net->nodes[addr]; - if (!node) { - mutex_exit(&net->lock); - return (RSMERR_UNKNOWN_RSM_ADDR); - } - /* Read route counter */ - bar->reroute_counter = *net->route_counterp; - bar->init_err_count = sum_errors_node(node->cesr_vaddr, - *node->link_stripesp); - bar->parent = (void *)net; - bar->cnodeid = (cnodeid_t)addr; - bar->transfer_errors = node->memseg->transfer_errors; - bar->state = BARRIER_OPENED; - mutex_exit(&net->lock); - - /* Make sure a session is established with the remote node */ - (void) wrsm_sess_establish(net, addr); - - PRINT_BAR(BARDBG, barrier); - return (RSM_SUCCESS); -} - -int -wrsm_open_barrier_region(rsm_memseg_import_handle_t im_memseg, - rsm_barrier_t *barrier) -{ - importseg_t *importseg; - wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; - int err; - - DTRC("wrsm_open_barrier_region"); - /* LINTED: E_TRUE_LOGICAL_EXPR */ - ASSERT(sizeof (wrsm_barrier_t) <= sizeof (rsm_barrier_t)); - - if (im_memseg == NULL) { - return (RSMERR_BAD_SEG_HNDL); - } - if (bar == NULL) { - return (RSMERR_BAD_BARRIER_PTR); - } - - /* we assume importseg will not be removed during barrier */ - importseg = (importseg_t *)im_memseg; - err = wrsm_open_barrier_node(importseg->iseginfo->network, - importseg->iseginfo->cnodeid, barrier); - bar->scope = BARRIER_TIME_REGION; - bar->parent = (void *)importseg; - bar->transfer_errors = importseg->iseginfo->transfer_errors; - bar->cnodeid = importseg->iseginfo->cnodeid; - - PRINT_BAR(BARDBG, barrier); - return (err); -} - -int -wrsm_open_barrier_regions(rsm_memseg_import_handle_t im_memseg[], - uint_t num_regions, rsm_barrier_t *barrier) -{ - importseg_t **importseg_list; - wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; - wrsm_network_t *net; - wrsm_cnode_bitmask_t cnodes; - uint_t i; - int err; - - DTRC("wrsm_open_barrier_regions"); - /* LINTED: E_TRUE_LOGICAL_EXPR */ - ASSERT(sizeof (wrsm_barrier_t) <= sizeof (rsm_barrier_t)); - - if (bar == NULL) { - return (RSMERR_BAD_BARRIER_PTR); - } - bar->state = BARRIER_CLOSED; /* Mark as closed until we're done */ - - if (num_regions == 0) { - return (RSMERR_BAD_SEG_HNDL); - } - - WRSMSET_ZERO(cnodes); - for (i = 0; i < num_regions; i++) { - if (im_memseg[i] == NULL) { - return (RSMERR_BAD_SEG_HNDL); - } - WRSMSET_ADD(cnodes, im_memseg[i]->iseginfo->cnodeid); - } - - /* we assume importsegs will not be removed during barrier */ - net = ((importseg_t *)im_memseg[0])->iseginfo->network; - bar->scope = BARRIER_TIME_REGIONS; - bar->reroute_counter = *net->route_counterp; - err = sum_errors_nodes(net, cnodes, &bar->init_err_count); - if (!err) { - bar->parent = (void *)kmem_alloc( - (num_regions * sizeof (importseg_t *)), KM_SLEEP); - bcopy(im_memseg, bar->parent, - (num_regions * sizeof (importseg_t *))); - bar->num_regions = num_regions; - importseg_list = (importseg_t **)bar->parent; - bar->transfer_errors = 0; - for (i = 0; i < num_regions; i++) { - bar->transfer_errors += - importseg_list[i]->iseginfo->transfer_errors; - } - bar->state = BARRIER_OPENED; - } - - PRINT_BAR(BARDBG, barrier); - return (err); -} - -int -wrsm_open_barrier_ctrl_thr(rsm_controller_handle_t ctrl, - rsm_barrier_t *barrier) -{ - DTRC("wrsm_open_barrier_ctrl_thr"); - return (wrsm_open_barrier_ctrl(ctrl, barrier)); -} - -int -wrsm_open_barrier_node_thr(rsm_controller_handle_t ctrl, rsm_addr_t addr, - rsm_barrier_t *barrier) -{ - DTRC("wrsm_open_barrier_node_thr"); - return (wrsm_open_barrier_node(ctrl, addr, barrier)); -} - -int -wrsm_open_barrier_region_thr(rsm_memseg_import_handle_t im_memseg, - rsm_barrier_t *barrier) -{ - DTRC("wrsm_open_barrier_region_thr"); - return (wrsm_open_barrier_region(im_memseg, barrier)); -} - -int -wrsm_open_barrier_regions_thr(rsm_memseg_import_handle_t im_memseg[], - uint_t num_regions, rsm_barrier_t *barrier) -{ - DTRC("wrsm_open_barrier_regions_thr"); - return (wrsm_open_barrier_regions(im_memseg, num_regions, barrier)); -} - -static int -close_barrier_time_node(wrsm_network_t *net, wrsm_barrier_t *bar) -{ - uint64_t error_sum; - wrsm_node_t *node; - DTRC("close_barrier_time_node"); - - /* Check to see if there were any errors */ - if (bar->init_err_count == UINT64_MAX) { - WARN("Barrier failed: error reading wci cluster error count"); - return (RSMERR_BARRIER_FAILURE); - } - mutex_enter(&net->lock); - node = net->nodes[bar->cnodeid]; - error_sum = sum_errors_node(node->cesr_vaddr, *node->link_stripesp); - mutex_exit(&net->lock); - if (bar->init_err_count != error_sum) { - WARN("Barrier failed: wci errors detected"); - return (RSMERR_BARRIER_FAILURE); - } - /* Make sure route hasn't changed */ - if (*net->reroutingp || bar->reroute_counter != *net->route_counterp) { - WARN("Barrier failed: route changed"); - return (RSMERR_BARRIER_FAILURE); - } - - return (RSM_SUCCESS); -} - -static int -close_barrier_time_nodes(wrsm_network_t *net, wrsm_barrier_t *bar, - wrsm_cnode_bitmask_t cnodes) -{ - uint64_t error_sum; - int err; - DTRC("close_barrier_time_nodes"); - - /* Check to see if there were any errors */ - if (bar->init_err_count == UINT64_MAX) { - WARN("Barrier failed: error reading wci cluster error count"); - return (RSMERR_BARRIER_FAILURE); - } - /* Sum errors for those remote nodes */ - err = sum_errors_nodes(net, cnodes, &error_sum); - if (err) { - return (err); - } - if (bar->init_err_count != error_sum) { - WARN("Barrier failed: wci errors detected"); - return (RSMERR_BARRIER_FAILURE); - } - /* Make sure route hasn't changed */ - if (*net->reroutingp || bar->reroute_counter != *net->route_counterp) { - WARN("Barrier failed: route changed"); - return (RSMERR_BARRIER_FAILURE); - } - - return (RSM_SUCCESS); -} - - -int -wrsm_close_barrier(rsm_barrier_t *barrier) -{ - wrsm_barrier_t *bar; - wrsm_network_t *net; - wrsm_node_t *node; - importseg_t *importseg; - importseg_t **importseg_list; - uint_t sum_transfer_errors = 0; - wrsm_cnode_bitmask_t cnodes; - int i; - int err = 0; - int retval = 0; - - DTRC("wrsm_close_barrier"); - PRINT_BAR(BARDBG, barrier); - - bar = (wrsm_barrier_t *)barrier; - if (bar == NULL) { - WARN("Barrier failed: barrier pointer is NULL"); - return (RSMERR_BAD_BARRIER_PTR); - } - if (bar->state != BARRIER_OPENED) { - WARN("Barrier failed: Barrier not open"); - return (RSMERR_BARRIER_NOT_OPENED); - } - bar->state = BARRIER_CLOSED; - - switch (bar->scope) { - case BARRIER_TIME_REGION: - importseg = (importseg_t *)bar->parent; - if (importseg->unpublished) { - WARN("Barrier failed: importseg was unpublished"); - return (RSMERR_CONN_ABORTED); - } - if (bar->transfer_errors != - importseg->iseginfo->transfer_errors) { - DPRINTF(BARWARN, (CE_WARN, - "Barrier failed: transfer errors; last err %d", - importseg->iseginfo->last_transfer_error)); - return (importseg->iseginfo->last_transfer_error); - } - net = importseg->iseginfo->network; - mutex_enter(&net->lock); - node = net->nodes[bar->cnodeid]; - if (node == NULL) { - WARN("Barrier failed: unknown node"); - retval = RSMERR_CONN_ABORTED; - } else { - /* Flush links to remote node */ - retval = wrsm_sess_touch_node(net, bar->cnodeid, - *node->link_stripesp); - } - mutex_exit(&net->lock); - if (retval == RSM_SUCCESS) { - retval = close_barrier_time_node(net, bar); - } - break; - - case BARRIER_TIME_REGIONS: - WRSMSET_ZERO(cnodes); - importseg_list = (importseg_t **)bar->parent; - ASSERT(importseg_list); - - /* get net from first importseg */ - net = importseg_list[0]->iseginfo->network; - - mutex_enter(&net->lock); - for (i = 0; i < bar->num_regions; i++) { - importseg = importseg_list[i]; - WRSMSET_ADD(cnodes, importseg->iseginfo->cnodeid); - if (importseg->unpublished) { - kmem_free(bar->parent, (bar->num_regions * - sizeof (importseg_t *))); - WARN("Barrier failed: importseg unpublished"); - mutex_exit(&net->lock); - return (RSMERR_CONN_ABORTED); - } - sum_transfer_errors += - importseg->iseginfo->transfer_errors; - /* Remember the first error encountered */ - if (err == 0) { - err = importseg->iseginfo->last_transfer_error; - } - if (retval == RSM_SUCCESS) { - node = net->nodes[importseg->iseginfo->cnodeid]; - if (node == NULL) { - WARN("Barrier failed: unknown node"); - retval = RSMERR_CONN_ABORTED; - } else { - /* Flush links to remote node */ - retval = wrsm_sess_touch_node(net, - importseg->iseginfo->cnodeid, - *node->link_stripesp); - } - } - } - mutex_exit(&net->lock); - kmem_free(bar->parent, - (bar->num_regions * sizeof (importseg_t *))); - if (bar->transfer_errors != sum_transfer_errors) { - DPRINTF(BARWARN, (CE_WARN, - "Barrier failed: transfer errors, last error %d", - err)); - return (err); - } - if (retval == RSM_SUCCESS) { - retval = close_barrier_time_nodes(net, bar, cnodes); - } - break; - - case BARRIER_TIME_NODE: - net = (wrsm_network_t *)bar->parent; - mutex_enter(&net->lock); - node = net->nodes[bar->cnodeid]; - if (!node) { - mutex_exit(&net->lock); - WARN("Barrier failed: node doesn't exist"); - return (RSMERR_CONN_ABORTED); - } - if (node->memseg->removing_session || - (wrsm_sess_get(net, node->config->cnodeid) == - SESS_ID_INVALID)) { - mutex_exit(&net->lock); - WARN("Barrier failed: no session to remote node"); - return (RSMERR_CONN_ABORTED); - } - if (bar->transfer_errors != node->memseg->transfer_errors) { - err = node->memseg->last_transfer_error; - DPRINTF(BARWARN, (CE_WARN, - "Barrier failed: transfer error; last err %d", - err)); - mutex_exit(&net->lock); - return (err); - } - /* Flush links to remote node */ - retval = wrsm_sess_touch_node(net, bar->cnodeid, - *node->link_stripesp); - mutex_exit(&net->lock); - if (retval == RSM_SUCCESS) { - retval = close_barrier_time_node(net, bar); - } - break; - - case BARRIER_TIME_CONTROLLER: - retval = RSMERR_UNSUPPORTED_OPERATION; - break; - - default: - ERR("Invalid barrier data"); - retval = RSMERR_BAD_BARRIER_HNDL; - } - -#ifdef DEBUG - if (retval) { - DPRINTF(BARWARN, (CE_WARN, "Barrier failed: %d", retval)); - } -#endif - return (retval); -} - -int -wrsm_reopen_barrier(rsm_barrier_t *barrier) -{ - rsm_controller_handle_t ctrl; - rsm_addr_t addr; - rsm_memseg_import_handle_t im_memseg; - rsm_memseg_import_handle_t *im_memsegp; - uint_t num_regions; - wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; - int retval; - - DTRC("wrsm_reopen_barrier"); - if (barrier == NULL) { - WARN("Barrier failed: barrier pointer is NULL"); - return (RSMERR_BAD_BARRIER_PTR); - } - switch (bar->scope) { - case BARRIER_TIME_NODE: - ctrl = bar->parent; - addr = bar->cnodeid; - retval = wrsm_close_barrier(barrier); - (void) wrsm_open_barrier_node(ctrl, addr, barrier); - break; - case BARRIER_TIME_REGION: - im_memseg = bar->parent; - retval = wrsm_close_barrier(barrier); - (void) wrsm_open_barrier_region(im_memseg, barrier); - break; - case BARRIER_TIME_REGIONS: - num_regions = bar->num_regions; - im_memsegp = (rsm_memseg_import_handle_t *)kmem_alloc( - num_regions * - sizeof (rsm_memseg_import_handle_t *), KM_SLEEP); - bcopy(bar->parent, im_memsegp, - num_regions * sizeof (rsm_memseg_import_handle_t *)); - retval = wrsm_close_barrier(barrier); - (void) wrsm_open_barrier_regions(im_memsegp, num_regions, - barrier); - kmem_free(im_memsegp, - num_regions * sizeof (rsm_memseg_import_handle_t *)); - break; - default: - retval = RSMERR_UNSUPPORTED_OPERATION; - } - return (retval); -} - -int -wrsm_order_barrier(rsm_barrier_t *barrier) -{ - wrsm_barrier_t *bar; - int i; - wrsm_network_t *net; - wrsm_node_t *node; - importseg_t *importseg; - importseg_t **importseg_list; - int retval = 0; - - DTRC("wrsm_order_barrier"); - PRINT_BAR(BARDBG, barrier); - - bar = (wrsm_barrier_t *)barrier; - if (bar == NULL) { - WARN("Barrier failed: barrier pointer is NULL"); - return (RSMERR_BAD_BARRIER_PTR); - } - if (bar->state != BARRIER_OPENED) { - WARN("Barrier failed: Barrier not open"); - return (RSMERR_BARRIER_NOT_OPENED); - } - - /* Figure out which remote cnode(s) we need to flush */ - switch (bar->scope) { - case BARRIER_TIME_REGION: - importseg = (importseg_t *)bar->parent; - net = importseg->iseginfo->network; - mutex_enter(&net->lock); - node = net->nodes[bar->cnodeid]; - if (node) { - retval = wrsm_sess_touch_node(net, bar->cnodeid, - *node->link_stripesp); - } else { - retval = RSMERR_CONN_ABORTED; - } - mutex_exit(&net->lock); - break; - - case BARRIER_TIME_REGIONS: - importseg_list = (importseg_t **)bar->parent; - ASSERT(importseg_list); - - /* get net from first importseg */ - net = importseg_list[0]->iseginfo->network; - - mutex_enter(&net->lock); - for (i = 0; i < bar->num_regions; i++) { - cnodeid_t cnode = importseg_list[i]->iseginfo->cnodeid; - node = net->nodes[cnode]; - if (node) { - int err = wrsm_sess_touch_node(net, cnode, - *node->link_stripesp); - retval = retval ? retval : err; - } else { - retval = RSMERR_CONN_ABORTED; - } - } - mutex_exit(&net->lock); - break; - - case BARRIER_TIME_NODE: - net = (wrsm_network_t *)bar->parent; - mutex_enter(&net->lock); - node = net->nodes[bar->cnodeid]; - if (node) { - retval = wrsm_sess_touch_node(net, bar->cnodeid, - *node->link_stripesp); - } else { - retval = RSMERR_CONN_ABORTED; - } - mutex_exit(&net->lock); - break; - - case BARRIER_TIME_CONTROLLER: - retval = RSMERR_UNSUPPORTED_OPERATION; - break; - - default: - ERR("Invalid barrier data"); - retval = RSMERR_BAD_BARRIER_HNDL; - } - return (retval); -} - -int -wrsm_thread_init(rsm_controller_handle_t ctrl) -{ - wrsm_network_t *net; - DTRC("wrsm_thread_init"); - - net = (wrsm_network_t *)ctrl; - if (net == NULL) { - return (RSMERR_BAD_CTLR_HNDL); - } - /* Thread Barriers not yet implemented, so nothing to do */ - return (RSM_SUCCESS); -} - -int -wrsm_thread_fini(rsm_controller_handle_t ctrl) -{ - wrsm_network_t *net; - DTRC("wrsm_thread_fini"); - - net = (wrsm_network_t *)ctrl; - if (net == NULL) { - return (RSMERR_BAD_CTLR_HNDL); - } - /* Thread Barriers not yet implemented, so nothing to do */ - return (RSM_SUCCESS); -} - -int -wrsm_get_barrier_mode(rsm_memseg_import_handle_t mem, rsm_barrier_mode_t *mode) -{ - importseg_t *importseg = (importseg_t *)mem; - int err; - - DTRC("wrsm_get_barrier_mode"); - - if ((err = wrsm_lock_importseg(importseg, RW_READER)) != RSM_SUCCESS) { - return (err); - } - - *mode = importseg->barrier_mode; - - rw_exit(&importseg->rw_lock); - return (RSM_SUCCESS); -} - -int -wrsm_set_barrier_mode(rsm_memseg_import_handle_t mem, rsm_barrier_mode_t mode) -{ - importseg_t *importseg = (importseg_t *)mem; - int err; - - DPRINTF(BARTRACE, (CE_CONT, - "wrsm_set_barrier_mode: importseg 0x%p mode %d", - (void *)importseg, mode)); - - if ((mode != RSM_BARRIER_MODE_EXPLICIT) && - mode != RSM_BARRIER_MODE_IMPLICIT) { - return (RSMERR_BAD_MODE); - } - - if ((err = wrsm_lock_importseg(importseg, RW_WRITER)) != RSM_SUCCESS) { - return (err); - } - - importseg->barrier_mode = mode; - - rw_exit(&importseg->rw_lock); - return (RSM_SUCCESS); -} - -#ifdef DEBUG -void -wrsm_print_barrier(rsm_barrier_t *barrier) -{ - wrsm_barrier_t *bar = (wrsm_barrier_t *)barrier; - - cmn_err(CE_CONT, "Barrier {"); - cmn_err(CE_CONT, " scope = %s", scope_txt[bar->scope]); - cmn_err(CE_CONT, " state = %s", - (bar->state == BARRIER_OPENED) ? "OPENED" : "CLOSED"); - cmn_err(CE_CONT, " reroute_counter = %u", bar->reroute_counter); - cmn_err(CE_CONT, " parent = 0x%p", bar->parent); - cmn_err(CE_CONT, " init_err_count = %lu", bar->init_err_count); - cmn_err(CE_CONT, " transfer_errors = %u", bar->transfer_errors); - if ((bar->scope == BARRIER_TIME_REGIONS) || - (bar->scope == BARRIER_THREAD_REGIONS)) { - cmn_err(CE_CONT, " num_regions = %u", bar->num_regions); - } - if ((bar->scope == BARRIER_TIME_NODE) || - (bar->scope == BARRIER_THREAD_NODE)) { - cmn_err(CE_CONT, " cnodeid = %u", bar->cnodeid); - } - cmn_err(CE_CONT, "}"); -} -#endif /* DEBUG */ diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_cf.c b/usr/src/uts/sun4u/io/wrsm/wrsm_cf.c deleted file mode 100644 index e6fa792833..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_cf.c +++ /dev/null @@ -1,2764 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Configuration layer of the WildCat RSM driver - * - * This file handles user interaction for the wrsm driver, including - * - receiving and parsing a configuration, - * - initiating controller configuration and reconfiguration, - * - keeping track of which wci devices and ncslices are owned by which - * controllers, - * - private test interfaces - */ - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/param.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/cmn_err.h> -#include <sys/errno.h> -#include <sys/kmem.h> -#include <sys/mutex.h> -#include <sys/policy.h> - -/* Driver specific headers */ -#include <sys/wrsm.h> -#include <sys/wrsm_common.h> -#include <sys/wrsm_lc.h> -#include <sys/wrsm_cf.h> -#include <sys/wrsm_cf_impl.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_plat.h> -#include <sys/wrsm_transport.h> -#include <sys/wrsm_session.h> - -#include <sys/rsm/rsmpi.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_memseg_impl.h> -#include <sys/wrsm_barrier.h> - -#ifdef DEBUG -#include <sys/promif.h> -#define CF_DEBUG 0x0001 -#define CF_WARN 0x0002 - -static uint_t wrsm_cf_debug = CF_WARN; -#define DPRINTF(a, b) { if (wrsm_cf_debug & a) wrsmdprintf b; } -#define DPRINT_BITMASK(m, b) dprint_bitmask(m, b) -#else -#define DPRINTF(a, b) { } -#define DPRINT_BITMASK(m, b) -#endif - - -#ifdef DEBUG -static void -dprint_bitmask(char *msg, ncslice_bitmask_t bits) -{ - int i; - - DPRINTF(CF_DEBUG, (CE_NOTE, "%s = {", msg)); - for (i = 0; i < WRSM_MAX_NCSLICES; ++i) { - if (WRSM_IN_SET(bits, i)) { - DPRINTF(CF_DEBUG, (CE_CONT, " %d", i)); - } - } - DPRINTF(CF_DEBUG, (CE_CONT, "}")); -} -#endif /* DEBUG */ - -/* - * Represents the state of the "admin" instance of the wrsm - * driver. There should be only one such instance. - */ -typedef struct { - int controller_devs; - kmutex_t state_lock; /* protects access to this state structure */ - kmutex_t wl_lock; /* protects changes to wci_list */ - kmutex_t cl_lock; /* protects changes to controller_list */ - kcondvar_t cv; /* for waiting on the SC */ - kmutex_t cv_lock; /* Used together with the above condvar */ - wrsm_wci_dev_t *wci_list; - wrsm_controller_dev_t *controller_list; - kmutex_t ncslices_lock; - ncslice_bitmask_t ncslices_allocated; - uint32_t ncslice_owner[WRSM_MAX_NCSLICES]; -} cf_state_t; - -static cf_state_t *cf_state = NULL; - -static wrsm_controller_dev_t *find_controller(uint_t controller_id); -static wrsm_wci_dev_t *find_wci(safari_port_t port); -static wci_ids_t *create_wci_ids(safari_port_t *wcis, int nwcis, - uint32_t controller_id, int *nfound); -static int verify_config(wrsm_controller_t *config, - ncslice_bitmask_t *new_ncslices); -static int verify_newconfig(wrsm_controller_t *old, wrsm_controller_t *new); - -static void cf_claim_slice(uint32_t controller_id, wrsm_ncslice_t slice); -static void cf_release_slice(uint32_t controller_id, wrsm_ncslice_t slice); -static int cf_claim_slices(uint32_t controller_id, ncslice_bitmask_t - req_slices); -static void cf_release_slices(uint32_t controller_id, ncslice_bitmask_t - rel_slices); -static void cf_release_all_slices(uint32_t controller_id); -static int wrsm_cf_ncslicelist_to_bitmask(wrsm_node_ncslice_array_t slice_array, - ncslice_t *small_ncslicep, ncslice_bitmask_t *large_slice_bitmask); - -static int wrsm_cf_replacecfg(intptr_t arg, int flag); -static int wrsm_cf_checkcfg(intptr_t arg, int flag); -static int wrsm_cf_installcfg(intptr_t arg, int flag); -static int wrsm_cf_initialcfg(intptr_t arg, int flag); -static int wrsm_cf_enablecfg(intptr_t arg, int flag); -static int wrsm_cf_removecfg(intptr_t arg, int flag); -static int wrsm_cf_startcfg(intptr_t arg, int flag); -static int wrsm_cf_stopcfg(intptr_t arg, int flag); -static int wrsm_cf_getcfg(intptr_t arg, int flag); - -static int wrsm_cf_ping(int cont_id, intptr_t arg, int flag); -static int wrsm_cf_mbox(int cont_id, intptr_t arg, int flag); -static int wrsm_cf_sess(int cont_id, intptr_t arg, int flag); -static int wrsm_cf_memory_loopback(int cont_id, intptr_t arg, int flag); - - -static boolean_t wrsm_large_pages_supported = B_FALSE; -static boolean_t wrsm_forwarding_supported = B_FALSE; - -/* - * Called from the driver _init() routine to initialize - * data private to the config layer. - */ -void -wrsm_cf_init(void) -{ - int i; - - cf_state = kmem_zalloc(sizeof (cf_state_t), KM_SLEEP); - mutex_init(&cf_state->wl_lock, NULL, MUTEX_DRIVER, NULL); - cf_state->wci_list = NULL; - mutex_init(&cf_state->cl_lock, NULL, MUTEX_DRIVER, NULL); - cf_state->controller_list = NULL; - mutex_init(&cf_state->ncslices_lock, NULL, MUTEX_DRIVER, NULL); - WRSMSET_ZERO(cf_state->ncslices_allocated); - for (i = 0; i < WRSM_MAX_NCSLICES; ++i) { - cf_state->ncslice_owner[i] = WRSM_BAD_RSM_ID; - } - mutex_init(&cf_state->cv_lock, NULL, MUTEX_DRIVER, NULL); - cv_init(&cf_state->cv, NULL, CV_DRIVER, NULL); -} - -/* - * Called from the driver _fini() routine to clean up - * cf specific things. - */ -void -wrsm_cf_fini(void) -{ - cv_destroy(&cf_state->cv); - - mutex_destroy(&cf_state->ncslices_lock); - mutex_destroy(&cf_state->wl_lock); - mutex_destroy(&cf_state->cl_lock); - mutex_destroy(&cf_state->cv_lock); - - kmem_free(cf_state, sizeof (cf_state_t)); -} - - - -/* - * Called from wrsm_ioctl() when called on a driver instance which - * has a type of wrsm_admin. All of the calls from the RSM proxy - * to install, update and query the configuration data come through - * here. - */ -/*ARGSUSED*/ -int -wrsm_cf_admin_ioctl(struct wrsm_soft_state *softsp, int cmd, intptr_t arg, - int flag, cred_t *cred_p, int *rval_p) -{ - int retval = EACCES; - - if (cmd != WRSM_CONTROLLERS && cmd != WRSM_GETCFG && - (retval = secpolicy_sys_config(cred_p, B_FALSE)) != 0) - return (retval); - - switch (cmd) { - case WRSM_CONTROLLERS: - *rval_p = cf_state->controller_devs; - return (0); - case WRSM_REPLACECFG: - retval = wrsm_cf_replacecfg(arg, flag); - break; - case WRSM_CHECKCFG: - retval = wrsm_cf_checkcfg(arg, flag); - break; - case WRSM_INSTALLCFG: - retval = wrsm_cf_installcfg(arg, flag); - break; - case WRSM_ENABLECFG: - retval = wrsm_cf_enablecfg(arg, flag); - break; - case WRSM_INITIALCFG: - retval = wrsm_cf_initialcfg(arg, flag); - break; - case WRSM_REMOVECFG: - retval = wrsm_cf_removecfg(arg, flag); - break; - case WRSM_STARTCFG: - retval = wrsm_cf_startcfg(arg, flag); - break; - case WRSM_STOPCFG: - retval = wrsm_cf_stopcfg(arg, flag); - break; - case WRSM_GETCFG: - retval = wrsm_cf_getcfg(arg, flag); - break; - default: - return (EINVAL); - } - - return (retval); -} - -/* For a give wci port, finds the controller it should belong to */ -static uint32_t -find_wci_controller(safari_port_t port) -{ - wrsm_controller_dev_t *cont; - - mutex_enter(&cf_state->cl_lock); - for (cont = cf_state->controller_list; cont; cont = cont->next) { - if (cont->controller) { - wrsm_controller_t *config = cont->controller; - int i; - - if (config->routing == NULL || - config->routing->wcis == NULL) { - mutex_exit(&cf_state->cl_lock); - return (WRSM_BAD_RSM_ID); - } - - for (i = 0; i < config->routing->nwcis; i++) { - if (config->routing->wcis[i]->port == port) { - mutex_exit(&cf_state->cl_lock); - return (cont->controller_id); - } - } - } - } - mutex_exit(&cf_state->cl_lock); - return (WRSM_BAD_RSM_ID); -} - -/* - * Called from _attach() when a new physical WCI is added. - * The LC handle and port id are saved so that when configuration - * data comes in which specifies WCIs by port id, it can be - * translated to the LC handle before being handed to the NC - */ -int -wrsm_cf_newwci(lcwci_handle_t lcwci, safari_port_t port) -{ - wrsm_wci_dev_t *wci; - wrsm_controller_dev_t *cont = NULL; - boolean_t newwci = B_FALSE; - - /* - * If we already have an wci_dev_t for this wci, that means - * that it had previously been attached, assigned to a controller - * removed by DR, and now is being added again. - */ - wci = find_wci(port); - - if (wci == NULL) { - /* This is a new WCI, so create an entry for it. */ - newwci = B_TRUE; - wci = (wrsm_wci_dev_t *)kmem_alloc(sizeof (wrsm_wci_dev_t), - KM_SLEEP); - } - wci->id.port = port; - wci->id.lcwci = lcwci; - wci->controller_id = find_wci_controller(port); - wci->attached = B_TRUE; - - if (newwci) { - /* If new wci, add to wci list */ - mutex_enter(&cf_state->wl_lock); - wci->next = cf_state->wci_list; - cf_state->wci_list = wci; - mutex_exit(&cf_state->wl_lock); - } - - /* See if this WCI belongs to an existing controller */ - cont = find_controller(wci->controller_id); - if (cont) { - /* Don't call wrsm_nc_newwci if controller isn't enabled */ - if (cont->state == cf_enabled) { - return (wrsm_nc_newwci(wci->controller_id, port, - lcwci, cont->controller)); - } else { - /* - * Tried to DR in a WCI which belongs to a - * controller which is in the middle of being - * reconfigured. - */ - DPRINTF(CF_WARN, (CE_WARN, "controller busy")); - return (EBUSY); - } - } - return (WRSM_SUCCESS); -} - -/* - * Remove an entry from the list of attached WCIs - */ -int -wrsm_cf_remove_wci(lcwci_handle_t lcwci) -{ - wrsm_wci_dev_t *wci, *to_remove; - wrsm_controller_dev_t *cont = NULL; - - DPRINTF(CF_DEBUG, (CE_CONT, "cf_remove_wci")); - - mutex_enter(&cf_state->wl_lock); - wci = cf_state->wci_list; - while (wci && wci->id.lcwci != lcwci) { - wci = wci->next; - } - mutex_exit(&cf_state->wl_lock); - - if (wci == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "remove_wci didn't find %p", - (void *)lcwci)); - return (WRSM_SUCCESS); - } - - /* - * If this WCI belongs to a controller, then check with - * nr to see if it's safe to let it be removed. If it is - * removed, we leave it on the wci_list so that when it - * comes back, cf_newwci() can plug it back into the same - * controller. - */ - if ((cont = find_controller(wci->controller_id))) { - ASSERT(cont); - if (cont->state == cf_enabled) { - int ier = wrsm_nc_removewci(wci->controller_id, - wci->id.port); - - if (!ier) - wci->attached = B_FALSE; - - return (ier); - } - else - return (EBUSY); - } - - /* - * If the WCI does not belong to a controller, then - * delete it from the list. - */ - mutex_enter(&cf_state->wl_lock); - wci = cf_state->wci_list; - if (wci->id.lcwci == lcwci) { - to_remove = wci; - cf_state->wci_list = wci->next; - } else { - while (wci && wci->next && wci->next->id.lcwci != lcwci) - wci = wci->next; - if (!wci || !wci->next) { - mutex_exit(&cf_state->wl_lock); - return (EINVAL); - } - to_remove = wci->next; - wci->next = to_remove->next; - } - mutex_exit(&cf_state->wl_lock); - kmem_free(to_remove, sizeof (wrsm_wci_dev_t)); - - return (WRSM_SUCCESS); -} - -/* - * Given the Safari port id of an attached wci, return - * the corresponding lcwci_handle_t. - */ -lcwci_handle_t -wrsm_cf_lookup_wci(safari_port_t port) -{ - wrsm_wci_dev_t *wci; - - wci = find_wci(port); - if (wci) - return (wci->id.lcwci); - else - return (NULL); -} - -/* - * This function is registered as a callback from the wrsm mailbox - * module and is called when it is notfied that the SC has come back - * up. This implies that the SC had previously crashed so any - * outstanding mailbox requests need to be re-sent. - */ -void -wrsm_cf_sc_failed() -{ - wrsm_wci_dev_t *cfwci; - - mutex_enter(&cf_state->wl_lock); - cfwci = cf_state->wci_list; - while (cfwci) { - wrsm_lc_sc_crash(cfwci->id.lcwci); - cfwci = cfwci->next; - } - mutex_exit(&cf_state->wl_lock); -} - -/* - * Reserve a wci for use by the specified controller - */ -int -wrsm_cf_claim_wci(uint32_t controller_id, safari_port_t wci_id) -{ - wrsm_wci_dev_t *wci; - - wci = find_wci(wci_id); - if (wci) { - if (wci->controller_id == WRSM_BAD_RSM_ID || - wci->controller_id == controller_id) { - wci->controller_id = controller_id; - return (WRSM_SUCCESS); - } else { - DPRINTF(CF_WARN, (CE_WARN, "claim_wci: " - "wci %d is unavailable", wci_id)); - return (EACCES); - } - } - - return (WRSM_SUCCESS); -} - -void -wrsm_cf_release_wci(safari_port_t wci_id) -{ - wrsm_wci_dev_t *wci; - - wci = find_wci(wci_id); - if (wci) - wci->controller_id = WRSM_BAD_RSM_ID; -} - -uint32_t -wrsm_cf_wci_owner(safari_port_t wci_id) -{ - wrsm_wci_dev_t *wci; - - wci = find_wci(wci_id); - if (wci) - return (wci->controller_id); - else - return (WRSM_BAD_RSM_ID); -} - -/* - * Return true if the local cnode is configured to be used as a - * starcat central switch. - */ -boolean_t -wrsm_cf_cnode_is_switch(wrsm_controller_t *config) -{ - int i; - wrsm_routing_data_t *routing; - - if (config == NULL || config->routing == NULL) - return (B_FALSE); - - routing = config->routing; - for (i = 0; i < routing->npolicy; ++i) { - wrsm_routing_policy_t *policy; - policy = routing->policy[i]; - if (policy->forwarding_allowed) { - DPRINTF(CF_DEBUG, (CE_CONT, "cf_cnode_is_switch: " - "forwarding is allowed")); - return (B_TRUE); - } - } - return (B_FALSE); -} - -/* - * This function is called from _attach() when a new instance of the - * driver is created represeting an RSM controller. The def_info - * pointer is stashed away allong with the controller id (instance - * number) so that we can later translate from controller ids coming - * in via ioctl to the appropriate dev_info to pass to the NC - */ -int -wrsm_cf_new_controller(int cont_id, dev_info_t *devi) -{ - wrsm_controller_dev_t *cont; - - cont = (wrsm_controller_dev_t *)kmem_alloc( - sizeof (wrsm_controller_dev_t), KM_SLEEP); - cont->controller_id = cont_id; - cont->devi = devi; - cont->controller = NULL; - cont->state = cf_invalid; - cont->in_ioctl = B_FALSE; - mutex_init(&cont->lock, NULL, MUTEX_DRIVER, NULL); - mutex_enter(&cf_state->cl_lock); - cont->next = cf_state->controller_list; - cf_state->controller_list = cont; - ++cf_state->controller_devs; - mutex_exit(&cf_state->cl_lock); - DPRINTF(CF_DEBUG, (CE_CONT, "wrsm_cf_new_controller:" - "new controller id %d", cont->controller_id)); - - return (WRSM_SUCCESS); -} - -/* - * Delete an entry from the list of valid controllers. This is called - * from the driver _detach() when the instance type is - * wrsm_rsm_controller. In this context a "controller" is just a - * driver instance and it's associated wrsm_controller_dev_t struct. - * If the controller has configuration data associated with it (ie it - * has been the subject of an INITIALCFG ioctl) then this will cause - * the detach to fail. - */ -int -wrsm_cf_remove_controller(int cont_id) -{ - wrsm_controller_dev_t *cont = NULL; - wrsm_controller_dev_t *to_remove = NULL; - - DPRINTF(CF_DEBUG, (CE_CONT, "remove_controller %d", cont_id)); - - if ((cont = find_controller(cont_id)) == NULL) - return (EINVAL); - - /* - * Do not allow the driver to be unloaded if there are - * any active controllers. - */ - if (cont->controller && cont->state != cf_invalid) { - DPRINTF(CF_WARN, (CE_WARN, "remove_controller: " - "%d is still active", cont_id)); - return (EBUSY); - } - - mutex_enter(&cf_state->cl_lock); - cont = cf_state->controller_list; - if (cont->controller_id == cont_id) { - to_remove = cont; - cf_state->controller_list = cont->next; - } else { - while (cont && cont->next && - cont->next->controller_id != cont_id) - cont = cont->next; - if (!cont || !cont->next) { - mutex_exit(&cf_state->cl_lock); - return (EINVAL); - } - to_remove = cont->next; - cont->next = to_remove->next; - } - --cf_state->controller_devs; - mutex_exit(&cf_state->cl_lock); - mutex_destroy(&to_remove->lock); - kmem_free(to_remove, sizeof (wrsm_controller_dev_t)); - return (WRSM_SUCCESS); -} - - -/*ARGSUSED*/ -static int -wrsm_cf_replacecfg(intptr_t arg, int flag) -{ - int retval = 0; - int i; - wrsm_admin_arg_config_t replace_arg; - wrsm_controller_dev_t *cont; - void *controller_data = NULL; - wrsm_controller_t *new = NULL; - wrsm_routing_data_t *routing; - wci_ids_t *attached_wcis = NULL; - safari_port_t *port_list = NULL; - boolean_t *new_wci = NULL; - int num_attached; - int num_claimed_wcis = 0; - boolean_t slices_allocated = B_FALSE; - ncslice_bitmask_t new_ncslices = {0}; - ncslice_bitmask_t added_ncslices = {0}; - - DPRINTF(CF_DEBUG, (CE_CONT, "wrsm_cf_replacecfg")); - if (ddi_copyin((void *)arg, (void *)&replace_arg, - sizeof (wrsm_admin_arg_config_t), flag) != 0) { - retval = EFAULT; - goto finish; - } - - if (replace_arg.ioctl_version != WRSM_CF_IOCTL_VERSION) { - cmn_err(CE_WARN, "replacecfg: user/kernel version mismatch"); - return (EINVAL); - } - - if (!(cont = find_controller(replace_arg.controller_id))) { - retval = EINVAL; - goto finish; - } - - if (cont->controller == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "cf_replacecfg: controller %d " - "does not exist", replace_arg.controller_id)); - retval = ENOENT; - goto finish; - } - - if (cont->state != cf_enabled) { - DPRINTF(CF_WARN, (CE_WARN, "cf_replacecfg: controller in " - "wrong state %d", cont->state)); - retval = EINVAL; - goto finish; - } - - controller_data = kmem_alloc(replace_arg.controller_data_size, - KM_SLEEP); - - if (ddi_copyin(replace_arg.controller, controller_data, - replace_arg.controller_data_size, flag) != 0) { - retval = EFAULT; - goto finish; - } - - if ((new = wrsm_cf_unpack(controller_data)) == NULL) { - retval = EINVAL; - goto finish; - } - - routing = new->routing; - - /* - * Scan through the wci list in the wrsm_routing_data - * structure and pull out the port numbers, then pass the list - * of port numbers to create_wci_ids which builds the list of - * wci_ids_t that the NC expects. This also has the side - * effect of marking the wcis as belonging to this controller. - */ - port_list = kmem_alloc(sizeof (safari_port_t) * - routing->nwcis, KM_SLEEP); - new_wci = kmem_zalloc(sizeof (boolean_t) * routing->nwcis, - KM_SLEEP); - for (i = 0; i < routing->nwcis; ++i) { - port_list[i] = routing->wcis[i]->port; - /* Check wci ownership/availability */ - if (wrsm_cf_wci_owner(port_list[i]) != - replace_arg.controller_id) { - new_wci[i] = B_TRUE; - if (wrsm_cf_claim_wci(replace_arg.controller_id, - port_list[i]) != 0) { - retval = EINVAL; - goto finish; - } - } - ++num_claimed_wcis; - } - - attached_wcis = create_wci_ids(port_list, routing->nwcis, - replace_arg.controller_id, &num_attached); - - /* LINTED: E_NOP_IF_STMT */ - if (!attached_wcis) { - DPRINTF(CF_DEBUG, (CE_CONT, "no attached_wcis")); - } - - if ((retval = verify_config(new, &new_ncslices)) != 0) { - cmn_err(CE_NOTE, "cf_replacecfg: illegal new config"); - goto finish; - } - - if ((retval = verify_newconfig(cont->controller, new)) != 0) { - cmn_err(CE_NOTE, "cf_replacecfg: illegal config change"); - retval = EINVAL; - goto finish; - } - - - /* - * Find all the slices in the new config not in the old one - * and attempt to allocate them. - */ - for (i = 0; i < WRSM_MAX_NCSLICES; ++i) { - if (WRSM_IN_SET(new_ncslices, i) && - !WRSM_IN_SET(cont->ncslices, i)) - WRSMSET_ADD(added_ncslices, i); - } - - DPRINT_BITMASK("cf_replacecfg: new config added slices", - added_ncslices); - - if ((retval = cf_claim_slices(cont->controller_id, added_ncslices)) - != 0) { - cmn_err(CE_NOTE, "cf_replacecfg: failed to get needed " - "ncslices"); - retval = EINVAL; - goto finish; - } - slices_allocated = B_TRUE; - - -#ifdef DEBUG - { - int j; - DPRINTF(CF_DEBUG, (CE_CONT, "number of attached wcis %d", - num_attached)); - for (j = 0; j < num_attached; ++j) - DPRINTF(CF_DEBUG, (CE_CONT, "attached[%d] " - "lcwci = %p port = %d", j, - (void *)attached_wcis[i].lcwci, - attached_wcis[i].port)); - } -#endif - - retval = wrsm_nc_replaceconfig(replace_arg.controller_id, new, - cont->devi, num_attached, attached_wcis); - -finish: - if (retval == 0) { - cont->state = cf_replaced; - cont->pending = new; - WRSMSET_COPY(new_ncslices, cont->pending_ncslices); - cont->pending_nbytes = replace_arg.controller_data_size; - } else { - if (port_list) { - for (i = 0; i < num_claimed_wcis; ++i) { - if (new_wci[i]) { - wrsm_cf_release_wci(port_list[i]); - } - } - } - - if (slices_allocated) { - cf_release_slices(cont->controller_id, added_ncslices); - } - - /* If unpack failed, free controller_data */ - if (controller_data) { - kmem_free(controller_data, - replace_arg.controller_data_size); - } - } - if (port_list) { - kmem_free(port_list, sizeof (safari_port_t) * routing->nwcis); - kmem_free(new_wci, sizeof (boolean_t) * routing->nwcis); - } - if (attached_wcis) { - kmem_free(attached_wcis, sizeof (wci_ids_t) * - routing->nwcis); - } - - return (retval); -} - -/* ARGSUSED */ -static void -cf_release_slice(uint32_t controller_id, wrsm_ncslice_t ncslice) -{ - ASSERT(mutex_owned(&cf_state->ncslices_lock)); - ASSERT(cf_state->ncslice_owner[ncslice] == controller_id); - ASSERT(WRSM_IN_SET(cf_state->ncslices_allocated, ncslice)); - cf_state->ncslice_owner[ncslice] = WRSM_BAD_RSM_ID; - WRSMSET_DEL(cf_state->ncslices_allocated, ncslice); -} - -static void -cf_release_slices(uint32_t controller_id, ncslice_bitmask_t rel_slices) -{ - int i, retval; - ncslice_bitmask_t granted; - - mutex_enter(&cf_state->ncslices_lock); - DPRINT_BITMASK("cf_release_slices: ncslices before removal", - cf_state->ncslices_allocated); - - for (i = 0; i < WRSM_MAX_NCSLICES; ++i) { - if (WRSM_IN_SET(rel_slices, i)) { - cf_release_slice(controller_id, i); - } - } - - /* - * Notify wrsmplat of the new list of allocated ncslices - */ - if ((retval = wrsmplat_alloc_slices(cf_state->ncslices_allocated, - &granted))) { - /* - * a failure should never happen, as we're releasing - * slices we already owned; ignore failure. - */ - cmn_err(CE_NOTE, "cf_claim_slices: wrsmplat_alloc " - "failed %d", retval); - } - - DPRINT_BITMASK("cf_release_slices: ncslices after removal", - cf_state->ncslices_allocated); - - mutex_exit(&cf_state->ncslices_lock); -} - -static void -cf_release_all_slices(uint32_t controller_id) -{ - int i, retval; - ncslice_bitmask_t granted; - - mutex_enter(&cf_state->ncslices_lock); - DPRINT_BITMASK("cf_release_all_slices: ncslices before removal", - cf_state->ncslices_allocated); - - for (i = 0; i < WRSM_MAX_NCSLICES; ++i) { - if (cf_state->ncslice_owner[i] == controller_id) { - cf_release_slice(controller_id, i); - } - } - - /* - * Notify wrsmplat of the new list of allocated ncslices - */ - if ((retval = wrsmplat_alloc_slices(cf_state->ncslices_allocated, - &granted))) { - /* - * a failure should never happen, as we're releasing - * slices we already owned; ignore failure. - */ - cmn_err(CE_NOTE, "cf_claim_slices: wrsmplat_alloc " - "failed %d", retval); - } - - DPRINT_BITMASK("cf_release_all_slices: ncslices after removal", - cf_state->ncslices_allocated); - - mutex_exit(&cf_state->ncslices_lock); -} - -static void -cf_claim_slice(uint32_t controller_id, wrsm_ncslice_t ncslice) -{ -#ifdef DEBUG - ASSERT(mutex_owned(&cf_state->ncslices_lock)); - if (WRSM_IN_SET(cf_state->ncslices_allocated, ncslice)) { - ASSERT(cf_state->ncslice_owner[ncslice] == controller_id); - } else { - ASSERT(cf_state->ncslice_owner[ncslice] == WRSM_BAD_RSM_ID); - } -#endif /* DEBUG */ - cf_state->ncslice_owner[ncslice] = controller_id; - WRSMSET_ADD(cf_state->ncslices_allocated, ncslice); -} - -static int -cf_claim_slices(uint32_t controller_id, ncslice_bitmask_t req_slices) -{ - int retval = 0; - ncslice_bitmask_t granted; - ncslice_bitmask_t union_slices; - ncslice_bitmask_t new_slices; - int i; - - mutex_enter(&cf_state->ncslices_lock); - DPRINT_BITMASK("cf_claim_slices: ncslices allocated", - cf_state->ncslices_allocated); - DPRINT_BITMASK("cf_claim_slices: ncslices requested", req_slices); - - /* - * Find out if any of the requsted slices are already taken - * by another controller. This will be the case if any of - * the slices in req_slices is allocated and the owner is - * someone else. - */ - for (i = 0; i < WRSM_MAX_NCSLICES; ++i) { - if (WRSM_IN_SET(req_slices, i) && - WRSM_IN_SET(cf_state->ncslices_allocated, i) && - cf_state->ncslice_owner[i] != controller_id) { - DPRINTF(CF_DEBUG, (CE_NOTE, "cf_claim_slices: " - "contid %d ncslice %d already taken by cont %d", - controller_id, i, cf_state->ncslice_owner[i])); - mutex_exit(&cf_state->ncslices_lock); - return (EACCES); - } - } - - /* Get the union of the old and new ncslices */ - WRSMSET_COPY(req_slices, union_slices); - WRSMSET_OR(union_slices, cf_state->ncslices_allocated); - - /* Determine what new slices are needed */ - WRSMSET_COPY(union_slices, new_slices); - WRSMSET_DIFF(new_slices, cf_state->ncslices_allocated); - - /* If there are new slices that are needed, allocate from SC */ - if (!WRSMSET_ISNULL(new_slices)) { - DPRINT_BITMASK("cf_claim_slices: new slices", - new_slices); - - /* wrsmplat needs to see list of ALL slices desired */ - if ((retval = wrsmplat_alloc_slices(union_slices, &granted))) { - cmn_err(CE_NOTE, "cf_claim_slices: wrsmplat_alloc " - "failed %d", retval); - mutex_exit(&cf_state->ncslices_lock); - return (retval); - } - - /* - * If we didn't get everything we requested, back out new - * ncslices, then fail. - */ - if (!WRSMSET_ISEQUAL(union_slices, granted)) { - if ((retval = wrsmplat_alloc_slices( - cf_state->ncslices_allocated, &granted))) { - /* ignore failure; this shouldn't happen */ - cmn_err(CE_NOTE, - "cf_claim_slices: wrsmplat_alloc " - "failed %d", retval); - } - mutex_exit(&cf_state->ncslices_lock); - return (EACCES); - } - - /* - * All requested slices were allocated, so update the - * ownership list. - */ - for (i = 0; i < WRSM_MAX_NCSLICES; ++i) { - if (WRSM_IN_SET(req_slices, i)) { - cf_claim_slice(controller_id, i); - } - } - } - - mutex_exit(&cf_state->ncslices_lock); - return (WRSM_SUCCESS); -} - -/*ARGSUSED*/ -static int -wrsm_cf_checkcfg(intptr_t arg, int flag) -{ - wrsm_controller_dev_t *cont; - int retval = 0; - boolean_t up; - - if (!(cont = find_controller(arg))) - return (EINVAL); - - if (cont->controller == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "cf_checkcfg: controller " - "not present %d", (int)arg)); - return (EINVAL); - } - - up = wrsm_nc_is_installed_up(arg); - if (!up) - retval = EBUSY; - return (retval); -} - - -/*ARGSUSED*/ -static int -wrsm_cf_installcfg(intptr_t arg, int flag) -{ - wrsm_admin_arg_wci_t install_arg; - wrsm_controller_dev_t *cont; - wci_ids_t *attached_wcis = NULL; - safari_port_t *wcis = NULL; - int retval = 0; - int num_attached; - ncslice_bitmask_t old_slices = {0}; - int i; - - if (ddi_copyin((void *)arg, (void *)&install_arg, - sizeof (wrsm_admin_arg_wci_t), flag) != 0) - return (EFAULT); - - if (install_arg.ioctl_version != WRSM_CF_IOCTL_VERSION) { - cmn_err(CE_WARN, "installcfg: user/kernel version mismatch"); - return (EINVAL); - } - - DPRINTF(CF_DEBUG, (CE_CONT, "wrsm_cf_installcfg controller %d", - install_arg.controller_id)); - - if (!(cont = find_controller(install_arg.controller_id))) - return (EINVAL); - if (cont->controller == NULL || cont->pending == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "cf_installcfg: " - "controller not present state=%d", cont->state)); - return (EINVAL); - } - - mutex_enter(&cont->lock); - if (cont->in_ioctl) { - mutex_exit(&cont->lock); - return (EBUSY); - } - cont->in_ioctl = B_TRUE; - mutex_exit(&cont->lock); - - if (cont->state != cf_replaced) { - DPRINTF(CF_WARN, (CE_WARN, "cf_installcfg: " - "controller in wrong state %d", cont->state)); - cont->in_ioctl = B_FALSE; - return (EINVAL); - } - - wcis = kmem_alloc(sizeof (safari_port_t) * install_arg.nwcis, - KM_SLEEP); - if (ddi_copyin((void *)install_arg.wci_ids, (void *)wcis, - sizeof (safari_port_t) * install_arg.nwcis, flag) != 0) { - retval = EFAULT; - goto finish; - } - - attached_wcis = create_wci_ids(wcis, install_arg.nwcis, - install_arg.controller_id, &num_attached); - kmem_free(wcis, sizeof (safari_port_t) * install_arg.nwcis); - - /* LINTED: E_NOP_IF_STMT */ - if (!attached_wcis) { - DPRINTF(CF_DEBUG, (CE_CONT, "no attached_wcis")); - } - - retval = wrsm_nc_cleanconfig(install_arg.controller_id, - num_attached, attached_wcis); - if (retval != 0) - goto finish; - - /* - * At this point, the NC guarantees that no accesses will be made - * to the old ncslices, so it's safe to release them. - */ - -#ifdef DEBUG - { - int j; - DPRINTF(CF_DEBUG, (CE_CONT, "number of attached wcis %d", - num_attached)); - for (j = 0; j < num_attached; ++j) - DPRINTF(CF_DEBUG, (CE_CONT, "attached[%d] " - "lcwci = %p port = %d", j, - (void *)attached_wcis[j].lcwci, - attached_wcis[j].port)); - } -#endif - - retval = wrsm_nc_installconfig(install_arg.controller_id); - if (retval != 0) - goto finish; - - WRSMSET_ZERO(old_slices); - for (i = 0; i < WRSM_MAX_NCSLICES; ++i) { - if (WRSM_IN_SET(cont->ncslices, i) && - !WRSM_IN_SET(cont->pending_ncslices, i)) { - WRSMSET_ADD(old_slices, i); - } - } - DPRINT_BITMASK("cf_installcfg: releasing old slices", old_slices); - cf_release_slices(cont->controller_id, old_slices); - -finish: - if (retval == 0) { - wrsm_routing_data_t *old_route, *new_route; - int i, j, old_port; - - /* - * Release WCIs from the old config not in the new. - * This relies on both the old and new lists of wcis - * to be sorted in ascending order by port number. - */ - old_route = cont->controller->routing; - new_route = cont->pending->routing; - j = 0; - for (i = 0; i < old_route->nwcis; ++i) { - old_port = old_route->wcis[i]->port; - while (j < new_route->nwcis && - new_route->wcis[j]->port < old_port) - ++j; - if (j >= new_route->nwcis || - new_route->wcis[j]->port > old_port) { - wrsm_cf_release_wci(old_port); - } - } - - cont->state = cf_installed; - cont->controller = cont->pending; - WRSMSET_COPY(cont->pending_ncslices, cont->ncslices); - cont->nbytes = cont->pending_nbytes; - } - - cont->in_ioctl = B_FALSE; - if (attached_wcis) { - kmem_free(attached_wcis, sizeof (wci_ids_t) * - install_arg.nwcis); - } - return (retval); -} - -static int -wrsm_cf_enablecfg(intptr_t arg, int flag) -{ - wrsm_admin_arg_wci_t enable_arg; - wrsm_controller_dev_t *cont; - int retval = 0; - safari_port_t *wcis = NULL; - wci_ids_t *attached_wcis = NULL; - int num_attached; - - if (ddi_copyin((void *)arg, (void *)&enable_arg, - sizeof (wrsm_admin_arg_wci_t), flag) != 0) - return (EFAULT); - - if (enable_arg.ioctl_version != WRSM_CF_IOCTL_VERSION) { - cmn_err(CE_WARN, "enablecfg: user/kernel version mismatch"); - return (EINVAL); - } - - DPRINTF(CF_DEBUG, (CE_CONT, "wrsm_cf_enablecfg controller %d", - enable_arg.controller_id)); - - if (!(cont = find_controller(enable_arg.controller_id))) - return (EINVAL); - - if (cont->controller == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "cf_enablecfg: " - "controller not present %d", enable_arg.controller_id)); - return (EINVAL); - } - - mutex_enter(&cont->lock); - if (cont->in_ioctl) { - mutex_exit(&cont->lock); - return (EBUSY); - } - cont->in_ioctl = B_TRUE; - mutex_exit(&cont->lock); - - if (cont->state != cf_installed) { - DPRINTF(CF_WARN, (CE_WARN, "cf_enablecfg: " - "controller int wrong state %d", cont->state)); - retval = EINVAL; - goto err_return; - } - - wcis = kmem_alloc(sizeof (safari_port_t) * enable_arg.nwcis, - KM_SLEEP); - if (ddi_copyin((void *)enable_arg.wci_ids, (void *)wcis, - sizeof (safari_port_t) * enable_arg.nwcis, flag) != 0) { - retval = EFAULT; - goto err_return; - } - - attached_wcis = create_wci_ids(wcis, enable_arg.nwcis, - enable_arg.controller_id, &num_attached); - /* LINTED: E_NOP_IF_STMT */ - if (!attached_wcis) { - DPRINTF(CF_DEBUG, (CE_CONT, "no attached_wcis")); - } - - retval = wrsm_nc_enableconfig(enable_arg.controller_id, - num_attached, attached_wcis); - if (attached_wcis) { - kmem_free(attached_wcis, sizeof (wci_ids_t) * - enable_arg.nwcis); - attached_wcis = NULL; - } - if (retval == 0) - cont->state = cf_enabled; - cont->in_ioctl = B_FALSE; - - return (retval); - -err_return: - if (wcis) - kmem_free(wcis, sizeof (safari_port_t) * - enable_arg.nwcis); - cont->in_ioctl = B_FALSE; - if (attached_wcis) { - kmem_free(attached_wcis, sizeof (wci_ids_t) * - enable_arg.nwcis); - } - - return (retval); -} - -/* - * Called as a result of an WRSM_INITIALCFG ioctl() call to the wrsm - * admin psuedo driver. The arg is a pointer to a wrsm_admin_arg_config_t - * structure which contains the address and size of a wrsm_controller_t. - * If successfull, this function brings the controller data in from user - * space and passes it to wsrm_nc_initialcfg(). - */ -static int -wrsm_cf_initialcfg(intptr_t arg, int flag) -{ - int retval = 0; - int i; - wrsm_admin_arg_config_t init_arg; - void *controller_data = NULL; - wrsm_controller_dev_t *cont; /* used to walk controller_list */ - wci_ids_t *attached_wcis = NULL; - wrsm_routing_data_t *routing; - safari_port_t *port_list = NULL; - int num_attached; - boolean_t slices_allocated = B_FALSE; - - DPRINTF(CF_DEBUG, (CE_CONT, "wrsm_cf_initialcfg")); - - if (ddi_copyin((void *)arg, (void *)&init_arg, - sizeof (wrsm_admin_arg_config_t), flag) != 0) { - DPRINTF(CF_DEBUG, (CE_WARN, "initialcfg: 1st ddi_copyin " - "failed")); - retval = EFAULT; - goto err_return; - } - - if (init_arg.ioctl_version != WRSM_CF_IOCTL_VERSION) { - cmn_err(CE_WARN, "initialcfg: user/kernel version mismatch"); - return (EINVAL); - } - - if (!(cont = find_controller(init_arg.controller_id))) { - retval = EINVAL; - DPRINTF(CF_DEBUG, (CE_WARN, "initialcfg: find_controller " - "failed")); - goto err_return; - } - - /* - * If there is already a cached wrsm_conroller_t pointer then - * we already have a config for this controller so it can't - * be "initial". - */ - if (cont->controller != NULL) { - cmn_err(CE_NOTE, "wrsm_cf_initial: " - "controller already configured"); - retval = EEXIST; - cont = NULL; - goto err_return; - } - - mutex_enter(&cont->lock); - if (cont->in_ioctl) { - mutex_exit(&cont->lock); - return (EBUSY); - } - cont->in_ioctl = B_TRUE; - mutex_exit(&cont->lock); - - /* Bring the controller data in from user space */ - controller_data = kmem_alloc(init_arg.controller_data_size, KM_SLEEP); - bzero(controller_data, init_arg.controller_data_size); - - if (ddi_copyin(init_arg.controller, controller_data, - init_arg.controller_data_size, flag) != 0) { - retval = EFAULT; - DPRINTF(CF_DEBUG, (CE_WARN, "initialcfg: 2nd ddi_copyin " - "failed")); - goto err_return; - } - - cont->nbytes = init_arg.controller_data_size; - if ((cont->controller = wrsm_cf_unpack(controller_data)) == NULL) { - retval = EINVAL; - DPRINTF(CF_DEBUG, (CE_WARN, "initialcfg: cf_unpack failed")); - goto err_return; - } - - routing = cont->controller->routing; - - /* - * Scan through the wci list in the wrsm_routing_data - * structure and pull out the port numbers, then pass the list - * of port numbers to create_wci_ids which builds the list of - * wci_ids_t that the NC expects. This also has the side - * effect of marking the wcis as belonging to this controller. - */ - port_list = kmem_alloc(sizeof (safari_port_t) * - routing->nwcis, KM_SLEEP); - for (i = 0; i < routing->nwcis; ++i) { - port_list[i] = routing->wcis[i]->port; - if (wrsm_cf_claim_wci(init_arg.controller_id, - port_list[i]) != 0) { - retval = EINVAL; - DPRINTF(CF_DEBUG, (CE_WARN, "initialcfg: cf_claim_wci " - "failed")); - goto err_return; - } - } - - attached_wcis = create_wci_ids(port_list, routing->nwcis, - init_arg.controller_id, &num_attached); - - if (!attached_wcis) { - DPRINTF(CF_DEBUG, (CE_CONT, "no attached_wcis")); - retval = EACCES; - goto err_return; - } - - if ((retval = verify_config(cont->controller, &cont->ncslices)) != 0) { - DPRINTF(CF_DEBUG, (CE_WARN, "initialcfg: verify_config " - "failed")); - goto err_return; - } - - retval = cf_claim_slices(cont->controller_id, cont->ncslices); - if (retval != 0) { - cmn_err(CE_NOTE, "cf_initial: failed to get needed ncslices"); - goto err_return; - } - slices_allocated = B_TRUE; - -#ifdef DEBUG - { - int j; - DPRINTF(CF_DEBUG, (CE_CONT, "number of attached wcis %d", - num_attached)); - for (j = 0; j < num_attached; ++j) - DPRINTF(CF_DEBUG, (CE_CONT, "attached[%d] " - "lcwci = %p port = %d", j, - (void *)attached_wcis[j].lcwci, - attached_wcis[j].port)); - } -#endif - - if ((retval = wrsm_nc_initialconfig(cont->controller_id, - cont->controller, cont->devi, num_attached, attached_wcis)) != 0) { - DPRINTF(CF_DEBUG, (CE_WARN, "initialcfg: nc_intiailconfig " - "failed")); - goto err_return; - } - - cont->state = cf_installed; - if (attached_wcis) - kmem_free(attached_wcis, sizeof (wci_ids_t) * routing->nwcis); - if (port_list) - kmem_free(port_list, sizeof (safari_port_t) * routing->nwcis); - cont->in_ioctl = B_FALSE; - - return (WRSM_SUCCESS); - -err_return: - - if (slices_allocated) { - cf_release_all_slices(cont->controller_id); - } - - if (port_list) - for (i = 0; i < routing->nwcis; ++i) { - /* - * Only release WCIs that we have succesfully claimed - */ - if (wrsm_cf_wci_owner(port_list[i]) == - init_arg.controller_id) - wrsm_cf_release_wci(port_list[i]); - } - - if (attached_wcis) { - kmem_free(attached_wcis, sizeof (wci_ids_t) * routing->nwcis); - } - if (port_list) { - kmem_free(port_list, sizeof (safari_port_t) * routing->nwcis); - } - - if (cont && cont->controller) { - DPRINTF(CF_DEBUG, (CE_WARN, "wrsm_cf_initialcfg failed")); - wrsm_cf_free(cont->controller); - } - if (controller_data) - kmem_free(controller_data, init_arg.controller_data_size); - - if (cont) { - cont->controller = NULL; - WRSMSET_ZERO(cont->ncslices); - cont->nbytes = 0; - cont->in_ioctl = B_FALSE; - } - - return (retval); -} - -/* - * Calledback from the NC to the CF in response to - * wrsm_nc_initialconfig(). This should be called as soon as - * the NC has enabled the config. - */ -void -wrsm_cf_is_enabled(uint32_t controller_id) -{ - wrsm_controller_dev_t *cont; - - if (!(cont = find_controller(controller_id))) { - cmn_err(CE_WARN, "cf_is_enabled: bad controller id %d", - controller_id); - return; - } - cont->state = cf_enabled; -} - -/*ARGSUSED*/ -static int -wrsm_cf_removecfg(intptr_t arg, int flag) -{ - uint_t controller_id = (uint_t)arg; - wrsm_controller_dev_t *cont; - wrsm_routing_data_t *routing; - int retval; - int i; - - if (!(cont = find_controller(controller_id))) - return (EINVAL); - if (!cont->controller) - return (ENOENT); - - mutex_enter(&cont->lock); - if (cont->in_ioctl) { - mutex_exit(&cont->lock); - return (EBUSY); - } - cont->in_ioctl = B_TRUE; - mutex_exit(&cont->lock); - - if ((retval = wrsm_nc_removeconfig(controller_id)) != 0) { - cont->in_ioctl = B_FALSE; - return (retval); - } - - /* remove ncslice request from inuse */ - cf_release_all_slices(cont->controller_id); - - routing = cont->controller->routing; - for (i = 0; i < routing->nwcis; ++i) - wrsm_cf_release_wci(routing->wcis[i]->port); - - wrsm_cf_free(cont->controller); - kmem_free(cont->controller, cont->nbytes); - cont->controller = NULL; - WRSMSET_ZERO(cont->ncslices); - cont->nbytes = 0; - cont->state = cf_invalid; - cont->in_ioctl = B_FALSE; - - return (WRSM_SUCCESS); -} - -/*ARGSUSED*/ -static int -wrsm_cf_startcfg(intptr_t arg, int flag) -{ - uint_t controller_id = (uint_t)arg; - wrsm_controller_dev_t *cont; - int retval; - - if (!(cont = find_controller(controller_id))) - return (EINVAL); - if (!cont->controller) - return (ENOENT); - - mutex_enter(&cont->lock); - if (cont->in_ioctl) { - mutex_exit(&cont->lock); - return (EBUSY); - } - cont->in_ioctl = B_TRUE; - mutex_exit(&cont->lock); - - retval = wrsm_nc_startconfig(controller_id); - cont->in_ioctl = B_FALSE; - return (retval); -} - - -/*ARGSUSED*/ -static int -wrsm_cf_stopcfg(intptr_t arg, int flag) -{ - uint_t controller_id = (uint_t)arg; - wrsm_controller_dev_t *cont; - int retval; - - if (!(cont = find_controller(controller_id))) - return (EINVAL); - if (!cont->controller) - return (ENOENT); - - mutex_enter(&cont->lock); - if (cont->in_ioctl) { - mutex_exit(&cont->lock); - return (EBUSY); - } - cont->in_ioctl = B_TRUE; - mutex_exit(&cont->lock); - - retval = wrsm_nc_stopconfig(controller_id); - cont->in_ioctl = B_FALSE; - return (retval); -} - - -static int -wrsm_cf_getcfg(intptr_t arg, int flag) -{ - wrsm_admin_arg_config_t get_arg; - wrsm_controller_dev_t *cont; - - if (ddi_copyin((void *)arg, (char *)&get_arg, - sizeof (wrsm_admin_arg_config_t), flag) != 0) - return (EFAULT); - - if (get_arg.ioctl_version != WRSM_CF_IOCTL_VERSION) { - cmn_err(CE_WARN, "getcfg: user/kernel version mismatch"); - return (EINVAL); - } - - /* - * Search for a controller with a matching id in the cache - */ - DPRINTF(CF_DEBUG, (CE_CONT, "getcfg: get controller id %d", - get_arg.controller_id)); - - if (!(cont = find_controller(get_arg.controller_id))) - return (EINVAL); - - if (!cont->controller) - return (ENOENT); - - DPRINTF(CF_DEBUG, (CE_CONT, "getcfg: found ctlr size=%ld avail=%ld", - cont->nbytes, get_arg.controller_data_size)); - - /* - * If the size of the user mode data block provided is not big - * enough to hold the controller data, fill in the required - * size, and return. Typically this function should be called - * once with size of 0 and then a second time with an - * appropriate size buffer. - */ - if (get_arg.controller_data_size < cont->nbytes) { - get_arg.controller_data_size = cont->nbytes; - get_arg.controller = 0; - if (ddi_copyout(&get_arg, (void *)arg, - sizeof (wrsm_admin_arg_config_t), 0) != 0) - return (EFAULT); - else - return (WRSM_SUCCESS); - } - - if (ddi_copyout(cont->controller, get_arg.controller, - cont->nbytes, 0) != 0) { - return (EFAULT); - } - - return (WRSM_SUCCESS); -} - -/* - * Search for the specified controller id in the list created - * by wrsm_cf_new_controller(). - */ -static wrsm_controller_dev_t * -find_controller(uint_t controller_id) -{ - wrsm_controller_dev_t *cont; /* used to walk controller_list */ - - if (controller_id == WRSM_BAD_RSM_ID) - return (NULL); - - cont = cf_state->controller_list; - while (cont) { - if (cont->controller_id == controller_id) - break; - cont = cont->next; - } - - return (cont); -} - -/* - * Search for the specified wci port id in the list created - * by wrsm_cf_newwci(). - */ -static wrsm_wci_dev_t * -find_wci(safari_port_t port) -{ - wrsm_wci_dev_t *wci; - - mutex_enter(&cf_state->wl_lock); - wci = cf_state->wci_list; - while (wci) { - if (wci->id.port == port) - break; - wci = wci->next; - } - mutex_exit(&cf_state->wl_lock); - - return (wci); -} - -/* - * A wrsm_controller_t contains a list of pointers to wrsm_wci_data_t. - * Before calling any of the nc_ functions, this list should be - * translated to an array of wci_ids_t. This is done by looking - * up the safari id of the WCIs in the list created by wrsm_cf_newwci() - */ -static wci_ids_t * -create_wci_ids(safari_port_t *wcis, int nwcis, uint32_t controller_id, - int *nfoundp) -{ - wci_ids_t *ret; - wrsm_wci_dev_t *wcidev = NULL; - int i; - int nfound = 0; - - ret = (wci_ids_t *)kmem_alloc(sizeof (wci_ids_t) * nwcis, KM_SLEEP); - for (i = 0; i < nwcis; ++i) { - safari_port_t port = wcis[i]; - wcidev = find_wci(port); - if (wcidev == NULL) { - DPRINTF(CF_DEBUG, (CE_CONT, "wrsm_cf: unknown wci " - "number %d", port)); - continue; - } - if (wcidev->controller_id != controller_id) { - DPRINTF(CF_DEBUG, (CE_WARN, "wci %d does not " - "belong to controller %d", wcidev->id.port, - controller_id)); - continue; - } - - if (wcidev->attached == B_FALSE) - continue; - - ret[nfound] = wcidev->id; - ++nfound; - } - - if (nfoundp) - *nfoundp = nfound; - return (ret); - -error_ret: - kmem_free(ret, sizeof (wci_ids_t) * nwcis); - if (nfoundp) - *nfoundp = 0; - return (NULL); -} - - -static int -verify_config(wrsm_controller_t *config, ncslice_bitmask_t *new_ncslices) -{ - ncslice_bitmask_t network_ncslices, member_ncslices, intersect, - imported_ncslices, imported_small_ncslices; - wrsm_ncslice_t member_small_ncslice; - int i, j; - int err; - wrsm_net_member_t *member; - - /* - * Verify that the local wnode is mentioned in the reachable - * list and that it points to the local cnode - */ - for (i = 0; i < config->routing->nwcis; ++i) { - wrsm_wci_data_t *wci = config->routing->wcis[i]; - if (!wci->wnode_reachable[wci->local_wnode] || - wci->reachable[wci->local_wnode] != config->cnodeid) { - cmn_err(CE_NOTE, "verify: wci %d loopback wnode not " - "reachable", wci->port); - return (EINVAL); - } - } - - WRSMSET_ZERO(network_ncslices); - - for (i = 0; i < config->nmembers; ++i) { - ncslice_bitmask_t intersect; - - member = config->members[i]; - err = wrsm_cf_ncslicelist_to_bitmask(member->exported_ncslices, - &member_small_ncslice, &member_ncslices); - if (err) { - return (err); - } - WRSMSET_ADD(member_ncslices, member_small_ncslice); - - /* Check that all ncslices exported to this node are unique */ - WRSMSET_COPY(member_ncslices, intersect); - WRSMSET_AND(intersect, network_ncslices); - - if (!WRSMSET_ISNULL(intersect)) { - /* - * If the intersection is not empty, then some - * of the slices are not unique, so scan - * through the list to find which ones for a - * better error message and return an error. - */ - cmn_err(CE_NOTE, "verify: ncslices not unique"); - for (j = 0; j < WRSM_MAX_NCSLICES; ++j) - if (WRSM_IN_SET(intersect, j)) - cmn_err(CE_NOTE, "conflict %d", j); - return (EINVAL); - } - WRSMSET_OR(network_ncslices, member_ncslices); - - - /* - * Check that comm_ncslice is one of the slices - * exported by the remote node. - */ - if (!WRSM_IN_SET(member_ncslices, member->comm_ncslice)) { - cmn_err(CE_NOTE, - "verify: comm_slice 0x%x not in exported set", - member->comm_ncslice); - return (EINVAL); - } - - /* Check that in and out driver comm offsets are unique */ - - for (j = 0; j < config->nmembers; ++j) { - wrsm_net_member_t *cmpmember = config->members[j]; - - if (member == cmpmember) - continue; - - if (member->local_offset == cmpmember->local_offset) { - cmn_err(CE_NOTE, "verify: conflicting " - "local_offsets, cnode %d and cnode %d\n", - member->cnodeid, cmpmember->cnodeid); - return (EINVAL); - } - } - } - - /* - * Collect the ncslices being imported by remote nodes (exported by - * this node). Note that each node's imported ncslices do _not_ - * need to be different from those of other nodes; however there - * must be an agreement on which are large and small ncslices. - */ - WRSMSET_ZERO(imported_ncslices); - WRSMSET_ZERO(imported_small_ncslices); - for (i = 0; i < config->nmembers; ++i) { - member = config->members[i]; - - err = wrsm_cf_ncslicelist_to_bitmask(member->imported_ncslices, - &member_small_ncslice, &member_ncslices); - if (err) { - return (err); - } - WRSMSET_ADD(imported_small_ncslices, member_small_ncslice); - WRSMSET_OR(imported_ncslices, member_ncslices); - } - - /* - * Check that no small slices are also used as large slices. - */ - WRSMSET_COPY(imported_small_ncslices, intersect); - WRSMSET_AND(intersect, imported_ncslices); - - if (!WRSMSET_ISNULL(intersect)) { - /* - * If the intersection is not empty, then some - * of the slices are being used both for large and - * small pages. - */ - cmn_err(CE_NOTE, "verify: " - "imported ncslices used for both large and small pages"); - for (j = 0; j < WRSM_MAX_NCSLICES; ++j) - if (WRSM_IN_SET(intersect, j)) - cmn_err(CE_NOTE, - "conflict %d", j); - return (EINVAL); - } - - WRSMSET_OR(imported_ncslices, imported_small_ncslices); - - /* - * Collect the ncslices used to allow this node to forward traffic - * from other nodes. - */ - WRSMSET_ZERO(intersect); - for (i = 0; i < config->nmembers; ++i) { - wrsm_routing_policy_t *policy; - - policy = config->routing->policy[i]; - if (policy->forwarding_allowed) { - if (!wrsm_forwarding_supported) { - return (ENOTSUP); - } - - WRSMSET_COPY(policy->forwarding_ncslices, intersect); - WRSMSET_AND(intersect, imported_ncslices); - if (!WRSMSET_ISNULL(intersect)) { - /* - * If the intersection is not empty, then - * some of the ncslices used for forwarding - * are also exported by this node. This - * isn't supported. - */ - cmn_err(CE_NOTE, "verify: " - "forwarding ncslices clash with import" - "ncslices"); - for (j = 0; j < WRSM_MAX_NCSLICES; ++j) - if (WRSM_IN_SET(intersect, j)) - cmn_err(CE_NOTE, - "conflict %d", j); - return (EINVAL); - } - } - WRSMSET_OR(network_ncslices, policy->forwarding_ncslices); - } - - WRSMSET_OR(network_ncslices, member_ncslices); - - DPRINT_BITMASK("cf_verify_config: new config slices", - network_ncslices); - - WRSMSET_COPY(network_ncslices, *new_ncslices); - return (WRSM_SUCCESS); -} - -static int -verify_newconfig(wrsm_controller_t *old, wrsm_controller_t *new) -{ - if (!new->routing) { - cmn_err(CE_NOTE, "verify: routing information required"); - return (EINVAL); - } - - /* - * The cnode of the local node never changes while it is - * participating in an RSM network. - */ - if (old->cnodeid != new->cnodeid) { - cmn_err(CE_NOTE, "verify: changing cnodeid"); - return (EINVAL); - } - - /* - * Three related constraints: - * - * 1) A new configuration must not assign an ncslice to a new - * cnode if it was used by a different cnode in the old - * configuration. This is overridden by the stronger constraint #3. - * - * 2) The ncslice and offset used for driver communication must - * not change on a cnode that is containd in both the old and - * new configuration. This is checked in wrsm_nc.c - * - * 3) No ncslices already exported by a node in the old - * configuration can be removed in the new configuration. - * This is checked in wrsm_nc.c - */ - - return (WRSM_SUCCESS); -} - -/* - * Called from wrsm_ioctl() when invoked on a driver instance which - * has a type of wrsm_rsm_controller. - */ -/* ARGSUSED */ -int -wrsm_cf_ctlr_ioctl(int cont_id, int cmd, intptr_t arg, int flag, - cred_t *cred_p, int *rval_p) -{ - int retval; - - switch (cmd) { - case WRSM_CTLR_PING: - retval = wrsm_cf_ping(cont_id, arg, flag); - break; - case WRSM_CTLR_MBOX: - retval = wrsm_cf_mbox(cont_id, arg, flag); - break; - case WRSM_CTLR_SESS: - retval = wrsm_cf_sess(cont_id, arg, flag); - break; - case WRSM_CTLR_MEM_LOOPBACK: - retval = wrsm_cf_memory_loopback(cont_id, arg, flag); - break; - default: - DPRINTF(CF_WARN, (CE_WARN, "unrecognized ioctl cmd %d\n", - cmd)); - retval = EINVAL; - } - return (retval); -} - -static int -wrsm_cf_ping(int cont_id, intptr_t arg, int flag) -{ - wrsm_ping_arg_t ping_arg; - wrsm_network_t *target_network; - wrsm_raw_message_t raw_req; - wrsm_raw_message_t raw_rsp; - wrsm_message_t *msg = (wrsm_message_t *)&raw_req; - wrsm_message_t *resp = (wrsm_message_t *)&raw_rsp; - timespec_t time1, time2; - int i, rc; - - if (ddi_copyin((void *)arg, (char *)&ping_arg, - sizeof (wrsm_ping_arg_t), flag) != 0) - return (EFAULT); - - if (ping_arg.ioctl_version != WRSM_CF_IOCTL_VERSION) { - cmn_err(CE_WARN, "ping: user/kernel version mismatch"); - return (EINVAL); - } - - if (find_controller(cont_id) == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "ping: invalid controller " - "id %d", cont_id)); - return (EINVAL); - } - - if ((target_network = wrsm_nc_ctlr_to_network(cont_id)) == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "ping: no network struct " - "for controller %d", cont_id)); - return (EINVAL); - } - - DPRINTF(CF_DEBUG, (CE_CONT, "ping: sending %d pings to node %d", - ping_arg.count, ping_arg.target)); - - msg->header.message_type = WRSM_MSG_PING; - for (i = 0; i < WRSM_MESSAGE_BODY_SIZE; i++) { - msg->body[i] = i; - } - - gethrestime(&time1); - - for (i = 0; i < ping_arg.count; ++i) { - rc = wrsm_tl_rpc(target_network, ping_arg.target, msg, resp); - if (rc != 0) { - DPRINTF(CF_WARN, (CE_WARN, "ping: wrsm_tl_rpc" - " failed rc=%x i=%d", rc, i)); - return (rc); - } - } - - gethrestime(&time2); - ping_arg.time = (time2.tv_sec * 1000000000 + time2.tv_nsec) - - (time1.tv_sec * 1000000000 + time1.tv_nsec); - - if (ddi_copyout(&ping_arg, (void *)arg, sizeof (wrsm_ping_arg_t), - 0) != 0) { - return (EFAULT); - } - - DPRINTF(CF_DEBUG, (CE_CONT, "ping: %d responses received", - ping_arg.count)); - - return (WRSM_SUCCESS); -} - -static int -wrsm_cf_mbox(int cont_id, intptr_t arg, int flag) -{ - wrsm_link_arg_t link_arg; - wrsm_controller_dev_t *cont = NULL; - wrsm_controller_t *config; - wrsm_wci_data_t *wci = NULL; - int i; - - if (ddi_copyin((void *)arg, (char *)&link_arg, - sizeof (wrsm_link_arg_t), flag) != 0) - return (EFAULT); - - if (link_arg.ioctl_version != WRSM_CF_IOCTL_VERSION) { - cmn_err(CE_WARN, "mbox: user/kernel version mismatch"); - return (EINVAL); - } - - if ((cont = find_controller(cont_id)) == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "mbox: invalid controller " - "id %d", cont_id)); - return (EINVAL); - } - - if ((config = cont->controller) == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "mbox: controller %d not " - "configured", cont_id)); - return (EINVAL); - } - - for (i = 0; i < config->routing->nwcis; ++i) - if (config->routing->wcis[i]->port == link_arg.wci_id) { - wci = config->routing->wcis[i]; - break; - } - - if (wci == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "mbox: unknown wci id %d", - link_arg.wci_id)); - return (EINVAL); - } - - switch (link_arg.cmd) { - case WRSM_CTLR_UPLINK: - wrsmplat_uplink(link_arg.wci_id, link_arg.link_num, - wci->local_gnid, config->fmnodeid, (uint64_t) - config->version_stamp, cont_id, B_FALSE); - break; - case WRSM_CTLR_DOWNLINK: - wrsmplat_downlink(link_arg.wci_id, link_arg.link_num, B_FALSE); - break; - case WRSM_CTLR_SET_LED: - wrsmplat_set_led(link_arg.wci_id, link_arg.link_num, - link_arg.led_state); - break; - case WRSM_CTLR_ALLOC_SLICES: - break; - case WRSM_CTLR_SET_SEPROM: - break; - default: - break; - } - return (WRSM_SUCCESS); -} - - - - - - -/* - * memory loopback test: read/write patterns into exported/imported - * loopback memory - */ - - -#ifdef DEBUG -#define DPRINT_DATA(a) dprint_pattern_data(a) - -void -dprint_pattern_data(unsigned char *d) -{ - DPRINTF(CF_DEBUG, (CE_CONT, "0x " - "%2x%2x%2x%2x%2x%2x%2x%2x %2x%2x%2x%2x%2x%2x%2x%2x " - "%2x%2x%2x%2x%2x%2x%2x%2x %2x%2x%2x%2x%2x%2x%2x%2x " - "%2x%2x%2x%2x%2x%2x%2x%2x %2x%2x%2x%2x%2x%2x%2x%2x " - "%2x%2x%2x%2x%2x%2x%2x%2x %2x%2x%2x%2x%2x%2x%2x%2x", - d[0x0], d[0x1], d[0x2], d[0x3], - d[0x4], d[0x5], d[0x6], d[0x7], - d[0x8], d[0x9], d[0xa], d[0xb], - d[0xc], d[0xd], d[0xe], d[0xf], - - d[0x10], d[0x11], d[0x12], d[0x13], - d[0x14], d[0x15], d[0x16], d[0x17], - d[0x18], d[0x19], d[0x1a], d[0x1b], - d[0x1c], d[0x1d], d[0x1e], d[0x1f], - - d[0x20], d[0x21], d[0x22], d[0x23], - d[0x24], d[0x25], d[0x26], d[0x27], - d[0x28], d[0x29], d[0x2a], d[0x2b], - d[0x2c], d[0x2d], d[0x2e], d[0x2f], - - d[0x30], d[0x31], d[0x32], d[0x33], - d[0x34], d[0x35], d[0x36], d[0x37], - d[0x38], d[0x39], d[0x3a], d[0x3b], - d[0x3c], d[0x3d], d[0x3e], d[0x3f])); -} - -#else -#define DPRINT_DATA(a) -#endif - -#define MEMLOOP_BSIZE (MMU_PAGESIZE * 8) -typedef int (*lpbk_ptest_t)(caddr_t memptr, size_t len, uint64_t *error_offset, - unsigned char *expected_data, unsigned char *actual_data); - -uint64_t sso_pat[6*8] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0x0, 0x0, 0x0, 0x0, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0x0, 0x0, 0x0, 0x0, -}; - -/* - * Write the entire memory region pointed to by memptr. Apply each of the - * 4 64 byte patterns in sso_pat to 4 consecutive cachelines. Keep doing - * this until the entire region is written. - */ -int -memloop_sso(caddr_t memptr, size_t len, uint64_t *error_offset, - unsigned char *expected_data, unsigned char *actual_data) -{ - wrsm_raw_message_t raw_msg; - char *send_data; - char *receive_data = (char *)&raw_msg; - uint_t pat = 0; - uint_t i, j; - - DPRINTF(CF_DEBUG, (CE_CONT, "memloop_sso")); - - for (i = 0; i < (len / 64); i++) { - - send_data = (char *)&(sso_pat[pat]); - DPRINT_DATA((unsigned char *)send_data); - wrsm_blkwrite(send_data, memptr, 1); - wrsm_blkread(memptr, receive_data, 1); - for (j = 0; j < 64; j++) { - if (send_data[j] != receive_data[j]) { - *error_offset = (i * 64) + j; - bcopy(send_data, expected_data, 64); - bcopy(receive_data, actual_data, 64); - return (EIO); - } - } - memptr += 64; - pat = (pat + 8) % (8 * 6); - } - - return (WRSM_SUCCESS); -} - - -unsigned char march_pat[2*64] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -/* - * Write the entire memory region pointed to by memptr, alternately writing - * 2 cachelines of all 0s followed by 2 cachelines of all 1s. March one - * bit along which has the opposite setting from the rest of the bits in - * each set of 4 cachelines. (Thus, in the first 4 cachelines, bit 0 is - * flipped. In the next 4 cachelines, bit 1 is flipped, and so on.) - */ -int -memloop_slowmarch(caddr_t memptr, size_t len, uint64_t *error_offset, - unsigned char *expected_data, unsigned char *actual_data) -{ - wrsm_raw_message_t raw_req; - wrsm_raw_message_t raw_rsp; - char *send_data = (char *)&raw_req; - char *receive_data = (char *)&raw_rsp; - uint_t i, j; - uint_t pat = 0; - unsigned char marcher = 1; - int march_index = 63; - boolean_t marcher_is_one = B_TRUE; - boolean_t first_cacheline = B_TRUE; - - DPRINTF(CF_DEBUG, (CE_CONT, "memloop_slowmarch")); - - for (i = 0; i < (len / 64); i++) { - bcopy((void *)&(march_pat[pat]), (void *)send_data, 64); - if (marcher_is_one) { - send_data[march_index] = - send_data[march_index] | marcher; - } else { - /* set marcher bit to 0 */ - send_data[march_index] = - send_data[march_index] & ~marcher; - } - DPRINT_DATA((unsigned char *)send_data); - - wrsm_blkwrite(send_data, memptr, 1); - wrsm_blkread(memptr, receive_data, 1); - for (j = 0; j < 64; j++) { - if (send_data[j] != receive_data[j]) { - *error_offset = (i * 64) + j; - bcopy(send_data, expected_data, 64); - bcopy(receive_data, actual_data, 64); - return (EIO); - } - } - memptr += 64; - - /* - * march a bit across the 64 byte cacheline. - */ - - if (first_cacheline) { - /* - * each 64 byte pattern is repeated - */ - first_cacheline = B_FALSE; - } else { - first_cacheline = B_TRUE; - if (marcher_is_one) { - /* - * second half of round: bits are all 1 - * except marcher, which is 0. - */ - marcher_is_one = B_FALSE; - pat = 64; - } else { - /* - * start new round: bits are all 0 except - * marcher, which is 1. - */ - marcher_is_one = B_TRUE; - pat = 0; - if (marcher & 0x80) { - /* - * wrap marcher back to start of - * 64 byte cacheline. - */ - marcher = 1; - march_index--; - if (march_index == -1) { - march_index = 63; - } - } else { - marcher = marcher << 1; - } - } - } - } - - return (WRSM_SUCCESS); -} - - -/* - * Write the entire memory region pointed to by memptr, alternately writing - * a cacheline of all 0s and all 1s. March one bit along at each 128 bit - * offset in the cacheline which has the opposite setting from the rest of - * the bits in each pair of cachelines. (Thus, in the first 2 cachelines, - * bits 0, 128, 256 and 384 are flipped. In the next 2 cachelines, bits 1, - * 129, 257, 385 are flipped, and so on.) - */ -int -memloop_fastmarch(caddr_t memptr, size_t len, uint64_t *error_offset, - unsigned char *expected_data, unsigned char *actual_data) -{ - wrsm_raw_message_t raw_req; - wrsm_raw_message_t raw_rsp; - char *send_data = (char *)&raw_req; - char *receive_data = (char *)&raw_rsp; - uint_t i, j; - uint_t pat = 0; - unsigned char marcher = 1; - uint_t march_index = 63; - uint_t index; - boolean_t turn_bit_off = B_FALSE; - - DPRINTF(CF_DEBUG, (CE_CONT, "memloop_fastmarch")); - - for (i = 0; i < (len / 64); i++) { - bcopy((void *)&(march_pat[pat]), (void *)send_data, 64); - for (j = 0; j < 4; j++) { - index = march_index - (16 * j); - if (turn_bit_off) { - send_data[index] = send_data[index] & ~marcher; - } else { - send_data[index] = send_data[index] | marcher; - } - } - DPRINT_DATA((unsigned char *)send_data); - - wrsm_blkwrite(send_data, memptr, 1); - wrsm_blkread(memptr, receive_data, 1); - for (j = 0; j < 64; j++) { - if (send_data[j] != receive_data[j]) { - *error_offset = (i * 64) + j; - bcopy(send_data, expected_data, 64); - bcopy(receive_data, actual_data, 64); - return (EIO); - } - } - memptr += 64; - - /* - * march alternating bit along - */ - - if (turn_bit_off) { - /* finished both passes; increment marcher bit */ - if (marcher & 0x80) { - marcher = 1; - march_index--; - if (march_index == 47) { - march_index = 63; - } - } else { - marcher = marcher << 1; - } - turn_bit_off = B_FALSE; - pat = 0; - } else { - turn_bit_off = B_TRUE; - pat = 64; - } - } - - return (WRSM_SUCCESS); -} - - -uint64_t xtalk_pat[4*8] = { - 0x5555555555555555, 0x5555555555555555, 0x5555555555555555, - 0x5555555555555555, 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa, - 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa, -}; - -/* - * Write the entire memory region pointed to by memptr. Apply the 64 byte - * pattern in xtalk_pat to each cacheline. Keep doing this until the - * entire region is written. - */ -int -memloop_xtalk(caddr_t memptr, size_t len, uint64_t *error_offset, - unsigned char *expected_data, unsigned char *actual_data) -{ - wrsm_raw_message_t raw_buf; - char *send_data = (char *)&(xtalk_pat[0]); - char *receive_data = (char *)&raw_buf; - uint_t i, j; - - DPRINTF(CF_DEBUG, (CE_CONT, "memloop_xtalk")); - - for (i = 0; i < (len / 64); i++) { - - DPRINT_DATA((unsigned char *)send_data); - wrsm_blkwrite(send_data, memptr, 1); - wrsm_blkread(memptr, receive_data, 1); - for (j = 0; j < 64; j++) { - if (send_data[j] != receive_data[j]) { - *error_offset = (i * 64) + j; - bcopy(send_data, expected_data, 64); - bcopy(receive_data, actual_data, 64); - return (EIO); - } - } - memptr += 64; - } - - return (WRSM_SUCCESS); -} - - -lpbk_ptest_t lpk_pattern_test[WRSM_MAX_PATTERN] = { - memloop_sso, - memloop_slowmarch, - memloop_fastmarch, - memloop_xtalk -}; - - -/* - * Loopback memory test. - * - * Create a memory segment, import it (loopback connection), then - * write and read a pattern to requested various offsets in the - * segment. Clean up (remove segment), and return whether the - * writes/reads succeeded. - * - * This test is intended for use by SunVTS. - */ -static int -wrsm_cf_memory_loopback(int cont_id, intptr_t arg, int flag) -{ - wrsm_memloopback_arg_t loop_arg; - wrsm_network_t *network; - rsm_access_entry_t access_list[1]; - rsm_memseg_export_handle_t exportseg; - rsm_memseg_import_handle_t importseg; - rsm_memory_local_t memory; - void *buf; - caddr_t aligned_buf; - off_t bufsize; - rsm_memseg_id_t segid; - int err = 0; - dev_info_t *dip; - uint_t dev_register; - off_t dev_offset; - caddr_t map_kaddr; - size_t map_len; - caddr_t memptr; - uint64_t error_offset; - int i; - rsm_barrier_t barrier; - - DPRINTF(CF_DEBUG, (CE_CONT, "in memory_loopback\n")); - - if (ddi_copyin((void *)arg, (char *)&loop_arg, - sizeof (wrsm_memloopback_arg_t), flag) != 0) { - DPRINTF(CF_WARN, (CE_WARN, "illegal arg address")); - return (EFAULT); - } - loop_arg.error_pattern = 0; - - if (find_controller(cont_id) == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "memory_loopback: invalid " - "controller id %d", cont_id)); - return (EINVAL); - } - - if ((network = wrsm_nc_ctlr_to_network(cont_id)) == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "memory_loopback: no network " - "struct for controller %d", cont_id)); - return (ENXIO); - } - - - /* - * We now use our own allocation routines rather than - * kmem_{z}alloc() because we require the underlying memory - * pages to be static in memory (i.e. non-relocatable). - */ - bufsize = MEMLOOP_BSIZE + MMU_PAGESIZE; - buf = wrsm_alloc(bufsize, VM_NOSLEEP); - - - if (buf == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "memory_loopback: no memory")); - return (ENOMEM); - } - aligned_buf = (caddr_t)((uint64_t) - ((caddr_t)buf + MMU_PAGEOFFSET) & (uint64_t)MMU_PAGEMASK); - - - /* - * create segment - */ - memory.ms_type = RSM_MEM_VADDR; - memory.ms_as = &kas; - memory.ms_length = MEMLOOP_BSIZE; - memory.ms_vaddr = aligned_buf; - - if ((err = wrsmrsm_seg_create(network, &exportseg, MEMLOOP_BSIZE, - 0, &memory, RSM_RESOURCE_DONTWAIT, 0)) != RSM_SUCCESS) { - DPRINTF(CF_WARN, (CE_WARN, "memory_loopback: seg_create" - "failed %d", err)); - wrsm_free(buf, bufsize); - /* distinguish from write/read error in pattern subtest */ - if (err == RSMERR_NOT_MEM) - err = EHOSTUNREACH; - else - err = EINVAL; - return (err); - } - - - /* - * publish segment - */ - access_list[0].ae_addr = RSM_ACCESS_PUBLIC; - access_list[0].ae_permission = RSM_PERM_RDWR; - - segid = RSM_USER_APP_ID_BASE; - while (segid <= RSM_USER_APP_ID_END) { - if ((err = wrsmrsm_publish(exportseg, access_list, - 1, segid, RSM_RESOURCE_DONTWAIT, 0)) - != RSM_SUCCESS) { - if (err == RSMERR_SEGID_IN_USE) { - /* segment id is already in use */ - segid++; - } else { - err = EINVAL; - goto export_cleanup; - } - } else { - /* successful publish */ - break; - } - } - if (segid > RSM_USER_APP_ID_END) { - err = EAGAIN; - DPRINTF(CF_WARN, (CE_WARN, "memory_loopback: no segid " - "available")); - goto export_cleanup; - } - - DPRINTF(CF_DEBUG, (CE_CONT, "memory_loopback: created and " - "published a segment with size of 0x%x and segid 0x%x\n", - MEMLOOP_BSIZE, segid)); - - - /* - * connect to segment - */ - if ((err = wrsmrsm_connect(network, network->cnodeid, segid, - &importseg)) != RSM_SUCCESS) { - /* - * distinguish from write/read error in pattern subtest - */ - DPRINTF(CF_WARN, (CE_WARN, "cf_memory_loopback: " - "wrsmrsm_connect failed err=%d cnodeid %d segid %d", - err, network->cnodeid, segid)); - - if (err == RSMERR_RSM_ADDR_UNREACHABLE) - err = EHOSTUNREACH; - else if (err == RSMERR_CONN_ABORTED) - err = ENETRESET; - else - err = EINVAL; - goto export_cleanup; - } - - /* - * map in segment - */ - err = wrsmrsm_map(importseg, 0, MEMLOOP_BSIZE, &map_len, &dip, - &dev_register, &dev_offset, NULL, 0); - if (err) { - (void) wrsmrsm_disconnect(importseg); - err = EINVAL; - goto export_cleanup; - } - - DPRINTF(CF_DEBUG, (CE_CONT, "memory_loopback: map returned " - "dip 0x%p, rnumber %d offset 0x%lx len 0x%lx\n", - (void *)dip, dev_register, dev_offset, map_len)); - - err = ddi_map_regs(dip, dev_register, &map_kaddr, dev_offset, map_len); - if (err != DDI_SUCCESS) { - (void) wrsmrsm_unmap(importseg); - (void) wrsmrsm_disconnect(importseg); - /* - * distinguish from write/read error in pattern subtest - */ - DPRINTF(CF_WARN, (CE_WARN, "cf_memory_loopback: ddi_map_regs " - "failed err = %d rnumber %d offset 0x%lx len 0x%lx", - err, dev_register, dev_offset, map_len)); - - err = EHOSTUNREACH; - goto export_cleanup; - } - - DPRINTF(CF_DEBUG, (CE_CONT, "memory_loopback: ddi_map_regs returned " - "map_kaddr 0x%p", (void *)map_kaddr)); - - - /* - * write/read through the WCI - */ - memptr = map_kaddr; - - loop_arg.paddr = va_to_pa((void *)aligned_buf); - for (i = 0; i < WRSM_MAX_PATTERN; i++) { - if (loop_arg.patterns & (1 << i)) { - /* - * make sure there are no accidentally correct - * patterns in the buffer - */ - bzero((void *)buf, bufsize); - if ((err = wrsm_open_barrier_region(importseg, - &barrier)) != RSM_SUCCESS) { - err = EINVAL; - goto import_cleanup; - } - if ((err = (lpk_pattern_test[i])(memptr, MEMLOOP_BSIZE, - &error_offset, loop_arg.expected_data, - loop_arg.actual_data)) != 0) { - loop_arg.error_pattern = (1 << i); - loop_arg.paddr = - va_to_pa((void *)(aligned_buf + - error_offset)); - err = EIO; - goto import_cleanup; - } - if ((err = wrsm_close_barrier(&barrier)) - != RSM_SUCCESS) { - /* - * distinguish from write/read error in - * pattern subtest - */ - if (err == RSMERR_BARRIER_FAILURE) - err = ENETRESET; - else - err = EINVAL; - goto import_cleanup; - } - } - } - - /* - * finished successfully - */ - -import_cleanup: - ddi_unmap_regs(dip, dev_register, &map_kaddr, dev_offset, - map_len); - (void) wrsmrsm_unmap(importseg); - (void) wrsmrsm_disconnect(importseg); - -export_cleanup: - (void) wrsmrsm_unpublish(exportseg); - (void) wrsmrsm_seg_destroy(exportseg); - wrsm_free(buf, bufsize); - - if (ddi_copyout(&loop_arg, (void *)arg, sizeof (wrsm_memloopback_arg_t), - 0) != 0) { - return (EFAULT); - } - - return (err); -} - - - -static int -wrsm_cf_sess(int cont_id, intptr_t arg, int flag) -{ - wrsm_network_t *network; - wrsm_sess_arg_t sess_arg; - int retval = 0; - - if (ddi_copyin((void *)arg, (char *)&sess_arg, - sizeof (wrsm_sess_arg_t), flag) != 0) { - return (EFAULT); - } - - if (sess_arg.ioctl_version != WRSM_CF_IOCTL_VERSION) { - cmn_err(CE_WARN, "sess ioctl: user/kernel version mismatch"); - return (EINVAL); - } - - if (find_controller(cont_id) == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "sess ioctl: invalid controller " - "id %d", cont_id)); - return (EINVAL); - } - - if ((network = wrsm_nc_ctlr_to_network(cont_id)) == NULL) { - DPRINTF(CF_WARN, (CE_WARN, "sess ioctl: no network struct " - "for controller %d", cont_id)); - return (EINVAL); - } - - DPRINTF(CF_DEBUG, (CE_CONT, "sess cmd %d: %u", - sess_arg.cmd, sess_arg.cnodeid)); - switch (sess_arg.cmd) { - case WRSM_CTLR_SESS_START: - if (wrsm_sess_establish(network, sess_arg.cnodeid) == 0) { - retval = EAGAIN; - } - break; - case WRSM_CTLR_SESS_END: - wrsm_sess_teardown(network, sess_arg.cnodeid); - break; - case WRSM_CTLR_SESS_ENABLE: - wrsm_sess_enable(network, sess_arg.cnodeid); - break; - case WRSM_CTLR_SESS_DISABLE: - retval = wrsm_sess_disable(network, sess_arg.cnodeid); - break; - case WRSM_CTLR_SESS_GET: - wrsm_sess_get_cnodes(network, &sess_arg.cnode_bitmask); - break; - default: - retval = ENOTSUP; - } - if (ddi_copyout(&sess_arg, (void *)arg, sizeof (wrsm_sess_arg_t), - 0) != 0) { - return (EFAULT); - } - return (retval); -} - - -/* - * verify that the ncslice array has valid values, then convert into - * a bitmask. Return 0 if valid. - */ -static int -wrsm_cf_ncslicelist_to_bitmask(wrsm_node_ncslice_array_t slice_array, - ncslice_t *small_ncslicep, - ncslice_bitmask_t *large_slice_bitmask) -{ - int i; - - *small_ncslicep = slice_array.id[0]; - if (*small_ncslicep == 0) { - return (EINVAL); - } - - /* - * Verify the large page ncslices are valid. The ncslice for entry - * 1 must end with b'001', the ncslice for entry 2 must end with - * b'010', entry 3 with b'011' and so on. An ncslice value of 0 - * indicates that the entry is invalid. - */ - WRSMSET_ZERO(*large_slice_bitmask); - for (i = 1; i < WRSM_NODE_NCSLICES; i++) { - if (slice_array.id[i] == 0) { - continue; - } - if (!wrsm_large_pages_supported) { - cmn_err(CE_NOTE, - "verify: large page ncslices not supported"); - return (ENOTSUP); - } - if ((slice_array.id[i] & 0x7) != i) { - cmn_err(CE_NOTE, "verify: invalid large page ncslice"); - return (EINVAL); - } - if (slice_array.id[i] == *small_ncslicep) { - cmn_err(CE_NOTE, - "verify: large page ncslice not unique"); - return (EINVAL); - } - - WRSMSET_ADD(*large_slice_bitmask, slice_array.id[i]); - } - DPRINT_BITMASK("wrsm_cf_ncslicelist_to_bitmask large slices", - *large_slice_bitmask); - - return (0); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_cmmu.c b/usr/src/uts/sun4u/io/wrsm/wrsm_cmmu.c deleted file mode 100644 index 95fb65376a..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_cmmu.c +++ /dev/null @@ -1,1563 +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 2001-2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file manages the CMMU entries for the Wildcat RSM driver. It keeps - * track of which entries can be used for large pages, which entries are - * free. It also keeps the CMMU entries on each WCI in sync, by providing - * generic CMMU read/write interfaces which it applies to each WCI. - */ - -#include <sys/types.h> - -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/errno.h> -#include <sys/debug.h> -#include <sys/wci_regs.h> -#include <sys/wci_offsets.h> - -#include <sys/wrsm_cmmu.h> -#include <sys/wrsm_config.h> -#include <sys/wrsm_nc.h> /* For wci_ids_t */ - -/* - * The following macros define a DPRINTF macro which can be used to enable - * or disable various levels of logging for this module. - */ -#ifdef DEBUG - -#define CMMUDBG 0x1 -#define CMMUWARN 0x2 -#define CMMUERR 0x4 -#define CMMUTRACE 0x8 -static uint_t cmmu_debug = CMMUERR; - -#define DPRINTF(a, b) { if (cmmu_debug & a) wrsmdprintf b; } - -#else /* DEBUG */ - -#define DPRINTF(a, b) { } - -#endif /* DEBUG */ - -#define ERR(s) DPRINTF(CMMUERR, (CE_WARN, s)) -#define WARN(s) DPRINTF(CMMUWARN, (CE_WARN, s)) -#define NOTE(s) DPRINTF(CMMUDBG, (CE_NOTE, s)) -#define DTRC(s) DPRINTF(CMMUTRACE, (CE_NOTE, s)) - -#define CMMU_SUCCESS 0 -#define RANGE_SIZE(start, end) ((end) - (start) + 1) -/* - * Local types, constants and macros - */ - -/* - * A cmmu index is 21 bits (up to 2 million entries, with 16MB SRAM). - * Each NcSlice can export either large pages or small pages. - * - * A single small page ncslice can export all 21 million pages. To go - * from cmmu entry to ncslice offset for small pages, just shift the - * cmmu index left 13 bits. - * - * Each large page ncslice can export 4096 entries of 4MB each. The - * large page CMMU indices are defined as follows: - * index<11:0> = ncslice offset<33:22> - * index<14:12> = ncslice<2:0> - * index<20:15> = 0 - * Since the lower three bits of the ncslice are used to discriminate between - * large page ncslice entries, only 8 large page ncslices can be exported - * (actually, more can be exported, but they would share CMMU entries, so - * there's no value in exporting more than 8). - */ - -#define MAX_LARGE_NCSLICES 8 -#define MAX_FREE_LISTS (1 + MAX_LARGE_NCSLICES) -#define FIRST_CMMU_ENTRY 2 /* 0 and 1 are special-cases */ -/* large ncslice can export 4096 pgs, minus pages 0 and 1 which are special */ -#define MAX_PAGES_LARGE_SLICE (0x1000 - FIRST_CMMU_ENTRY) -#define LOW_3_BITS 0x7 -#define MAX_LARGE_PAGE_INDEX 0x7fff -#define CESR_PAGE 0 -#define WRITELOCKOUT_PAGE 1 - -/* Constants for cluster_members_bits */ -static const uint64_t MEMBERS_PER_REGISTER = 64; -static const uint64_t ONE_BIT = 0x1; - -/* Constants for ncslice_config bits */ -static const uint64_t SLICES_PER_REGISTER = 32; -static const uint64_t BITS_PER_SLICE = 2; -static const uint64_t TWO_BITS = 0x3; - -/* - * The free_region structure defines a range of free CMMU entries (i.e., - * a start and an end). It is designed to be an element of a doubly - * linked list to track free CMMU entries. - */ -typedef struct free_region_struct { - wrsm_cmmu_index_t start; - wrsm_cmmu_index_t end; - struct free_region_struct *prev; - struct free_region_struct *next; -} free_region_t; - -/* - * The free_list_t contains a linked list of free regions and the - * ncslice that these CMMU entries belong to. It also includes a mutex, - * used whenever the linked list is being modified/traversed. - */ -typedef struct { - kmutex_t mutex; - ncslice_t ncslice; - wrsm_cmmu_page_size_t page_size; - free_region_t *list; -} free_list_t; - -/* Set of free pages for absolute alloc */ -#define NUM_COMM_PAGES WRSM_MAX_CNODES /* One per remote cnode */ -#define COMM_MASKS WRSMMASKS(NUM_COMM_PAGES, 32) -typedef struct { - uint32_t b[COMM_MASKS]; -} comm_bitmask_t; - -/* Structure to keep track of which WCIs belong to us */ -typedef struct wci_handle_struct -{ - lcwci_handle_t wci_handle; - struct wci_handle_struct *next; - struct wci_handle_struct *prev; -} wci_handle_t; - -/* State structure for the CMMU allocator */ -struct wrsm_cmmu_alloc { - kmutex_t mutex; - free_list_t free_lists[MAX_FREE_LISTS]; - unsigned num_free_lists; - wrsm_cmmu_index_t max_entries; - wrsm_cmmu_index_t num_free_entries; - kcondvar_t resource_cv; - wci_handle_t *wci_list; - comm_bitmask_t comm_pages; -}; - -/* - * Local Functions - */ -static void cmmu_attributes(wrsm_network_t *); - -/* Converts an ncslice/offset to a CMMU index */ -static wrsm_cmmu_index_t -offset_to_index(free_list_t *head, wrsm_cmmu_offset_t offset) -{ - uint64_t off = (uint64_t)offset; - wrsm_cmmu_index_t index; - - ASSERT(head); - if (head->page_size == CMMU_PAGE_SIZE_SMALL) { - index = ((off >> 13) & 0x1fffff); - } else { - index = ((head->ncslice & 0x7) << 12) | - ((off >> 22) & 0x0fff); - } - return (index); -} - -/* Converts a CMMU index to an ncslice offset */ -static wrsm_cmmu_offset_t -index_to_offset(free_list_t *head, wrsm_cmmu_index_t index) -{ - wrsm_cmmu_offset_t offset; - uint64_t idx = (uint64_t)index; - - ASSERT(head); - - if (head->page_size == CMMU_PAGE_SIZE_SMALL) { - offset = (caddr_t)(idx << 13); - } else { - offset = (caddr_t)((idx & 0xfff) << 22); - } - return (offset); -} - -/* Converts large page ncslice to starting CMMU entry */ -static wrsm_cmmu_index_t -ncslice_to_start(ncslice_t ncslice) -{ - unsigned start = ((ncslice & 0x7) << 12) + FIRST_CMMU_ENTRY; - return (start); -} - -/* Converts large page ncslice to starting CMMU entry */ -static wrsm_cmmu_index_t -ncslice_to_end(ncslice_t ncslice) -{ - unsigned start = ncslice_to_start(ncslice); - return (start + MAX_PAGES_LARGE_SLICE - 1); -} - -/* Converts an index to an ncslice */ -static free_list_t * -IndexToFreeList(wrsm_cmmu_alloc_t *cmmu, wrsm_cmmu_index_t index) -{ - unsigned i; - ASSERT(cmmu); - - /* If only lower 15 bits are set, this could be a large page */ - if (index <= MAX_LARGE_PAGE_INDEX) { - /* Look for large ncslices with matching lower 3 bits */ - for (i = 0; i < cmmu->num_free_lists; i++) { - ncslice_t ncslice = cmmu->free_lists[i].ncslice; - wrsm_cmmu_index_t start = ncslice_to_start(ncslice); - wrsm_cmmu_index_t end = ncslice_to_end(ncslice); - if (start <= index && index <= end) { - return (&cmmu->free_lists[i]); - } - } - } - /* We didn't find a large page ncslice, so use first small ncslice */ - for (i = 0; i < cmmu->num_free_lists; i++) { - if (cmmu->free_lists[i].page_size == CMMU_PAGE_SIZE_SMALL) { - return (&cmmu->free_lists[i]); - } - } - /* No ncslice was found */ - return (NULL); -} - -/* Copies the wci_cluster_members_bits registers from one WCI to another */ -static void -clustermember_copy(lcwci_handle_t dest, lcwci_handle_t src) -{ - uint_t i; - uint64_t reg; - uint64_t offset = ADDR_WCI_CLUSTER_MEMBERS_BITS; - DTRC("clustermember_copy"); - - for (i = 0; i < ENTRIES_WCI_CLUSTER_MEMBERS_BITS; i++) { - wrsm_lc_csr_read(src, offset, ®); - wrsm_lc_csr_write(dest, offset, reg); - offset += STRIDE_WCI_CLUSTER_MEMBERS_BITS; - } -} - -/* Copies the wci_ncslice_config_array registers from one WCI to another */ -static void -ncsliceconfig_copy(lcwci_handle_t dest, lcwci_handle_t src) -{ - uint_t i; - uint64_t reg; - uint64_t offset = ADDR_WCI_NC_SLICE_CONFIG_ARRAY; - DTRC("ncsliceconfig_copy"); - - for (i = 0; i < ENTRIES_WCI_NC_SLICE_CONFIG_ARRAY; i++) { - wrsm_lc_csr_read(src, offset, ®); - wrsm_lc_csr_write(dest, offset, reg); - offset += STRIDE_WCI_NC_SLICE_CONFIG_ARRAY; - } -} - -/* - * Functions to manipulate a free region structure - */ - -#ifdef DEBUG -/* Prints a region */ -static void -region_print(char *msg, free_region_t *region) -{ - ASSERT(region); - - DPRINTF(CMMUDBG, (CE_NOTE, - "%s 0x%p: start=%u, end=%u, next=0x%p, prev=0x%p", - msg, (void *)region, region->start, region->end, - (void *)region->next, (void *)region->prev)); -} -#endif /* DEBUG */ - -#ifdef DEBUG -/* Returns the size of a region, i.e., the number of pages in the region */ -static unsigned -region_size(free_region_t *region) -{ - ASSERT(region); - return (RANGE_SIZE(region->start, region->end)); -} -#endif - -/* Creates a free region (from start to end), in the list 'head' */ -static void -region_create(free_list_t *head, free_region_t *after, - wrsm_cmmu_index_t start, wrsm_cmmu_index_t end) -{ - free_region_t *p = kmem_zalloc(sizeof (free_region_t), KM_SLEEP); - DPRINTF(CMMUTRACE, (CE_NOTE, "region_create(start=%u, end=%u)", - start, end)); - ASSERT(head); - ASSERT(mutex_owned(&head->mutex)); - ASSERT(p); - - p->start = start; - p->end = end; - p->prev = after; - /* If after is NULL, adding to head of list */ - if (after == NULL) { - p->next = head->list; - head->list = p; - } else { - p->next = after->next; - after->next = p; - } - if (p->next) { - (p->next)->prev = p; - } -} - -/* Deletes a region from a free list, and frees its memory */ -static void -region_delete(free_list_t *head, free_region_t *region) -{ - DTRC("region_delete"); - ASSERT(head); - ASSERT(mutex_owned(&head->mutex)); - ASSERT(region); - - /* If this is first region in list, update head to point around it */ - if (region->prev == NULL) { - head->list = region->next; - } else { - (region->prev)->next = region->next; - } - if (region->next) { - (region->next)->prev = region->prev; - } - kmem_free(region, sizeof (free_region_t)); -} - -/* - * The following function allows you to allocate a range of items from - * a given region. Assumes the start and end are within the region. If - * necessary, it will split the region, or delete it. - */ -static int -region_alloc(free_list_t *head, free_region_t *region, - wrsm_cmmu_index_t start, wrsm_cmmu_index_t end) -{ - int retval = CMMU_SUCCESS; - DPRINTF(CMMUTRACE, (CE_NOTE, "region_alloc(start=%u, end=%u)", - start, end)); - ASSERT(head); - ASSERT(region); - ASSERT(start <= end); - ASSERT(mutex_owned(&head->mutex)); - - /* Check that range is inclusive */ - if (start < region->start || end > region->end) { - WARN("region_alloc: invalid args"); - retval = EINVAL; - } else if (start == region->start && end == region->end) { - /* A perfect fit, remove the region */ - region_delete(head, region); - } else if (start == region->start) { - /* Removing from the front of the region */ - region->start = end + 1; - } else if (end == region->end) { - /* Removing from the end of the region */ - region->end = start - 1; - } else { - /* Removing from the middle, must create new region */ - region_create(head, region, end + 1, region->end); - /* Now "shrink" old region */ - region->end = start - 1; - } - return (retval); -} - -/* - * Functions to manipulate a free list - */ -#ifdef DEBUG -/* Traverses a list, print all its regions */ -static void -/* LINTED: static unused: list_print (E_STATIC_UNUSED) */ -list_print(free_list_t *head) -{ - free_region_t *p; - ASSERT(head); - ASSERT(mutex_owned(&head->mutex)); - - DPRINTF(CMMUDBG, (CE_NOTE, " ncslice = 0x%02X", head->ncslice)); - for (p = head->list; p; p = p->next) { - region_print(" region:", p); - } -} -#endif /* DEBUG */ - -#ifdef DEBUG -/* Traverses a list, checking the pointers */ -static void -/* LINTED: static unused: list_check (E_STATIC_UNUSED) */ -list_check(free_list_t *head) -{ - free_region_t *p; - boolean_t ok = B_TRUE; - ASSERT(head); - ASSERT(mutex_owned(&head->mutex)); - - for (p = head->list; p; p = p->next) { - if (p->end < p->start) { - DPRINTF(CMMUDBG, (CE_WARN, "p->end=%u >= p->start=%u", - p->end, p->start)); - ok = B_FALSE; - break; - } - if (p->next) { - if (p->end >= p->next->start) { - DPRINTF(CMMUDBG, (CE_WARN, - "p->end=%u < p->next->start=%u", - p->end, p->next->start)); - ok = B_FALSE; - break; - } - if (p->next->prev != p) { - DPRINTF(CMMUDBG, (CE_WARN, - "p->next->prev=%p != p=%p", - (void *)p->next->prev, (void *)p)); - ok = B_FALSE; - break; - } - } - } - if (!ok) { - list_print(head); - } -} -#endif /* DEBUG */ - -#ifdef DEBUG -/* - * Returns the size of the list, i.e., the free pages in all regions - * You must already own the mutex - */ -static unsigned -list_size(free_list_t *head) -{ - free_region_t *p; - unsigned size = 0; - ASSERT(head); - ASSERT(mutex_owned(&head->mutex)); - - list_check(head); - for (p = head->list; p; p = p->next) { - size += region_size(p); - } - return (size); -} -#endif - -/* Initializes the given ncslice free list */ -static void -list_init(free_list_t *head, ncslice_t ncslice_num, - wrsm_cmmu_page_size_t page_size) -{ - DPRINTF(CMMUTRACE, (CE_CONT, "list_init ncslice %d\n", ncslice_num)); - ASSERT(head); - - mutex_init(&head->mutex, NULL, MUTEX_DRIVER, NULL); - head->ncslice = ncslice_num; - head->page_size = page_size; - head->list = NULL; -} - -/* Deletes all regions in the list */ -static void -list_delete(free_list_t *head) -{ - DTRC("list_delete"); - ASSERT(head); - ASSERT(mutex_owned(&head->mutex)); - while (head->list) { - region_delete(head, head->list); - } -} - -/* Destroys the given ncslice free list */ -static void -list_fini(free_list_t *head) -{ - DTRC("list_fini"); - ASSERT(head); - mutex_enter(&head->mutex); - list_delete(head); - mutex_exit(&head->mutex); - mutex_destroy(&head->mutex); -} - -/* - * Allocates a page at the given index. - * Returns ENOMEM if the index was already allocated. - */ -static int -list_absolute_alloc(free_list_t *head, wrsm_cmmu_index_t start, - unsigned count) -{ - int retval = ENOMEM; - free_region_t *p; - wrsm_cmmu_index_t end = start + count - 1; -#ifdef DEBUG - unsigned old_size, new_size; /* To check for free page leaks */ -#endif /* DEBUG */ - - DTRC("list_absolute_alloc"); - ASSERT(head); - - mutex_enter(&head->mutex); -#ifdef DEBUG - old_size = list_size(head); -#endif /* DEBUG */ - for (p = head->list; p; p = p->next) { - if (p->start <= start && start <= p->end) { - /* Starts somewhere within this region */ - retval = region_alloc(head, p, start, end); - break; - } - } - if (p == NULL) { - DPRINTF(CMMUWARN, (CE_WARN, "list_absolute_alloc: " - "region [%d, %d] already allocated", start, end)); - retval = ENOMEM; - } - -#ifdef DEBUG - /* Make sure we aren't leaking any pages */ - new_size = list_size(head); - if (retval == 0) { - ASSERT(old_size == new_size + count); - } else { - ASSERT(old_size == new_size); - } -#endif /* DEBUG */ - - mutex_exit(&head->mutex); - return (retval); -} - -/* - * Allocates a range of entries with the best fit available. If it can't - * allocate all the requested pages, it will respond with the number - * of entries actually allocated. Returns ENOMEM if there aren't any - * entries left. - */ -static int -list_best_alloc(free_list_t *head, unsigned desired_num, - wrsm_cmmu_tuple_t *tuple) -{ - int retval = ENOMEM; - free_region_t *p; - free_region_t *best_region = NULL; - unsigned best_diff = UINT_MAX; - free_region_t *biggest_region = NULL; - unsigned biggest_count = 0; -#ifdef DEBUG - unsigned old_size, new_size; /* To check for free page leaks */ -#endif /* DEBUG */ - - DPRINTF(CMMUTRACE, (CE_NOTE, "list_best_alloc(num=%u)", desired_num)); - ASSERT(head); - - mutex_enter(&head->mutex); -#ifdef DEBUG - old_size = list_size(head); -#endif /* DEBUG */ - for (p = head->list; p; p = p->next) { - unsigned count = RANGE_SIZE(p->start, p->end); - - if (count == desired_num) { - /* An exact match, can't beat that! */ - best_region = p; - break; - } else if (count > desired_num) { - /* This range is too big, look for best fit */ - unsigned diff = count - desired_num; - if (diff < best_diff) { - best_region = p; - best_diff = diff; - } - } else { - /* Remember biggest, in case we don't fit anywhere */ - if (count > biggest_count) { - biggest_region = p; - biggest_count = count; - } - } - } - if (best_region != NULL) { - /* We found a region at least large enough */ - tuple->index = best_region->start; - tuple->count = desired_num; - tuple->ncslice = head->ncslice; - tuple->offset = index_to_offset(head, tuple->index); - retval = region_alloc(head, best_region, best_region->start, - best_region->start + desired_num - 1); - } else if (biggest_region != NULL) { - /* None were big enough, so just use the biggest region */ - tuple->index = biggest_region->start; - tuple->count = RANGE_SIZE(biggest_region->start, - biggest_region->end); - tuple->ncslice = head->ncslice; - tuple->offset = index_to_offset(head, tuple->index); - region_delete(head, biggest_region); - retval = CMMU_SUCCESS; - } - -#ifdef DEBUG - /* Make sure we aren't leaking any pages */ - new_size = list_size(head); - if (retval == 0) { - ASSERT(old_size == new_size + tuple->count); - } else { - ASSERT(old_size == new_size); - } -#endif /* DEBUG */ - - mutex_exit(&head->mutex); - - return (retval); -} - -/* Frees a region to a free list. Returns EINVAL if region wasn't allocated */ -static int -list_free(free_list_t *head, wrsm_cmmu_index_t start, - wrsm_cmmu_index_t end) -{ - free_region_t *p; - int retval = CMMU_SUCCESS; -#ifdef DEBUG - unsigned old_size, new_size; /* To check for free page leaks */ -#endif /* DEBUG */ - - DPRINTF(CMMUTRACE, (CE_NOTE, "list_free(start=%u, end=%u)", - start, end)); - ASSERT(head); - - mutex_enter(&head->mutex); -#ifdef DEBUG - old_size = list_size(head); -#endif /* DEBUG */ - if (head->list == NULL) { - region_create(head, NULL, start, end); - } else for (p = head->list; p; p = p->next) { - /* Make sure the region being freed isn't already free */ - ASSERT(!(p->start <= start && start <= p->end)); - ASSERT(!(p->start <= end && end <= p->end)); - if (p->end == start - 1) { - /* Region is contiguous at end of this region */ - p->end = end; - /* Check to see if we can merge with next region */ - if (p->next && (p->next)->start == end + 1) { - p->end = (p->next)->end; - region_delete(head, p->next); - } - break; - } else if (p->start > end) { - /* We over shot */ - if (p->start == end + 1) { - /* See if it fits just before this region */ - p->start = start; - } else { - /* Need to insert new region in list */ - region_create(head, p->prev, start, end); - } - break; - } else if (p->next == NULL) { - /* We're at the end of the line */ - region_create(head, p, start, end); - break; - } - } - -#ifdef DEBUG - /* Make sure we aren't leaking any pages */ - new_size = list_size(head); - if (retval == 0) { - ASSERT(old_size == new_size - RANGE_SIZE(start, end)); - } else { - ASSERT(old_size == new_size); - } -#endif /* DEBUG */ - - mutex_exit(&head->mutex); - return (retval); -} - - -static unsigned -cmmu_free(wrsm_network_t *net, unsigned ntuples, - wrsm_cmmu_tuple_t *tuples) -{ - wrsm_cmmu_alloc_t *cmmu; - unsigned i, n; - - DTRC("cmmu_free"); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - ASSERT(MUTEX_HELD(&cmmu->mutex)); - - ASSERT(tuples); - ASSERT(ntuples > 0); - - n = 0; - for (i = 0; i < ntuples; i++) { - wrsm_cmmu_index_t end; - /* - * Don't trust ncslice provided by user. We may have - * allocated small pages from large page free list, - * so we'd want to free them back to the right list, - * so use index to find correct free list. - */ - free_list_t *head = - IndexToFreeList(cmmu, tuples[i].index); - ASSERT(head); - - end = tuples[i].index + tuples[i].count - 1; - n += tuples[i].count; - (void) list_free(head, tuples[i].index, end); - } - cv_broadcast(&cmmu->resource_cv); - return (n); -} - - -/* - * Allocates a region from a specific ncslice, specified by head. - * Attempts a best-fit allocation. This function can be used iteratively on - * each available ncslice when searching for an ncslice to allocate entries - * from. - */ -static void -ncslice_alloc(free_list_t *head, wrsm_cmmu_tuple_t *tuples, - unsigned *nentries, unsigned *ntuples, unsigned availtuples) -{ - ASSERT(head); - DPRINTF(CMMUTRACE, (CE_NOTE, "ncslice_alloc(ncslice=%u, nentries=%u)", - head->ncslice, *nentries)); - - /* Allocate from this ncslice until we're done or, or it's drained */ - while (*nentries > 0 && - *ntuples < availtuples && - list_best_alloc(head, *nentries, &tuples[*ntuples]) == 0) { - *nentries -= tuples[*ntuples].count; - (*ntuples)++; - } -} - -/* Adds a WCI to the linked list */ -static void -wci_add(wrsm_cmmu_alloc_t *cmmu, lcwci_handle_t wci, boolean_t replicate) -{ - wci_handle_t *p; - wci_handle_t *newp; - DTRC("wci_add"); - ASSERT(cmmu); - - newp = kmem_zalloc(sizeof (wci_handle_t), KM_SLEEP); - ASSERT(newp); - - mutex_enter(&cmmu->mutex); - - /* Make sure the WCI doesn't already exist */ - for (p = cmmu->wci_list; p; p = p->next) { - if (p->wci_handle == wci) { - WARN("wci_add: WCI already exists"); - mutex_exit(&cmmu->mutex); - kmem_free(newp, sizeof (wci_handle_t)); - return; - } - } - /* Check if we need to replicate, and if we have ANY other WCIs */ - if (replicate && cmmu->wci_list) { - lcwci_handle_t master = cmmu->wci_list->wci_handle; - unsigned index; - unsigned i; - free_region_t *p[MAX_FREE_LISTS]; - - /* First, replicate the ncslice array */ - ncsliceconfig_copy(wci, master); - - /* Now, replicate the cluster members bits registers */ - clustermember_copy(wci, master); - - /* - * Next, the CMMU. Initialize an array of pointers for all - * free lists. We'll walk the free lists, and skip all free - * entries -- there's no need to copy free (i.e., unused) - * CMMU entries, and there should be a lot of them! - */ - for (i = 0; i < cmmu->num_free_lists; i++) { - p[i] = cmmu->free_lists[i].list; - } - /* Walk the CMMU array from start to finish */ - for (index = 0; index < cmmu->max_entries; index++) { - boolean_t in_use = B_TRUE; - /* First, check if this index is on free list */ - for (i = 0; i < cmmu->num_free_lists; i++) { - if (p[i] && (p[i]->start == index)) { - /* On a free list, so not in use */ - in_use = B_FALSE; - /* Skip over rest of pages in region */ - index = p[i]->end; - /* Get next region for this list */ - p[i] = p[i]->next; - break; - } - } - if (in_use) { - /* Not free, so make copy */ - wrsm_cmmu_t entry; - wrsm_lc_cmmu_read(master, &entry, index); - wrsm_lc_cmmu_update(wci, &entry, index, - CMMU_UPDATE_ALL); - } - } - } - - /* Add it to the list */ - newp->wci_handle = wci; - newp->next = cmmu->wci_list; - newp->prev = NULL; - if (newp->next) { - (newp->next)->prev = newp; - } - cmmu->wci_list = newp; - - mutex_exit(&cmmu->mutex); -} - -/* Initializes free list structures once we have WCIs */ -static void -init_free_lists(wrsm_cmmu_alloc_t *cmmu) -{ - unsigned i; - wrsm_cmmu_index_t start; - wrsm_cmmu_index_t end; - DTRC("init_free_lists"); - - ASSERT(cmmu); - ASSERT(cmmu->num_free_lists > 0); - ASSERT(cmmu->max_entries > 0); - - /* First, allocate all non-comm pages to the small page ncslice */ - start = NUM_COMM_PAGES; - end = cmmu->max_entries - 1; - (void) list_free(&cmmu->free_lists[0], start, end); - - /* Mark all comm pages as free (zero) */ - WRSMSET_ZERO(cmmu->comm_pages); - /* Then allocate the CESR and write lockout pages */ - WRSMSET_ADD(cmmu->comm_pages, CESR_PAGE); - WRSMSET_ADD(cmmu->comm_pages, WRITELOCKOUT_PAGE); - - /* For each large page ncslice, move pages from small ncslice */ - for (i = 1; i < cmmu->num_free_lists; i++) { - ncslice_t ncslice = cmmu->free_lists[i].ncslice; - wrsm_cmmu_index_t start = ncslice_to_start(ncslice); - wrsm_cmmu_index_t end = ncslice_to_end(ncslice); - unsigned count = end - start + 1; - - /* Allocate these pages away from small page free list */ - /* LINTED */ - if (list_absolute_alloc(&cmmu->free_lists[0], start, count)) { - ASSERT(0); - } - - /* Free these pages to the large page free list */ - (void) list_free(&cmmu->free_lists[i], start, end); - } -#ifdef DEBUG - for (i = 0; i < cmmu->num_free_lists; i++) { - mutex_enter(&cmmu->free_lists[i].mutex); - list_print(&cmmu->free_lists[i]); - mutex_exit(&cmmu->free_lists[i].mutex); - } -#endif /* DEBUG */ -} - -/* Calculates CMMU-based attributes */ -static void -cmmu_attributes(wrsm_network_t *net) -{ - wrsm_cmmu_alloc_t *cmmu; - uint64_t num_large_ncslices; - uint64_t num_large_pages; - uint64_t num_small_pages; - - DTRC("wrsm_cmmu_attributes"); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - if (cmmu->num_free_lists == 0 || cmmu->max_entries == 0) { - net->attr.attr_max_export_segments = 0; - net->attr.attr_tot_export_segment_size = 0; - net->attr.attr_max_export_segment_size = 0; - } else { - num_large_ncslices = cmmu->num_free_lists - 1; - num_large_pages = num_large_ncslices * MAX_PAGES_LARGE_SLICE; - num_small_pages = cmmu->max_entries - num_large_pages; - - net->attr.attr_max_export_segments = cmmu->max_entries; - net->attr.attr_tot_export_segment_size = - num_large_pages * CMMU_LARGE_PAGE_SIZE + - num_small_pages * CMMU_SMALL_PAGE_SIZE; - net->attr.attr_max_export_segment_size = - net->attr.attr_tot_export_segment_size; - } -} - -/* - * API Functions. See wrsm_cmmu.h for function descriptions. - */ -void -wrsm_cmmu_init(wrsm_network_t *net, unsigned nwcis, wci_ids_t wcis[]) -{ - unsigned i; - wrsm_cmmu_alloc_t *cmmu; - DTRC("wrsm_cmmu_init"); - - ASSERT(net); - ASSERT(net->cmmu == NULL); - - net->cmmu = kmem_zalloc(sizeof (wrsm_cmmu_alloc_t), KM_SLEEP); - ASSERT(net->cmmu); - cmmu = net->cmmu; - - mutex_init(&cmmu->mutex, NULL, MUTEX_DRIVER, NULL); - cv_init(&cmmu->resource_cv, NULL, CV_DEFAULT, NULL); - cmmu->max_entries = (nwcis > 0)?UINT_MAX:0; - cmmu->wci_list = NULL; - - for (i = 0; i < nwcis; i++) { - int n = 0; - n = wrsm_lc_num_cmmu_entries_get(wcis[i].lcwci); - /* Our max will be the smallest of all WCIs */ - if (n < cmmu->max_entries) { - cmmu->max_entries = n; - } - /* Add this WCI to our linked list */ - wci_add(cmmu, wcis[i].lcwci, B_FALSE); - } - DPRINTF(CMMUDBG, (CE_NOTE, "cmmu_init: max_entries = %u", - cmmu->max_entries)); - cmmu->num_free_entries = cmmu->max_entries; - - /* - * Build Empty Free Lists - */ - /* Make sure there is a small page ncslice */ - ASSERT(net->exported_ncslices.id[0] != 0); - list_init(&cmmu->free_lists[0], net->exported_ncslices.id[0], - CMMU_PAGE_SIZE_SMALL); - cmmu->num_free_lists++; - - /* For each large page ncslice, move pages from small ncslice */ - for (i = 1; i < WRSM_NODE_NCSLICES; i++) { - ncslice_t ncslice = net->exported_ncslices.id[i]; - if (ncslice == 0) - continue; - /* Create new list for this ncslice */ - list_init(&cmmu->free_lists[cmmu->num_free_lists], ncslice, - CMMU_PAGE_SIZE_LARGE); - cmmu->num_free_lists++; - } - /* If there are real WCIs, populate free lists */ - if (nwcis > 0) { - init_free_lists(cmmu); - } - cmmu_attributes(net); -} - -void -wrsm_cmmu_fini(wrsm_network_t *net) -{ - unsigned i; - wrsm_cmmu_alloc_t *cmmu; - - DTRC("wrsm_cmmu_fini"); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - while (cmmu->wci_list) { - (void) wrsm_cmmu_delwci(net, (cmmu->wci_list)->wci_handle); - } - mutex_enter(&cmmu->mutex); - for (i = 0; i < cmmu->num_free_lists; i++) { - list_fini(&cmmu->free_lists[i]); - } - cmmu->num_free_lists = 0; - cv_destroy(&cmmu->resource_cv); - mutex_exit(&cmmu->mutex); - mutex_destroy(&cmmu->mutex); - kmem_free(net->cmmu, sizeof (wrsm_cmmu_alloc_t)); - net->cmmu = NULL; -} - -int -wrsm_cmmu_newwci(wrsm_network_t *net, lcwci_handle_t wci) -{ - wrsm_cmmu_alloc_t *cmmu; - int retval = CMMU_SUCCESS; - - DTRC("wrsm_cmmu_newwci"); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - /* If this is the first WCI, initialize free lists */ - if (cmmu->wci_list == NULL) { - cmmu->max_entries = wrsm_lc_num_cmmu_entries_get(wci); - init_free_lists(cmmu); - } - - /* Make sure the WCI has enough SRAM */ - if (wrsm_lc_num_cmmu_entries_get(wci) < cmmu->max_entries) { - return (ENOMEM); - } - wci_add(cmmu, wci, B_TRUE); - - /* Update attributes */ - cmmu_attributes(net); - - return (retval); -} - -int -wrsm_cmmu_delwci(wrsm_network_t *net, lcwci_handle_t wci) -{ - wrsm_cmmu_alloc_t *cmmu; - wci_handle_t *p; - unsigned i; - int retval = EINVAL; - - DTRC("wrsm_cmmu_delwci"); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - mutex_enter(&cmmu->mutex); - for (p = cmmu->wci_list; p; p = p->next) { - if (p->wci_handle == wci) { - if (p->prev) { - (p->prev)->next = p->next; - } else { - cmmu->wci_list = p->next; - } - if (p->next) { - (p->next)->prev = p->prev; - } - kmem_free(p, sizeof (wci_handle_t)); - retval = CMMU_SUCCESS; - break; - } - } - /* If this was the last WCI, delete all free lists */ - if (cmmu->wci_list == NULL) { - for (i = 0; i < cmmu->num_free_lists; i++) { - mutex_enter(&cmmu->free_lists[i].mutex); - list_delete(&cmmu->free_lists[i]); - mutex_exit(&cmmu->free_lists[i].mutex); - } - cmmu->max_entries = 0; - } - /* Update attributes */ - cmmu_attributes(net); - - mutex_exit(&cmmu->mutex); - - return (retval); -} - -int -wrsm_cmmu_alloc(wrsm_network_t *net, wrsm_cmmu_page_size_t page_size, - unsigned nentries, wrsm_cmmu_tuple_t **tuples, unsigned *ntuples, - boolean_t sleep) -{ - int retval = CMMU_SUCCESS; - unsigned i, n; - int availtuples = nentries + 1; /* Make availtuples large */ - size_t tmp_size = availtuples * sizeof (wrsm_cmmu_tuple_t); - wrsm_cmmu_tuple_t *tmp_tuples = kmem_zalloc(tmp_size, - KM_SLEEP); - wrsm_cmmu_alloc_t *cmmu; - - DPRINTF(CMMUTRACE, (CE_NOTE, "wrsm_cmmu_alloc(size=%s, nentries=%u)", - (page_size == CMMU_PAGE_SIZE_SMALL)?"SMALL":"LARGE", nentries)); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - mutex_enter(&cmmu->mutex); - /* - * For each free list (ncslice) of the right size, try a - * best-fit alloc from that ncslice's free list, until we - * either run out of free lists, succeed in allocating - * enough entries, or run out of tuples to store results. - */ -retry: - n = nentries; - *ntuples = 0; - *tuples = NULL; - for (i = 0; i < cmmu->num_free_lists && - n > 0 && - *ntuples < availtuples; i++) { - /* If wrong page size, bail */ - if (cmmu->free_lists[i].page_size != page_size) { - continue; - } - ncslice_alloc(&cmmu->free_lists[i], tmp_tuples, - &n, ntuples, availtuples); - } - /* - * If we didn't allocate all the entries requested, and - * there's still free tuples, and we were allocating small - * pages, let's steal from the large page ncslices. - */ - if (n > 0 && *ntuples < availtuples && - page_size == CMMU_PAGE_SIZE_SMALL) { - for (i = 1; i < cmmu->num_free_lists; i++) { - free_list_t *head = &cmmu->free_lists[i]; - ASSERT(head->page_size == CMMU_PAGE_SIZE_LARGE); - ncslice_alloc(head, tmp_tuples, &n, - ntuples, availtuples); - } - } - if (n > 0) { - /* - * we failed, so free up any cmmu entries we - * allocated - */ - if (*ntuples > 0) - (void) cmmu_free(net, *ntuples, tmp_tuples); - - if (*ntuples == availtuples) { - retval = ENOSPC; - } else { - if (sleep) { - retval = cv_wait_sig( - &cmmu->resource_cv, - &cmmu->mutex); - if (retval > 0) { - retval = CMMU_SUCCESS; - goto retry; - } else { - /* got a signal */ - retval = EINTR; - } - } else { - retval = EAGAIN; - } - } - mutex_exit(&cmmu->mutex); - *ntuples = 0; - } else { - /* copy the data to the output array */ - - size_t size = *ntuples * sizeof (wrsm_cmmu_tuple_t); - - cmmu->num_free_entries -= nentries; - mutex_exit(&cmmu->mutex); - *tuples = kmem_zalloc(size, KM_SLEEP); - bcopy(tmp_tuples, *tuples, size); - - } - kmem_free(tmp_tuples, tmp_size); - -#ifdef DEBUG - if (retval == CMMU_SUCCESS) { - int i; - for (i = 0; i < *ntuples; i++) { - DPRINTF(CMMUTRACE, (CE_NOTE, "alloced tuple %d " - "ncslice %d count %d offset 0x%p index %d\n", - i, - (*tuples)[i].ncslice, - (*tuples)[i].count, - (void *)(*tuples)[i].offset, - (*tuples)[i].index)); - } - } -#endif - return (retval); -} - -void -wrsm_cmmu_free(wrsm_network_t *net, unsigned ntuples, - wrsm_cmmu_tuple_t *tuples) -{ - wrsm_cmmu_alloc_t *cmmu = net->cmmu; - unsigned nentries; - DTRC("wrsm_cmmu_free"); - - if (tuples == NULL) - return; -#ifdef DEBUG - { - int i; - for (i = 0; i < ntuples; i++) { - DPRINTF(CMMUTRACE, (CE_NOTE, "freeing tuple %d " - "ncslice %d count %d offset 0x%p index %d\n", - i, - tuples[i].ncslice, - tuples[i].count, - (void *)tuples[i].offset, - tuples[i].index)); - } - } -#endif - - mutex_enter(&cmmu->mutex); - nentries = cmmu_free(net, ntuples, tuples); - cmmu->num_free_entries += nentries; - kmem_free(tuples, ntuples * sizeof (wrsm_cmmu_tuple_t)); - mutex_exit(&cmmu->mutex); -} - -int -wrsm_cmmu_comm_alloc(wrsm_network_t *net, ncslice_t ncslice, - wrsm_cmmu_offset_t offset, wrsm_cmmu_tuple_t *tuple) -{ - int retval = CMMU_SUCCESS; - wrsm_cmmu_alloc_t *cmmu; - wrsm_cmmu_index_t index; - - DPRINTF(CMMUTRACE, (CE_WARN, - "wrsm_cmmu_comm_alloc(ncslice=0x%x, offset=0x%p)", - ncslice, (void *)offset)); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - /* Make sure user requested small page ncslice */ - if (ncslice != cmmu->free_lists[0].ncslice) { - WARN("wrsm_cmmu_comm_alloc: Must use small pages"); - return (EINVAL); - } - index = offset_to_index(&cmmu->free_lists[0], offset); - ASSERT(index_to_offset(&cmmu->free_lists[0], index) == offset); - if (index >= NUM_COMM_PAGES) { - WARN("wrsm_cmmu_comm_alloc: index out of range"); - return (EINVAL); - } - - /* If page isn't already allocated, allocate it */ - mutex_enter(&cmmu->mutex); - if (WRSM_IN_SET(cmmu->comm_pages, index)) { - retval = ENOMEM; - } else { - WRSMSET_ADD(cmmu->comm_pages, index); - tuple->ncslice = ncslice; - tuple->offset = offset; - tuple->index = index; - tuple->count = 1; - cmmu->num_free_entries--; - retval = CMMU_SUCCESS; - } - mutex_exit(&cmmu->mutex); - - return (retval); -} - -void -wrsm_cmmu_comm_free(wrsm_network_t *net, wrsm_cmmu_tuple_t *tuple) -{ - wrsm_cmmu_alloc_t *cmmu; - - DPRINTF(CMMUTRACE, (CE_NOTE, "wrsm_cmmu_comm_free(index=%u)", - tuple->index)); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - ASSERT(tuple->index >= FIRST_CMMU_ENTRY); - ASSERT(tuple->index < NUM_COMM_PAGES); - ASSERT(tuple->ncslice == cmmu->free_lists[0].ncslice); - - mutex_enter(&cmmu->mutex); - ASSERT(WRSM_IN_SET(cmmu->comm_pages, tuple->index)); - WRSMSET_DEL(cmmu->comm_pages, tuple->index); - cmmu->num_free_entries++; - mutex_exit(&cmmu->mutex); -} - -void -wrsm_cmmu_update(wrsm_network_t *net, wrsm_cmmu_t *entry, - wrsm_cmmu_index_t index, wrsm_cmmu_flags_t flags) -{ - wci_handle_t *p; - wrsm_cmmu_alloc_t *cmmu; - - DPRINTF(CMMUTRACE, (CE_NOTE, "wrsm_cmmu_update index %d", index)); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - mutex_enter(&cmmu->mutex); - for (p = cmmu->wci_list; p; p = p->next) { - wrsm_lc_cmmu_update(p->wci_handle, entry, - index, flags); - } - mutex_exit(&cmmu->mutex); -} - -void -wrsm_cmmu_read(wrsm_network_t *net, wrsm_cmmu_t *entry, - wrsm_cmmu_index_t index) -{ - wrsm_cmmu_alloc_t *cmmu; - - DTRC("wrsm_cmmu_read"); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - mutex_enter(&cmmu->mutex); - ASSERT(cmmu->wci_list); - /* If there are WCIs, just use the first WCI on our list */ - wrsm_lc_cmmu_read(cmmu->wci_list->wci_handle, entry, index); - mutex_exit(&cmmu->mutex); -} - -/* - * Cluster members bits functions - */ -void -wrsm_clustermember_add(wrsm_network_t *net, cnodeid_t cnode) -{ - /* - * The wci_cluster_members_bits is an array of 4 64-bit registers, - * spaced out by some stride. Need to calculate which of the 4 - * entries to modify, which position within the entry to modify, - * and the offset of the entry for the request to LC. - */ - const uint64_t entry = cnode / MEMBERS_PER_REGISTER; - const uint64_t position = cnode % MEMBERS_PER_REGISTER; - const uint64_t offset = ADDR_WCI_CLUSTER_MEMBERS_BITS + - (entry * STRIDE_WCI_CLUSTER_MEMBERS_BITS); - uint64_t members; - wci_handle_t *wci; - wrsm_cmmu_alloc_t *cmmu; - - DPRINTF(CMMUTRACE, (CE_NOTE, "wrsm_clustermember_add(%u)", cnode)); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - mutex_enter(&cmmu->mutex); - /* If there are no WCIs, just return */ - if (cmmu->wci_list == NULL) { - mutex_exit(&cmmu->mutex); - return; - } - wrsm_lc_csr_read(cmmu->wci_list->wci_handle, offset, &members); - members |= ONE_BIT << position; - - for (wci = cmmu->wci_list; wci; wci = wci->next) { - wrsm_lc_csr_write(wci->wci_handle, offset, members); - } - mutex_exit(&cmmu->mutex); -} - -void -wrsm_clustermember_delete(wrsm_network_t *net, cnodeid_t cnode) -{ - /* - * The wci_cluster_members_bits is an array of 4 64-bit registers, - * spaced out by some stride. Need to calculate which of the 4 - * entries to modify, which position within the entry to modify, - * and the offset of the entry for the request to LC. - */ - const uint64_t entry = cnode / MEMBERS_PER_REGISTER; - const uint64_t position = cnode % MEMBERS_PER_REGISTER; - const uint64_t offset = ADDR_WCI_CLUSTER_MEMBERS_BITS + - (entry * STRIDE_WCI_CLUSTER_MEMBERS_BITS); - uint64_t members; - wci_handle_t *wci; - wrsm_cmmu_alloc_t *cmmu; - - DPRINTF(CMMUTRACE, (CE_NOTE, "wrsm_clustermember_delete(%u)", cnode)); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - mutex_enter(&cmmu->mutex); - /* If there are no WCIs, just return */ - if (cmmu->wci_list == NULL) { - mutex_exit(&cmmu->mutex); - return; - } - wrsm_lc_csr_read(cmmu->wci_list->wci_handle, offset, &members); - members &= ~(ONE_BIT << position); - for (wci = cmmu->wci_list; wci; wci = wci->next) { - wrsm_lc_csr_write(wci->wci_handle, offset, members); - } - mutex_exit(&cmmu->mutex); -} - -void -wrsm_clustermember_list(wrsm_network_t *net, cnode_bitmask_t *cnodes) -{ - uint_t i; - uint_t j; - wrsm_cmmu_alloc_t *cmmu = net->cmmu; - - DTRC("wrsm_clustermember_list"); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - WRSMSET_ZERO(*cnodes); - mutex_enter(&cmmu->mutex); - /* If there are no WCIs, just return */ - if (cmmu->wci_list == NULL) { - mutex_exit(&cmmu->mutex); - return; - } - - /* Loop for each of the array entries... */ - for (i = 0; i < ENTRIES_WCI_CLUSTER_MEMBERS_BITS; i++) { - uint64_t members; - uint64_t mask = ONE_BIT; - uint64_t offset = ADDR_WCI_CLUSTER_MEMBERS_BITS + - (i * STRIDE_WCI_CLUSTER_MEMBERS_BITS); - - wrsm_lc_csr_read(cmmu->wci_list->wci_handle, - offset, &members); - - /* Loop for each bit in the array... */ - for (j = 0; j < MEMBERS_PER_REGISTER; j++) { - if (members & mask) { - WRSMSET_ADD(*cnodes, - j + i * MEMBERS_PER_REGISTER); - } - mask = mask << 1; - } - } - mutex_exit(&cmmu->mutex); -} - -/* - * ncslice config array functions - */ -void -wrsm_ncsliceconfig_set(wrsm_network_t *net, ncslice_t ncslice, - wrsm_ncslice_mode_t mode) -{ - /* - * The wci_nc_slice_config_array is an 8 entry array with 64-bits - * per entry. Each entry has 2-bits per ncslice. Need to determine - * which entry to modify, the starting position within the entry - * for this ncslice, and the register offset. Also need to create - * masks to isolate the two bits being set by mode. - */ - const uint64_t entry = ncslice / SLICES_PER_REGISTER; - const uint64_t position = (ncslice % SLICES_PER_REGISTER) * - BITS_PER_SLICE; - const uint64_t offset = ADDR_WCI_NC_SLICE_CONFIG_ARRAY + - (entry * STRIDE_WCI_NC_SLICE_CONFIG_ARRAY); - /* Mask has two zeros where bits go, all other bits are 1 */ - const uint64_t mask = ~(TWO_BITS << position); - /* Make sure only 2 bits are set! Also, cast to 64-bits */ - const uint64_t mode64 = mode & TWO_BITS; - uint64_t config; - wci_handle_t *wci; - wrsm_cmmu_alloc_t *cmmu; - - DPRINTF(CMMUTRACE, (CE_NOTE, - "wrsm_ncsliceconfig_set(ncslice=%u, mode=%u)", ncslice, mode)); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - mutex_enter(&cmmu->mutex); - /* If there are no WCIs, just return */ - if (cmmu->wci_list == NULL) { - WARN("NO WCIS!!!!!"); - mutex_exit(&cmmu->mutex); - return; - } - wrsm_lc_csr_read(cmmu->wci_list->wci_handle, - offset, &config); - config = (config & mask) | (mode64 << position); - for (wci = cmmu->wci_list; wci; wci = wci->next) { - wrsm_lc_csr_write(wci->wci_handle, offset, config); - } - mutex_exit(&cmmu->mutex); -} - -wrsm_ncslice_mode_t -wrsm_ncsliceconfig_get(wrsm_network_t *net, ncslice_t ncslice) -{ - /* - * The wci_nc_slice_config_array is an 8 entry array with 64-bits - * per entry. Each entry has 2-bits per ncslice. Need to determine - * which entry to modify, the starting position within the entry - * for this ncslice, and the register offset. - */ - const uint64_t entry = ncslice / SLICES_PER_REGISTER; - const uint64_t position = (ncslice % SLICES_PER_REGISTER) * - BITS_PER_SLICE; - const uint64_t offset = ADDR_WCI_NC_SLICE_CONFIG_ARRAY + - (entry * STRIDE_WCI_NC_SLICE_CONFIG_ARRAY); - wrsm_ncslice_mode_t mode = ncslice_invalid; - uint64_t config; - wrsm_cmmu_alloc_t *cmmu; - - DTRC("wrsm_ncsliceconfig_get"); - ASSERT(net); - cmmu = net->cmmu; - ASSERT(cmmu); - - mutex_enter(&cmmu->mutex); - /* If there are no WCIs, just return */ - if (cmmu->wci_list == NULL) { - mutex_exit(&cmmu->mutex); - return (ncslice_invalid); - } - wrsm_lc_csr_read(cmmu->wci_list->wci_handle, offset, &config); - mode = (config >> position) & TWO_BITS; - mutex_exit(&cmmu->mutex); - return (mode); -} - -wrsm_cmmu_index_t -wrsm_cmmu_num_free(wrsm_network_t *net) -{ - ASSERT(net); - return (net->cmmu->num_free_entries); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_common.c b/usr/src/uts/sun4u/io/wrsm/wrsm_common.c deleted file mode 100644 index 7b1e64e8c6..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_common.c +++ /dev/null @@ -1,179 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file provides common helper routines to the Wildcat RSM driver. - */ - -#include <sys/types.h> -#include <sys/cmn_err.h> -#include <sys/wrsm_common.h> -#include <sys/varargs.h> - -#ifdef DEBUG -#define WRSM_USE_CIRCBUF 0x01 -#define WRSM_USE_CMNERR 0x02 -static int wrsmdbgmode = WRSM_USE_CMNERR | WRSM_USE_CIRCBUF; - -#ifdef DEBUG_LOG -kmutex_t wrsmdbglock; -#endif -#endif - - -/* - * The protocol_versions_supported is a bit mask representing all of - * the protocols supported by this driver. protocol_version is the - * preferred native version. - */ -#define BIT(arg) (1 << arg) -int protocol_version = 1; -uint32_t protocol_versions_supported = BIT(0); - -uint_t -wrsmset_isnull(uint32_t *s, int masksize) -{ - uint32_t *tmp = (uint32_t *)s; - - while (masksize--) { - if (*tmp++ != 0) - return (0); - } - return (1); -} - -uint_t -wrsmset_cmp(uint32_t *s1, uint32_t *s2, int masksize) -{ - uint32_t *t1 = (uint32_t *)s1, *t2 = (uint32_t *)s2; - - while (masksize--) { - if (*t1++ != *t2++) - return (0); - } - return (1); -} - - - -#ifdef DEBUG -void -dprintnodes(cnode_bitmask_t cb) -{ - int i; - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (WRSM_IN_SET(cb, i)) { - wrsmdprintf(CE_CONT, " %d", i); - } - } -} - - -#define WRSM_DEBUG_LINE 512 - -#ifdef DEBUG_LOG - -/* - * The following variables support the debug log buffer scheme. - */ -#define WRSM_DEBUG_LOG_SIZE 0x80000 - -/* don't make these static; we want to access through adb */ -int wrsmdbginit = 0; /* Nonzero if wrsmdbglock's inited */ -char wrsmdbgbuf[WRSM_DEBUG_LOG_SIZE]; /* The log buffer */ -int wrsmdbgsize = sizeof (wrsmdbgbuf); /* Size of the log buffer */ -int wrsmdbgnext; /* Next byte to write in buffer (note */ - /* this is an index, not a pointer */ - -/* - * Add the string str to the end of the debug log, followed by a newline. - */ -static void -wrsmdbglog(char *str) -{ - int length, remlen; - - mutex_enter(&wrsmdbglock); - - /* - * Note the log is circular; if this string would run over the end, - * we copy the first piece to the end and then the last piece to - * the beginning of the log. - */ - length = strlen(str); - - remlen = sizeof (wrsmdbgbuf) - wrsmdbgnext; - - if (length > remlen) { - if (remlen) - bcopy(str, wrsmdbgbuf + wrsmdbgnext, remlen); - str += remlen; - length -= remlen; - wrsmdbgnext = 0; - } - - bcopy(str, wrsmdbgbuf + wrsmdbgnext, length); - wrsmdbgnext += length; - - if (wrsmdbgnext >= sizeof (wrsmdbgbuf)) - wrsmdbgnext = 0; - - /* - * We probably don't need to append a \n, but if we did, we - * could do this: - * wrsmdbgbuf[wrsmdbgnext++] = '\n'; - */ - - mutex_exit(&wrsmdbglock); -} - -#endif /* DEBUG_LOG */ - -/* - * Add a printf-style message to whichever debug logs we're currently using. - */ -void -wrsmdprintf(int ce, const char *fmt, ...) -{ - char buf[WRSM_DEBUG_LINE]; - va_list ap; - - va_start(ap, fmt); - (void) vsprintf(buf, fmt, ap); - va_end(ap); - -#ifdef DEBUG_LOG - if (wrsmdbgmode & WRSM_USE_CIRCBUF) - wrsmdbglog(buf); -#endif /* DEBUG_LOG */ - - if (wrsmdbgmode & WRSM_USE_CMNERR) - cmn_err(ce, "%s", buf); -} -#endif /* DEBUG */ diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_confpack.c b/usr/src/uts/sun4u/io/wrsm/wrsm_confpack.c deleted file mode 100644 index bbeda20fb4..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_confpack.c +++ /dev/null @@ -1,220 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Configuration parser for the Wildcat RSM driver. This file parses the - * configuration data structure passed in by the INITIALCONFIG and - * REPLACECONFIG ioctls, and constructs a config data structure usable by - * the Wildcat RSM driver. - */ - -#include <sys/param.h> -#include <sys/kmem.h> -#include <sys/wrsm_common.h> - -#include <sys/cmn_err.h> -#include <sys/wrsm_config.h> - -#define PACK_DEBUG 1 - -#ifdef DEBUG -static uint_t wrsm_pack_debug = 0; -#define DPRINTF(a, b) { if (wrsm_pack_debug & a) wrsmdprintf b; } -#else -#define DPRINTF(a, b) { } -#endif /* DEBUG */ - -#define ROUNDUP(x) (((x) + 0x07) & ~0x07) - -void wrsm_cf_free(wrsm_controller_t *cont); - -/* - * wrsm_controller - * wrsm_routing_data (1) - * wrsm_wci_data (nwcis) - * wrsm_stripe_group (ngroups) - * wrsm_routing_policy (npolicy) - * wrsm_preferred_route (nroutes) - * wrsm_net_member (nmembers) - */ -wrsm_controller_t * -wrsm_cf_unpack(char *data) -{ - wrsm_controller_t *cont; - wrsm_routing_data_t *routing; - int size; - int i, j; - - size = 0; - - /* wrsm_controller */ - cont = (wrsm_controller_t *)data; - size += ROUNDUP(sizeof (wrsm_controller_t)); - - /* wrsm_routing_data */ - cont->routing = (wrsm_routing_data_t *)(data+size); - size += ROUNDUP(sizeof (wrsm_routing_data_t)); - - routing = cont->routing; - routing->wcis = kmem_alloc(sizeof (wrsm_wci_data_t *) * - routing->nwcis, KM_SLEEP); - if (!routing->wcis) { - DPRINTF(PACK_DEBUG, (CE_WARN, "cf_unpack: no wcis")); - goto err_finish; - } - - DPRINTF(PACK_DEBUG, (CE_CONT, "cf_unpack: nwcis=%d", routing->nwcis)); - - for (i = 0; i < routing->nwcis; ++i) { - routing->wcis[i] = (wrsm_wci_data_t *)(data+size); - size += ROUNDUP(sizeof (wrsm_wci_data_t)); - DPRINTF(PACK_DEBUG, (CE_CONT, "cf_unpack: wci %d port=%d", i, - routing->wcis[i]->port)); - } - - if (routing->ngroups) { - DPRINTF(PACK_DEBUG, (CE_CONT, "cf_unpack: ngroups=%d", - routing->ngroups)); - routing->stripe_groups = - kmem_alloc(sizeof (wrsm_stripe_group_t *) * - routing->ngroups, KM_SLEEP); - if (!routing->stripe_groups) { - DPRINTF(PACK_DEBUG, (CE_WARN, "cf_unpack: " - "no stripe_groups")); - goto err_finish; - } - - for (i = 0; i < routing->ngroups; ++i) { - routing->stripe_groups[i] = (wrsm_stripe_group_t *) - (data+size); - size += ROUNDUP(sizeof (wrsm_stripe_group_t)); - } - } - - DPRINTF(PACK_DEBUG, (CE_CONT, "cf_unpack: npolicy=%d", - routing->npolicy)); - - routing->policy = kmem_alloc(sizeof (wrsm_routing_policy_t *) * - routing->npolicy, KM_SLEEP); - if (!routing->policy) { - DPRINTF(PACK_DEBUG, (CE_WARN, "cf_unpack: no policy")); - goto err_finish; - } - - for (i = 0; i < routing->npolicy; ++i) { - wrsm_routing_policy_t *policy; - - routing->policy[i] = (wrsm_routing_policy_t *)(data+size); - size += ROUNDUP(sizeof (wrsm_routing_policy_t)); - - policy = routing->policy[i]; - - DPRINTF(PACK_DEBUG, (CE_CONT, "cf_unpack: policy 0x%p, " - "cnodeid=%d", (void *)policy, policy->cnodeid)); - DPRINTF(PACK_DEBUG, (CE_CONT, "cf_unpack: nroutes=%d", - policy->nroutes)); - policy->preferred_routes = - kmem_alloc(sizeof (wrsm_preferred_route_t *) * - policy->nroutes, KM_SLEEP); - if (!policy->preferred_routes) { - DPRINTF(PACK_DEBUG, (CE_WARN, "cf_unpack: " - "no preferred_routes nroutes=%d", - policy->nroutes)); - goto err_finish; - } - - for (j = 0; j < policy->nroutes; ++j) { - policy->preferred_routes[j] = - (wrsm_preferred_route_t *)(data+size); - size += ROUNDUP(sizeof (wrsm_preferred_route_t)); - } - } - - cont->members = kmem_alloc(sizeof (wrsm_net_member_t *) * - cont->nmembers, KM_SLEEP); - if (!cont->members) { - DPRINTF(PACK_DEBUG, (CE_WARN, "cf_unpack: no members")); - goto err_finish; - } - - for (i = 0; i < cont->nmembers; ++i) { - cont->members[i] = (wrsm_net_member_t *)(data+size); - size += ROUNDUP(sizeof (wrsm_net_member_t)); - } - - return (cont); - -err_finish: - DPRINTF(PACK_DEBUG, (CE_WARN, "wrsm_cf_unpack failed")); - wrsm_cf_free(cont); - return (NULL); -} - -/* - * Free all the components of an wrsm_controller_t struct - */ -void -wrsm_cf_free(wrsm_controller_t *cont) -{ - wrsm_routing_data_t *routing; - int i; - - if (!cont) - return; - - routing = cont->routing; - - if (!routing) - return; - - if (routing->nwcis && routing->wcis) - kmem_free(routing->wcis, sizeof (wrsm_wci_data_t *) - * routing->nwcis); - - if (routing->ngroups && routing->stripe_groups) - kmem_free(routing->stripe_groups, - sizeof (wrsm_stripe_group_t *) * routing->ngroups); - - if (routing->npolicy && routing->policy) { - wrsm_routing_policy_t *policy; - for (i = 0; i < routing->npolicy; ++i) { - policy = routing->policy[i]; - if (policy->nroutes && policy->preferred_routes) - kmem_free(policy->preferred_routes, - sizeof (wrsm_preferred_route_t *) * - policy->nroutes); - } - - kmem_free(routing->policy, sizeof (wrsm_routing_policy_t *) * - routing->npolicy); - } - - if (cont->nmembers && cont->members) - kmem_free(cont->members, sizeof (wrsm_net_member_t *) * - cont->nmembers); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_copy.s b/usr/src/uts/sun4u/io/wrsm/wrsm_copy.s deleted file mode 100644 index b5c8f0c046..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_copy.s +++ /dev/null @@ -1,891 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#if !defined(lint) -#include <sys/asm_linkage.h> -#include <sys/asi.h> -#include <sys/machasi.h> -#include <sys/privregs.h> -#include <sys/machthread.h> -#include <sys/fsr.h> -#include <sys/machparam.h> -#include <sys/wrsm_intr.h> -#include <sys/wrsm_intr_impl.h> -#include <wrsm_offsets.h> -#endif /* lint */ - -#if defined(lint) -#include <sys/types.h> -#else /* lint */ -#include "assym.h" -#endif /* lint */ - -/* - * Pseudo-code to aid in understanding the control flow of the - * wrsm_blkwrite - * - * On entry: - * - * %l6 = curthread->t_lofault; - * if (%l6 != NULL) { - * curthread->t_lofault = .copyerr; - * caller_error_handler = TRUE ! %l6 |= 1 - * } - * - * if (curthread->t_lwp == NULL) { - * ! Kernel threads do not have pcb's in which to store - * ! the floating point state, disallow preemption during - * ! the copy. - * kpreempt_disable(curthread); - * } - * - * old_fprs = %fprs; - * old_gsr = %gsr; - * if (%fprs.fef) { - * ! If we need to save 3 blocks of fpregs then make sure - * ! the length is still appropriate for that extra overhead. - * if (length < (large_length + (64 * 3))) { - * if (curthread->t_lwp == NULL) - * kpreempt_enable(curthread); - * goto regular_copy; - * } - * %fprs.fef = 1; - * save current fpregs on stack using blockstore - * } else { - * %fprs.fef = 1; - * } - * - * if (length < HW_THRESHOLD) - * goto slow_copy; - * - * - * do blockcopy or slow_copy here; - * - * - * On exit (in lofault handler as well): - * - * %gsr = old_gsr; - * if (old_fprs & FPRS_FEF) - * restore fpregs from stack using blockload - * else - * zero fpregs - * %fprs = old_fprs; - * if (curthread->t_lwp == NULL) - * kpreempt_enable(curthread); - * curthread->t_lofault = (%l6 & ~1); - * return (0) - */ - -/* - * Number of bytes needed to "break even" using VIS-accelerated - * memory operations. - */ -#define HW_THRESHOLD 256 - -/* - * Number of outstanding prefetches. 5 seems to be a good number - * right now. - */ -#define CHEETAH_PREFETCH 5 - -/* - * Size of stack frame in order to accomodate a 64-byte aligned - * floating-point register save area and 2 64-bit temp locations. - */ -#define VIS_BLOCKSIZE 64 - -#define HWCOPYFRAMESIZE ((VIS_BLOCKSIZE * 4) + (2 * 8)) - -#define SAVED_FPREGS_OFFSET (VIS_BLOCKSIZE * 4) -#define SAVED_FPREGS_ADJUST ((VIS_BLOCKSIZE * 3) - 1) -#define SAVED_FPRS_OFFSET (SAVED_FPREGS_OFFSET + 8) -#define SAVED_GSR_OFFSET (SAVED_FPRS_OFFSET + 8) - -/* - * Common macros used by the various versions of the block copy - * routines in this file. - */ - -/* - * Zero the parts of the fpreg file that we actually use - * ( 2 or 3 sets of 8 registers ) - */ -#define FZERO3 \ - fzero %f0 ;\ - fzero %f2 ;\ - faddd %f0, %f2, %f4 ;\ - fmuld %f0, %f2, %f6 ;\ - faddd %f0, %f2, %f8 ;\ - fmuld %f0, %f2, %f10 ;\ - faddd %f0, %f2, %f12 ;\ - fmuld %f0, %f2, %f14 ;\ - faddd %f0, %f2, %f16 ;\ - fmuld %f0, %f2, %f18 ;\ - faddd %f0, %f2, %f20 ;\ - fmuld %f0, %f2, %f22 ;\ - faddd %f0, %f2, %f24 ;\ - fmuld %f0, %f2, %f26 ;\ - faddd %f0, %f2, %f28 ;\ - fmuld %f0, %f2, %f30 ;\ - faddd %f0, %f2, %f32 ;\ - fmuld %f0, %f2, %f34 ;\ - faddd %f0, %f2, %f36 ;\ - fmuld %f0, %f2, %f38 ;\ - faddd %f0, %f2, %f40 ;\ - fmuld %f0, %f2, %f42 ;\ - faddd %f0, %f2, %f44 ;\ - fmuld %f0, %f2, %f46 - -#define FZERO2 \ - fzero %f0 ;\ - fzero %f2 ;\ - faddd %f0, %f2, %f4 ;\ - fmuld %f0, %f2, %f6 ;\ - faddd %f0, %f2, %f8 ;\ - fmuld %f0, %f2, %f10 ;\ - faddd %f0, %f2, %f12 ;\ - fmuld %f0, %f2, %f14 ;\ - faddd %f0, %f2, %f16 ;\ - fmuld %f0, %f2, %f18 ;\ - faddd %f0, %f2, %f20 ;\ - fmuld %f0, %f2, %f22 ;\ - faddd %f0, %f2, %f24 ;\ - fmuld %f0, %f2, %f26 ;\ - faddd %f0, %f2, %f28 ;\ - fmuld %f0, %f2, %f30 - -/* - * Copy a block of storage, returning an error code if `from' or - * `to' takes a kernel pagefault which cannot be resolved. - * Returns errno value on pagefault error, 0 if all ok - */ - -#if defined(lint) - -/* ARGSUSED */ -void -wrsm_blkwrite(void *from, void *to, size_t num_blocks) -{} - -#else /* lint */ - - .seg ".text" - .align 4 - - ENTRY(wrsm_blkwrite) - - save %sp, -SA(MINFRAME + HWCOPYFRAMESIZE), %sp - ldn [THREAD_REG + T_LOFAULT], %l6 ! save t_lofault - brz,pt %l6, .do_copy - nop - set .copyerr, %o2 - stn %o2, [THREAD_REG + T_LOFAULT] ! install new vector - b .do_copy ! copy code - or %l6, 1, %l6 ! error should trampoline - -/* - * We got here because of a fault during kcopy. - * Errno value is in %g1. - */ -.copyerr: - membar #Sync - - ldx [%fp + STACK_BIAS - SAVED_GSR_OFFSET], %o2 ! restore gsr - wr %o2, 0, %gsr - - ld [%fp + STACK_BIAS - SAVED_FPRS_OFFSET], %o3 - btst FPRS_FEF, %o3 - bz 4f - nop - - ! restore fpregs from stack - membar #Sync - add %fp, STACK_BIAS - SAVED_FPREGS_ADJUST, %o2 - and %o2, -VIS_BLOCKSIZE, %o2 - ldda [%o2]ASI_BLK_P, %d0 - add %o2, VIS_BLOCKSIZE, %o2 - ldda [%o2]ASI_BLK_P, %d16 - add %o2, VIS_BLOCKSIZE, %o2 - ldda [%o2]ASI_BLK_P, %d32 - membar #Sync - - ba 2f - wr %o3, 0, %fprs ! restore fprs - -4: - FZERO3 ! zero all of the fpregs - wr %o3, 0, %fprs ! restore fprs - -2: ldn [THREAD_REG + T_LWP], %o2 - tst %o2 - bnz,pt %ncc, 1f - nop - - ldsb [THREAD_REG + T_PREEMPT], %l0 - deccc %l0 - bnz,pn %ncc, 1f - stb %l0, [THREAD_REG + T_PREEMPT] - - ! Check for a kernel preemption request - ldn [THREAD_REG + T_CPU], %l0 - ldub [%l0 + CPU_KPRUNRUN], %l0 - tst %l0 - bz,pt %ncc, 1f - nop - - ! Attempt to preempt - call kpreempt - rdpr %pil, %o0 ! pass %pil - -1: - btst 1, %l6 - andn %l6, 1, %l6 - bnz,pn %ncc, 3f - stn %l6, [THREAD_REG + T_LOFAULT] ! restore old t_lofault - ret - restore %g1, 0, %o0 - -3: - jmp %l6 ! goto real handler - restore %g0, 0, %o0 ! dispose of copy window - -.do_copy: - sllx %i2, 6, %i2 ! convert blocks to bytes - - ldn [THREAD_REG + T_LWP], %o3 - tst %o3 - bnz,pt %ncc, 1f - nop - - ! kpreempt_disable(); - ldsb [THREAD_REG + T_PREEMPT], %o2 - inc %o2 - stb %o2, [THREAD_REG + T_PREEMPT] - -1: - rd %fprs, %o2 ! check for unused fp - st %o2, [%fp + STACK_BIAS - SAVED_FPRS_OFFSET] ! save orig %fprs - btst FPRS_FEF, %o2 - bz,a .do_blockcopy - wr %g0, FPRS_FEF, %fprs - -.fpregs_inuse: - - wr %g0, FPRS_FEF, %fprs - - ! save in-use fpregs on stack - membar #Sync - add %fp, STACK_BIAS - SAVED_FPREGS_ADJUST, %o2 - and %o2, -VIS_BLOCKSIZE, %o2 - stda %d0, [%o2]ASI_BLK_P - add %o2, VIS_BLOCKSIZE, %o2 - stda %d16, [%o2]ASI_BLK_P - add %o2, VIS_BLOCKSIZE, %o2 - stda %d32, [%o2]ASI_BLK_P - membar #Sync - -.do_blockcopy: - membar #StoreStore|#StoreLoad|#LoadStore - - rd %gsr, %o2 - stx %o2, [%fp + STACK_BIAS - SAVED_GSR_OFFSET] ! save gsr - -#define REALSRC %i0 -#define DST %i1 -#define CNT %i2 -#define SRC %i3 - - cmp %i2, HW_THRESHOLD ! for large counts - blu %ncc, .slow_copy - .empty - -2: membar #StoreLoad - alignaddr REALSRC, %g0, SRC - - ! SRC - 8-byte aligned - ! DST - 64-byte aligned - prefetch [SRC], #one_read - prefetch [SRC + (1 * VIS_BLOCKSIZE)], #one_read - prefetch [SRC + (2 * VIS_BLOCKSIZE)], #one_read - prefetch [SRC + (3 * VIS_BLOCKSIZE)], #one_read - ldd [SRC], %f0 -#if CHEETAH_PREFETCH >= 4 - prefetch [SRC + (4 * VIS_BLOCKSIZE)], #one_read -#endif - ldd [SRC + 0x08], %f2 -#if CHEETAH_PREFETCH >= 5 - prefetch [SRC + (5 * VIS_BLOCKSIZE)], #one_read -#endif - ldd [SRC + 0x10], %f4 -#if CHEETAH_PREFETCH >= 6 - prefetch [SRC + (6 * VIS_BLOCKSIZE)], #one_read -#endif - faligndata %f0, %f2, %f32 - ldd [SRC + 0x18], %f6 -#if CHEETAH_PREFETCH >= 7 - prefetch [SRC + (7 * VIS_BLOCKSIZE)], #one_read -#endif - faligndata %f2, %f4, %f34 - ldd [SRC + 0x20], %f8 - faligndata %f4, %f6, %f36 - ldd [SRC + 0x28], %f10 - faligndata %f6, %f8, %f38 - ldd [SRC + 0x30], %f12 - faligndata %f8, %f10, %f40 - ldd [SRC + 0x38], %f14 - faligndata %f10, %f12, %f42 - ldd [SRC + VIS_BLOCKSIZE], %f0 - sub CNT, VIS_BLOCKSIZE, CNT - add SRC, VIS_BLOCKSIZE, SRC - add REALSRC, VIS_BLOCKSIZE, REALSRC - ba,a,pt %ncc, 1f - .align 32 -1: - ldd [SRC + 0x08], %f2 - faligndata %f12, %f14, %f44 - ldd [SRC + 0x10], %f4 - faligndata %f14, %f0, %f46 - stda %f32, [DST]ASI_BLK_P - ldd [SRC + 0x18], %f6 - faligndata %f0, %f2, %f32 - ldd [SRC + 0x20], %f8 - faligndata %f2, %f4, %f34 - ldd [SRC + 0x28], %f10 - faligndata %f4, %f6, %f36 - ldd [SRC + 0x30], %f12 - faligndata %f6, %f8, %f38 - ldd [SRC + 0x38], %f14 - faligndata %f8, %f10, %f40 - ldd [SRC + VIS_BLOCKSIZE], %f0 - prefetch [SRC + (CHEETAH_PREFETCH * VIS_BLOCKSIZE)], #one_read - faligndata %f10, %f12, %f42 - sub CNT, VIS_BLOCKSIZE, CNT - add DST, VIS_BLOCKSIZE, DST - add REALSRC, VIS_BLOCKSIZE, REALSRC - cmp CNT, VIS_BLOCKSIZE + 8 - bgu,pt %ncc, 1b - add SRC, VIS_BLOCKSIZE, SRC - - ! only if REALSRC & 0x7 is 0 - andcc REALSRC, 0x7, %g0 - bz %ncc, 2f - nop -3: - ldd [SRC + 0x08], %f2 - faligndata %f12, %f14, %f44 - ldd [SRC + 0x10], %f4 - faligndata %f14, %f0, %f46 - stda %f32, [DST]ASI_BLK_P - ldd [SRC + 0x18], %f6 - faligndata %f0, %f2, %f32 - ldd [SRC + 0x20], %f8 - faligndata %f2, %f4, %f34 - ldd [SRC + 0x28], %f10 - faligndata %f4, %f6, %f36 - ldd [SRC + 0x30], %f12 - faligndata %f6, %f8, %f38 - ldd [SRC + 0x38], %f14 - faligndata %f8, %f10, %f40 - ldd [SRC + VIS_BLOCKSIZE], %f0 - faligndata %f10, %f12, %f42 - add REALSRC, VIS_BLOCKSIZE, REALSRC - sub CNT, VIS_BLOCKSIZE, CNT - add DST, VIS_BLOCKSIZE, DST - faligndata %f12, %f14, %f44 - faligndata %f14, %f0, %f46 - stda %f32, [DST]ASI_BLK_P - ba 4f - add SRC, VIS_BLOCKSIZE, SRC - -2: - ldd [SRC + 0x08], %f2 - fsrc1 %f12, %f44 - ldd [SRC + 0x10], %f4 - fsrc1 %f14, %f46 - stda %f32, [DST]ASI_BLK_P - ldd [SRC + 0x18], %f6 - ldd [SRC + 0x20], %f8 - ldd [SRC + 0x28], %f10 - ldd [SRC + 0x30], %f12 - ldd [SRC + 0x38], %f14 - sub CNT, VIS_BLOCKSIZE, CNT - add DST, VIS_BLOCKSIZE, DST - add REALSRC, VIS_BLOCKSIZE, REALSRC - stda %f0, [DST]ASI_BLK_P - ba 4f - add SRC, VIS_BLOCKSIZE, SRC -4: -.copy_exit: - membar #StoreLoad|#StoreStore - - andn %l6, 1, %l6 - - ldx [%fp + STACK_BIAS - SAVED_GSR_OFFSET], %o2 ! restore gsr - wr %o2, 0, %gsr - - ld [%fp + STACK_BIAS - SAVED_FPRS_OFFSET], %o3 - btst FPRS_FEF, %o3 - bz 4f - nop - - ! restore fpregs from stack - membar #Sync - add %fp, STACK_BIAS - SAVED_FPREGS_ADJUST, %o2 - and %o2, -VIS_BLOCKSIZE, %o2 - ldda [%o2]ASI_BLK_P, %d0 - add %o2, VIS_BLOCKSIZE, %o2 - ldda [%o2]ASI_BLK_P, %d16 - add %o2, VIS_BLOCKSIZE, %o2 - ldda [%o2]ASI_BLK_P, %d32 - membar #Sync - - ba 2f - wr %o3, 0, %fprs ! restore fprs - -4: - FZERO3 ! zero all of the fpregs - wr %o3, 0, %fprs ! restore fprs - -2: ldn [THREAD_REG + T_LWP], %o2 - tst %o2 - bnz,pt %ncc, 1f - nop - - ldsb [THREAD_REG + T_PREEMPT], %l0 - deccc %l0 - bnz,pn %ncc, 1f - stb %l0, [THREAD_REG + T_PREEMPT] - - ! Check for a kernel preemption request - ldn [THREAD_REG + T_CPU], %l0 - ldub [%l0 + CPU_KPRUNRUN], %l0 - tst %l0 - bz,pt %ncc, 1f - nop - - ! Attempt to preempt - call kpreempt - rdpr %pil, %o0 ! pass %pil - -1: - stn %l6, [THREAD_REG + T_LOFAULT] ! restore old t_lofault - ret - restore %g0, 0, %o0 - -.slow_copy: - - andcc REALSRC, 0x7, %g0 - bz %ncc, 3f - alignaddr REALSRC, %g0, SRC - -1: brlez,pn CNT, .copy_exit - nop - ldd [SRC], %f0 - ldd [SRC + 0x08], %f2 - ldd [SRC + 0x10], %f4 - faligndata %f0, %f2, %f32 - ldd [SRC + 0x18], %f6 - faligndata %f2, %f4, %f34 - ldd [SRC + 0x20], %f8 - faligndata %f4, %f6, %f36 - ldd [SRC + 0x28], %f10 - faligndata %f6, %f8, %f38 - ldd [SRC + 0x30], %f12 - faligndata %f8, %f10, %f40 - ldd [SRC + 0x38], %f14 - faligndata %f10, %f12, %f42 - ldd [SRC + VIS_BLOCKSIZE], %f0 - sub CNT, VIS_BLOCKSIZE, CNT - add SRC, VIS_BLOCKSIZE, SRC - add REALSRC, VIS_BLOCKSIZE, REALSRC - faligndata %f12, %f14, %f44 - faligndata %f14, %f0, %f46 - stda %f32, [DST]ASI_BLK_P - ba 1b - add DST, VIS_BLOCKSIZE, DST - - ! SRC - 8-byte aligned - ! DST - 64-byte aligned - -3: brlez,pn CNT, .copy_exit - nop - ldd [SRC], %f0 - ldd [SRC + 0x08], %f2 - ldd [SRC + 0x10], %f4 - ldd [SRC + 0x18], %f6 - ldd [SRC + 0x20], %f8 - ldd [SRC + 0x28], %f10 - ldd [SRC + 0x30], %f12 - ldd [SRC + 0x38], %f14 - sub CNT, VIS_BLOCKSIZE, CNT - add SRC, VIS_BLOCKSIZE, SRC - add REALSRC, VIS_BLOCKSIZE, REALSRC - stda %f0, [DST]ASI_BLK_P - ba 3b - add DST, VIS_BLOCKSIZE, DST - - SET_SIZE(wrsm_blkwrite) -#endif /* lint */ - - -/* - * wrsm_blkread - * - * disable preemption - * if FPREGS need to be saved, save them - * check alignment: - * if (64 alignment) go to loop 3 - * if (8 alinment) go to loop 2 - * else - * if done, go to exit - * block load 64 bytes into FPREGS - * store 64 bytes on the stack - * load 8 bytes into %l0 - * store byte by byte - * repeat - * - * loop 2: - * if done, go to exit - * block load 64 bytes into FPREGS - * store the 8 - 8 byte values from FPREGS to mem - * repeat - * - * loop 3: - * if done, go to exit - * block load 64 bytes into FPREGS - * block store 64 bytes to memory - * repeat - * - * exit: - * restore FPREGS or clear them - * check for preemption requests - * return - */ - -/* we need to save two blocks of 8 registers on the stack + alignment */ -#define READFRAMESIZE (VIS_BLOCKSIZE * 3) -/* where we put FPREGS */ -#define READ_FPREGS_ADJUST (VIS_BLOCKSIZE - 1) -/* where we put data on stack during byte copy */ -#define READ_STACK_ADJUST ((VIS_BLOCKSIZE * 2) - 1) - -#if defined(lint) -/* ARGSUSED */ -void -wrsm_blkread(void *src, void *dst, size_t num_blocks) -{} -#else /* !lint */ -! -! Move multiple cache lines of data. -! The source must be 64-byte aligned. -! -! %i0 = src va (64 byte aligned - remote side) -! %i1 = dst va (non alligned - local side) -! %i2 = num_blocks -! -! %l0 = may be used as temporary place holder for data -! %l1 = cache of fpu state -! %l2 = temp address of data on stack -! - - ENTRY(wrsm_blkread) - - save %sp, -SA(MINFRAME + READFRAMESIZE), %sp - - membar #Sync - - ! kpreempt_disable(); - ldsb [THREAD_REG + T_PREEMPT], %o2 - inc %o2 - stb %o2, [THREAD_REG + T_PREEMPT] - - ! check if we need to save the state of the fpu? - rd %fprs, %l1 - btst FPRS_FEF, %l1 - - ! always enable FPU - wr %g0, FPRS_FEF, %fprs - - bz,a 1f - nop - - ! save in-use fpregs on stack - membar #Sync - add %fp, STACK_BIAS - READ_FPREGS_ADJUST, %o2 - and %o2, -64, %o2 - stda %d0, [%o2]ASI_BLK_P - membar #Sync - - ! check alignment -1: andcc %i1, 63, %g0 ! *dst aligned 64 bytes - bz %ncc, .loop3 - - andcc %i1, 0x7, %g0 ! *dst aligned 8 bytes - bz %ncc, .loop2 - nop - - ! we do not have any alignment for destination (loop 1) - - ! calculate address for extra space on the stack (below fpregs) - add %fp, STACK_BIAS - READ_STACK_ADJUST, %o2 - and %o2, -64, %o2 - - ! Perform block move -.loop1: - brz,pn %i2, 2f ! while (%i2 > 0) { - nop - ldda [%i0]ASI_BLK_P, %d0 ! tmp = *src; - - ! save the data on stack - membar #Sync - stda %d0, [%o2]ASI_BLK_P - membar #Sync - ! read the data into local regs - - add %o2, 0, %l2 ! store the location of data into %l2 - ldx [%l2], %l0 - stb %l0, [%i1+7] ! not aligned , store byte at a time - srlx %l0, 8, %l0 ! (*dst = tmp;) - stb %l0, [%i1+6] - srlx %l0, 8, %l0 - stb %l0, [%i1+5] - srlx %l0, 8, %l0 - stb %l0, [%i1+4] - srlx %l0, 8, %l0 - stb %l0, [%i1+3] - srlx %l0, 8, %l0 - stb %l0, [%i1+2] - srlx %l0, 8, %l0 - stb %l0, [%i1+1] - srlx %l0, 8, %l0 - stb %l0, [%i1] - - add %l2, 8, %l2 ! increment location of data - ldx [%l2], %l0 - stb %l0, [%i1+15] - srlx %l0, 8, %l0 - stb %l0, [%i1+14] - srlx %l0, 8, %l0 - stb %l0, [%i1+13] - srlx %l0, 8, %l0 - stb %l0, [%i1+12] - srlx %l0, 8, %l0 - stb %l0, [%i1+11] - srlx %l0, 8, %l0 - stb %l0, [%i1+10] - srlx %l0, 8, %l0 - stb %l0, [%i1+9] - srlx %l0, 8, %l0 - stb %l0, [%i1+8] - - add %l2, 8, %l2 ! increment location of data - ldx [%l2], %l0 - stb %l0, [%i1+23] - srlx %l0, 8, %l0 - stb %l0, [%i1+22] - srlx %l0, 8, %l0 - stb %l0, [%i1+21] - srlx %l0, 8, %l0 - stb %l0, [%i1+20] - srlx %l0, 8, %l0 - stb %l0, [%i1+19] - srlx %l0, 8, %l0 - stb %l0, [%i1+18] - srlx %l0, 8, %l0 - stb %l0, [%i1+17] - srlx %l0, 8, %l0 - stb %l0, [%i1+16] - - add %l2, 8, %l2 ! increment location of data - ldx [%l2], %l0 - stb %l0, [%i1+31] - srlx %l0, 8, %l0 - stb %l0, [%i1+30] - srlx %l0, 8, %l0 - stb %l0, [%i1+29] - srlx %l0, 8, %l0 - stb %l0, [%i1+28] - srlx %l0, 8, %l0 - stb %l0, [%i1+27] - srlx %l0, 8, %l0 - stb %l0, [%i1+26] - srlx %l0, 8, %l0 - stb %l0, [%i1+25] - srlx %l0, 8, %l0 - stb %l0, [%i1+24] - - add %l2, 8, %l2 ! increment location of data - ldx [%l2], %l0 - stb %l0, [%i1+39] - srlx %l0, 8, %l0 - stb %l0, [%i1+38] - srlx %l0, 8, %l0 - stb %l0, [%i1+37] - srlx %l0, 8, %l0 - stb %l0, [%i1+36] - srlx %l0, 8, %l0 - stb %l0, [%i1+35] - srlx %l0, 8, %l0 - stb %l0, [%i1+34] - srlx %l0, 8, %l0 - stb %l0, [%i1+33] - srlx %l0, 8, %l0 - stb %l0, [%i1+32] - - add %l2, 8, %l2 ! increment location of data - ldx [%l2], %l0 - stb %l0, [%i1+47] - srlx %l0, 8, %l0 - stb %l0, [%i1+46] - srlx %l0, 8, %l0 - stb %l0, [%i1+45] - srlx %l0, 8, %l0 - stb %l0, [%i1+44] - srlx %l0, 8, %l0 - stb %l0, [%i1+43] - srlx %l0, 8, %l0 - stb %l0, [%i1+42] - srlx %l0, 8, %l0 - stb %l0, [%i1+41] - srlx %l0, 8, %l0 - stb %l0, [%i1+40] - - add %l2, 8, %l2 ! increment location of data - ldx [%l2], %l0 - stb %l0, [%i1+55] - srlx %l0, 8, %l0 - stb %l0, [%i1+54] - srlx %l0, 8, %l0 - stb %l0, [%i1+53] - srlx %l0, 8, %l0 - stb %l0, [%i1+52] - srlx %l0, 8, %l0 - stb %l0, [%i1+51] - srlx %l0, 8, %l0 - stb %l0, [%i1+50] - srlx %l0, 8, %l0 - stb %l0, [%i1+49] - srlx %l0, 8, %l0 - stb %l0, [%i1+48] - - add %l2, 8, %l2 ! increment location of data - ldx [%l2], %l0 - stb %l0, [%i1+63] - srlx %l0, 8, %l0 - stb %l0, [%i1+62] - srlx %l0, 8, %l0 - stb %l0, [%i1+61] - srlx %l0, 8, %l0 - stb %l0, [%i1+60] - srlx %l0, 8, %l0 - stb %l0, [%i1+59] - srlx %l0, 8, %l0 - stb %l0, [%i1+58] - srlx %l0, 8, %l0 - stb %l0, [%i1+57] - srlx %l0, 8, %l0 - stb %l0, [%i1+56] - - add %i0, 64, %i0 ! src++; - add %i1, 64, %i1 ! dst++; - membar #Sync - ba .loop1 ! %i2-- ; - dec %i2 ! } - - - ! we have 8 byte alignment (loop 2) -.loop2: - brz,pn %i2, 2f ! while (%i2 > 0) { - nop - ldda [%i0]ASI_BLK_P, %f0 ! tmp = *src; - - std %f0, [%i1] ! *dst = tmp; - std %f2, [%i1 + 0x08] - std %f4, [%i1 + 0x10] - std %f6, [%i1 + 0x18] - std %f8, [%i1 + 0x20] - std %f10, [%i1 + 0x28] - std %f12, [%i1 + 0x30] - std %f14, [%i1 + 0x38] - add %i0, 64, %i0 ! src++; - add %i1, 64, %i1 ! dst++; - membar #Sync - ba .loop2 ! %i2-- ; - dec %i2 ! } - - ! we have 64 byte alignment (loop 3) -.loop3: - brz,pn %i2, 2f ! while (%i2 > 0) { - nop - ldda [%i0]ASI_BLK_P, %f0 ! tmp = *src; - - stda %d0, [%i1]ASI_BLK_P ! *dst = tmp; - add %i0, 64, %i0 ! src++; - add %i1, 64, %i1 ! dst++; - membar #Sync - ba .loop3 ! %i2-- ; - dec %i2 ! } - -2: ! coming out of loop 1, 2 or 3 - ! restore fp to the way we got it - btst FPRS_FEF, %l1 - bz,a 3f - nop - - ! restore fpregs from stack - add %fp, STACK_BIAS - READ_FPREGS_ADJUST, %o2 - and %o2, -64, %o2 - ldda [%o2]ASI_BLK_P, %d0 - membar #Sync - ba 4f - wr %g0, %l1, %fprs ! fpu back to the way it was -3: - FZERO2 ! zero all of the fpregs - wr %g0, %l1, %fprs ! restore fprs - -4: ! kpreempt_enable(); - ldsb [THREAD_REG + T_PREEMPT], %o2 - deccc %o2 - stb %o2, [THREAD_REG + T_PREEMPT] - - ! Check for a kernel preemption request - ldn [THREAD_REG + T_CPU], %o2 - ldub [%o2 + CPU_KPRUNRUN], %o2 - tst %o2 - bz,pt %icc, 5f - nop - - ! Attempt to preempt - call kpreempt - rdpr %pil, %o0 ! pass %pil - -5: ret - restore - SET_SIZE(wrsm_blkread) -#endif /* lint */ - diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_driver.c b/usr/src/uts/sun4u/io/wrsm/wrsm_driver.c deleted file mode 100644 index fd13090931..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_driver.c +++ /dev/null @@ -1,1765 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file implements the standard DDI interface functions for - * the Wildcat RSM driver. - */ - -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/mutex.h> -#include <sys/param.h> -#include <sys/modctl.h> -#include <sys/open.h> -#include <sys/stat.h> -#include <sys/obpdefs.h> -#include <sys/cmn_err.h> -#include <sys/mman.h> -#include <sys/file.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/machsystm.h> -#include <sys/policy.h> - -/* Driver specific headers */ -#include <sys/wci_common.h> -#include <sys/wci_regs.h> -#include <sys/wrsm_driver.h> -#include <sys/wrsm_lc.h> -#include <sys/wrsm.h> -#include <sys/wrsm_plugin.h> -#include <sys/wrsm_cf.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_memseg_impl.h> -#include <sys/wrsm_rsmpi.h> -#include <sys/rsm/rsmpi_driver.h> - -/* Headers for modules that wrsm depends on */ - -#include <sys/wrsm_plat.h> -#include <sys/rsm/rsmpi.h> - -/* - * Exported data structures; - */ -dev_info_t *wrsm_ncslice_dip; /* devinfo for ncslice mappings */ -static kmutex_t wrsm_attach_mutex; -static int wrsm_attachcnt = 0; /* # of instances attached */ -wrsm_softstate_t *wrsm_admin_softsp = NULL; - -/* - * Internal Function prototypes - */ -static int wrsm_attach(dev_info_t *, ddi_attach_cmd_t); -static int wrsm_info(dev_info_t *, ddi_info_cmd_t, void *, void **); -static int wrsm_detach(dev_info_t *, ddi_detach_cmd_t); - -static int wrsm_open(dev_t *, int, int, cred_t *); -static int wrsm_close(dev_t, int, int, cred_t *); -static int wrsm_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); - -static int wrsm_segmap(dev_t, off_t, struct as *, caddr_t *, off_t, - unsigned int, unsigned int, unsigned int, cred_t *); -static int wrsm_devmap(dev_t, devmap_cookie_t, offset_t, size_t, - size_t *, uint_t); -static int wrsm_device_ioctl(wrsm_softstate_t *softsp, int cmd, - intptr_t arg, int flag, cred_t *cred_p, int *rval_p); -static int wrsm_map_regs(wrsm_softstate_t *softsp); - -static void wrsm_unmap_regs(wrsm_softstate_t *softsp); - -static void wrsm_add_status_kstat(wrsm_softstate_t *softsp); -static void wrsm_del_status_kstat(wrsm_softstate_t *softsp); -static int wrsm_status_kstat_update(kstat_t *ksp, int rw); - -/* - * Configuration data structures - */ - -static struct cb_ops wrsm_cb_ops = { - wrsm_open, /* open */ - wrsm_close, /* close */ - nulldev, /* strategy */ - nulldev, /* print */ - nodev, /* dump */ - nulldev, /* read */ - nulldev, /* write */ - wrsm_ioctl, /* ioctl */ - wrsm_devmap, /* devmap */ - nodev, /* mmap */ - wrsm_segmap, /* segmap */ - nochpoll, /* poll */ - ddi_prop_op, /* cb_prop_op */ - 0, /* streamtab */ - D_MP | D_NEW /* Driver compatibility flag */ -}; - -static rsmops_registry_t wrsm_rsmops = { - RSM_VERSION, - "wrsm", - wrsmrsm_get_controller_handler, - wrsmrsm_release_controller_handler, - NULL /* rsm_thread_entry_pt */ -}; - -static struct dev_ops wrsm_ops = { - DEVO_REV, /* devo_rev, */ - 0, /* refcnt */ - wrsm_info, /* getinfo */ - nulldev, /* identify */ - nulldev, /* probe */ - wrsm_attach, /* attach */ - wrsm_detach, /* detach */ - nulldev, /* reset */ - &wrsm_cb_ops, /* cb_ops */ - (struct bus_ops *)0, /* bus_ops */ - nulldev /* power */ -}; - -static wrsm_plat_ops_t wrsm_plat_ops = { - wrsm_lc_phys_link_up, /* discovery success-msg from SC */ - wrsm_lc_phys_link_down, /* link down - msg from SC */ - wrsm_cf_sc_failed, /* report that the SC has reset */ - wrsm_cf_lookup_wci, /* give lcwci_handle for wci id */ - get_remote_config_data /* lookup remote config info */ -}; - -/* - * Driver globals - */ - -extern void wrsm_redist(void *); - -static void *wrsm_softstates; /* wrsm soft state hook */ -extern struct mod_ops mod_driverops; - -static struct modldrv modldrv = { - &mod_driverops, /* Type of module. This one is a driver */ - "WRSM v%I%" /* name of module */ -#ifdef DEBUG - " (Debug)" -#endif -, - &wrsm_ops, /* driver ops */ -}; - -static struct modlinkage modlinkage = { - MODREV_1, /* rev */ - (void *)&modldrv, - NULL -}; - - -/* - * Controllers must be assigned a minor number that matches their - * controller id. This means that the device instance number can't be used - * for the minor number. The minor_to_instance table is used to translate - * between the 2. To ensure that lower numbered minor numbers are - * available (controllers ids are assigned starting with 0), the admin - * device is assigned a minor number of (MAX_INSTANCE - 1), and wci devices - * are assigned a minor number of (MAX_INSTANCE - 2 - instance#) - */ -#define MAX_INSTANCES 1024 -static int minor_to_instance[MAX_INSTANCES]; - -#ifdef DEBUG - - -#define WRSM_DEBUG 0x0001 -#define WRSM_WARN 0x0002 -static uint32_t wrsm_debug = WRSM_WARN; - -#define DPRINTF(a, b) { if (wrsm_debug & a) wrsmdprintf b; } -#else -#define DPRINTF(a, b) { } -#endif - - -/* - * ************************************************************************* - * - * These are the module initialization routines. - */ - -int -_init(void) -{ - int error; - int i; - -#if defined(DEBUG) && defined(DEBUG_LOG) - bzero(wrsmdbgbuf, wrsmdbgsize); - wrsmdbgnext = 0; - wrsmdbginit = 1; - mutex_init(&wrsmdbglock, NULL, MUTEX_DRIVER, NULL); -#endif - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_init\n")); - - for (i = 0; i < MAX_INSTANCES; i++) { - minor_to_instance[i] = -1; - } - - /* Initialize soft state pointer. */ - if ((error = ddi_soft_state_init(&wrsm_softstates, - sizeof (wrsm_softstate_t), 1)) != 0) { - DPRINTF(WRSM_WARN, (CE_WARN, "ddi_soft_state_init failed")); -#if defined(DEBUG) && defined(DEBUG_LOG) - mutex_destroy(&wrsmdbglock); -#endif - return (error); - } - - mutex_init(&wrsm_attach_mutex, NULL, MUTEX_DRIVER, NULL); - /* Install the module. */ - if ((error = mod_install(&modlinkage)) != 0) { - DPRINTF(WRSM_WARN, (CE_WARN, "mod_install failed")); - goto err_cleanup; - } - - /* - * initialize the various RSM driver sub-modules - */ - wrsm_nc_init(); - wrsm_cf_init(); - wrsm_memseg_init(); - - /* register call backs with platform specific mailbox layer */ - if ((error = wrsmplat_reg_callbacks(&wrsm_plat_ops)) != 0) { - wrsm_memseg_fini(); - wrsm_cf_fini(); - (void) wrsm_nc_fini(); - goto err_cleanup; - } - - /* - * register with RSM - */ - if ((error = rsm_register_driver(&wrsm_rsmops)) != RSM_SUCCESS) { - cmn_err(CE_WARN, "wrsm_init: rsm_register_driver failed"); - (void) wrsmplat_unreg_callbacks(); - wrsm_memseg_fini(); - wrsm_cf_fini(); - (void) wrsm_nc_fini(); - goto err_cleanup; - } - - return (WRSM_SUCCESS); - -err_cleanup: - ddi_soft_state_fini(&wrsm_softstates); - mutex_destroy(&wrsm_attach_mutex); - -#if defined(DEBUG) && defined(DEBUG_LOG) - mutex_destroy(&wrsmdbglock); -#endif - return (error); - -} - -int -_fini(void) -{ - int error; - - /* - * Make sure there are no RSMPI users before allowing driver to - * be removed. - */ - if (rsm_unregister_driver(&wrsm_rsmops) != RSM_SUCCESS) { - return (EBUSY); - } - - /* - * Make sure there are no configurations installed before allowing - * driver to be removed. - */ - if (wrsm_nc_check() != WRSM_SUCCESS) { - (void) rsm_register_driver(&wrsm_rsmops); - return (EBUSY); - } - - /* Prepare the module to be removed. */ - if ((error = mod_remove(&modlinkage)) != 0) { - (void) rsm_register_driver(&wrsm_rsmops); - return (error); - } - - /* - * mod_remove() succeeded. We can do cleanup now. - */ - wrsm_nc_cleanup(); - - wrsm_cf_fini(); - - /* unregister call backs with platform specific module */ - (void) wrsmplat_unreg_callbacks(); - - wrsm_memseg_fini(); - - /* Free the soft state info. */ - ddi_soft_state_fini(&wrsm_softstates); - mutex_destroy(&wrsm_attach_mutex); - -#if defined(DEBUG) && defined(DEBUG_LOG) - mutex_destroy(&wrsmdbglock); -#endif - return (0); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - -/* device driver entry points */ - - -/* - * Translate "dev_t" to a pointer to the associated "dev_info_t". - */ -/* ARGSUSED */ -static int -wrsm_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) -{ - dev_t dev; - int instance; - int minor; - wrsm_softstate_t *softsp; - - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_info\n")); - - switch (infocmd) { - case DDI_INFO_DEVT2DEVINFO: - dev = (dev_t)arg; - minor = getminor(dev); - if (minor >= MAX_INSTANCES) - return (DDI_FAILURE); - instance = minor_to_instance[minor]; - if (instance == -1) - return (DDI_FAILURE); - if ((softsp = ddi_get_soft_state(wrsm_softstates, instance)) - == NULL) { - DPRINTF(WRSM_WARN, (CE_WARN, "wrsm_info: " - "ddi_get_soft_state failed for wrsm%d", - instance)); - *result = NULL; - return (DDI_FAILURE); - } - *result = softsp->dip; - return (DDI_SUCCESS); - - case DDI_INFO_DEVT2INSTANCE: - dev = (dev_t)arg; - minor = getminor(dev); - if (minor >= MAX_INSTANCES) - return (DDI_FAILURE); - instance = minor_to_instance[minor]; - if (instance == -1) - return (DDI_FAILURE); - *result = (void *)(uintptr_t)instance; - return (DDI_SUCCESS); - - default: - return (DDI_FAILURE); - } -} - - - -static int -wrsm_do_resume(wrsm_softstate_t *softsp) -{ - int ret; - - switch (softsp->type) { - - case wrsm_admin: - /* do nothing */ - return (DDI_SUCCESS); - - case wrsm_rsm_controller: - ret = wrsm_nc_resume(softsp->minor); - if (ret == WRSM_SUCCESS) { - return (DDI_SUCCESS); - } else { - return (DDI_FAILURE); - } - - default: - ASSERT(softsp->type == wrsm_device); - wrsm_lc_resume(softsp); - return (DDI_SUCCESS); - } -} - - - -static int -wrsm_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) -{ - int instance, link_no; - wrsm_softstate_t *softsp; - wci_sw_link_status_u wci_sw_link_status_tmp; - char *special_name; - int minor; - char *ddi_type; - - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_attach\n")); - - switch (cmd) { - case DDI_ATTACH: - break; - case DDI_RESUME: - instance = ddi_get_instance(devi); - if ((softsp = ddi_get_soft_state(wrsm_softstates, instance)) - == NULL) { - DPRINTF(WRSM_DEBUG, (CE_CONT, - "DDI_RESUME - no device\n")); - return (DDI_FAILURE); - } - ASSERT(softsp->instance == instance); - return (wrsm_do_resume(softsp)); - default: - return (DDI_FAILURE); - } - - /* Allocate soft data structure */ - instance = ddi_get_instance(devi); - - if (ddi_soft_state_zalloc(wrsm_softstates, instance) != DDI_SUCCESS) { - cmn_err(CE_WARN, "wrsm_attach: ddi_soft_state_zalloc failed " - "for wrsm%d", instance); - return (DDI_FAILURE); - } - - if ((softsp = ddi_get_soft_state(wrsm_softstates, instance)) == NULL) { - DPRINTF(WRSM_WARN, (CE_WARN, "wrsm_attach: " - "ddi_get_soft_state failed for wrsm%d", instance)); - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - - /* Set the devi in the soft state */ - softsp->dip = devi; - softsp->instance = instance; - softsp->wci_common_softst.instance = instance; - - - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm%d: devi= 0x%p, softsp=0x%p\n", - instance, (void *)devi, (void *)softsp)); - - if (((minor = ddi_getprop(DDI_DEV_T_ANY, devi, - DDI_PROP_DONTPASS, WRSM_RSM_CTR, -1))) != -1) { - /* - * controller device - */ - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm%d is rsm_controller %d", - instance, minor)); - if (minor >= MAX_INSTANCES) { - cmn_err(CE_WARN, "wrsm_attach: (wrsm%d) - " - "can't support controller id %d " - "(instance >= %d)", - instance, minor, MAX_INSTANCES); - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - if (minor_to_instance[minor] != -1) { - cmn_err(CE_WARN, "wrsm_attach: (wrsm%d) - " - "controller can't use minor dev %d " - "(in use by wrsm instance %d)", - instance, minor, - minor_to_instance[minor]); - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - softsp->type = wrsm_rsm_controller; - ddi_type = DDI_PSEUDO; - special_name = "ctrl"; - - (void) ddi_prop_create(DDI_DEV_T_NONE, devi, DDI_PROP_CANSLEEP, - "pm-hardware-state", (caddr_t)"needs-suspend-resume", - strlen("needs-suspend-resume") + 1); - - } else if ((ddi_getprop(DDI_DEV_T_ANY, devi, - DDI_PROP_DONTPASS, WRSM_ADMIN, -1)) != -1) { - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm%d is the admin dev\n", - instance)); - /* - * admin device - */ - mutex_enter(&wrsm_attach_mutex); - if (wrsm_admin_softsp) { - cmn_err(CE_WARN, "wrsm_attach: an admin dev " - "is already attached (wrsm%d) - not " - "attaching wrsm%d", - wrsm_admin_softsp->instance, instance); - mutex_exit(&wrsm_attach_mutex); - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - wrsm_admin_softsp = softsp; - mutex_exit(&wrsm_attach_mutex); - - softsp->type = wrsm_admin; - ddi_type = NULL; - special_name = "admin"; - - /* - * record this devi in wrsm_ncslice_dip. - */ - - wrsm_ncslice_dip = devi; - minor = MAX_INSTANCES - 1; - } else { - /* - * wci device - */ - /* request safari port id (extended agent id from OBP */ - if ((softsp->portid = - (safari_port_t)ddi_getprop(DDI_DEV_T_ANY, devi, - DDI_PROP_DONTPASS, OBP_WRSM_PORTID, -1)) == -1) { - cmn_err(CE_WARN, "wrsm%d: unable to retrieve %s " - "property", instance, OBP_WRSM_PORTID); - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm%d is the wci at port %d\n", - instance, softsp->portid)); - minor = (MAX_INSTANCES - 2) - instance; - if (minor < 0) { - cmn_err(CE_WARN, "wrsm_attach: (wrsm%d) - " - "instance out of range (>= %d) for wci %d", - instance, MAX_INSTANCES - 1, softsp->portid); - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - if (minor_to_instance[minor] != -1) { - cmn_err(CE_WARN, "wrsm_attach: (wrsm%d) - " - "wci can't use minor dev %d " - "(in use by wrsm instance %d)", - - instance, minor, - minor_to_instance[minor]); - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - - softsp->type = wrsm_device; - ddi_type = DDI_NT_NEXUS; - special_name = ddi_get_name(devi); - - if (wrsm_map_regs(softsp) != DDI_SUCCESS) { - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - - /* copy the regs base address into wci common soft state */ - softsp->wci_common_softst.wci_regs = softsp->wrsm_regs; - - /* pre-calc virtual addr's for ecc registers */ - softsp->wci_dco_ce_cnt_vaddr = (volatile uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_DCO_CE_COUNT); - softsp->wci_dc_esr_vaddr = (volatile uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_DC_ESR); - softsp->wci_dco_state_vaddr = (volatile uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_DCO_STATE); - - softsp->wci_ca_esr_0_vaddr = (volatile uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_CA_ESR_0); - softsp->wci_ra_esr_1_vaddr = (volatile uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_RA_ESR_1); - - softsp->wci_ca_ecc_addr_vaddr = (volatile uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_CA_ECC_ADDRESS); - softsp->wci_ra_ecc_addr_vaddr = (volatile uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_RA_ECC_ADDRESS); - - softsp->wci_cci_esr_vaddr = (volatile uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_CCI_ESR); - - - for (link_no = 0; link_no < WRSM_LINKS_PER_WCI; link_no++) { - - /* pre-calculate virtual address of link error reg */ - softsp->links[link_no].wrsm_link_err_cnt_addr = - ((volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_SW_LINK_ERROR_COUNT + (link_no - * STRIDE_WCI_SW_LINK_ERROR_COUNT))); - /* check if paroli present */ - wci_sw_link_status_tmp.val = *((volatile uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_SW_LINK_STATUS + - (link_no * STRIDE_WCI_SW_LINK_STATUS))); - if (wci_sw_link_status_tmp.bit.paroli_present != - WCI_PAROLI_PRESENT) { - /* no paroli module attached for this link */ - softsp->links[link_no].link_req_state = - lc_not_there; - } else { - softsp->links[link_no].link_req_state = - lc_down; - } - if (ddi_getprop(DDI_DEV_T_ANY, softsp->dip, - DDI_PROP_DONTPASS, "simwci", -1) > 0) { - softsp->links[link_no].link_req_state = - lc_down; - } - } - - /* pre-calc virtual addrs for Performance Counters registers */ - softsp->wci_common_softst.wci_misc_ctr_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_MISC_CTR); - softsp->wci_common_softst.wci_misc_ctr_ctl_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_MISC_CTR_CTL); - softsp->wci_common_softst.wci_cluster_ctr_ctl_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_CLUSTER_CTR_CTL); - softsp->wci_common_softst.wci_lpbk_ctr_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_LPBK_CTR); - softsp->wci_common_softst.wci_lpbk_ctr_ctl_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_LPBK_CTR_CTL); - for (link_no = 0; link_no < WCI_NUM_LINKS; link_no++) { - softsp->wci_common_softst.wci_link_ctr_vaddr[link_no] = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_LINK_CTR + - (link_no * STRIDE_WCI_LINK_CTR)); - softsp->wci_common_softst. - wci_link_ctr_ctl_vaddr[link_no] = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_LINK_CTR_CTL + - (link_no * STRIDE_WCI_LINK_CTR_CTL)); - } - - softsp->wci_common_softst.wci_sfi_sw_ctr_ctl = 0; - /* map the sfari histogrammming counter registers */ - softsp->wci_common_softst.wci_sfi_ctr0_mask_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_SFI_CTR0_MASK); - softsp->wci_common_softst.wci_sfi_ctr0_match_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_SFI_CTR0_MATCH); - softsp->wci_common_softst.wci_sfi_ctr0_match_transaction_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_SFI_CTR0_MATCH_TRANSACTION); - softsp->wci_common_softst.wci_sfi_ctr1_mask_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_SFI_CTR1_MASK); - softsp->wci_common_softst.wci_sfi_ctr1_match_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_SFI_CTR1_MATCH); - softsp->wci_common_softst.wci_sfi_ctr1_match_transaction_vaddr = - (volatile uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_SFI_CTR1_MATCH_TRANSACTION); - - /* - * Create the picN kstats if we are the first instance - * to attach. We use wrsm_attachcnt as a count of how - * many instances have attached. This is protected by - * a lock. - */ - mutex_enter(&wrsm_attach_mutex); - if (wrsm_attachcnt++ == 0) { - /* add misc, lpbk, link picN kstats */ - wci_add_picN_kstats("wrsm"); - wrsm_avg_weight = ddi_getprop(DDI_DEV_T_ANY, - softsp->dip, 0, "wrsm-avg-weight", - WRSM_AVG_WEIGHT); - wrsm_shortterm_interval = - ddi_getprop(DDI_DEV_T_ANY, softsp->dip, 0, - "wrsm-shortterm-interval", - WRSM_SHORTTERM_INTERVAL); - wrsm_shorts_per_longterm = - ddi_getprop(DDI_DEV_T_ANY, softsp->dip, 0, - "wrsm-shorts-per-longterm", - WRSM_SHORTS_PER_LONGTERM); - wrsm_lc_setup_timeout_speeds(); - } - mutex_exit(&wrsm_attach_mutex); - - /* Create the counters kstats for this device */ - wci_add_counters_kstats(&softsp->wci_common_softst, "wrsm"); - - /* Create the wci-links kstat for this device */ - wrsm_add_status_kstat(softsp); - } - - /* This creates the device node */ - softsp->minor = minor; - minor_to_instance[minor] = instance; - if (ddi_create_minor_node(devi, special_name, S_IFCHR, - minor, ddi_type, NULL) == DDI_FAILURE) { - DPRINTF(WRSM_WARN, (CE_WARN, "ddi_create_minor_" - "node failed on wrsm%d", instance)); - minor_to_instance[minor] = -1; - if (softsp->type == wrsm_device) { - wrsm_del_status_kstat(softsp); - wci_del_counters_kstats(&softsp->wci_common_softst); - wrsm_unmap_regs(softsp); - } else if (softsp->type == wrsm_admin) { - wrsm_admin_softsp = NULL; - } - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - - /* wrsm_mutex used with driver open and close */ - mutex_init(&softsp->wrsm_mutex, NULL, MUTEX_DRIVER, NULL); - /* - * cmmu_mutex used during cmmu_update for CMMU_UPDATE_FLUSH flag - * as only one thread at a time may request a FLUSH (sync cmmu's) - */ - mutex_init(&softsp->cmmu_mutex, NULL, MUTEX_DRIVER, NULL); - - /* init to NOT opened - just to be paranoid */ - softsp->open = 0; - if (softsp->type == wrsm_device) { - /* - * create lock to protect the links, the link counters: - * link_req_cntdown, and link_req_cntup - * and to prevent changes made to the config in softsp->config - * while in process of executing config request - */ - mutex_init(&softsp->lc_mutex, NULL, MUTEX_DRIVER, NULL); - - /* - * Create condition var to allow installconfig to go once there - * are no outstanding link_takedown request pending. - * lc_cleanconfig will increment oldlink_waitdown_cnt for each - * takedown request there is in lc_cleanconfig. - * lc_installconfig will cv_wait until oldlink_waitdown_cnt = - * 0. lc_phys_link_down is responsible for signalling - * lc_installconfig if there are takedown request. - */ - cv_init(&softsp->goinstallconfig, NULL, CV_DRIVER, NULL); - - if (wrsm_cf_newwci(softsp, softsp->portid) != WRSM_SUCCESS) { - cmn_err(CE_WARN, "wrsm_attach:cf_newwci failed " - "for wrsm%d", instance); - mutex_destroy(&softsp->wrsm_mutex); - mutex_destroy(&softsp->cmmu_mutex); - cv_destroy(&softsp->goinstallconfig); - mutex_destroy(&softsp->lc_mutex); - ddi_remove_minor_node(devi, NULL); - minor_to_instance[minor] = -1; - wrsm_del_status_kstat(softsp); - wci_del_counters_kstats(&softsp->wci_common_softst); - wrsm_unmap_regs(softsp); - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - } else if (softsp->type == wrsm_rsm_controller) { - /* - * Notify config layer that this RSM controller - * pseudo device is available - */ - if (wrsm_cf_new_controller(softsp->minor, devi) != - WRSM_SUCCESS) { - cmn_err(CE_WARN, "wrsm_attach:cf_new_controller" - " failed for wrsm%d", instance); - mutex_destroy(&softsp->wrsm_mutex); - mutex_destroy(&softsp->cmmu_mutex); - ddi_remove_minor_node(devi, NULL); - minor_to_instance[minor] = -1; - ddi_soft_state_free(wrsm_softstates, instance); - return (DDI_FAILURE); - } - - intr_dist_add(wrsm_redist, devi); - } - - ddi_report_dev(devi); - return (DDI_SUCCESS); -} - - -static int -wrsm_do_suspend(wrsm_softstate_t *softsp) -{ - int ret; - - switch (softsp->type) { - case wrsm_admin: - /* do nothing */ - return (DDI_SUCCESS); - - case wrsm_rsm_controller: - ret = wrsm_nc_suspend(softsp->minor); - if (ret == WRSM_SUCCESS) { - return (DDI_SUCCESS); - } else { - return (DDI_FAILURE); - } - - default: - ASSERT(softsp->type == wrsm_device); - wrsm_lc_suspend(softsp); - return (DDI_SUCCESS); - } -} - - -static int -wrsm_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) -{ - int instance, i; - wrsm_softstate_t *softsp; - uint32_t wci_owner; - - switch (cmd) { - case DDI_SUSPEND: - break; - case DDI_DETACH: - break; - default: - return (DDI_FAILURE); - } - - instance = ddi_get_instance(devi); - DPRINTF(WRSM_DEBUG, (CE_CONT, " wrsm_detach %d cmd %d\n", instance, - cmd)); - if ((softsp = ddi_get_soft_state(wrsm_softstates, instance)) == NULL) - return (DDI_FAILURE); - ASSERT(softsp->instance == instance); - - if (cmd == DDI_SUSPEND) { - return (wrsm_do_suspend(softsp)); - } - - switch (softsp->type) { - - case wrsm_rsm_controller: - if (wrsm_cf_remove_controller(softsp->minor) != WRSM_SUCCESS) { - cmn_err(CE_WARN, "wrsm_detach:cf_remove_controller " - "failed for wrsm%d", instance); - return (DDI_FAILURE); - } - intr_dist_rem(wrsm_redist, devi); - break; - - case wrsm_admin: - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_detach: admin")); - mutex_enter(&wrsm_attach_mutex); - wrsm_admin_softsp = NULL; - mutex_exit(&wrsm_attach_mutex); - break; - - default: - ASSERT(softsp->type == wrsm_device); - - /* find out which controller (if any) this WCI belongs to */ - wci_owner = wrsm_cf_wci_owner(softsp->portid); - - /* - * If this wci has been claimed for external loopback - * testing then the owner will be WRSM_LOOPBACK_ID. - * If this is the case, then just shut down all the - * links. - */ - if (wci_owner == WRSM_LOOPBACK_ID) { - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) - (void) wrsm_lc_loopback_disable(softsp, i); - wrsm_cf_release_wci(softsp->portid); - } - - if (wrsm_cf_remove_wci(softsp) != WRSM_SUCCESS) { - DPRINTF(WRSM_WARN, (CE_WARN, "wsm_detach:cf_remove_wci" - " failed for wrsm%d", instance)); - return (DDI_FAILURE); - } - - /* check if links are all lc_down/lc_not_there */ - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - if (softsp->links[i].link_req_state != lc_down) - if (softsp->links[i].link_req_state != - lc_not_there) { - DPRINTF(WRSM_DEBUG, (CE_CONT, - "link in invalid state")); - (void) wrsm_cf_newwci(softsp, - softsp->portid); - return (DDI_FAILURE); - } - } - - /* LINTED: E_NOP_IF_STMT */ - if (untimeout(softsp->err_timeout_id) == -1) { - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_detach:" - " err_timeout_id not valid\n")); - } - wrsm_del_status_kstat(softsp); - wci_del_counters_kstats(&softsp->wci_common_softst); - - /* - * See if we are the last instance to detach. - * If so, we need to remove the picN kstats - */ - mutex_enter(&wrsm_attach_mutex); - if (--wrsm_attachcnt == 0) { - /* delete misc, lpbk, link picN kstats driver */ - wci_del_picN_kstats(); - } - mutex_exit(&wrsm_attach_mutex); - - - /* LINTED: E_NOP_IF_STMT */ - if (untimeout(softsp->restart_timeout_id) == -1) { - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_detach:" - " restart_timeout_id not valid\n")); - } - cv_destroy(&softsp->goinstallconfig); - mutex_destroy(&softsp->lc_mutex); - wrsm_unmap_regs(softsp); - break; - } - - minor_to_instance[softsp->minor] = -1; - - /* release minor node */ - ddi_remove_minor_node(softsp->dip, NULL); - /* destroy per instance mutex's */ - mutex_destroy(&softsp->wrsm_mutex); - mutex_destroy(&softsp->cmmu_mutex); - /* release soft state */ - ddi_soft_state_free(wrsm_softstates, instance); - /* - * create lock for a per link basis - needed to - * secure state change of softsp->links[i].link_req_state - */ - - return (DDI_SUCCESS); -} - - -/* ARGSUSED */ -static int -wrsm_open(dev_t *devp, int flags, int otyp, cred_t *cred_p) -{ - int instance; - int minor; - int retval = 0; - wrsm_softstate_t *softsp; - - /* Verify we are being opened as a character device */ - if (otyp != OTYP_CHR) - return (EINVAL); - - minor = getminor(*devp); - if (minor >= MAX_INSTANCES) - return (ENXIO); - instance = minor_to_instance[minor]; - if (instance == -1) - return (ENXIO); - - softsp = ddi_get_soft_state(wrsm_softstates, instance); - - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_open:wrsm%d: dev=0x%lx, " - "minor=%d softsp=0x%p\n", instance, *devp, minor, (void *)softsp)); - - /* Verify instance structure */ - if (softsp == NULL) - return (ENXIO); - - switch (softsp->type) { - - case wrsm_device: - mutex_enter(&softsp->wrsm_mutex); /* exclusive open check */ - if (softsp->open == WRSM_OPEN_EXCLUSIVE) { - DPRINTF(WRSM_WARN, (CE_CONT, "wrsm_open: " - "can't open, already opened exclusively")); - retval = EBUSY; - } else if ((flags & FEXCL) && (softsp->open > 0)) { - DPRINTF(WRSM_WARN, (CE_CONT, "wrsm_open: " - "can't open exclusively, already open")); - retval = EBUSY; - } else { - DPRINTF(WRSM_DEBUG, (CE_CONT, " successful open ")); - retval = WRSM_SUCCESS; - if (flags & FEXCL) { - softsp->open = WRSM_OPEN_EXCLUSIVE; - } else { - softsp->open++; - } - } - mutex_exit(&softsp->wrsm_mutex); - break; - - case wrsm_rsm_controller: - /* - * controllers are opened by the wrsm plugin library - * librsmwrsm.so - */ - retval = wrsm_nc_open_controller(minor); - break; - - default: - ASSERT(softsp->type == wrsm_admin); - /* - * admin devices can also be opened, but there is no need - * for an exclusive check. - */ - retval = WRSM_SUCCESS; - break; - } - return (retval); - -} -/* ARGSUSED */ -static int -wrsm_close(dev_t dev, int flag, int otyp, cred_t *cred_p) -{ - int instance; - int minor; - wrsm_softstate_t *softsp; - - /* Verify we are being closed as a character device */ - if (otyp != OTYP_CHR) - return (EINVAL); - - minor = getminor(dev); - if (minor >= MAX_INSTANCES) - return (ENXIO); - instance = minor_to_instance[minor]; - if (instance == -1) - return (ENXIO); - - softsp = ddi_get_soft_state(wrsm_softstates, instance); - - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_close:wrsm%d: dev=0x%lx, " - "minor=%d softsp=0x%p", instance, dev, minor, (void *)softsp)); - - if (softsp == NULL) { - cmn_err(CE_WARN, "wrsm: could not get state structure " - "for instance %d", instance); - return (ENXIO); - } - - if (softsp->type == wrsm_rsm_controller) { - wrsm_nc_close_controller(minor); - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_close:wrsm%d: " - " minor=%d", instance, minor)); - } - mutex_enter(&softsp->wrsm_mutex); - softsp->open = 0; - mutex_exit(&softsp->wrsm_mutex); - - return (WRSM_SUCCESS); -} - - -/* ARGSUSED */ -static int -wrsm_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred_p, - int *rval_p) -{ - struct wrsm_soft_state *softsp; - int minor; - int instance; - int retval; - - minor = getminor(dev); - if (minor >= MAX_INSTANCES) - return (ENXIO); - instance = minor_to_instance[minor]; - if (instance == -1) - return (ENXIO); - - softsp = ddi_get_soft_state(wrsm_softstates, instance); - /* Verify instance structure */ - if (softsp == NULL) - return (ENXIO); - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_ioctl:wrsm%d: dev=0x%lx, " - "softsp=0x%p\n", instance, dev, (void *)softsp)); - - /* - * The 3 types of WCI devices support different ioctls. Use a - * different ioctl handling function for each type, so it's easier - * to fail on an unsupported ioctl. - */ - - switch (softsp->type) { - - case wrsm_admin: - retval = wrsm_cf_admin_ioctl(softsp, cmd, arg, flag, cred_p, - rval_p); - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_ioctl:ret %d rval %d", - retval, *rval_p)); - return (retval); - - case wrsm_rsm_controller: - switch (cmd) { - case WRSM_CTLR_PLUGIN_SMALLPUT: - /* - * the wrsm_smallput_plugin_ioctl is required - * functionality the so that the plugin library can - * perform smallputs. - */ - return (wrsm_smallput_plugin_ioctl(softsp->minor, cmd, - arg, flag, cred_p, rval_p)); - case WRSM_CTLR_PLUGIN_GETLOCALNODE: - /* - * the plugin library needs to know if the export cnode - * is a local node - */ - return (wrsm_nc_getlocalnode_ioctl(softsp->minor, cmd, - arg, flag, cred_p, rval_p)); - default: - /* provided solely for debuging and testing */ - return (wrsm_cf_ctlr_ioctl(softsp->minor, cmd, arg, - flag, cred_p, rval_p)); - } - - default: - ASSERT(softsp->type == wrsm_device); - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm_ioctl - wrsm_device")); - retval = wrsm_device_ioctl(softsp, cmd, arg, flag, cred_p, - rval_p); - return (retval); - } -} - - -/* ARGSUSED */ -static int -wrsm_segmap(dev_t dev, off_t off, struct as *asp, caddr_t *addrp, - off_t len, unsigned int prot, unsigned int maxprot, - unsigned int flags, cred_t *cred) -{ - - /* - * wrsm_segmap is currently handling only controller related segmaps. - * In the event other wrsm type devices (wci or admin( require the - * use of segmap, appropriate ddi calls to fetch the softstate - * structure will be needed. We know the call into the - * wrsm_memseg_segmap will fail for wci or admin devices because the - * minor dev won't map to a valid controller id. - */ - return (wrsm_memseg_segmap(dev, off, asp, addrp, len, prot, maxprot, - flags, cred)); - -} - -/* ARGSUSED */ -static int -wrsm_devmap(dev_t dev, devmap_cookie_t handle, offset_t off, - size_t len, size_t *maplen, uint_t model) -{ - - /* - * wrsm_devmap is currently handling only controller related segmaps. - * In the event other wrsm type devices (wci or admin( require the - * use of segmap, appropriate ddi calls to fetch the softstate - * structure will be needed. We know the call into the - * wrsm_memseg_devmap will fail for wci or admin devices because the - * minor dev won't map to a valid controller id. - */ - return (wrsm_memseg_devmap(dev, handle, off, len, maplen, model)); -} - - - -/*ARGSUSED*/ -static int -wrsm_device_ioctl(wrsm_softstate_t *softsp, int cmd, intptr_t arg, - int flag, cred_t *cred_p, int *rval_p) -{ - int retval = 0; - uint32_t wci_owner; - wrsm_linktest_arg_t linktest; - int linkno; - - DPRINTF(WRSM_DEBUG, (CE_CONT, " in wrsm_device_ioctl\n")); - - /* Only allow privileged users to do this */ - if ((retval = secpolicy_sys_config(cred_p, B_FALSE)) != 0) - return (retval); - - switch (cmd) { - - case WRSM_WCI_LOOPBACK_ON: - retval = wrsm_lc_loopback_enable(softsp, (uint32_t)arg); - break; - - case WRSM_WCI_LOOPBACK_OFF: - retval = wrsm_lc_loopback_disable(softsp, (uint32_t)arg); - break; - - case WRSM_WCI_LINKTEST: - if (ddi_copyin((void *)arg, &linktest, - sizeof (wrsm_linktest_arg_t), flag) != 0) { - retval = EFAULT; - break; - } - if ((retval = wrsm_lc_linktest(softsp, &linktest)) != 0) - break; - if (ddi_copyout(&linktest, (void *)arg, - sizeof (wrsm_linktest_arg_t), flag) != 0) - retval = EFAULT; - break; - - case WRSM_WCI_CLAIM: - retval = wrsm_cf_claim_wci(WRSM_LOOPBACK_ID, softsp->portid); - break; - - case WRSM_WCI_RELEASE: - /* find out which controller (if any) this WCI belongs to */ - wci_owner = wrsm_cf_wci_owner(softsp->portid); - if (wci_owner != WRSM_LOOPBACK_ID) { - retval = EACCES; - break; - } - wrsm_cf_release_wci(softsp->portid); - return (0); - - case WRSM_WCI_LINKUP: - if (ddi_copyin((void *)arg, &linkno, - sizeof (linkno), flag) != 0) { - retval = EFAULT; - break; - } - retval = wrsm_lc_user_linkup(softsp, linkno); - break; - - case WRSM_WCI_LINKDOWN: - if (ddi_copyin((void *)arg, &linkno, - sizeof (linkno), flag) != 0) { - retval = EFAULT; - break; - } - retval = wrsm_lc_user_linkdown(softsp, linkno); - break; - - default: - retval = wrsm_lc_register_ioctl(softsp, cmd, arg, flag, - cred_p, rval_p); - break; - } - - return (retval); -} - -static int -wrsm_map_regs(wrsm_softstate_t *softsp) -{ - volatile unsigned char *sram_vaddr; - - DPRINTF(WRSM_DEBUG, (CE_CONT, "in wrsm_map_regs \n")); - - /* Map in the device registers */ - ASSERT(softsp->type == wrsm_device); - if (ddi_map_regs(softsp->dip, WRSM_REGS, - (caddr_t *)&softsp->wrsm_regs, 0, 0)) { - cmn_err(CE_WARN, "wrsm%d: unable to map register set %d", - softsp->instance, WRSM_REGS); - return (DDI_FAILURE); - } - /* - * since OBP provides SRAM as a register set - * we use ddi_map_regs to get the vaddr - * for the SRAM and then we use va_to_pa to get - * the physical addr. - */ - if (ddi_map_regs(softsp->dip, WRSM_SRAM, - (caddr_t *)&sram_vaddr, 0, 1)) { - cmn_err(CE_WARN, "wrsm%d: unable to map register set %d", - softsp->instance, WRSM_SRAM); - wrsm_unmap_regs(softsp); - return (DDI_FAILURE); - } - if (ddi_dev_regsize(softsp->dip, WRSM_SRAM, - &softsp->sramsize) != DDI_SUCCESS) { - cmn_err(CE_WARN, "wrsm%d: sramsize not" - " available %d", softsp->instance, - WRSM_SRAM); - ddi_unmap_regs(softsp->dip, WRSM_SRAM, (caddr_t *)&sram_vaddr, - 0, 1); - wrsm_unmap_regs(softsp); - return (DDI_FAILURE); - } - /* physical addr for sram */ - softsp->wrsm_sram = (unsigned char *)va_to_pa((void *)sram_vaddr); - DPRINTF(WRSM_DEBUG, (CE_CONT, "wrsm%d sram physical addr %p", - softsp->instance, softsp->wrsm_sram)); - - ddi_unmap_regs(softsp->dip, WRSM_SRAM, (caddr_t *)&sram_vaddr, 0, 1); - return (DDI_SUCCESS); -} - -static void -wrsm_unmap_regs(wrsm_softstate_t *softsp) -{ - DPRINTF(WRSM_DEBUG, (CE_CONT, " unmapped wrsm regs")); - - if (softsp->wrsm_regs) - ddi_unmap_regs(softsp->dip, WRSM_REGS, - (caddr_t *)&softsp->wrsm_regs, 0, 0); -} - -static void -wrsm_add_status_kstat(wrsm_softstate_t *softsp) -{ - struct kstat *status_ksp; - wrsm_status_kstat_t *status_named_ksp; - int instance; - int i; - char tmp_str[100]; - - /* Get the instance */ - instance = softsp->instance; - - if ((status_ksp = kstat_create(WRSM_KSTAT_WRSM, instance, - WRSM_KSTAT_STATUS, - "bus", KSTAT_TYPE_NAMED, - sizeof (wrsm_status_kstat_t) / sizeof (kstat_named_t), - 0)) == NULL) { - cmn_err(CE_WARN, "wci%d: kstat_create failed", instance); - return; - } - - status_named_ksp = (wrsm_status_kstat_t *)(status_ksp->ks_data); - - /* initialize the named kstats */ - kstat_named_init(&status_named_ksp->ks_version, - WRSMKS_WCI_VERSION_NAMED, KSTAT_DATA_UINT64); - - kstat_named_init(&status_named_ksp->controller_id, - WRSMKS_CONTROLLER_ID_NAMED, KSTAT_DATA_UINT32); - - kstat_named_init(&status_named_ksp->portid, - WRSMKS_PORTID, KSTAT_DATA_UINT32); - - kstat_named_init(&status_named_ksp->error_limit, - WRSMKS_ERROR_LIMIT, KSTAT_DATA_UINT32); - - kstat_named_init(&status_named_ksp->errstat_interval, - WRSMKS_ERRSTAT_INTERVAL, KSTAT_DATA_UINT32); - - kstat_named_init(&status_named_ksp->intervals_per_lt, - WRSMKS_INTERVALS_PER_LT, KSTAT_DATA_UINT32); - - kstat_named_init(&status_named_ksp->avg_weight, - WRSMKS_AVG_WEIGHT, KSTAT_DATA_UINT32); - - for (i = 0; i < WCI_NUM_LINKS; i++) { - - (void) sprintf(tmp_str, WRSMKS_VALID_LINK, i); - kstat_named_init(&status_named_ksp->valid_link[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_REMOTE_CNODE_ID, i); - kstat_named_init(&status_named_ksp->remote_cnode_id[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_REMOTE_WNODE, i); - kstat_named_init(&status_named_ksp->remote_wnode_id[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_REMOTE_WCI_PORTID, i); - kstat_named_init(&status_named_ksp->remote_wci_portid[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_REMOTE_LINKNUM, i); - kstat_named_init(&status_named_ksp->remote_linknum[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_LC_LINK_STATE, i); - kstat_named_init(&status_named_ksp->state[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_PHYS_LINK_STATE, i); - kstat_named_init(&status_named_ksp->link_state[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_PHYS_LASER_ENABLE, i); - kstat_named_init(&status_named_ksp->laser[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_PHYS_XMIT_ENABLE, i); - kstat_named_init(&status_named_ksp->xmit_enable[i], - tmp_str, KSTAT_DATA_UINT32); - - (void) sprintf(tmp_str, WRSMKS_LINK_ERR_TAKEDOWNS, i); - kstat_named_init(&status_named_ksp->link_err_takedowns[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_LAST_LINK_ERR_TAKEDOWNS, i); - kstat_named_init(&status_named_ksp->last_link_err_takedowns[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_MAX_LINK_ERR_TAKEDOWNS, i); - kstat_named_init(&status_named_ksp->max_link_err_takedowns[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_AVG_LINK_ERR_TAKEDOWNS, i); - kstat_named_init(&status_named_ksp->avg_link_err_takedowns[i], - tmp_str, KSTAT_DATA_UINT32); - - (void) sprintf(tmp_str, WRSMKS_LINK_DISCON_TAKEDOWNS, i); - kstat_named_init(&status_named_ksp-> - link_disconnected_takedowns[i], tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_LINK_CFG_TAKEDOWNS, i); - kstat_named_init(&status_named_ksp->link_cfg_takedowns[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_LINK_FAILED_BRINGUPS, i); - kstat_named_init(&status_named_ksp->link_failed_bringups[i], - tmp_str, KSTAT_DATA_UINT32); - - (void) sprintf(tmp_str, WRSMKS_LINK_ENABLED, i); - kstat_named_init(&status_named_ksp->link_enabled[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_LINK_INTERVAL_COUNT, i); - kstat_named_init(&status_named_ksp->link_interval_count[i], - tmp_str, KSTAT_DATA_UINT32); - - (void) sprintf(tmp_str, WRSMKS_LINK_ERRORS, i); - kstat_named_init(&status_named_ksp->link_errors[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_LAST_LINK_ERRORS, i); - kstat_named_init(&status_named_ksp->last_link_errors[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_MAX_LINK_ERRORS, i); - kstat_named_init(&status_named_ksp->max_link_errors[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_AVG_LINK_ERRORS, i); - kstat_named_init(&status_named_ksp->avg_link_errors[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_LAST_LT_LINK_ERRORS, i); - kstat_named_init(&status_named_ksp->last_lt_link_errors[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_MAX_LT_LINK_ERRORS, i); - kstat_named_init(&status_named_ksp->max_lt_link_errors[i], - tmp_str, KSTAT_DATA_UINT32); - (void) sprintf(tmp_str, WRSMKS_AVG_LT_LINK_ERRORS, i); - kstat_named_init(&status_named_ksp->avg_lt_link_errors[i], - tmp_str, KSTAT_DATA_UINT32); - - - (void) sprintf(tmp_str, WRSMKS_AUTO_SHUTDOWN_EN, i); - kstat_named_init(&status_named_ksp->auto_shutdown_en[i], - tmp_str, KSTAT_DATA_UINT32); - - } - - kstat_named_init(&status_named_ksp->cluster_error_count, - WRSMKS_CLUSTER_ERROR_COUNT, KSTAT_DATA_UINT64); - - kstat_named_init(&status_named_ksp->uc_sram_ecc_error, - WRSMKS_UC_SRAM_ECC_ERROR, KSTAT_DATA_UINT32); - - kstat_named_init(&status_named_ksp->sram_ecc_errors, - WRSMKS_LAST_SRAM_ECC_ERRORS, KSTAT_DATA_UINT32); - - kstat_named_init(&status_named_ksp->last_sram_ecc_errors, - WRSMKS_LAST_SRAM_ECC_ERRORS, KSTAT_DATA_UINT32); - - kstat_named_init(&status_named_ksp->max_sram_ecc_errors, - WRSMKS_MAX_SRAM_ECC_ERRORS, KSTAT_DATA_UINT32); - - kstat_named_init(&status_named_ksp->avg_sram_ecc_errors, - WRSMKS_AVG_SRAM_ECC_ERRORS, KSTAT_DATA_UINT32); - - /* Save the kstat pointer in the softstate */ - softsp->wrsm_wci_ksp = status_ksp; - - status_ksp->ks_update = wrsm_status_kstat_update; - status_ksp->ks_private = (void *)softsp; - kstat_install(status_ksp); - -} - -static int -wrsm_status_kstat_update(kstat_t *ksp, int rw) -{ - wrsm_status_kstat_t *link_ksp; - wrsm_softstate_t *softsp; - uint32_t controller_id; - - wrsm_wci_data_t *config; - wnodeid_t remote_wnode; - gnid_t remote_gnid; - int num_failed_bringups; - int i; - wci_sw_link_control_u reg; - wci_cluster_error_count_u errors; - - link_ksp = (wrsm_status_kstat_t *)ksp->ks_data; - softsp = (wrsm_softstate_t *)ksp->ks_private; - - mutex_enter(&softsp->lc_mutex); - link_ksp->portid.value.ui32 = softsp->portid; - link_ksp->error_limit.value.ui32 = MAXERRORS; - link_ksp->errstat_interval.value.ui32 = wrsm_shortterm_interval; - link_ksp->intervals_per_lt.value.ui32 = wrsm_shorts_per_longterm; - link_ksp->avg_weight.value.ui32 = wrsm_avg_weight; - - if (softsp->config == NULL) { - /* Device is not part of a controller */ - link_ksp->controller_id.value.ui32 = - (uint32_t)WRSM_KSTAT_NO_CTRLR; - link_ksp->ks_version.value.ui64 = 0; - /* Set all links to be invalid status */ - for (i = 0; i < WCI_NUM_LINKS; i++) { - link_ksp->valid_link[i].value.ui32 = - (uint32_t)WRSMKS_LINK_NOT_PRESENT; - /* - * The rest of these fields should be ignored since - * link is marked "not present", but set to 0 just - * to be sure. - */ - link_ksp->remote_cnode_id[i].value.ui32 = 0; - link_ksp->remote_wnode_id[i].value.ui32 = 0; - link_ksp->remote_wci_portid[i].value.ui32 = 0; - link_ksp->remote_linknum[i].value.ui32 = 0; - link_ksp->state[i].value.ui32 = 0; - link_ksp->laser[i].value.ui32 = 0; - link_ksp->xmit_enable[i].value.ui32 = 0; - link_ksp->link_state[i].value.ui32 = 0; - link_ksp->link_err_takedowns[i].value.ui32 = 0; - link_ksp->last_link_err_takedowns[i].value.ui32 = 0; - link_ksp->max_link_err_takedowns[i].value.ui32 = 0; - link_ksp->avg_link_err_takedowns[i].value.ui32 = 0; - link_ksp->link_disconnected_takedowns[i].value.ui32 = - 0; - link_ksp->link_cfg_takedowns[i].value.ui32 = 0; - link_ksp->link_failed_bringups[i].value.ui32 = 0; - link_ksp->link_interval_count[i].value.ui32 = 0; - link_ksp->link_enabled[i].value.ui32 = 0; - link_ksp->link_errors[i].value.ui32 = 0; - link_ksp->last_link_errors[i].value.ui32 = 0; - link_ksp->max_link_errors[i].value.ui32 = 0; - link_ksp->avg_link_errors[i].value.ui32 = 0; - link_ksp->last_lt_link_errors[i].value.ui32 = 0; - link_ksp->max_lt_link_errors[i].value.ui32 = 0; - link_ksp->avg_lt_link_errors[i].value.ui32 = 0; - link_ksp->auto_shutdown_en[i].value.ui32 = 0; - } - /* Set error kstats to 0 -- not applicable if not in ctrl */ - link_ksp->cluster_error_count.value.ui64 = 0; - link_ksp->uc_sram_ecc_error.value.ui32 = 0; - link_ksp->sram_ecc_errors.value.ui32 = 0; - link_ksp->max_sram_ecc_errors.value.ui32 = 0; - link_ksp->last_sram_ecc_errors.value.ui32 = 0; - link_ksp->avg_sram_ecc_errors.value.ui32 = 0; - - mutex_exit(&softsp->lc_mutex); - return (WRSM_SUCCESS); - } - - if (rw == KSTAT_WRITE) { - mutex_exit(&softsp->lc_mutex); - return (EACCES); - } - - config = softsp->config; - controller_id = wrsm_cf_wci_owner(softsp->portid); - link_ksp->ks_version.value.ui64 = - softsp->ctlr_config->version_stamp; - link_ksp->controller_id.value.ui32 = (uint32_t)controller_id; - - for (i = 0; i < WCI_NUM_LINKS; i++) { - - if (config->links[i].present == 1) { - /* read the wci_sw_controll register */ - wrsm_lc_csr_read(softsp, - ADDR_WCI_SW_LINK_CONTROL + - (i * STRIDE_WCI_SW_LINK_CONTROL), - ®.val); - - link_ksp->valid_link[i].value.ui32 = - (uint32_t)WRSMKS_LINK_PRESENT; - - remote_gnid = config->links[i].remote_gnid; - remote_wnode = config->gnid_to_wnode[remote_gnid]; - - link_ksp->remote_cnode_id[i].value.ui32 = - (uint32_t)config->reachable[remote_wnode]; - - link_ksp->remote_wnode_id[i].value.ui32 = - (uint32_t)remote_wnode; - - link_ksp->remote_wci_portid[i].value.ui32 = - (uint32_t)config->links[i].remote_port; - - link_ksp->remote_linknum[i].value.ui32 = - (uint32_t)config->links[i].remote_link_num; - - link_ksp->state[i].value.ui32 = - (uint32_t)softsp->links[i].link_req_state; - - link_ksp->link_state[i].value.ui32 = - reg.bit.link_state; - - link_ksp->laser[i].value.ui32 = - reg.bit.laser_enable; - - link_ksp->xmit_enable[i].value.ui32 = - reg.bit.xmit_enable; - - num_failed_bringups = - softsp->links[i].num_requested_bringups - - softsp->links[i].num_completed_bringups; - - link_ksp->link_failed_bringups[i].value.ui32 = - num_failed_bringups; - - /* link takedown stats */ - link_ksp->link_err_takedowns[i].value.ui32 = - softsp->links[i].num_err_takedown; - - link_ksp->last_link_err_takedowns[i].value.ui32 = - softsp->links[i].last_err_takedown; - - link_ksp->max_link_err_takedowns[i].value.ui32 = - softsp->links[i].max_err_takedown; - - /* note that avg_err is average * weight */ - link_ksp->avg_link_err_takedowns[i].value.ui32 = - (softsp->links[i].avg_err_takedown / - wrsm_avg_weight); - - link_ksp->link_disconnected_takedowns[i]. - value.ui32 = - softsp->links[i].num_disconnected_takedown; - - link_ksp->link_cfg_takedowns[i].value.ui32 = - softsp->links[i].num_cfg_takedown; - - link_ksp->link_enabled[i].value.ui32 = - softsp->links[i].user_down_requested ? - 0 : 1; - - /* shortterm interval count */ - link_ksp->link_interval_count[i].value.ui32 = - softsp->links[i].interval_count; - - /* shortterm link error stats */ - link_ksp->link_errors[i].value.ui32 = - softsp->links[i].num_errors; - - link_ksp->last_link_errors[i].value.ui32 = - softsp->links[i].shortterm_last_errors; - - link_ksp->max_link_errors[i].value.ui32 = - softsp->links[i].shortterm_max_errors; - - /* note that avg_errors is average * weight */ - link_ksp->avg_link_errors[i].value.ui32 = - (softsp->links[i].shortterm_avg_errors / - wrsm_avg_weight); - - /* longterm link error stats */ - link_ksp->last_lt_link_errors[i].value.ui32 = - softsp->links[i].longterm_last_errors; - - link_ksp->max_lt_link_errors[i].value.ui32 = - softsp->links[i].longterm_max_errors; - - /* note that avg_errors is average * weight */ - link_ksp->avg_lt_link_errors[i].value.ui32 = - (softsp->links[i].longterm_avg_errors - / wrsm_avg_weight); - - - /* set the auto_shutdown_en[i] field */ - link_ksp->auto_shutdown_en[i].value.ui32 = - reg.bit.auto_shut_en; - - } else { - /* This link does not exist */ - link_ksp->valid_link[i].value.ui32 = - (uint32_t)WRSMKS_LINK_NOT_PRESENT; - /* - * The rest of these fields should be ignored since - * link is marked "not present", but set to 0 just - * to be sure. - */ - link_ksp->remote_cnode_id[i].value.ui32 = 0; - link_ksp->remote_wnode_id[i].value.ui32 = 0; - link_ksp->remote_wci_portid[i].value.ui32 = 0; - link_ksp->remote_linknum[i].value.ui32 = 0; - link_ksp->state[i].value.ui32 = 0; - link_ksp->laser[i].value.ui32 = 0; - link_ksp->xmit_enable[i].value.ui32 = 0; - link_ksp->link_state[i].value.ui32 = 0; - link_ksp->link_err_takedowns[i].value.ui32 = 0; - link_ksp->last_link_err_takedowns[i].value.ui32 = 0; - link_ksp->max_link_err_takedowns[i].value.ui32 = 0; - link_ksp->avg_link_err_takedowns[i].value.ui32 = 0; - link_ksp->link_disconnected_takedowns[i].value.ui32 = - 0; - link_ksp->link_cfg_takedowns[i].value.ui32 = 0; - link_ksp->link_failed_bringups[i].value.ui32 = 0; - link_ksp->link_interval_count[i].value.ui32 = 0; - link_ksp->link_enabled[i].value.ui32 = 0; - link_ksp->link_errors[i].value.ui32 = 0; - link_ksp->last_link_errors[i].value.ui32 = 0; - link_ksp->max_link_errors[i].value.ui32 = 0; - link_ksp->avg_link_errors[i].value.ui32 = 0; - link_ksp->last_lt_link_errors[i].value.ui32 = 0; - link_ksp->max_lt_link_errors[i].value.ui32 = 0; - link_ksp->avg_lt_link_errors[i].value.ui32 = 0; - link_ksp->auto_shutdown_en[i].value.ui32 = 0; - } - } - wrsm_lc_csr_read(softsp, ADDR_WCI_CLUSTER_ERROR_COUNT, &errors.val); - - link_ksp->cluster_error_count.value.ui64 = errors.val; - link_ksp->uc_sram_ecc_error.value.ui32 = softsp->uc_sram_ecc_error; - link_ksp->sram_ecc_errors.value.ui32 = softsp->num_sram_ecc_errors; - link_ksp->max_sram_ecc_errors.value.ui32 = - softsp->max_sram_ecc_errors; - link_ksp->last_sram_ecc_errors.value.ui32 = - softsp->last_sram_ecc_errors; - /* note that the avg_sram_ecc_errors is the average * weight */ - link_ksp->avg_sram_ecc_errors.value.ui32 = - (softsp->avg_sram_ecc_errors / wrsm_avg_weight); - - mutex_exit(&softsp->lc_mutex); - - return (WRSM_SUCCESS); -} - - -static void -wrsm_del_status_kstat(wrsm_softstate_t *softsp) -{ - kstat_delete(softsp->wrsm_wci_ksp); -} - - -/* - * translate from dip to network pointer - */ -wrsm_network_t * -wrsm_dip_to_network(dev_info_t *dip) -{ - int instance; - wrsm_softstate_t *softsp; - - instance = ddi_get_instance(dip); - if ((softsp = ddi_get_soft_state(wrsm_softstates, instance)) == NULL) { - return (NULL); - } - if (softsp->type != wrsm_rsm_controller) { - return (NULL); - } - return (wrsm_nc_ctlr_to_network(softsp->minor)); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_getput.c b/usr/src/uts/sun4u/io/wrsm/wrsm_getput.c deleted file mode 100644 index 2dc85fcd50..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_getput.c +++ /dev/null @@ -1,802 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file implements the RSMPI rsm_get* and rsm_put* functions - * in the Wildcat RSM driver. - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/systm.h> -#include <sys/vmsystm.h> -#include <sys/errno.h> -#include <sys/kmem.h> -#include <vm/seg_kmem.h> -#include <vm/page.h> -#include <sys/file.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/ddimapreq.h> - -#include <sys/rsm/rsmpi.h> - -#include <sys/wrsm_common.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_memseg_impl.h> -#include <sys/wrsm_barrier.h> -#include <sys/wci_common.h> -#include <sys/wrsm_intr.h> -#include <sys/wrsm_plugin.h> - -#ifdef DEBUG -extern char platform[]; - - -#define DBG_WARN 0x001 -#define DBG_SMPUT 0x008 -#define DBG_SMPUT_EXTRA 0x080 - -static uint_t wrsm_getput_debug = DBG_WARN; - -#define DPRINTF(a, b) { if (wrsm_getput_debug & a) wrsmdprintf b; } - -#else /* DEBUG */ -#define DPRINTF(a, b) { } -#endif /* DEBUG */ - - -static void -record_error(wrsm_network_t *network, cnodeid_t cnodeid, int err) -{ - wrsm_node_t *node; - - mutex_enter(&network->lock); - network->memseg->transfer_errors++; - network->memseg->last_transfer_error = err; - node = network->nodes[cnodeid]; - if (node) { - node->memseg->transfer_errors++; - node->memseg->last_transfer_error = err; - } - mutex_exit(&network->lock); -} - - - -/* - * Send one or more interrupt requests to cause <len> bytes from buffer - * <buf> be written at offset <offset> into the segment. - */ -static int -small_put(iseginfo_t *iseginfo, off_t offset, uint_t len, caddr_t buf) -{ - wrsm_raw_message_t msgbuf; - wrsm_smallput_msg_t *msg = (wrsm_smallput_msg_t *)&msgbuf; - int writesize; - int put_offset; - int err; -#ifdef DEBUG - uint_t smallput_body_size = WRSM_SMALLPUT_BODY_SIZE; -#endif - DPRINTF(DBG_SMPUT, (CE_CONT, "small_put - segid %d offset 0x%lx " - "len %d\n", iseginfo->segid, offset, len)); - - /* LINTED */ - ASSERT(WRSM_SMALLPUT_BODY_SIZE == 48); - -#ifdef DEBUG - if (strncmp(platform, "SUNW,Ultra", 10) == 0) { - DPRINTF(DBG_SMPUT_EXTRA, - (CE_CONT, "small put buffer is 8 bytes\n")); - smallput_body_size = 8; - } else { - smallput_body_size = 48; - } -#endif - - msg->header.sending_cnode = iseginfo->network->cnodeid; - - while (len) { - /* - * Place the data in putdata buffer so that it is long - * aligned with respect to the segment offset. (Note that - * the start of the putdata buffer is long aligned.) - */ -#ifdef DEBUG - if (len < smallput_body_size) - writesize = len; - else - writesize = smallput_body_size; - - put_offset = offset & WRSM_LONG_MASK; - if (writesize > (smallput_body_size - put_offset)) - writesize = smallput_body_size - put_offset; -#else - if (len < WRSM_SMALLPUT_BODY_SIZE) - writesize = len; - else - writesize = WRSM_SMALLPUT_BODY_SIZE; - - put_offset = offset & WRSM_LONG_MASK; - if (writesize > (WRSM_SMALLPUT_BODY_SIZE - put_offset)) - writesize = WRSM_SMALLPUT_BODY_SIZE - put_offset; -#endif - msg->header.offset = offset; - msg->header.len = writesize; - msg->header.start = put_offset; - - DPRINTF(DBG_SMPUT_EXTRA, - (CE_CONT, "len 0x%x offset 0x%lx writesize %d " - "put_offset %d msg 0x%p msg-buf-start 0x%p " - "put-paddr 0x%lx\n", - len, offset, writesize, put_offset, (void *)msg, - (void *)&(msg->putdata[put_offset]), - va_to_pa(iseginfo->kernel_mapping.small_put_offset))); - bcopy(buf, &(msg->putdata[put_offset]), writesize); - - err = wrsm_intr_send(iseginfo->network, - iseginfo->kernel_mapping.small_put_offset, - iseginfo->cnodeid, msg, 0, WRSM_INTR_WAIT_DEFAULT, 0); - if (err) { - DPRINTF(DBG_SMPUT_EXTRA, - (CE_CONT, "SMALL PUT err is %d", err)); - mutex_enter(&iseginfo->lock); - iseginfo->transfer_errors++; - iseginfo->last_transfer_error = RSMERR_BARRIER_FAILURE; - mutex_exit(&iseginfo->lock); - return (RSMERR_BARRIER_FAILURE); - } - - len -= writesize; - offset += writesize; - buf += writesize; - } - - return (RSM_SUCCESS); -} - - -int -wrsmrsm_put(rsm_memseg_import_handle_t im_memseg, off_t offset, void *datap, - size_t length) -{ - importseg_t *importseg = (importseg_t *)im_memseg; - iseginfo_t *iseginfo; - caddr_t dp = datap; - uint_t partial_cacheline; - uint_t num_cachelines; - int err = RSM_SUCCESS; - caddr_t segptr; - rsm_barrier_t barrier; - wrsm_network_t *network; - cnodeid_t cnodeid; - wrsm_raw_message_t msgbuf; - wrsm_smallput_msg_t *msg = (wrsm_smallput_msg_t *)&msgbuf; - boolean_t did_small_puts = B_FALSE; - - if ((err = wrsm_lock_importseg(importseg, RW_READER)) != - RSM_SUCCESS) { - return (err); - } - - if (importseg->unpublished) { - rw_exit(&importseg->rw_lock); - return (RSMERR_CONN_ABORTED); - } - - iseginfo = importseg->iseginfo; - - if (!(iseginfo->perms & RSM_PERM_WRITE)) { - rw_exit(&importseg->rw_lock); - return (RSMERR_PERM_DENIED); - } - - if (iseginfo->size < (offset + length)) { - rw_exit(&importseg->rw_lock); - return (RSMERR_BAD_LENGTH); - } - - if (length == 0) { - rw_exit(&importseg->rw_lock); - return (RSM_SUCCESS); - } - - if (!importseg->kernel_user) { - importseg->kernel_user = B_TRUE; - mutex_enter(&iseginfo->lock); - if (!iseginfo->kernel_users) { - err = create_segment_mapping(iseginfo); - if (err) { - iseginfo->transfer_errors++; - iseginfo->last_transfer_error = err; - mutex_exit(&iseginfo->lock); - network = iseginfo->network; - cnodeid = iseginfo->cnodeid; - rw_exit(&importseg->rw_lock); - record_error(network, cnodeid, err); - return (err); - } - } - iseginfo->kernel_users++; - mutex_exit(&iseginfo->lock); - } - - - if (importseg->barrier_mode == RSM_BARRIER_MODE_IMPLICIT) { - if ((err = wrsm_open_barrier_region(importseg, &barrier)) != - RSM_SUCCESS) { - rw_exit(&importseg->rw_lock); - return (err); - } - } - - /* - * handle partial line write at start of buffer - */ - if (offset & WRSM_CACHELINE_MASK) { - partial_cacheline = WRSM_CACHELINE_SIZE - - (offset & WRSM_CACHELINE_MASK); - if (partial_cacheline > length) - partial_cacheline = length; - - did_small_puts = B_TRUE; - msg->header.offset = 0; - msg->header.len = 0; - msg->header.start = 0; - err = small_put(iseginfo, offset, partial_cacheline, dp); - if (err) { - network = iseginfo->network; - cnodeid = iseginfo->cnodeid; - rw_exit(&importseg->rw_lock); - record_error(network, cnodeid, err); - - if (importseg->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - (void) wrsm_close_barrier(&barrier); - } - /* - * guarantee that any outstanding small puts have - * finished - */ - (void) wrsm_intr_send(importseg->iseginfo->network, - importseg->iseginfo->kernel_mapping. - small_put_offset, - importseg->iseginfo->cnodeid, - msg, 0, WRSM_INTR_WAIT_DEFAULT, 0); - return (err); - } - - length -= partial_cacheline; - dp += partial_cacheline; - offset += partial_cacheline; - - if (length == 0) { - int intr_err; - /* - * this put call is finished - */ - rw_exit(&importseg->rw_lock); - /* - * guarantee that any outstanding small - * puts have finished - */ - if (importseg->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - err = wrsm_close_barrier(&barrier); - } - intr_err = wrsm_intr_send(importseg->iseginfo->network, - importseg->iseginfo->kernel_mapping. - small_put_offset, - importseg->iseginfo->cnodeid, - msg, 0, WRSM_INTR_WAIT_DEFAULT, 0); - /* - * Return the barrier error, or if that succeeded, - * the send error if there was one. - */ - err = err ? err : intr_err; - return (err); - } - } - - /* - * handle cacheline sized writes - */ - num_cachelines = length >> WRSM_CACHELINE_SHIFT; - DPRINTF(DBG_SMPUT, (CE_CONT, "putting %d cachelines\n", - num_cachelines)); - if (num_cachelines) { - segptr = iseginfo->kernel_mapping.seg + offset; - - DPRINTF(DBG_SMPUT, (CE_CONT, "doing all at once\n")); - wrsm_blkwrite(dp, segptr, num_cachelines); - - length -= (num_cachelines * WRSM_CACHELINE_SIZE); - dp += (num_cachelines * WRSM_CACHELINE_SIZE); - offset += (num_cachelines * WRSM_CACHELINE_SIZE); - } - - /* - * handle partial line write at end of buffer - */ - if (length) { - did_small_puts = B_TRUE; - msg->header.offset = 0; - msg->header.len = 0; - msg->header.start = 0; - err = small_put(iseginfo, offset, length, dp); - if (err) { - network = iseginfo->network; - cnodeid = iseginfo->cnodeid; - rw_exit(&importseg->rw_lock); - record_error(network, cnodeid, err); - - /* - * guarantee that any outstanding small puts have - * finished - */ - (void) wrsm_intr_send(importseg->iseginfo->network, - importseg->iseginfo->kernel_mapping. - small_put_offset, - importseg->iseginfo->cnodeid, - msg, 0, WRSM_INTR_WAIT_DEFAULT, 0); - if (importseg->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - (void) wrsm_close_barrier(&barrier); - } - return (err); - } - } - - rw_exit(&importseg->rw_lock); - - if (did_small_puts) { - /* - * guarantee that any outstanding small puts have finished - */ - (void) wrsm_intr_send(importseg->iseginfo->network, - importseg->iseginfo->kernel_mapping.small_put_offset, - importseg->iseginfo->cnodeid, - msg, 0, WRSM_INTR_WAIT_DEFAULT, 0); - } - - if (importseg->barrier_mode == RSM_BARRIER_MODE_IMPLICIT) { - err = wrsm_close_barrier(&barrier); - } - - return (err); -} - -/* ARGSUSED */ -int -wrsmrsm_put8(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint8_t *datap, ulong_t rep_cnt, boolean_t byte_swap) -{ - /* Since Wildcat is SPARC-only, don't need to worry about byte_swap */ - return (wrsmrsm_put(im_memseg, offset, datap, rep_cnt)); -} - -/* ARGSUSED */ -int -wrsmrsm_put16(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint16_t *datap, ulong_t rep_cnt, boolean_t byte_swap) -{ - /* Check alignment */ - if ((((uint64_t)datap) & 0x1) != 0 || - (((uint64_t)offset) & 0x1) != 0) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - /* Since Wildcat is SPARC-only, don't need to worry about byte_swap */ - return (wrsmrsm_put(im_memseg, offset, datap, 2 * rep_cnt)); -} - -/* ARGSUSED */ -int -wrsmrsm_put32(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint32_t *datap, ulong_t rep_cnt, boolean_t byte_swap) -{ - /* Check alignment */ - if ((((uint64_t)datap) & 0x3) != 0 || - (((uint64_t)offset) & 0x3) != 0) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - /* Since Wildcat is SPARC-only, don't need to worry about byte_swap */ - return (wrsmrsm_put(im_memseg, offset, datap, 4 * rep_cnt)); -} - -/* ARGSUSED */ -int -wrsmrsm_put64(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint64_t *datap, ulong_t rep_cnt, boolean_t byte_swap) -{ - /* Check alignment */ - if ((((uint64_t)datap) & 0x7) != 0 || - (((uint64_t)offset) & 0x7) != 0) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - /* Since Wildcat is SPARC-only, don't need to worry about byte_swap */ - return (wrsmrsm_put(im_memseg, offset, datap, 8 * rep_cnt)); -} - - -static int -small_get(iseginfo_t *iseginfo, off_t offset, uint_t len, caddr_t buf) -{ - wrsm_raw_message_t cachelinebuf; - caddr_t aligned_cacheline = (caddr_t)&cachelinebuf; - off_t read_offset; - uint_t cacheline_offset; - caddr_t seg; - - DPRINTF(DBG_SMPUT, (CE_CONT, "small_get - segid %d offset 0x%lx " - "len %d\n", iseginfo->segid, offset, len)); - - cacheline_offset = offset & WRSM_CACHELINE_MASK; - ASSERT((cacheline_offset + len) <= WRSM_CACHELINE_SIZE); - - seg = iseginfo->kernel_mapping.seg; - - read_offset = offset & ~WRSM_CACHELINE_MASK; - wrsm_blkread(seg + read_offset, aligned_cacheline, 1); - - bcopy(aligned_cacheline + cacheline_offset, buf, len); - return (RSM_SUCCESS); -} - - - -int -wrsmrsm_get(rsm_memseg_import_handle_t im_memseg, off_t offset, void *datap, - size_t length) -{ - importseg_t *importseg = (importseg_t *)im_memseg; - iseginfo_t *iseginfo; - caddr_t dp = datap; - uint_t partial_cacheline; - uint_t num_cachelines; - int err; - caddr_t seg; - rsm_barrier_t barrier; - wrsm_network_t *network; - cnodeid_t cnodeid; - - DPRINTF(DBG_SMPUT, (CE_CONT, - "wrsmrsm_get - importseg 0x%p offset 0x%lx len %ld\n", - (void *)importseg, offset, length)); - - if ((err = wrsm_lock_importseg(importseg, RW_READER)) != - RSM_SUCCESS) { - return (err); - } - - iseginfo = importseg->iseginfo; - - if (importseg->unpublished) { - mutex_enter(&iseginfo->lock); - iseginfo->transfer_errors++; - iseginfo->last_transfer_error = RSMERR_CONN_ABORTED; - mutex_exit(&iseginfo->lock); - network = iseginfo->network; - cnodeid = iseginfo->cnodeid; - rw_exit(&importseg->rw_lock); - record_error(network, cnodeid, RSMERR_CONN_ABORTED); - return (RSMERR_CONN_ABORTED); - } - - if (!importseg->kernel_user) { - importseg->kernel_user = B_TRUE; - mutex_enter(&iseginfo->lock); - if (!iseginfo->kernel_users) { - err = create_segment_mapping(iseginfo); - if (err) { - iseginfo->transfer_errors++; - iseginfo->last_transfer_error = err; - mutex_exit(&iseginfo->lock); - network = iseginfo->network; - cnodeid = iseginfo->cnodeid; - rw_exit(&importseg->rw_lock); - record_error(network, cnodeid, err); - return (err); - } - } - iseginfo->kernel_users++; - mutex_exit(&iseginfo->lock); - } - - if (!(iseginfo->perms & (rsm_permission_t)RSM_PERM_READ)) { - mutex_enter(&iseginfo->lock); - iseginfo->transfer_errors++; - iseginfo->last_transfer_error = RSMERR_PERM_DENIED; - mutex_exit(&iseginfo->lock); - network = iseginfo->network; - cnodeid = iseginfo->cnodeid; - rw_exit(&importseg->rw_lock); - record_error(network, cnodeid, RSMERR_PERM_DENIED); - return (RSMERR_PERM_DENIED); - } - - if (iseginfo->size < (offset + length)) { - /* barrier doesn't record this type of error */ - rw_exit(&importseg->rw_lock); - return (RSMERR_BAD_LENGTH); - } - - if (length == 0) { - rw_exit(&importseg->rw_lock); - return (RSM_SUCCESS); - } - - if (importseg->barrier_mode == RSM_BARRIER_MODE_IMPLICIT) { - if ((err = wrsm_open_barrier_region(importseg, &barrier)) != - RSM_SUCCESS) { - return (err); - } - } - - /* - * handle partial line read at start of buffer - */ - if (offset & WRSM_CACHELINE_MASK) { - partial_cacheline = WRSM_CACHELINE_SIZE - - (offset & WRSM_CACHELINE_MASK); - if (partial_cacheline > length) - partial_cacheline = length; - - if ((err = small_get(iseginfo, offset, partial_cacheline, dp)) - != 0) { - rw_exit(&importseg->rw_lock); - if (importseg->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - (void) wrsm_close_barrier(&barrier); - } - return (err); - } - - length -= partial_cacheline; - dp += partial_cacheline; - offset += partial_cacheline; - - if (length == 0) { - rw_exit(&importseg->rw_lock); - if (importseg->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - return (wrsm_close_barrier(&barrier)); - } else { - return (RSM_SUCCESS); - } - } - } - - /* - * handle cacheline sized reads - */ - num_cachelines = length >> WRSM_CACHELINE_SHIFT; - if (num_cachelines) { - seg = importseg->iseginfo->kernel_mapping.seg + offset; - - DPRINTF(DBG_SMPUT, (CE_CONT, - "full cacheline read offset 0x%lx num_cachelines %d\n", - offset, num_cachelines)); - - wrsm_blkread( - seg, - dp, - num_cachelines); - length -= (num_cachelines * WRSM_CACHELINE_SIZE); - dp += (num_cachelines * WRSM_CACHELINE_SIZE); - offset += (num_cachelines * WRSM_CACHELINE_SIZE); - } - - /* - * handle partial line read at end of buffer - */ - if (length) { - if ((err = small_get(iseginfo, offset, length, dp)) != 0) { - rw_exit(&importseg->rw_lock); - if (importseg->barrier_mode == - RSM_BARRIER_MODE_IMPLICIT) { - (void) wrsm_close_barrier(&barrier); - } - return (err); - } - } - - rw_exit(&importseg->rw_lock); - - if (importseg->barrier_mode == RSM_BARRIER_MODE_IMPLICIT) { - err = wrsm_close_barrier(&barrier); - } - - return (err); -} - -/* ARGSUSED */ -int -wrsmrsm_get8(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint8_t *datap, ulong_t rep_cnt, boolean_t byte_swap) -{ - /* Since Wildcat is SPARC-only, don't need to worry about byte_swap */ - return (wrsmrsm_get(im_memseg, offset, (void *)datap, rep_cnt)); -} - -/* ARGSUSED */ -int -wrsmrsm_get16(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint16_t *datap, ulong_t rep_cnt, boolean_t byte_swap) -{ - /* Check alignment */ - if ((((uint64_t)datap) & 0x1) != 0 || - (((uint64_t)offset) & 0x1) != 0) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - /* Since Wildcat is SPARC-only, don't need to worry about byte_swap */ - return (wrsmrsm_get(im_memseg, offset, (void *)datap, 2 * rep_cnt)); -} - -/* ARGSUSED */ -int -wrsmrsm_get32(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint32_t *datap, ulong_t rep_cnt, boolean_t byte_swap) -{ - /* Check alignment */ - if ((((uint64_t)datap) & 0x3) != 0 || - (((uint64_t)offset) & 0x3) != 0) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - /* Since Wildcat is SPARC-only, don't need to worry about byte_swap */ - return (wrsmrsm_get(im_memseg, offset, (void *)datap, 4 * rep_cnt)); -} - -/* ARGSUSED */ -int -wrsmrsm_get64(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint64_t *datap, ulong_t rep_cnt, boolean_t byte_swap) -{ - /* Check alignment */ - if ((((uint64_t)datap) & 0x7) != 0 || - (((uint64_t)offset) & 0x7) != 0) { - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - /* Since Wildcat is SPARC-only, don't need to worry about byte_swap */ - return (wrsmrsm_get(im_memseg, offset, (void *)datap, 8 * rep_cnt)); -} - -/* - * Called from wrsm_ioctl() when invoked on a driver instance which - * has a type of wrsm_rsm_controller and cmd = WRSM_CTLR_PLUGIN_SMALLPUT - */ -/* ARGSUSED */ -int -wrsm_smallput_plugin_ioctl(int minor, int cmd, intptr_t arg, int mode, - cred_t *cred_p, int *rval_p) -{ - wrsm_raw_message_t msgbuf; - msg_pluginput_args_t pluginmsg; - msg_pluginput_args32_t pluginmsg32; - iseginfo_t *iseginfo; - int err; - int datamodel; - - wrsm_smallput_msg_t *msg = (wrsm_smallput_msg_t *)&msgbuf; - - DPRINTF(DBG_SMPUT, (CE_CONT, "wrsm_smallput_plugin_ioctl")); - - - datamodel = ddi_model_convert_from(mode & FMODELS); - switch (datamodel) { - case DDI_MODEL_ILP32: - if (ddi_copyin((void *)arg, (char *)&pluginmsg32, - sizeof (msg_pluginput_args32_t), mode) != 0) { - DPRINTF(DBG_SMPUT, (CE_WARN, "wrsm_smallput_plugin_" - "ioctl ddi_copyin failed 32 bit ")); - return (EFAULT); - } - DPRINTF(DBG_SMPUT, (CE_CONT, "wrsm_smallput_plugin_ioctl 32 " - "app. segid %d length %ld cnode %ld", - pluginmsg32.segment_id, pluginmsg32.len, - pluginmsg32.remote_cnodeid)); - - pluginmsg.segment_id = pluginmsg32.segment_id; - pluginmsg.len = pluginmsg32.len; - pluginmsg.remote_cnodeid = pluginmsg32.remote_cnodeid; - pluginmsg.offset = pluginmsg32.offset; - - if (ddi_copyin((void *)(uintptr_t)pluginmsg32.buf, msg->putdata, - pluginmsg32.len, mode) - != 0) { - DPRINTF(DBG_SMPUT, (CE_WARN, "wrsm_smallput_plugin_" - "ioctl ddicopyin msg buffer failed ")); - return (EFAULT); - } - - break; - default: - if (ddi_copyin((void *)arg, (char *)&pluginmsg, - sizeof (msg_pluginput_args_t), mode) != 0) { - DPRINTF(DBG_SMPUT, (CE_WARN, "wrsm_smallput_plugin_" - "ioctl ddi_copyin failed 64 bit ")); - return (EFAULT); - } - DPRINTF(DBG_SMPUT, (CE_CONT, "wrsm_smallput_plugin_ioctl 64 " - " bit app. segid %d length %ld cnode %ld", - pluginmsg.segment_id, pluginmsg.len, - pluginmsg.remote_cnodeid)); - - if (ddi_copyin((void *)pluginmsg.buf, msg->putdata, - pluginmsg.len, mode) - != 0) { - DPRINTF(DBG_SMPUT, (CE_WARN, "wrsm_smallput_plugin_" - "ioctl ddicopyin msg buffer failed ")); - return (EFAULT); - } - - break; - } - - - /* - * Get iseginfo for this controller, cnodeid, and segment_id. - * iseginfo is returned locked. - */ - err = wrsm_memseg_remote_node_to_iseginfo(minor, - (cnodeid_t)pluginmsg.remote_cnodeid, pluginmsg.segment_id, - &iseginfo); - - if (err != RSM_SUCCESS) { - return (err); - } - - /* - * RSM Kernel Agent prevents iseginfo being removed (it holds - * an importseg on behalf of the caller), so it is not necessary - * to hold iseginfo->lock during the call to small_put(). - */ - mutex_exit(&iseginfo->lock); - - err = small_put(iseginfo, pluginmsg.offset, pluginmsg.len, - (caddr_t)msg->putdata); - if (err != RSM_SUCCESS) { - return (EIO); - } - /* send 0 length, 0 buf to assure put finished */ - msg->header.offset = 0; - msg->header.len = 0; - msg->header.start = 0; - (void) wrsm_intr_send(iseginfo->network, - iseginfo->kernel_mapping.small_put_offset, iseginfo->cnodeid, - msg, 0, WRSM_INTR_WAIT_DEFAULT, 0); - - return (0); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_intr.c b/usr/src/uts/sun4u/io/wrsm/wrsm_intr.c deleted file mode 100644 index e0de44a476..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_intr.c +++ /dev/null @@ -1,2802 +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" - -/* - * This file implements the RSMPI sendq functions in the Wildcat RSM - * driver. In addition, the driver uses Wildcat interrupts to communicate; - * this file also implements the driver internal interrupt generation and - * receiving functions. - */ - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/processor.h> -#include <sys/dmv.h> -#include <sys/cpuvar.h> -#include <sys/param.h> -#include <sys/sysconf.h> -#include <sys/machsystm.h> -#include <sys/errno.h> -#include <sys/ivintr.h> -#include <sys/promif.h> -#include <sys/cpu_module.h> -#include <sys/atomic.h> /* For cas atomics */ - -#include <sys/wrsm_intr.h> -#include <sys/wrsm_intr_impl.h> -#include <sys/wrsm_cmmu.h> -#include <sys/wrsm_plat.h> -#include <sys/sysmacros.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_lc.h> -#include <sys/wci_regs.h> -#include <sys/wci_common.h> -#include <sys/wrsm_session.h> -#include <sys/wrsm_transport.h> -#include <sys/wrsm_memseg_impl.h> - -#ifdef DEBUG -extern char platform[]; - -static wrsm_network_t *networks[WRSM_MAX_CNODES] = {0}; -#endif /* DEBUG */ - -/* - * Manifest Constants and Macros - */ -#define WRSM_INTR_MAX_DRAINERS 8 -#define WRSM_INTR_MAX_TARGETS 8 - -#define RECVQ_HIGHWATER_MARGIN 10 - -#define BIT31SET (((uint_t)1) << 31) -#define MAKE_INTR_DIST_MONDO(safari_id, index) \ - (int)(BIT31SET | ((safari_id) << 16) | (index)) -#define NULL_INTR_DIST_MONDO 0 /* Valid mondo has bit 31 set */ -#define CPUID_TO_DESTNODE(cpu) ((cpu >> 5) & 0xf) -#define CPUID_TO_DESTDEV(cpu) (cpu & 0x1f) - -#define INVALID_SAFARI_ID (uint_t)-1 - -#define INFINITY LONG_MAX - -extern kmutex_t intr_dist_lock; -extern int servicing_interrupt(void); - -/* - * The following macros define a DPRINTF macro which can be used to enable - * or disable various levels of logging for this module. - */ -#ifdef DEBUG - -#define INTRDBG 0x1 -#define INTRWARN 0x2 -#define INTRERR 0x4 -#define INTRTRACE 0x8 -#define INTRCESR 0x10 -static uint_t wrsm_intr_debug = INTRERR; - -#define DPRINTF(a, b) { if (wrsm_intr_debug & a) wrsmdprintf b; } - -#else /* DEBUG */ - -#define DPRINTF(a, b) - -#endif /* DEBUG */ - -#define DTRC(s) DPRINTF(INTRTRACE, (CE_CONT, s)) -#define WARN(s) DPRINTF(INTRWARN, (CE_WARN, s)) -#define NOTE(s) DPRINTF(INTRDBG, (CE_CONT, s)) - -/* - * The recvq_table entries can contain recvq pointers, or when not in use, - * contain an overlaid free list. As a result, you can't just compare - * the recvq pointer to NULL, since it may in fact be a free list index. - * To differentiate, we purposely set the LSB of the entry while it's - * free (and store the free list info in the upper bits). - * Macro MONDO2RECVQ does the shifting/oring to put a free list mondo - * in the aforementioned format. - * Macro RECVQ2MONDO extracts the mondo value from the aforementioned format. - * Macro RECVQ_VALID tests to see if the item is indeed a valid recvq pointer. - */ -#define CAST_MONDO2RECVQ(mondo) \ - (wrsm_intr_recvq_t *)(uintptr_t)(((mondo) << 16) | 0x1) -#define CAST_RECVQ2MONDO(recvq) (((uint_t)(uintptr_t)(recvq)) >> 16) -#define RECVQ_VALID(recvq) ((recvq) && (((uint64_t)(recvq)) & 0x1) == 0) - -/* - * Message Structures - */ - -/* Format of message for WRSM_MSG_INTR_RECVQ_CREATE request */ -typedef struct recvq_create_req { - wrsm_message_header_t header; - rsm_intr_t service; - rsm_intr_pri_t prio; - size_t qdepth; -} recvq_create_req_t; - -/* Format of message for WRSM_MSG_INTR_RECVQ_CREATE_RESPONSE */ -typedef struct recvq_create_rsp { - wrsm_message_header_t header; - int retval; /* RSM_SUCCESS or errno */ - off_t nc_off; /* Offset into comm ncslice page */ - uint64_t qid; /* ID of remote recvq */ - uint_t mondo; /* CMMU mondo of remote recvq */ -} recvq_create_rsp_t; - -/* Format of message for WRSM_MSG_INTR_RECVQ_CONFIG request */ -typedef struct recvq_config_req { - wrsm_message_header_t header; - uint64_t qid; - uint_t mondo; - size_t new_qdepth; -} recvq_config_req_t; - -/* Format of message for WRSM_MSG_INTR_RECVQ_CONFIG_RESPONSE */ -typedef struct recvq_config_rsp { - wrsm_message_header_t header; - int retval; /* RSM_SUCCESS or errno */ -} recvq_config_rsp_t; - -/* Format of message for WRSM_MSG_INTR_RECVQ_DESTROY request */ -typedef struct recvq_destroy { - wrsm_message_header_t header; - uint64_t qid; - uint_t mondo; - rsm_intr_t service; -} recvq_destroy_t; - -/* - * Local functions - */ - -/* Handler functions */ -static void -handler_init(wrsm_intr_handler_t *handler, rsm_intr_hand_t func, - rsm_intr_hand_arg_t arg, cnode_bitmask_t cnodes, - rsm_controller_object_t *controller_obj) -{ - DTRC("handler_init"); - handler->func = func; - handler->arg = arg; - handler->controller_obj = controller_obj; - WRSMSET_COPY(cnodes, handler->cnodes); -} - -/* ARGSUSED */ -static void -handler_fini(wrsm_intr_handler_t *handler) -{ - DTRC("handler_fini"); - /* Nothing to do */ -} - -/* ARGSUSED */ -static void -handler_print(wrsm_intr_handler_t *handler) -{ - DPRINTF(INTRDBG, (CE_CONT, - " handler 0x%p func 0x%p arg 0x%p ctlr-obj 0x%p next 0x%p", - (void *)handler, - (void *)handler->func, - (void *)handler->arg, - (void *)handler->controller_obj, - (void *)handler->next)); -} - -/* Calls back the client with an interrupt event */ -static rsm_intr_hand_ret_t -handler_callback(wrsm_intr_handler_t *handler, rsm_intr_q_op_t q_op, - cnodeid_t from_cnode, void *is_data, size_t is_size) -{ - rsm_intr_hand_ret_t retval = RSM_INTR_HAND_UNCLAIMED; - DTRC("handler_callback"); - - handler_print(handler); - - /* If source is allowed to send to this handler, do callback */ - if (WRSM_IN_SET(handler->cnodes, from_cnode)) { - retval = (*handler->func)(handler->controller_obj, - q_op, - (rsm_addr_t)from_cnode, - is_data, - is_size, - handler->arg); - } - return (retval); -} - -/* Service functions */ - -/* Initializes a service */ -static void -service_init(wrsm_intr_service_t *service, wrsm_network_t *net, rsm_intr_t t) -{ - DTRC("service_init"); - bzero(service, sizeof (wrsm_intr_service_t)); - service->net = net; - service->type = t; - mutex_init(&service->handler_mutex, NULL, MUTEX_DRIVER, NULL); - mutex_init(&service->recvq_mutex, NULL, MUTEX_DRIVER, NULL); -} - -static void -service_fini(wrsm_intr_service_t *service) -{ - /* Destroy the handler list */ - wrsm_intr_handler_t *p = service->handler_list; - DTRC("service_fini"); - - while (p) { - wrsm_intr_handler_t *next = p->next; - handler_fini(p); - kmem_free(p, sizeof (wrsm_intr_handler_t)); - p = next; - } - mutex_destroy(&service->handler_mutex); - mutex_destroy(&service->recvq_mutex); -} - -static void -service_print(wrsm_intr_service_t *service) -{ - wrsm_intr_handler_t *h; - - DPRINTF(INTRDBG, (CE_CONT, " service 0x%p id=%d ctlr=%d\n", - (void *)service, - service->type, - service->net->rsm_ctlr_id)); - - DPRINTF(INTRDBG, (CE_CONT, " service handler list:\n")); - for (h = service->handler_list; h; h = h->next) { - handler_print(h); - } -} - -/* Adds a recvq to the service's linked list of recvqs */ -static void -service_add_recvq(wrsm_intr_service_t *service, wrsm_intr_recvq_t *recvq) -{ - DTRC("service_add_recvq"); - - mutex_enter(&service->recvq_mutex); - recvq->service_next = service->recvq_list; - service->recvq_list = recvq; - service_print(service); - mutex_exit(&service->recvq_mutex); -} - -/* Finds and removes a recvq from the service's linked list of recvqs */ -static void -service_rem_recvq(wrsm_intr_service_t *service, wrsm_intr_recvq_t *recvq) -{ - wrsm_intr_recvq_t *p; - DTRC("service_rem_recvq"); - - mutex_enter(&service->recvq_mutex); - /* If recvq is first on list, handle special */ - if (service->recvq_list == recvq) { - service->recvq_list = recvq->service_next; - } else { - for (p = service->recvq_list; p; p = p->service_next) { - if (p->service_next == recvq) { - p->service_next = recvq->service_next; - break; - } - } - } - mutex_exit(&service->recvq_mutex); -} - -/* Adds a handler to the linked list of handlers for this service */ -static void -service_add_handler(wrsm_intr_service_t *service, wrsm_intr_handler_t *handler) -{ - wrsm_intr_handler_t *p; - DTRC("service_add_handler"); - mutex_enter(&service->handler_mutex); - handler->next = NULL; - - /* Add to end of list */ - if (service->handler_list == NULL) { - service->handler_list = handler; - } else { - /* Advance to last node in list */ - for (p = service->handler_list; p->next; p = p->next) - ; - p->next = handler; - } - - service_print(service); - - mutex_exit(&service->handler_mutex); -} - -/* Removes and returns a handler from the service's handler list */ -static wrsm_intr_handler_t * -service_rem_handler(wrsm_intr_service_t *service, - rsm_intr_hand_t func, rsm_intr_hand_arg_t arg) -{ - wrsm_intr_handler_t *handler = NULL; - DTRC("service_rem_handler"); - - mutex_enter(&service->handler_mutex); - if (service->handler_list == NULL) { - handler = NULL; - } else if (service->handler_list->func == func && - service->handler_list->arg == arg) { - /* If this is the first handler in the list, handle special */ - handler = service->handler_list; - service->handler_list = handler->next; - handler->next = NULL; - } else { - wrsm_intr_handler_t *p; - for (p = service->handler_list; p->next; p = p->next) { - if (p->next->func == func && p->next->arg == arg) { - handler = p->next; - p->next = handler->next; - handler->next = NULL; - break; - } - } - } - mutex_exit(&service->handler_mutex); - return (handler); -} - -/* Distributes a packet to all handlers registered for this service. */ -static void -service_callback(wrsm_intr_service_t *service, void *buffer, size_t size, - cnodeid_t from_cnode) -{ - wrsm_intr_handler_t *h; - - DTRC("service_callback"); - - mutex_enter(&service->handler_mutex); /* Lock the handler list */ - for (h = service->handler_list; h; h = h->next) { - if (handler_callback(h, RSM_INTR_Q_OP_RECEIVE, from_cnode, - buffer, size) == RSM_INTR_HAND_CLAIMED_EXCLUSIVE) { - break; - } - } - mutex_exit(&service->handler_mutex); -} - - -/* Initializes the service list */ -static void -service_list_init(wrsm_interrupt_t *intr, wrsm_network_t *net) -{ - uint_t i; - DTRC("service_list_init"); - - for (i = 0; i < WRSM_INTR_TYPE_MAX; i++) { - service_init(&intr->services[i], net, i); - } -} - -/* Destroys the service list */ -static void -service_list_fini(wrsm_interrupt_t *intr) -{ - uint_t i; - DTRC("service_list_fini"); - - for (i = 0; i < WRSM_INTR_TYPE_MAX; i++) { - service_fini(&intr->services[i]); - } -} - - -/* Recvq Functions */ - -/* Initializes/Refreshes the recvq CMMU entry */ -static void -recvq_cmmu_update(wrsm_intr_recvq_t *recvq, boolean_t set_invalid, - boolean_t set_user_error) -{ - wrsm_cmmu_t cmmu; - uint_t cpu_id = recvq->target->cpu_id; - boolean_t user_err; - - ASSERT(recvq); - ASSERT(recvq->net); - - /* - * If the high water mark is 0, then the user must have created - * a queue of length 0. Force the user error to be set right - * from the start. This would probably only be done in testing, - * but the spec doesn't say it's not allowed. - */ - user_err = (set_user_error || recvq->high_water_mark == 0) ? - B_TRUE : B_FALSE; - - cmmu.entry_0.val = 0; - cmmu.entry_1.val = 0; - cmmu.entry_0.bit.count_enable = B_FALSE; - cmmu.entry_0.bit.large_page = B_FALSE; - cmmu.entry_0.bit.user_err = user_err; - cmmu.entry_0.bit.writable = B_TRUE; - cmmu.entry_0.bit.from_all = (recvq->exportseg ? B_TRUE : B_FALSE); - cmmu.entry_0.bit.valid = (set_invalid ? B_FALSE : B_TRUE); - cmmu.entry_0.bit.type = CMMU_TYPE_INTERRUPT; - cmmu.entry_0.bit.from_node = recvq->from_cnode; - cmmu.entry_1.intr.mondo = recvq->cmmu_mondo; - cmmu.entry_1.intr.lpa_page_2 = (cpu_id<<1); - - wrsm_cmmu_update(recvq->net, &cmmu, recvq->cmmu_index, - CMMU_UPDATE_ALL | CMMU_UPDATE_FLUSH); -} - -/* Destroys the receive queue contents */ -static void -recvq_fini(wrsm_network_t *net, wrsm_intr_recvq_t *recvq) -{ - wrsm_cmmu_tuple_t *tuples; - - wrsm_interrupt_t *intr; - DTRC("recvq_fini"); - - intr = net->interrupt; - ASSERT(mutex_owned(&intr->mutex)); - - /* Set the CMMU entry to invalid */ - recvq_cmmu_update(recvq, B_TRUE, B_FALSE); - - /* Cross trap to make sure trap handler isn't running */ - wrsmplat_xt_sync(recvq->target->cpu_id); - - /* Take recvq mutex to ensure drainer isn't using it */ - mutex_enter(&recvq->mutex); - - tuples = recvq->tuples; - - /* Use cmmu_mondo to free recvq table entry */ - recvq_table_free_entry(intr, recvq->cmmu_mondo); - cv_broadcast(&intr->resource_cv); - - /* Remove from target and service lists */ - target_rem_recvq(recvq->target, recvq); - service_rem_recvq(recvq->service, recvq); - - /* Delete packet ring */ - if (recvq->packet_ring) { - kmem_free(recvq->packet_ring, - recvq->packet_ring_info.info.size * - sizeof (wrsm_intr_packet_t)); - } - - /* If it's on a drainer list, can't free yet, let drainer do it */ - if ((recvq->packet_ring_info.info.head != - recvq->packet_ring_info.info.tail) || - (recvq->drainer_next != NULL) || - recvq->in_use) { - recvq->delete_me = B_TRUE; - mutex_exit(&recvq->mutex); - } else { - DPRINTF(INTRTRACE, (CE_CONT, - "freeing recvq 0x%p\n", (void *)recvq)); - mutex_exit(&recvq->mutex); - mutex_destroy(&recvq->mutex); - /* else, free the receive queue now */ - kmem_free(recvq, sizeof (wrsm_intr_recvq_t)); - } - - /* Free the CMMU tuples */ - wrsm_cmmu_free(net, 1, tuples); -} - -/* Retrieves a packet from the recvq. Returns size of packet */ -static size_t -recvq_get_packet(wrsm_intr_recvq_t *recvq, wrsm_intr_packet_t buffer, - uint32_t *num_packets) -{ - wrsm_intr_packet_ring_union_t new; - wrsm_intr_packet_ring_union_t old; - volatile uint64_t *p = &(recvq->packet_ring_info.val); - int tail = recvq->packet_ring_info.info.tail; - uint64_t *data = (uint64_t *)&recvq->packet_ring[tail]; - size_t size = sizeof (wrsm_intr_packet_t); - - *num_packets = 0; - - /* If packet ring is empty, return 0 */ - if (recvq->packet_ring_info.info.tail == - recvq->packet_ring_info.info.head) { - return (0); - } - /* - * For user interrupts, first word contains size in - * lower 6 bits, garbage in rest of word. Advance - * start of data by 1 64-bit word so user sees only - * the user data portion of the interrupt. - */ - if (recvq->user_interrupt) { - size = (uint_t)(data[0] & 0x3f); - data++; - } - - /* Copy data from recvq to a caller's buffer */ - bcopy(data, buffer, size); - - /* Atomically increment the tail */ - do { - /* Keep reading info until lock bit not set */ - old.val = *p; - if (old.info.lock) { - continue; - } - *num_packets = (old.info.tail <= old.info.head) ? - (old.info.head - old.info.tail) : - (old.info.size - (old.info.tail - old.info.head)); - new.val = old.val; - new.info.tail = (new.info.tail + 1) % new.info.size; - if (cas64((uint64_t *)p, old.val, new.val) == old.val) - break; - /* LINTED: E_CONST_EXPR */ - } while (1); - - return (size); -} - -static void -recvq_callback(wrsm_intr_recvq_t *recvq) -{ - wrsm_intr_service_t *service; - wrsm_intr_packet_t buf; - size_t size; - uint32_t num_packets; - cnodeid_t from_cnode; - - mutex_enter(&recvq->mutex); - - ASSERT(recvq->in_use == B_FALSE); - ASSERT(recvq->drainer_next != NULL); - - if (recvq->delete_me) { - /* recvq_was deleted while on the pending service list */ - DPRINTF(INTRTRACE, (CE_CONT, - "freeing recvq in recvq_callback 0x%p\n", - (void *)recvq)); - mutex_exit(&recvq->mutex); - mutex_destroy(&recvq->mutex); - kmem_free(recvq, sizeof (wrsm_intr_recvq_t)); - return; - } - - /* - * in_use prevents recvq_fini from removing recvq even after the - * last packet is removed from the packet ring and drainer_next is - * NULL. - */ - recvq->in_use = B_TRUE; - - /* - * Allow recvq to be queued to pending service queue again by - * setting drainer_next to NULL. This must be allowed prior to - * emptying the packet ring. If drainer_next were NULLed after - * processing the packet ring, we could have a race, where - * recvq_callback thinks it has processed all packets, then a trap - * comes in and queues a packet, then recvq_callback sets - * drainer_next to NULL. This would leave the new packet - * unprocessed, with recvq not in the pending service queue. - */ - recvq->drainer_next = NULL; - - NOTE("Servicing recvq: "); - recvq_print(recvq); - - service = recvq->service; - from_cnode = recvq->from_cnode; - - for (size = recvq_get_packet(recvq, buf, &num_packets); - num_packets > 0; - size = recvq_get_packet(recvq, buf, &num_packets)) { - - mutex_exit(&recvq->mutex); - /* Callback handlers for this service */ - service_callback(service, buf, size, from_cnode); - mutex_enter(&recvq->mutex); - /* - * At the point where recvq->delete_me is set, it is - * guaranteed that no further traps for this recvq will - * arrive, as the cmmu entry was invalidated and traps were - * flushed. This means the recvq won't be added to the - * pending service queue, and the state of drainer_next - * will not change to non-NULL after revq->delete_me is - * set. This means we can check the value of drainer_next - * here. - * - * If drainer_next is not NULL, this means this recvq was - * added back onto the pending service queue since this - * function set drainer_next to NULL. In this case, the - * recvq will be deleted during the servicing of this recvq - * the next time it is taken off the pending service queue. - */ - if (recvq->delete_me) { - /* recvq was deleted during the callback */ - if (recvq->drainer_next == NULL) { - DPRINTF(INTRTRACE, (CE_CONT, - "freeing recvq post service_callback " - "in recvq_callback 0x%p\n", - (void *)recvq)); - mutex_exit(&recvq->mutex); - mutex_destroy(&recvq->mutex); - kmem_free(recvq, sizeof (wrsm_intr_recvq_t)); - return; - } else { - /* don't process any more packets */ - break; - } - - } else if (num_packets >= recvq->high_water_mark) { - recvq_cmmu_update(recvq, B_FALSE, B_FALSE); - } - } - - recvq->in_use = B_FALSE; - mutex_exit(&recvq->mutex); -} - -/* ARGSUSED */ -static void -recvq_print(wrsm_intr_recvq_t *recvq) -{ - DPRINTF(INTRDBG, (CE_CONT, - " recvq 0x%X from=%d head=%d tail=%d target=%d drainer=0x%X " - "drainer_next=%p", - recvq->cmmu_mondo, - recvq->from_cnode, - recvq->packet_ring_info.info.head, - recvq->packet_ring_info.info.tail, - recvq->target->index, - recvq->drainer->drainer_inum, - (void *)recvq->drainer_next)); -} - -/* Recvq Table Functions */ - -/* Initialized the recvq tables */ -/* ARGSUSED */ -static void -recvq_table_init(wrsm_interrupt_t *intr) -{ - DTRC("recvq_table_init"); - /* Allocate first table, since we'll eventually need it */ - recvq_table_alloc_table(intr, 0); -} - -/* Deletes the recvq table and all the recvqs */ -static void -recvq_table_fini(wrsm_interrupt_t *intr, wrsm_network_t *net) -{ - uint_t i; - uint_t j; - DTRC("recvq_table_fini"); - - for (i = 0; i < WRSM_INTR_RECVQ_TABLES; i++) { - /* Once we hit a null table, we can break */ - if (intr->recvq_tables[i] == NULL) { - break; - } - /* For each pointer in table, kill it */ - for (j = 0; j < WRSM_INTR_RECVQ_TABLE_SIZE; j++) { - wrsm_intr_recvq_t *recvq = (*intr->recvq_tables[i])[j]; - if (RECVQ_VALID(recvq)) { - wrsm_intr_destroy_recvq(net, recvq); - } - } - kmem_free(intr->recvq_tables[i], - WRSM_INTR_RECVQ_TABLES_ARRAY_SIZE); - } -} - -/* Prints all recvqs */ -static void -recvq_table_print(wrsm_interrupt_t *intr) -{ - uint_t i; - uint_t j; - - mutex_enter(&intr->mutex); - for (i = 0; i < WRSM_INTR_RECVQ_TABLES; i++) { - /* Once we hit a null table, we can break */ - if (intr->recvq_tables[i] == NULL) { - break; - } - /* For each pointer in table, kill it */ - for (j = 0; j < WRSM_INTR_RECVQ_TABLE_SIZE; j++) { - wrsm_intr_recvq_t *recvq = (*intr->recvq_tables[i])[j]; - if (RECVQ_VALID(recvq)) { - recvq_print(recvq); - } - } - } - mutex_exit(&intr->mutex); -} - -/* Allocates and initializes a recvq_table array */ -static void -recvq_table_alloc_table(wrsm_interrupt_t *intr, unsigned table) -{ - unsigned i; - int mondo; - - DPRINTF(INTRTRACE, (CE_NOTE, "recvq_table_alloc_table(%d)", table)); - - ASSERT(intr->recvq_tables[table] == NULL); - /* - * In order to provide fast identification of the next freerecvq_table - * entry, the unused entries in the recvq_table contain the cmmu_mondo - * of the next free entry in a linked free list sort of fashion. In - * other words, at initialization, entry 0 contains the number 1, - * entry 1 contains the number 2, etc. When entry 1 is allocated, - * for example, entry 0 is updated to contain a 2 since 2 is now the - * first free entry. Since it is not allowed to use - * cmmu_mondo == 0, entry 0 is used as the implicit head of the linked - * list. When someone wants to allocate a cmmu entry, we look at the - * value in entry 0, which is the mondo of the first free entry. We - * then allocate that entry, and whatever value was in that location - * goes into entry 0 to maintain the free list. - */ - - /* Calculate mondo of first entry in this table */ - mondo = WRSM_INTR_RECVQ_TABLE_SIZE * table; - intr->recvq_tables[table] = - kmem_zalloc(WRSM_INTR_RECVQ_TABLES_ARRAY_SIZE, KM_SLEEP); - for (i = 0; i < WRSM_INTR_RECVQ_TABLE_SIZE; i++) { - mondo++; /* Point to next (free) entry for free list */ - (*intr->recvq_tables[table])[i] = CAST_MONDO2RECVQ(mondo); - } -} - -/* Allocates a recvq table entry. Returns cmmu_mondo, or 0 if out of space. */ -static int -recvq_table_alloc_entry(wrsm_interrupt_t *intr) -{ - int free_mondo; - unsigned table; - unsigned index; - - DTRC("recvq_table_alloc_entry"); - - ASSERT(mutex_owned(&intr->mutex)); - - /* - * The recvq table entries are overlaid with a linked list. Entry - * (0,0) contains the mondo of the next free entry. That - * entry contains the mondo of the second free entry, and so forth. - * If the next free mondo points beyond the last table, then we're - * out of entries. - */ - free_mondo = CAST_RECVQ2MONDO((*intr->recvq_tables[0])[0]); - table = WRSM_MONDO2TABLE(free_mondo); - index = WRSM_MONDO2INDEX(free_mondo); - - /* Check for empty */ - if (table >= WRSM_INTR_RECVQ_TABLES) { - WARN("recvq_table_alloc_entry: out of memory"); - return (NULL); - } - - /* - * We only allocate tables when needed, so it's possible the table - * doesn't exist yet. If it doesn't, allocate it. - */ - if (intr->recvq_tables[table] == NULL) { -#ifdef DEBUG - if (index != 0) { - DPRINTF(INTRERR, (CE_WARN, - "alloc_entry table %d: index = %d != 0", - table, index)); - } -#endif /* DEBUG */ - recvq_table_alloc_table(intr, table); - } - - /* Make head of list point at "next" free entry */ - (*intr->recvq_tables[0])[0] = (*intr->recvq_tables[table])[index]; - - /* Be nice and null the new entry */ - (*intr->recvq_tables[table])[index] = NULL; - - return (free_mondo); -} - -/* Places a recvq_table_entry back on the free list */ -static void -recvq_table_free_entry(wrsm_interrupt_t *intr, int cmmu_mondo) -{ - unsigned table = WRSM_MONDO2TABLE(cmmu_mondo); - unsigned index = WRSM_MONDO2INDEX(cmmu_mondo); - - ASSERT(mutex_owned(&intr->mutex)); -#ifdef DEBUG - if (!RECVQ_VALID((*intr->recvq_tables[table])[index])) { - DPRINTF(INTRERR, (CE_WARN, "recvq_table_free_entry: " - "attempt to free an unused recvq entry: %d", - cmmu_mondo)); - return; - } -#endif /* DEBUG */ - - /* Places this entry at head of free list */ - (*intr->recvq_tables[table])[index] = (*intr->recvq_tables[0])[0]; - (*intr->recvq_tables[0])[0] = CAST_MONDO2RECVQ(cmmu_mondo); -} - -/* Sets the recvq table entry based on the cmmu_mondo */ -static void -recvq_table_set(wrsm_interrupt_t *intr, int cmmu_mondo, - wrsm_intr_recvq_t *recvq) -{ - unsigned table = WRSM_MONDO2TABLE(cmmu_mondo); - unsigned index = WRSM_MONDO2INDEX(cmmu_mondo); - wrsm_intr_recvq_table_t *ptable = intr->recvq_tables[table]; - DTRC("recvq_table_set"); - - ASSERT(ptable); -#ifdef DEBUG - if ((*ptable)[index]) { - DPRINTF(INTRERR, (CE_WARN, "recvq_table_set: " - "attempt to set in-use entry %d", cmmu_mondo)); - } -#endif /* DEBUG */ - (*ptable)[index] = recvq; -} - -/* Target functions */ - -/* Initializes a target structure */ -static void -target_init(wrsm_intr_target_t *target, wrsm_intr_drainer_t *drainer, - uint32_t target_index) -{ - DPRINTF(INTRTRACE, (CE_CONT, "target_init: %d", target_index)); - DPRINTF(INTRDBG, (CE_CONT, " Got drainer 0x%X", - drainer->drainer_inum)); - - bzero(target, sizeof (wrsm_intr_target_t)); - target->index = target_index; - target->intr_dist_mondo = NULL_INTR_DIST_MONDO; - target->drainer = drainer; - target->cpu_id = INVALID_SAFARI_ID; -} - -/* Destroys a target struct */ -static void -target_fini(wrsm_intr_target_t *target) -{ - DPRINTF(INTRTRACE, (CE_CONT, "target_fini %d", target->index)); -} - -/* - * Repeats the intr_dist_cpu process if the safari port id of the WCI - * changes, thus changing the interrupt distribution mondo. This - * may happen if the WCI is removed from the controller. If we didn't - * repeat the intr_dist_cpu with a new intr_dist_mondo, and the WCI - * is moved to a new controller, that new controller would have - * conflicting intr_dist_mondos. Also, we must use a valid WCI - * id, since other devices/drivers may also use the interrupt - * distribution mechanism. - */ -static void -target_readd_cpu(wrsm_network_t *net, wrsm_intr_target_t *target) -{ - safari_port_t safid = net->interrupt->wci_safari_port; - - if (safid == INVALID_SAFARI_ID) { - target->intr_dist_mondo = NULL_INTR_DIST_MONDO; - } else { - target->intr_dist_mondo = - MAKE_INTR_DIST_MONDO(safid, target->index); - target->cpu_id = intr_dist_cpuid(); - } - - /* Retarget all the CMMU entries for this target */ - target_retarget(net, target); -} - -/* - * This function is called by OS when a CPU we're targeted at is removed. - */ -void -wrsm_redist(void *dip) -{ - wrsm_intr_target_t *start; - wrsm_intr_target_t *target; - wrsm_network_t *net; - wrsm_interrupt_t *intr; - - /* Use dip to get wrsm_network_t, then interrupt structure */ - net = wrsm_dip_to_network(dip); - if (net == NULL) { - return; - } - - if (net->cmmu == NULL) { - return; - } - - intr = net->interrupt; - if (intr == NULL) { - return; - } - - mutex_enter(&intr->mutex); - - if (intr->targets == NULL) { - mutex_exit(&intr->mutex); - return; - } - - start = target = intr->targets; - - do { - /* Save new cpu id */ - target->cpu_id = intr_dist_cpuid(); - - DPRINTF(INTRDBG, (CE_CONT, "wrsm_redist cpu: 0x%04X", - target->cpu_id)); - - /* Retarget all the CMMU entries for this target */ - target_retarget(net, target); - - target = target->next; - - } while (target != start); - - mutex_exit(&intr->mutex); -} - -/* - * Updates the CMMU entries for a given target, presumable because the - * target->cpu_id has changed. - */ -static void -target_retarget(wrsm_network_t *net, wrsm_intr_target_t *target) -{ - wrsm_intr_recvq_t *p; - wrsm_cmmu_t cmmu; - processorid_t cpu_id = target->cpu_id; - uint64_t lpa_page_2 = (cpu_id<<1); - - /* - * Walk list of recvq's pointed at this target, and change cmmu - * entries to point to new cpu - */ - for (p = target->recvq_list; p; p = p->target_next) { - DPRINTF(INTRDBG, (CE_CONT, " Update cmmu entry %u", - p->cmmu_index)); - - /* Read the current cmmu entry */ - wrsm_cmmu_read(net, &cmmu, p->cmmu_index); - - /* Set user error bit */ - cmmu.entry_0.bit.user_err = B_TRUE; - wrsm_cmmu_update(net, &cmmu, p->cmmu_index, - CMMU_UPDATE_USERERROR | CMMU_UPDATE_FLUSH); - - /* - * Do a cross trap to the target CPU to make sure that any - * in-process interrupts are complete. - */ - wrsmplat_xt_sync(target->cpu_id); - - /* Update CMMU to the new target cpu and clear user err bit */ - cmmu.entry_1.intr.lpa_page_2 = lpa_page_2; - cmmu.entry_0.bit.user_err = B_FALSE; - wrsm_cmmu_update(net, &cmmu, p->cmmu_index, - CMMU_UPDATE_INTRDEST | - CMMU_UPDATE_USERERROR | - CMMU_UPDATE_FLUSH); - } -} - -/* Adds a recvq to the target's linked list of recvqs. Must own intr->mutex */ -static void -target_add_recvq(wrsm_intr_target_t *target, wrsm_intr_recvq_t *recvq) -{ - DTRC("target_add_recvq"); - - recvq->target_next = target->recvq_list; - target->recvq_list = recvq; -} - -/* Finds and removes a recvq from linked list. Must own intr->mutex */ -static void -target_rem_recvq(wrsm_intr_target_t *target, wrsm_intr_recvq_t *recvq) -{ - wrsm_intr_recvq_t *p; - DTRC("target_rem_recvq"); - - /* If recvq is first on list, handle special */ - if (target->recvq_list == recvq) { - target->recvq_list = recvq->target_next; - } else { - for (p = target->recvq_list; p; p = p->target_next) { - if (p->target_next == recvq) { - p->target_next = recvq->target_next; - break; - } - } - } -} - -/* Prints interesting info about the target, mostly for debug */ -/* ARGSUSED */ -static void -target_print(wrsm_intr_target_t *target) -{ - DPRINTF(INTRDBG, (CE_CONT, - " target %d cpuid=%d mondo=0x%X drainer=0x%X", - target->index, - target->cpu_id, - target->intr_dist_mondo, - target->drainer->drainer_inum)); -} - -/* Builds the list of targets and places it in the interrupt structure */ -static void -target_list_init(wrsm_interrupt_t *intr) -{ - int num_targets = MIN(ncpus, WRSM_INTR_MAX_TARGETS); - int i; - DTRC("target_list_init"); - - for (i = 0; i < num_targets; i++) { - /* Allocate space for each target */ - wrsm_intr_target_t *target = - kmem_alloc(sizeof (wrsm_intr_target_t), KM_SLEEP); - /* Pick a drainer */ - wrsm_intr_drainer_t *drainer = drainer_list_get_next(intr); - /* Init the target structure */ - target_init(target, drainer, i); - - - if (intr->targets == NULL) { - /* If list is empty, point at this item */ - (intr->targets) = target; - } else { - /* Otherwise, point at whoever was next */ - target->next = (intr->targets)->next; - } - /* Point head of list at this new item */ - (intr->targets)->next = target; - } -} - -/* Deletes the entire target list */ -static void -target_list_fini(wrsm_interrupt_t *intr) -{ - wrsm_intr_target_t *first = intr->targets; - wrsm_intr_target_t *target = first; - DTRC("target_list_fini"); - - ASSERT(first); /* Target list should never be empty */ - - /* Repeat until we loop around to first again */ - do { - /* Remember which comes next */ - wrsm_intr_target_t *next = target->next; - - /* Now it's safe to kill it */ - target_fini(target); - kmem_free(target, sizeof (wrsm_intr_target_t)); - - /* We're done when next points back to original target */ - target = next; - } while (target != first); - - intr->targets = NULL; -} - -/* Repeats the intr_dist_cpu process for all targets with new wci */ -static void -target_list_readd_cpu(wrsm_network_t *net) -{ - wrsm_intr_target_t *first = net->interrupt->targets; - wrsm_intr_target_t *target = first; - DTRC("target_list_readd"); - - ASSERT(first); /* Target list should never be empty */ - - /* Repeat until we loop around to first again */ - do { - target_readd_cpu(net, target); - target = target->next; - } while (target != first); -} - -static wrsm_intr_target_t * -target_list_get_next(wrsm_interrupt_t *intr) -{ - wrsm_intr_target_t *target; - DTRC("target_list_get_next"); - - ASSERT(mutex_owned(&intr->mutex)); - ASSERT(intr->targets != NULL); - - target = intr->targets; - intr->targets = (intr->targets)->next; - return (target); -} - -/* Prints the entire target list */ -static void -target_list_print(wrsm_interrupt_t *intr) -{ - wrsm_intr_target_t *start = intr->targets; - wrsm_intr_target_t *target = start; - - DPRINTF(INTRDBG, (CE_CONT, " target_list:")); - mutex_enter(&intr->mutex); - do { - target_print(target); - target = target->next; - } while (target != start); - mutex_exit(&intr->mutex); -} - -/* Drainer functions */ - -static int -drainer_init(wrsm_intr_drainer_t *drainer) -{ - DTRC("drainer_init"); - - bzero(drainer, sizeof (wrsm_intr_drainer_t)); - - drainer->drainer_inum = - add_softintr(PIL_6, (softintrfunc)drainer_handler, - (caddr_t)drainer, SOFTINT_ST); - if (drainer->drainer_inum == 0) { - DPRINTF(INTRERR, (CE_WARN, "add_softintr() failed")); - return (EAGAIN); - } - DPRINTF(INTRDBG, (CE_CONT, "soft_vec: 0x%X\n", drainer->drainer_inum)); - drainer->drainer_psl = (wrsm_intr_recvq_t *)WRSM_INTR_PSL_IDLE; - - return (0); -} - -/* Prints interesting info about a drainer */ -/* ARGSUSED */ -static void -drainer_print(wrsm_intr_drainer_t *drainer) -{ - DPRINTF(INTRDBG, (CE_CONT, " drainer 0x%X", drainer->drainer_inum)); -} - -/* Destroys a drainer */ -static void -drainer_fini(wrsm_intr_drainer_t *drainer) -{ - DTRC("drainer_fini"); - (void) rem_softintr(drainer->drainer_inum); -} - -/* Returns the old psl pointer, atomically setting new psl to empty */ -static wrsm_intr_recvq_t * -drainer_get_psl(wrsm_intr_drainer_t *drainer) -{ - wrsm_intr_recvq_t *sl; - wrsm_intr_recvq_t *oldval; - do { - /* Copy psl to sl */ - sl = drainer->drainer_psl; - /* If psl hasn't changed, oldval will be sl, psl will be 0 */ - oldval = (wrsm_intr_recvq_t *)casptr( - &drainer->drainer_psl, - sl, - WRSM_INTR_PSL_EMPTY); - } while (oldval != sl); - /* The following shouldn't happen, but just to be sure... */ - if (sl == (wrsm_intr_recvq_t *)WRSM_INTR_PSL_IDLE) { - WARN("drainer_get_psl: psl was IDLE"); - sl = WRSM_INTR_PSL_EMPTY; - } - return (sl); -} - -/* If psl is empty, set it to idle and return true; else return false */ -static boolean_t -drainer_psl_empty(wrsm_intr_drainer_t *drainer) -{ - return (WRSM_INTR_PSL_EMPTY == - casptr(&drainer->drainer_psl, - WRSM_INTR_PSL_EMPTY, - (void *)WRSM_INTR_PSL_IDLE)); -} - -/* Drainer soft interrupt handler */ -static uint_t -drainer_handler(caddr_t arg) -{ - wrsm_intr_recvq_t *sl; - wrsm_intr_drainer_t *drainer = (wrsm_intr_drainer_t *)arg; - wrsm_intr_recvq_t *recvq; - - DTRC("drainer_handler"); - ASSERT(drainer); - - drainer_print(drainer); - - /* Swap service list with pending service list */ - do { - sl = drainer_get_psl(drainer); - - /* While there's something on the service list */ - while (sl != WRSM_INTR_PSL_EMPTY) { - /* Get head of service list */ - recvq = sl; - - /* Update service list to point to next recvq */ - sl = recvq->drainer_next; - ASSERT(recvq != sl); - - /* If we've reached the end, set to empty */ - if (sl == (wrsm_intr_recvq_t *)WRSM_INTR_PSL_IDLE) { - sl = WRSM_INTR_PSL_EMPTY; - } - /* - * Process the recvq - this also sets drainer_next - * to NULL - */ - recvq_callback(recvq); - } - } while (!drainer_psl_empty(drainer)); - return (DDI_INTR_CLAIMED); -} - -/* Drainer List functions */ - -/* Builds the list of drainers and places it in the interrupt structure */ -static int -drainer_list_init(wrsm_interrupt_t *intr) -{ - int retval = 0; - int i; - int num_drainers = MIN(ncpus, WRSM_INTR_MAX_DRAINERS); - DTRC("drainer_list_init"); - - intr->drainers = NULL; - for (i = 0; i < num_drainers; i++) { - wrsm_intr_drainer_t *drainer = - kmem_alloc(sizeof (wrsm_intr_drainer_t), KM_SLEEP); - int retval = drainer_init(drainer); - - if (retval) { - kmem_free(drainer, sizeof (wrsm_intr_drainer_t)); - break; - } - - if (intr->drainers == NULL) { - /* If list is empty, point at this item */ - (intr->drainers) = drainer; - } else { - /* Otherwise, point at whoever was next */ - drainer->next = (intr->drainers)->next; - } - /* Point head of list at this new item */ - (intr->drainers)->next = drainer; - } - /* If we weren't able to allocate ANY soft interrupts... */ - if (i == 0) { - cmn_err(CE_WARN, "Unable to allocate any soft interrupts"); - } - return (retval); -} - -/* Deletes the entire drainer list */ -static void -drainer_list_fini(wrsm_interrupt_t *intr) -{ - wrsm_intr_drainer_t *first = intr->drainers; - wrsm_intr_drainer_t *drainer = first; - DTRC("drainer_list_fini"); - - ASSERT(first); /* Drainer list should never be empty */ - - /* Repeat until we loop around to first again */ - do { - /* Remember which comes next */ - wrsm_intr_drainer_t *next = drainer->next; - - /* Now it's safe to kill it */ - drainer_fini(drainer); - kmem_free(drainer, sizeof (wrsm_intr_drainer_t)); - - /* We're done when next points back to original drainer */ - drainer = next; - } while (drainer != first); - - intr->drainers = NULL; -} - -static wrsm_intr_drainer_t * -drainer_list_get_next(wrsm_interrupt_t *intr) -{ - wrsm_intr_drainer_t *drainer; - DTRC("drainer_list_get_next"); - - /* Don't need lock since this is only called building target list */ - ASSERT(intr->drainers != NULL); - - drainer = intr->drainers; - intr->drainers = (intr->drainers)->next; - return (drainer); -} - -/* Prints the entire drainer list */ -static void -drainer_list_print(wrsm_interrupt_t *intr) -{ - wrsm_intr_drainer_t *start = intr->drainers; - wrsm_intr_drainer_t *drainer = start; - - DPRINTF(INTRDBG, (CE_CONT, " drainer_list:")); - mutex_enter(&intr->mutex); - do { - drainer_print(drainer); - drainer = drainer->next; - } while (drainer != start); - mutex_exit(&intr->mutex); -} - -/* Prints all members of the interrupt component */ -void -wrsm_intr_print(wrsm_network_t *net) -{ - DPRINTF(INTRDBG, (CE_CONT, "interrupt_print")); - ASSERT(net); - ASSERT(net->interrupt); - - drainer_list_print(net->interrupt); - target_list_print(net->interrupt); - recvq_table_print(net->interrupt); -} - -/* - * Message Handlers - */ -/* Handler for the recvq create request from a remote node */ -static boolean_t -msg_recvq_create(wrsm_network_t *net, wrsm_message_t *msg) -{ - int retval; - cnodeid_t from_cnode; - unsigned ntuples; - wrsm_interrupt_t *intr; - wrsm_cmmu_tuple_t *tuples; - wrsm_intr_recvq_t *recvq; - wrsm_intr_service_t *service; - wrsm_intr_handler_t *hdlr; - wrsm_raw_message_t raw_resp; - recvq_create_req_t *req = (recvq_create_req_t *)msg; - recvq_create_rsp_t *rsp = (recvq_create_rsp_t *)&raw_resp; - - DPRINTF(INTRDBG, (CE_NOTE, "Cnode %d is requesting a recvq to %d", - msg->header.source_cnode, - net->cnodeid)); - intr = net->interrupt; - from_cnode = req->header.source_cnode; - rsp->header.message_type = WRSM_MSG_INTR_RECVQ_CREATE_RESPONSE; - rsp->qid = 0; - rsp->mondo = 0; - rsp->nc_off = 0; - rsp->retval = RSMERR_NO_HANDLER; - - /* Find the service */ - service = &intr->services[req->service]; - - mutex_enter(&service->handler_mutex); - /* Search for a handler willing to accept messages from this node */ - for (hdlr = service->handler_list; hdlr; hdlr = hdlr->next) { - if (WRSM_IN_SET(hdlr->cnodes, req->header.source_cnode)) { - rsp->retval = 0; - break; - } - } - mutex_exit(&service->handler_mutex); - - /* No handler -- send an error response */ - if (rsp->retval) { - WARN("msg_recvq_create: no message handler"); - (void) wrsm_tl_rsp(net, msg, (wrsm_message_t *)rsp); - return (B_TRUE); - } - - /* Allocate a CMMU entry for this recvq */ - retval = wrsm_cmmu_alloc(net, - CMMU_PAGE_SIZE_SMALL, - 1, /* nentries */ - &tuples, - &ntuples, - B_FALSE); - if (retval) { - WARN("msg_recvq_create: unable to allocate cmmu entry"); - rsp->retval = RSMERR_INSUFFICIENT_RESOURCES; - (void) wrsm_tl_rsp(net, msg, (wrsm_message_t *)rsp); - return (B_TRUE); - } - - /* Create the recvq */ - retval = wrsm_intr_create_recvq(net, - req->service, - req->qdepth, - tuples->index, - &recvq, - req->header.source_cnode, - NULL, - WRSM_CREATE_RECVQ_USER); - if (retval) { - WARN("msg_recvq_create: unable to create recvq"); - rsp->retval = RSMERR_INSUFFICIENT_RESOURCES; - wrsm_cmmu_free(net, ntuples, tuples); - (void) wrsm_tl_rsp(net, msg, (wrsm_message_t *)rsp); - return (B_TRUE); - } - - /* Link this new recvq into recvq_list for from_cnode */ - mutex_enter(&net->interrupt->mutex); - recvq->recvq_next = intr->recvq_list[from_cnode]; - intr->recvq_list[from_cnode] = recvq; - mutex_exit(&net->interrupt->mutex); - - /* Since creator is remote, store tuple pointer in recvq */ - recvq->tuples = tuples; - - /* Tell the handlers that a new recvq exists */ - for (hdlr = service->handler_list; hdlr; hdlr = hdlr->next) { - (void) handler_callback(hdlr, RSM_INTR_Q_OP_CREATE, - req->header.source_cnode, NULL, 0); - } - - /* Recvq has been created. Notify requestor */ - rsp->nc_off = (off_t)((tuples->index) * CMMU_SMALL_PAGE_SIZE); - rsp->qid = (uint64_t)recvq; - rsp->mondo = recvq->cmmu_mondo; - - /* If response fails, destroy the recvq */ - /* LINTED */ - if (wrsm_tl_rsp(net, msg, (wrsm_message_t *)rsp) != RSM_SUCCESS) { - /* - * Don't need to destroy the recvq since, if rsp fails, - * TL tears down the session and the recvq gets - * destroyed anyway. - */ - WARN("msg_recvq_create: Unable to send response"); - } - return (B_TRUE); -} - -/* Handler for the recvq config request from a remote node */ -static boolean_t -msg_recvq_config(wrsm_network_t *net, wrsm_message_t *msg) -{ - wrsm_interrupt_t *intr = net->interrupt; - recvq_config_req_t *req = (recvq_config_req_t *)msg; - wrsm_raw_message_t raw_resp; - recvq_config_rsp_t *rsp = (recvq_config_rsp_t *)&raw_resp; - unsigned table; - unsigned index; - wrsm_intr_recvq_table_t *ptable; - wrsm_intr_recvq_t *recvq = (wrsm_intr_recvq_t *)(req->qid); - wrsm_intr_packet_t *new_ring = NULL; - size_t new_size; - cnodeid_t source_cnode = msg->header.source_cnode; - - DTRC("msg_recvq_config"); - mutex_enter(&intr->mutex); - - /* Validate that the CMMU mondo and recvq pointer match */ - table = WRSM_MONDO2TABLE(req->mondo); - index = WRSM_MONDO2INDEX(req->mondo); - ptable = intr->recvq_tables[table]; - if ((ptable == NULL) || - ((*ptable)[index] != recvq) || - (recvq->from_cnode != source_cnode)) { - /* The recvq doesn't exist or is invalid */ - WARN("msg_recvq_config: Recvq doesn't exist or is invalid"); - rsp->retval = RSMERR_NO_HANDLER; - } else { - rsp->retval = RSM_SUCCESS; - } - - if (rsp->retval == RSM_SUCCESS) { - /* - * Since the sender will take a lock before sending the - * recvq_config request, there should be no more interrupts - * arriving; however, set user_error bit in cmmu just to - * play it safe. - */ - recvq_cmmu_update(recvq, B_FALSE, B_TRUE); - - /* - * Now all we have to do is wait for the trap handler to - * finish any outstanding interrupts. This can be done with - * a cross-trap sync (xt_sync). - */ - wrsmplat_xt_sync(recvq->target->cpu_id); - - /* Lock servicing of recvq */ - mutex_enter(&recvq->mutex); - - /* Calculate size of new packet ring */ - new_size = req->new_qdepth + RECVQ_HIGHWATER_MARGIN; - - /* Alloc new packet ring if required */ - if (new_size > recvq->packet_ring_info.info.size) { - new_ring = kmem_zalloc( - new_size * sizeof (wrsm_intr_packet_t), - KM_SLEEP); - } - - /* If we've allocated a new ring, and we have an old ring... */ - if (new_ring && recvq->packet_ring) { - /* Copy old ring contents to new ring */ - bcopy(recvq->packet_ring, new_ring, - recvq->packet_ring_info.info.size * - sizeof (wrsm_intr_packet_t)); - /* And free the old ring */ - kmem_free(recvq->packet_ring, - recvq->packet_ring_info.info.size * - sizeof (wrsm_intr_packet_t)); - } - - /* If we've allocated a new ring, update recvq */ - if (new_ring) { - recvq->packet_ring = new_ring; - recvq->packet_ring_info.info.size = new_size; - } - - recvq->high_water_mark = req->new_qdepth; - - recvq_cmmu_update(recvq, B_FALSE, B_FALSE); - - mutex_exit(&recvq->mutex); - } - - mutex_exit(&intr->mutex); - - rsp->header.message_type = WRSM_MSG_INTR_RECVQ_CONFIG_RESPONSE; - /* LINTED */ - if (wrsm_tl_rsp(net, msg, (wrsm_message_t *)rsp) != RSM_SUCCESS) { - /* Nothing to do - a failed rsp will cause seesion to end */ - WARN("msg_recvq_config: Unable to send response"); - } - return (B_TRUE); -} - -/* Handler for the recvq destroy request from a remote node */ -static boolean_t -msg_recvq_destroy(wrsm_network_t *net, wrsm_message_t *msg) -{ - wrsm_interrupt_t *intr = net->interrupt; - recvq_destroy_t *req = (recvq_destroy_t *)msg; - unsigned table; - unsigned index; - wrsm_intr_recvq_table_t *ptable; - wrsm_intr_recvq_t *recvq = (wrsm_intr_recvq_t *)(req->qid); - wrsm_intr_recvq_t *rq; - wrsm_intr_handler_t *hdlr; - cnodeid_t source_cnode = msg->header.source_cnode; - - mutex_enter(&intr->mutex); - /* Validate that the CMMU mondo and recvq pointer match */ - table = WRSM_MONDO2TABLE(req->mondo); - index = WRSM_MONDO2INDEX(req->mondo); - ptable = intr->recvq_tables[table]; - if (ptable == NULL) { - mutex_exit(&intr->mutex); - return (B_TRUE); - } - if ((*ptable)[index] != recvq) { - mutex_exit(&intr->mutex); - return (B_TRUE); - } - - /* Validate that this is the right source cnode */ - if (recvq->from_cnode != source_cnode) { - mutex_exit(&intr->mutex); - return (B_TRUE); - } - - /* Tell the handlers that the recvq is destroyed */ - for (hdlr = recvq->service->handler_list; hdlr; hdlr = hdlr->next) { - (void) handler_callback(hdlr, RSM_INTR_Q_OP_DESTROY, - req->header.source_cnode, NULL, 0); - } - - /* Unlink this recvq from that node's recvq_list */ - rq = intr->recvq_list[source_cnode]; - if (rq == recvq) { - intr->recvq_list[source_cnode] = recvq->recvq_next; - } else while (rq->recvq_next) { - if (rq->recvq_next == recvq) { - rq->recvq_next = recvq->recvq_next; - recvq->recvq_next = NULL; - break; - } - rq = rq->recvq_next; - } - - /* Destroy the recvq */ - recvq_fini(net, recvq); - - mutex_exit(&intr->mutex); - - return (B_TRUE); -} - -/* - * Client functions - */ - -static safari_port_t -find_a_wci(wrsm_interrupt_t *intr) -{ - int i; - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (intr->wci_ids[i] != INVALID_SAFARI_ID) { - return (intr->wci_ids[i]); - } - } - return (INVALID_SAFARI_ID); -} - -/* Initialize the interrupt component for this network */ -int -wrsm_intr_init(wrsm_network_t *net) -{ - wrsm_interrupt_t *intr; - int i; - int retval = 0; - DTRC("wrsm_intr_init"); - - ASSERT(net); - ASSERT(net->interrupt == NULL); - - intr = kmem_zalloc(sizeof (wrsm_interrupt_t), KM_SLEEP); - ASSERT(intr); - - mutex_init(&intr->mutex, NULL, MUTEX_DRIVER, NULL); - cv_init(&intr->resource_cv, NULL, CV_DEFAULT, NULL); - - retval = drainer_list_init(intr); - ASSERT(retval == 0); - if (retval) { - mutex_destroy(&intr->mutex); - kmem_free(intr, sizeof (wrsm_interrupt_t)); - return (retval); - } - - /* We don't yet know the safari ids of any of our wcis... */ - for (i = 0; i < WRSM_MAX_WCIS; i++) { - intr->wci_ids[i] = INVALID_SAFARI_ID; - } - intr->wci_safari_port = INVALID_SAFARI_ID; - - /* Initialize the other interrupt components */ - recvq_table_init(intr); - service_list_init(intr, net); - target_list_init(intr); - - net->interrupt = intr; /* Publish it! */ - -#ifdef DEBUG - networks[net->cnodeid] = net; -#endif /* DEBUG */ - - return (retval); -} - -/* Destroy the interrupt component for this network */ -void -wrsm_intr_fini(wrsm_network_t *net) -{ - wrsm_interrupt_t *intr; - DTRC("wrsm_intr_fini"); - - ASSERT(net); - ASSERT(net->interrupt); - intr = net->interrupt; - - /* Fini all our children */ - recvq_table_fini(intr, net); - - drainer_list_fini(intr); - target_list_fini(intr); - service_list_fini(intr); - cv_destroy(&intr->resource_cv); - mutex_destroy(&intr->mutex); - - /* Remove us from the network structure */ - net->interrupt = NULL; - - /* Free the memory */ - kmem_free(intr, sizeof (wrsm_interrupt_t)); - -#ifdef DEBUG - networks[net->cnodeid] = NULL; -#endif /* DEBUG */ -} - -/* - * WCI Functions - Can/should these be moved to LC? - */ - -/* Inform the interrupt component of a new WCI */ -int -wrsm_intr_newwci(wrsm_network_t *net, lcwci_handle_t lc) -{ - int retval; - wrsm_interrupt_t *intr; - safari_port_t safid; - void *arg; - int i; - caddr_t sram_paddr; - - DTRC("wrsm_intr_newwci"); - ASSERT(net); - ASSERT(net->interrupt); - intr = net->interrupt; - - sram_paddr = wrsm_lc_get_sram_paddr(lc); - safid = wrsm_lc_get_safid(lc); - - arg = (void *)&(intr->recvq_tables[0]); - DPRINTF(INTRDBG, (CE_CONT, "dmv_add_intr(0x%08X)", safid)); - retval = dmv_add_intr(safid, wrsm_tl1_handler, arg); - - if (retval) { - cmn_err(CE_WARN, - "dmv_add_intr() failed for device %d: %d", - safid, retval); - } - /* Store phys addr of cmmu sram for trap handler, and safari port id */ - mutex_enter(&intr->mutex); - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (intr->sram_paddr[i] == NULL) { - intr->sram_paddr[i] = sram_paddr; - intr->wci_ids[i] = safid; - break; - } - } - ASSERT(i < WRSM_MAX_WCIS); - /* - * If we don't have a valid wci_safari_port, this must be the first - * WCI, so notify the targets. - */ - if (intr->wci_safari_port == INVALID_SAFARI_ID) { - DPRINTF(INTRWARN, (CE_CONT, "wrsm_intr_newwci: First wci %d", - safid)); - intr->wci_safari_port = safid; - target_list_readd_cpu(net); - } - - mutex_exit(&intr->mutex); - - return (retval); -} - -/* Inform the interrupt component that a WCI is going away */ -void -wrsm_intr_delwci(wrsm_network_t *net, lcwci_handle_t lc) -{ - safari_port_t safid; - caddr_t sram_paddr; - int i; - wrsm_interrupt_t *intr; - - DTRC("wrsm_intr_delwci"); - ASSERT(net); - ASSERT(net->interrupt); - intr = net->interrupt; - - mutex_enter(&intr->mutex); - - /* Remove the dmv interrupt registration */ - safid = wrsm_lc_get_safid(lc); - (void) dmv_rem_intr(safid); - - /* Clear phys addr of cmmu sram */ - sram_paddr = wrsm_lc_get_sram_paddr(lc); - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (intr->sram_paddr[i] == sram_paddr) { - intr->sram_paddr[i] = NULL; - intr->wci_ids[i] = INVALID_SAFARI_ID; - break; - } - } - /* - * If this was the WCI we were using for interrupt target - * redistribution, we need to repeat the intr_dist_cpu process - * for all the targets with a different WCI, if one exists. - */ - if (safid == intr->wci_safari_port) { - safari_port_t new_wci = find_a_wci(intr); - if (new_wci != INVALID_SAFARI_ID) { - DPRINTF(INTRWARN, (CE_CONT, "wrsm_intr_delwci: " - "Changing golden wci from %d to %d", - safid, new_wci)); - intr->wci_safari_port = new_wci; - target_list_readd_cpu(net); - } - } - - mutex_exit(&intr->mutex); -} - -/* - * Handler Management Functions - */ - -/* Registers a handler for a specific interrupt type - rsmpi interface */ -int -wrsmrsm_register_handler( - rsm_controller_handle_t controller, - rsm_controller_object_t *controller_obj, - rsm_intr_t type, - rsm_intr_hand_t func, - rsm_intr_hand_arg_t arg, - rsm_addr_t senders_list[], - uint_t senders_list_length) -{ - wrsm_network_t *net = (wrsm_network_t *)controller; - int retval; - if (type < RSM_INTR_T_SUN_BASE) { - retval = RSMERR_PERM_DENIED; - } else if (net == NULL || net->interrupt == NULL) { - retval = RSMERR_BAD_CTLR_HNDL; - } else { - retval = wrsm_register_handler(controller, controller_obj, - type, func, arg, senders_list, senders_list_length); - } - return (retval); -} - -/* Registers a handler for a specific interrupt type - driver interface */ -int -wrsm_register_handler( - wrsm_network_t *net, - rsm_controller_object_t *controller_obj, - rsm_intr_t type, - rsm_intr_hand_t func, - rsm_intr_hand_arg_t arg, - rsm_addr_t senders_list[], - uint_t senders_list_length) -{ - wrsm_intr_handler_t *handler; - wrsm_interrupt_t *intr; - uint_t i; - - /* Assume all senders, unless a senders_list is provided */ - cnode_bitmask_t cnode_list = { - 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff}; - DPRINTF(INTRTRACE, (CE_CONT, "wrsm_register_handler - ctlr %d " - "service id %d func 0x%p arg 0x%p", net->rsm_ctlr_id, type, - (void *)func, (void *)arg)); - - ASSERT(net); - ASSERT(net->interrupt); - intr = net->interrupt; - - if (type > RSM_INTR_T_USR_END) { - return (RSMERR_PERM_DENIED); - } - /* If a sender's list is provided, record it */ - if (senders_list_length != 0) { - WRSMSET_ZERO(cnode_list); - for (i = 0; i < senders_list_length; i++) { - if (senders_list[i] >= WRSM_MAX_CNODES) { - return (RSMERR_UNKNOWN_RSM_ADDR); - } - WRSMSET_ADD(cnode_list, senders_list[i]); - } - } - - /* Allocate and initialize handler structure */ - handler = kmem_alloc(sizeof (wrsm_intr_handler_t), KM_SLEEP); - handler_init(handler, func, arg, cnode_list, controller_obj); - - /* Add this handler to the list of handlers for this service */ - service_add_handler(&intr->services[type], handler); - - /* Count non-driver handlers */ - if (type > RSM_INTR_T_DRV_END) { - mutex_enter(&intr->mutex); - net->handler_num++; - mutex_exit(&intr->mutex); - } - - return (RSM_SUCCESS); -} - -/* Unregisters a handler - rsmpi interface */ -int -wrsmrsm_unregister_handler( - rsm_controller_handle_t controller, - rsm_intr_t type, - rsm_intr_hand_t func, - rsm_intr_hand_arg_t arg) -{ - wrsm_network_t *net = (wrsm_network_t *)controller; - int retval; - if (type < RSM_INTR_T_SUN_BASE) { - retval = RSMERR_PERM_DENIED; - } else if (net == NULL || net->interrupt == NULL) { - retval = RSMERR_BAD_CTLR_HNDL; - } else { - retval = wrsm_unregister_handler(controller, type, func, arg); - } - return (retval); -} - -/* Unregisters a handler - driver interface */ -int -wrsm_unregister_handler( - wrsm_network_t *net, - rsm_intr_t type, - rsm_intr_hand_t func, - rsm_intr_hand_arg_t arg) -{ - wrsm_interrupt_t *intr; - wrsm_intr_service_t *service; - wrsm_intr_handler_t *handler; - int num_unregistered_client_handlers = 0; - int retval = RSM_SUCCESS; - DTRC("wrsm_unregister_handler"); - - ASSERT(net); - ASSERT(net->interrupt); - intr = net->interrupt; - service = &intr->services[type]; - - if (func == NULL) { - DPRINTF(INTRWARN, (CE_CONT, "wrsm_unregister_handler: " - "Unregister all handlers for service %d", type)); - /* If handler func is null, remove all handlers of that type */ - mutex_enter(&service->handler_mutex); - handler = service->handler_list; - while (handler) { - wrsm_intr_handler_t *next = handler->next; - handler_fini(handler); - kmem_free(handler, sizeof (wrsm_intr_handler_t)); - handler = next; - /* Update count of user handlers */ - if (type > RSM_INTR_T_DRV_END) { - num_unregistered_client_handlers++; - } - } - service->handler_list = NULL; - mutex_exit(&service->handler_mutex); - } else { - handler = service_rem_handler(service, func, arg); - if (handler) { - handler_fini(handler); - kmem_free(handler, sizeof (wrsm_intr_handler_t)); - /* Update count of user handlers */ - if (type > RSM_INTR_T_DRV_END) { - num_unregistered_client_handlers = 1; - } - } else { - DPRINTF(INTRERR, (CE_WARN, "wrsm_unregister_handler: " - "Handler not found")); - retval = RSMERR_HANDLER_NOT_REGISTERED; - } - } - mutex_enter(&intr->mutex); - net->handler_num -= num_unregistered_client_handlers; - mutex_exit(&intr->mutex); - - return (retval); -} - -/* - * Receive Queue Functions - */ - -/* Creates a receive queue of a given type */ -int -wrsm_intr_create_recvq( - wrsm_network_t *net, - rsm_intr_t type, - size_t qdepth, - wrsm_cmmu_index_t cmmu_index, - wrsm_intr_recvq_t **recvq, - cnodeid_t from_cnode, - void *exportseg, - int flags) -{ - wrsm_interrupt_t *intr; - unsigned cmmu_mondo; - int retval; - int ring_size; - - DTRC("wrsm_intr_create_recvq"); - - ASSERT(net); - ASSERT(net->interrupt); - intr = net->interrupt; - - /* First, find if there's space to allocate a new recvq */ - mutex_enter(&intr->mutex); -retry: - cmmu_mondo = recvq_table_alloc_entry(intr); - DPRINTF(INTRDBG, (CE_CONT, "Recvq from cnode %d got cmmu_mondo = %d", - exportseg ? -1 : from_cnode, cmmu_mondo)); - if (cmmu_mondo <= 0) { - WARN("wrsm_intr_create_recvq: Unable to allocate a mondo"); - if (flags & WRSM_CREATE_RECVQ_SLEEP) { - WARN("wrsm_intr_create_recvq: waiting for resources"); - retval = cv_wait_sig(&intr->resource_cv, &intr->mutex); - if (retval > 0) { - goto retry; - } else { - /* got a signal */ - mutex_exit(&intr->mutex); - return (EINTR); - } - } else { - mutex_exit(&intr->mutex); - return (EAGAIN); - } - } - - /* Create and initialize recvq structure */ - *recvq = kmem_zalloc(sizeof (wrsm_intr_recvq_t), KM_SLEEP); - DPRINTF(INTRTRACE, (CE_CONT, - "created recvq 0x%p\n", (void *)*recvq)); - mutex_init(&(*recvq)->mutex, NULL, MUTEX_DRIVER, NULL); - if (qdepth > 0) { - /* Alloc extra space to give margin for flow ctrl */ - ring_size = qdepth + RECVQ_HIGHWATER_MARGIN; - (*recvq)->packet_ring_info.info.size = ring_size; - (*recvq)->packet_ring = - kmem_zalloc(ring_size * sizeof (wrsm_intr_packet_t), - KM_SLEEP); - (*recvq)->high_water_mark = qdepth; - } - (*recvq)->net = net; - (*recvq)->low_water_mark = 0; /* Force them to drain it */ - (*recvq)->sram_paddr = intr->sram_paddr; - (*recvq)->service = &(intr->services[type]); - (*recvq)->cmmu_mondo = cmmu_mondo; - (*recvq)->cmmu_index = cmmu_index; - (*recvq)->from_cnode = from_cnode; - (*recvq)->user_interrupt = (flags & WRSM_CREATE_RECVQ_USER); - (*recvq)->exportseg = exportseg; - - /* Get next target */ - (*recvq)->target = target_list_get_next(intr); - /* Remember it's drainer */ - (*recvq)->drainer = (*recvq)->target->drainer; - - /* Add this recvq to target and service lists */ - target_add_recvq((*recvq)->target, *recvq); - service_add_recvq((*recvq)->service, *recvq); - - /* Use cmmu_mondo to store recvq */ - recvq_table_set(intr, cmmu_mondo, *recvq); - - mutex_exit(&intr->mutex); - - /* Update CMMU entry to enable the interrupt. */ - recvq_cmmu_update(*recvq, - (flags & WRSM_CREATE_RECVQ_INVALID) ? B_TRUE : B_FALSE, B_FALSE); - - return (RSM_SUCCESS); -} - -/* Destroys the receive queue */ -void -wrsm_intr_destroy_recvq(wrsm_network_t *net, wrsm_intr_recvq_t *recvq) -{ - DTRC("wrsm_destroy_recvq"); - - ASSERT(net); - ASSERT(net->interrupt); - ASSERT(recvq); - - mutex_enter(&net->interrupt->mutex); - recvq_fini(net, recvq); - mutex_exit(&net->interrupt->mutex); -} - -/* Flushes the receive queue */ -void -wrsm_intr_flush_recvq(wrsm_intr_recvq_t *recvq) -{ - DTRC("wrsm_flush_recvq"); - ASSERT(recvq); - - /* - * Do a cross trap to the target CPU to make sure that any - * in-process interrupts are complete. - */ - wrsmplat_xt_sync(recvq->target->cpu_id); -} - -/* - * Send Functions - */ - -/* - * Reads the CESR pointed to by p, until the not_valid flag is clear, then - * sets the CESR to the new value. Returns EIO if the not_valid flag never - * clears (implies the WCI is hung). - */ -#define CESR_READ_DELAY 10 /* 10 usec */ -#define CESR_READ_RETRY_LIMIT (1500000 / CESR_READ_DELAY) /* 1.5 sec */ -#define CESR_FAILFAST_DISABLED 0x20 - -#define UINT64S_PER_BLOCK (WRSM_CACHELINE_SIZE / sizeof (uint64_t)) - -static int -cesr_swap(volatile uint64_t *p, uint64_t new, uint64_t *old) -{ - uint64_t block[UINT64S_PER_BLOCK]; - wci_cluster_error_status_array_u cesr; - uint_t i = 0; - - do { - wrsm_blkread((void*)p, (void *)block, 1); - cesr.val = block[0]; - if (i++ > CESR_READ_RETRY_LIMIT) { - return (EIO); - } - if (cesr.bit.not_valid) { - drv_usecwait(CESR_READ_DELAY); - } - } while (cesr.bit.not_valid); - - DPRINTF(INTRCESR, (CE_WARN, "cesr_swap: changing cesr from " - "0x%lx to 0x%lx", cesr.val, new)); - *old = cesr.val; - /* - * Put new value in both half cachelines -- don't know - * which one will actually get stored into wci. - */ - block[0] = new; - block[UINT64S_PER_BLOCK / 2] = new; - wrsm_blkwrite((void *)block, (void *)p, 1); - /* Read back to force flush to physical memory */ - wrsm_blkread((void *)p, (void *)block, 1); - DPRINTF(INTRCESR, (CE_WARN, "cesr_swap: read back cesr as 0x%lx", - block[0])); - - return (0); -} - -/* Does the send, with CESR swapping and kpreemt disabling */ -static int -send(void *remote_addr, void *aligned_buf, caddr_t p_cesr) -{ - uint64_t offset; - wci_cluster_error_status_array_u cesr_before; - wci_cluster_error_status_array_u cesr_after; - - /* - * With preemption disabled, we want to clear the CESR to - * disable fail-fast, send the interrupt, then restore the - * CESR. If the CESR was set during the transaction, the - * interupt failed. If the error was destination CPU busy, - * then we should retry. - */ - kpreempt_disable(); - offset = ((uint64_t)remote_addr) & (PAGESIZE - 1); - - /* Read CESR and replace with a value of 0 and failfast disabled */ - - wrsmplat_set_asi_cesr_id(); - - if (cesr_swap((uint64_t *)(p_cesr + offset), CESR_FAILFAST_DISABLED, - &cesr_before.val)) { - wrsmplat_clr_asi_cesr_id(); - kpreempt_enable(); - return (WCI_CESR_BUSY_TOO_LONG); - } - - /* Send interrupt */ - wrsm_blkwrite(aligned_buf, remote_addr, 1); - - /* Read CESR and restore original value */ - if (cesr_swap((uint64_t *)(p_cesr + offset), cesr_before.val, - &cesr_after.val)) { - wrsmplat_clr_asi_cesr_id(); - kpreempt_enable(); - return (WCI_CESR_BUSY_TOO_LONG); - } - - - wrsmplat_clr_asi_cesr_id(); - kpreempt_enable(); - - return ((int)cesr_after.bit.value); -} - -/* - * wrsm_intr_send -- The parameters is_flags, is_wait and sendq_flags are - * normally provided by wrsm_send from the sendq or is data structures. - * To allow this function to be called from the driver, make sure that: - * is_flags of 0 => don't sleep - * sendq_flags of 0 => don't fail on full - * Since is_wait of 0 is a valid input, the caller must provide a valid - * value for is_wait, or WRSM_INTR_WAIT_DEFAULT to use a default driver - * timeout. - */ -int -wrsm_intr_send(wrsm_network_t *net, - void *remote_addr, - cnodeid_t remote_cnode, - void *aligned_buf, - int is_flags, - clock_t is_wait, - int sendq_flags) -{ - const clock_t spin_time = 10; /* microseconds */ - const clock_t sleep_time = 20000; /* microseconds */ - const clock_t sleep_ticks = drv_usectohz(sleep_time); - clock_t time_limit; - int cesr; - int retval = RSM_SUCCESS; - const clock_t def_wait_time = drv_usectohz(90000); - const int min_retries = 10; - int retries = 0; - - int was_busy = 0; - - ASSERT(net); - ASSERT(net->interrupt); - - if (is_wait == WRSM_INTR_WAIT_DEFAULT) { - is_wait = def_wait_time; - } - - /* Calculate time to wait when trying to send */ - time_limit = ddi_get_lbolt() + is_wait; - - DPRINTF(INTRDBG, (CE_NOTE, - "wrsm_blkwrite(src=0x%p, dst=0x%p) from cpu %d", - (void *)aligned_buf, (void *)remote_addr, CPU->cpu_id)); - - /* - * Keep retrying until we exceed the time limit. However, even - * if we run out of time, we should at least make min_retries - * attempts before giving up. - */ - while ((ddi_get_lbolt() < time_limit) || (retries++ < min_retries)) { - cesr = send(remote_addr, aligned_buf, - net->nodes[remote_cnode]->cesr_vaddr); - - if (cesr == WCI_CESR_INTR_DEST_BUSY) { - was_busy++; - /* If "inter dest busy", retry */ - retval = RSMERR_TIMEOUT; - } else if (cesr == WCI_CESR_USER_ERROR_BIT_SET) { - /* - * User error means overflow, retry unless sendq - * was created with full-fail flag set or no - * wait time was specified. - */ - if ((sendq_flags & RSM_INTR_SEND_Q_FULL_FAIL) || - (is_wait == 0)) { - retval = RSMERR_QUEUE_FULL; - break; - } else { - /* Assume we might timeout */ - retval = RSMERR_TIMEOUT; - } - } else if (cesr != 0) { - DPRINTF(INTRERR, (CE_CONT, "wrsm_intr_send: cesr=%d", - cesr)); - /* All other comm errors, break from retrying */ - retval = RSMERR_COMM_ERR_NOT_DELIVERED; - break; - } else { - /* Success! */ - retval = RSM_SUCCESS; - break; - } - - /* If we got here, we've failed and may retry */ - if ((is_flags & RSM_INTR_SEND_SLEEP) && - !servicing_interrupt()) { - delay(sleep_ticks); - } else { - drv_usecwait(spin_time); - } - } - - if ((retval != RSM_SUCCESS) && was_busy) - DPRINTF(INTRWARN, (CE_WARN, - "wrsm_intr_send: intr dest busy %d times", was_busy)); - return (retval); -} - -/* Callback from session, sets net_reset flag when session goes away */ -boolean_t -wrsm_intr_sess_callback(wrsm_network_t *net, cnodeid_t cnode, - wrsm_sess_state state) -{ - wrsm_interrupt_t *intr; - wrsm_sendq_t *sq; - wrsm_sendq_t *sq_next; - wrsm_intr_recvq_t *rq; - wrsm_intr_recvq_t *rq_next; - DPRINTF(INTRTRACE, (CE_CONT, "wrsm_intr_sess_callback(" - "cnode=%d, state=%d)", cnode, state)); - - ASSERT(net); - ASSERT(net->interrupt); - intr = net->interrupt; - - if (state == SESSION_DOWN) { - mutex_enter(&net->interrupt->mutex); - /* - * Mark "net reset" on all sendq's to remote node, then - * unlink from sendq_list and forget about them. Could move - * them to a "zombie" list and free in wrsm_intr_fini. - */ - for (sq = intr->sendq_list[cnode]; sq; sq = sq_next) { - sq_next = sq->next; - sq->net_reset = B_TRUE; - sq->next = NULL; - } - intr->sendq_list[cnode] = NULL; - - /* Delete all recvq's from remote node */ - for (rq = intr->recvq_list[cnode]; rq; rq = rq_next) { - wrsm_intr_handler_t *h; - rq_next = rq->recvq_next; - /* Tell the handlers that the recvq is destroyed */ - for (h = rq->service->handler_list; h; h = h->next) { - (void) handler_callback(h, - RSM_INTR_Q_OP_DESTROY, - rq->from_cnode, NULL, 0); - } - recvq_fini(net, rq); - } - intr->recvq_list[cnode] = NULL; - mutex_exit(&net->interrupt->mutex); - } - - return (B_TRUE); -} - -/* Initializes the rsmpi portion of interrupts */ -void -wrsm_intr_rsminit(wrsm_network_t *net) -{ - DTRC("wrsm_intr_rsminit"); - - /* Register sendq create message handler */ - (void) wrsm_tl_add_handler(net, WRSM_MSG_INTR_RECVQ_CREATE, - wrsm_tl_txhandler_sessionid, msg_recvq_create); - (void) wrsm_tl_add_handler(net, WRSM_MSG_INTR_RECVQ_CREATE_RESPONSE, - wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid); - - /* Register sendq config message handler */ - (void) wrsm_tl_add_handler(net, WRSM_MSG_INTR_RECVQ_CONFIG, - wrsm_tl_txhandler_sessionid, msg_recvq_config); - (void) wrsm_tl_add_handler(net, WRSM_MSG_INTR_RECVQ_CONFIG_RESPONSE, - wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid); - - /* Register sendq destroy message handler */ - (void) wrsm_tl_add_handler(net, WRSM_MSG_INTR_RECVQ_DESTROY, - wrsm_tl_txhandler_sessionid, msg_recvq_destroy); - - /* Register with Session for callbacks */ - wrsm_sess_register(net, wrsm_intr_sess_callback); -} - -/* Cleans-up the rsmpi portion of interrupts */ -void -wrsm_intr_rsmfini(wrsm_network_t *net) -{ - uint_t cnode; - DTRC("wrsm_intr_rsmfini"); - - ASSERT(net); - ASSERT(net->interrupt); - - /* Unregister with session */ - wrsm_sess_unregister(net, wrsm_intr_sess_callback); - - /* Make sure everything's been cleaned up */ - for (cnode = 0; cnode < WRSM_MAX_CNODES; cnode++) { - (void) wrsm_intr_sess_callback(net, cnode, SESSION_DOWN); - } - mutex_enter(&net->interrupt->mutex); - -#ifdef DEBUG - for (cnode = 0; cnode < WRSM_MAX_CNODES; cnode++) { - /* Check sendq's are marked invalid */ - if (net->interrupt->sendq_list[cnode]) { - DPRINTF(INTRWARN, (CE_WARN, - "sendq_list[%d] not empty!", cnode)); - } - /* Make sure all recvq's have been deleted */ - if (net->interrupt->recvq_list[cnode]) { - DPRINTF(INTRWARN, (CE_WARN, - "revq_list[%d] not empty!", cnode)); - } - } -#endif /* DEBUG */ - - /* Unregister sendq create message handler */ - (void) wrsm_tl_add_handler(net, WRSM_MSG_INTR_RECVQ_CREATE, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - (void) wrsm_tl_add_handler(net, WRSM_MSG_INTR_RECVQ_CREATE_RESPONSE, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - - /* Unregister sendq destroy message handler */ - (void) wrsm_tl_add_handler(net, WRSM_MSG_INTR_RECVQ_DESTROY, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - - mutex_exit(&net->interrupt->mutex); -} - -/* - * RSMPI public functions - */ - -/* Creates a send queue */ -/* ARGSUSED */ -int -wrsm_sendq_create( - rsm_controller_handle_t controller, - rsm_addr_t addr, - rsm_intr_t service, - rsm_intr_pri_t prio, - size_t qdepth, - uint_t flags, - rsm_resource_callback_t fn, - rsm_resource_callback_arg_t arg, - rsm_send_q_handle_t *send_q) -{ - wrsm_network_t *net = (wrsm_network_t *)controller; - wrsm_sendq_t *sendq; - wrsm_raw_message_t raw_req; - wrsm_raw_message_t raw_rsp; - recvq_create_req_t *req = (recvq_create_req_t *)&raw_req; - recvq_create_rsp_t *rsp = (recvq_create_rsp_t *)&raw_rsp; - cnodeid_t dest_cnode = (cnodeid_t)addr; - caddr_t vaddr; - - DPRINTF(INTRTRACE, (CE_CONT, "wrsm_sendq_create(addr = %d)", - dest_cnode)); - - *send_q = NULL; /* Make sure to return NULL on error */ - ASSERT(net); - ASSERT(net->interrupt); - - if (fn != RSM_RESOURCE_SLEEP && fn != RSM_RESOURCE_DONTWAIT) { - DPRINTF(INTRERR, (CE_WARN, "wrsm_sendq_create: " - "invalid callback 0x%p", (void *)fn)); - return (RSMERR_CALLBACKS_NOT_SUPPORTED); - } - - if (addr >= WRSM_MAX_CNODES) { - DPRINTF(INTRERR, (CE_WARN, "wrsm_sendq_create: " - "invalid cnode")); - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - req->header.message_type = WRSM_MSG_INTR_RECVQ_CREATE; - req->service = service; - req->prio = prio; - req->qdepth = qdepth; - - /* Send request to remote node to create a receive queue */ - do { - if (wrsm_tl_rpc(net, dest_cnode, (wrsm_message_t *)req, - (wrsm_message_t *)rsp)) { - DPRINTF(INTRERR, (CE_WARN, "wrsm_sendq_create: " - "rpc failed")); - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - if (rsp->retval && rsp->retval != - RSMERR_INSUFFICIENT_RESOURCES) { - DPRINTF(INTRERR, (CE_WARN, "wrsm_sendq_create: " - "remote reject: %d", rsp->retval)); - return (RSMERR_NO_HANDLER); - } - if (rsp->retval == RSMERR_INSUFFICIENT_RESOURCES && - fn != RSM_RESOURCE_SLEEP) { - /* Temporary failure, but user said don't sleep */ - DPRINTF(INTRERR, (CE_WARN, "wrsm_sendq_create: " - "remote reject: EAGAIN")); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - } while (rsp->retval); - - /* Map-in interrupt page */ - if (ddi_map_regs(wrsm_ncslice_dip, - (uint_t)net->nodes[dest_cnode]->config->comm_ncslice, - &vaddr, - (off_t)rsp->nc_off, - PAGESIZE) != DDI_SUCCESS) { - /* Send recvq_destroy message */ - wrsm_raw_message_t raw_msg; - recvq_destroy_t *msg = (recvq_destroy_t *)&raw_msg; - DPRINTF(INTRERR, (CE_WARN, "wrsm_sendq_create: " - "ddi_map_regs failed")); - - msg->header.message_type = WRSM_MSG_INTR_RECVQ_DESTROY; - msg->qid = rsp->qid; - msg->mondo = rsp->mondo; - msg->service = service; - (void) wrsm_tl_dg(net, dest_cnode, (wrsm_message_t *)msg); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - - /* Create sendq structure and pass back result */ - sendq = kmem_zalloc(sizeof (wrsm_sendq_t), KM_SLEEP); - mutex_init(&sendq->mutex, NULL, MUTEX_DRIVER, NULL); - sendq->net = net; - sendq->vaddr = vaddr; - sendq->nc_off = rsp->nc_off; - sendq->nc_slice = net->nodes[dest_cnode]->config->comm_ncslice; - sendq->offset = NULL; - sendq->qid = rsp->qid; - sendq->mondo = rsp->mondo; - sendq->dest_cnode = dest_cnode; - sendq->qdepth = qdepth; - sendq->service = service; - sendq->flags = flags; - - /* Add sendq to linked list of sendqs */ - mutex_enter(&net->interrupt->mutex); - sendq->next = net->interrupt->sendq_list[dest_cnode]; - net->interrupt->sendq_list[dest_cnode] = sendq; - net->sendqs_num++; - mutex_exit(&net->interrupt->mutex); - - *send_q = (rsm_send_q_handle_t)sendq; - return (RSM_SUCCESS); -} - -/* Reconfigure some of the attributes of an interrupt queue */ -/* ARGSUSED */ -int -wrsm_sendq_config( - rsm_send_q_handle_t send_q, - rsm_intr_pri_t prio, - size_t qdepth, - uint_t flags, - rsm_resource_callback_t fn, - rsm_resource_callback_arg_t arg) -{ - wrsm_sendq_t *sendq = (wrsm_sendq_t *)send_q; - wrsm_network_t *net = sendq->net; - wrsm_raw_message_t raw_req; - wrsm_raw_message_t raw_rsp; - recvq_config_req_t *req = (recvq_config_req_t *)&raw_req; - recvq_config_rsp_t *rsp = (recvq_config_rsp_t *)&raw_rsp; - cnodeid_t dest_cnode; - int retval = RSM_SUCCESS; - - DTRC("wrsm_sendq_config"); - - if (fn != RSM_RESOURCE_SLEEP && fn != RSM_RESOURCE_DONTWAIT) { - DPRINTF(INTRERR, (CE_WARN, "wrsm_sendq_config: " - "invalid callback 0x%p", (void *)fn)); - return (RSMERR_CALLBACKS_NOT_SUPPORTED); - } - - if (sendq->net_reset) { - WARN("Attempt to sendq_config after net reset"); - return (RSMERR_CONN_ABORTED); - } - - mutex_enter(&sendq->mutex); - - sendq->flags = flags; - /* If fence was up, and we're getting rid of fence, then lower it */ - if (sendq->flags & RSM_INTR_SEND_Q_NO_FENCE) { - sendq->fence_up = B_FALSE; - } - - /* Request remote node reconfigure the receive queue */ - if (sendq->qdepth != qdepth) { - req->header.message_type = WRSM_MSG_INTR_RECVQ_CONFIG; - req->qid = sendq->qid; - req->mondo = sendq->mondo; - req->new_qdepth = qdepth; - dest_cnode = sendq->dest_cnode; - NOTE(" Sending recvq_config rpc to remote node"); - if (wrsm_tl_rpc(net, dest_cnode, (wrsm_message_t *)req, - (wrsm_message_t *)rsp)) { - DPRINTF(INTRERR, (CE_WARN, "wrsm_sendq_config: " - "rpc failed")); - retval = RSMERR_CONN_ABORTED; - } else if (rsp->retval) { - DPRINTF(INTRERR, (CE_WARN, "wrsm_sendq_config: " - "remote reject: %d", rsp->retval)); - retval = rsp->retval; - } else { - /* Update the qdepth */ - sendq->qdepth = qdepth; - } - } - mutex_exit(&sendq->mutex); - - return (retval); -} - -/* Destroys an interrupt queue, freeing all resources allocated */ -/* ARGSUSED */ -int -wrsm_sendq_destroy(rsm_send_q_handle_t send_q) -{ - wrsm_sendq_t *sendq = (wrsm_sendq_t *)send_q; - wrsm_interrupt_t *intr; - DTRC("wrsm_sendq_destroy"); - - ASSERT(sendq); - - intr = sendq->net->interrupt; - ASSERT(intr); - - mutex_enter(&intr->mutex); - mutex_enter(&sendq->mutex); - - if (!sendq->net_reset) { - cnodeid_t dest_cnode = sendq->dest_cnode; - wrsm_sendq_t *sq; - wrsm_raw_message_t raw_msg; - recvq_destroy_t *msg = (recvq_destroy_t *)&raw_msg; - - /* Remove from sendq_list */ - sq = intr->sendq_list[dest_cnode]; - if (sq == sendq) { - intr->sendq_list[dest_cnode] = sendq->next; - sendq->next = NULL; - } else while (sq && sq->next) { - if (sq->next == sendq) { - sq->next = sendq->next; - sendq->next = NULL; - break; - } - sq = sq->next; - } - - /* Send message to remove node */ - msg->header.message_type = WRSM_MSG_INTR_RECVQ_DESTROY; - msg->qid = sendq->qid; - msg->mondo = sendq->mondo; - msg->service = sendq->service; - (void) wrsm_tl_dg(sendq->net, sendq->dest_cnode, - (wrsm_message_t *)msg); - } - mutex_exit(&sendq->mutex); - sendq->net->sendqs_num--; - mutex_exit(&intr->mutex); - - mutex_destroy(&sendq->mutex); - - ddi_unmap_regs(wrsm_ncslice_dip, - (uint_t)sendq->nc_slice, - &sendq->vaddr, - (off_t)sendq->nc_off, - PAGESIZE); - kmem_free(sendq, sizeof (wrsm_sendq_t)); - - return (RSM_SUCCESS); -} - -/* Enqueues a datagram on an interrupt queue */ -/* ARGSUSED */ -int -wrsm_send( - rsm_send_q_handle_t send_q, - rsm_send_t *is, - rsm_barrier_t *barrier) -{ - int retval; - wrsm_sendq_t *sendq = (wrsm_sendq_t *)send_q; - wrsm_raw_message_t raw_buf; - uint64_t *buf = (uint64_t *)&raw_buf; - clock_t wait_time; - cnodeid_t dest_cnode; - caddr_t vaddr; - int sendq_flags; - - mutex_enter(&sendq->mutex); - if (barrier) { - mutex_exit(&sendq->mutex); - return (RSMERR_BAD_BARRIER_HNDL); - } - if (sendq->net_reset) { - mutex_exit(&sendq->mutex); - return (RSMERR_CONN_ABORTED); - } - if (is->is_flags & RSM_INTR_SEND_LOWER_FENCE) { - sendq->fence_up = B_FALSE; - } - if (sendq->fence_up) { - mutex_exit(&sendq->mutex); - return (RSMERR_QUEUE_FENCE_UP); - } - ASSERT(sendq->net->attr.attr_intr_data_size_max <= - (WRSM_TL_MSG_SIZE - sizeof (uint64_t))); - - if (is->is_size > sendq->net->attr.attr_intr_data_size_max) { - mutex_exit(&sendq->mutex); - return (RSMERR_BAD_BARRIER_HNDL); - } - - /* Copy data to an aligned buffer */ - bcopy(is->is_data, &buf[1], is->is_size); - buf[0] = is->is_size; - -#ifdef DEBUG - ((caddr_t)(buf))[6] = sendq->net->cnodeid; -#endif /* DEBUG */ - - /* Increment the offset, to take advantage of striping */ - sendq->offset = (sendq->offset + WCI_CLUSTER_STRIPE_STRIDE) & - WCI_CLUSTER_STRIPE_MASK; - - /* If method-of-wait is SLEEP, is_wait of 0 means "wait forever" */ - wait_time = is->is_wait; - if (wait_time == 0 && (is->is_flags & RSM_INTR_SEND_SLEEP)) { - wait_time = INFINITY; - } - - vaddr = sendq->vaddr + sendq->offset; - dest_cnode = sendq->dest_cnode; - sendq_flags = sendq->flags; - - mutex_exit(&sendq->mutex); - - /* Send the packet */ - retval = wrsm_intr_send(sendq->net, - vaddr, - dest_cnode, - buf, - is->is_flags, - wait_time, - sendq_flags); - - if (retval && !(sendq_flags & RSM_INTR_SEND_Q_NO_FENCE)) { - sendq->fence_up = B_TRUE; - } - - return (retval); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_lc.c b/usr/src/uts/sun4u/io/wrsm/wrsm_lc.c deleted file mode 100644 index e761cb1a8f..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_lc.c +++ /dev/null @@ -1,4106 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file manages WCIs for the Wildcat RSM driver. It orchestrates link - * bringup and takedown based on configuration changes and changes in - * remote connectivity, monitors links, and reports status to higher layers - * (specifically, the multi-hop layer and syseventd). - */ - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/debug.h> -#include <sys/errno.h> -#include <sys/cmn_err.h> -#include <sys/int_fmtio.h> -#include <sys/modctl.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/machsystm.h> -#include <sys/async.h> -#include <sys/cheetahregs.h> -#include <sys/nvpair.h> -#include <sys/policy.h> - -#include <sys/wci_common.h> -#include <sys/wci_regs.h> -#include <sys/wci_offsets.h> -#include <sys/wci_masks.h> -#include <sys/wrsm_lc.h> -#include <sys/wrsm_driver.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_cf.h> -#include <sys/wrsm_plat.h> - - -#ifdef DEBUG -#define LC_DEBUG 0x001 -#define LC_CSR_WRITE_DEBUG 0x002 -#define LC_CSR_READ_DEBUG 0x004 -#define LC_POLL 0x008 -#define LC_CMMU 0x010 -#define LC_CESR 0x020 -#define LC_HWSH 0x040 -#define LC_DEBUG_EXTRA 0x100 -#define LC_WARN 0x200 -#define LC_ECC 0x400 -#define LC_DEBUG_PLAT 0x800 -static uint32_t wrsm_lc_debug = LC_WARN; -#define DPRINTF(a, b) { if (wrsm_lc_debug & a) wrsmdprintf b; } - -#else /* DEBUG */ - -#define DPRINTF(a, b) { } - -#endif /* DEBUG */ - -#define LC_MAX_CONT_ERRS 100 -#define ADDR_LAST_CSR (ADDR_WCI_DNID2GNID) /* Address of last CSR */ - -/* globals */ -/* weight of old average in error average */ -uint_t wrsm_avg_weight = 10; -/* minutes in shortterm error interval */ -uint_t wrsm_shortterm_interval = 60; -/* number of shortterm intervals per long term interval */ -uint_t wrsm_shorts_per_longterm = 24; - -/* - * Artificially limit ourselves to only enough CMMU entries to map 4GB - * of exported memory. This is to work around a bug in sun4u/rootnex.c - * in that it's not 64bit clean. - * - * Normal value: 0x200000 2M entries, 16GB - * Workaround value: 0x80000 .5M entries, 4GB - */ -static uint_t wrsm_cmmu_max_entries = 0x80000; - -static clock_t wrsm_poll_hz; -static clock_t wrsm_restart_hz; -static clock_t wrsm_shortterm_hz; -boolean_t wrsm_log_link_errors = B_FALSE; - -#define BIT(id, bits) (((id) & (1 << (bits))) >> (bits)) -/* calculate the weight over wrsm_avg_weight intervals */ -#define RUNNING_AVG(value, avg) (value + avg - (avg/wrsm_avg_weight)) -#define MAX(i, j) ((i > j)?i:j) - -/* prototypes for local functions */ -static void wrsm_lc_link_bringup(wrsm_softstate_t *softsp, uint32_t link_num); -static void wrsm_lc_link_takedown(wrsm_softstate_t *softsp, - uint32_t local_link_num, boolean_t linkerr, boolean_t user_requested); -static void wrsm_lc_wciinit(wrsm_softstate_t *softsp, cnodeid_t local_cnode, - wnodeid_t local_wnode); -static void wrsm_lc_platform_wciinit(wrsm_softstate_t *softsp); -static void wrsm_lc_wcifini(wrsm_softstate_t *softsp); -static void wrsm_lc_err_cnt(wrsm_softstate_t *softsp, - boolean_t do_shortterm); -static void wrsm_lc_poll_timeout(wrsm_softstate_t *softsp); -static void wrsm_lc_check_lockout(wrsm_softstate_t *softsp); -static uint32_t get_index(wrsm_softstate_t *softsp, uint32_t dev_id); -static void wrsm_lc_clear_cmmu(wrsm_softstate_t *softsp); -static void wrsm_lc_ecc_check(wrsm_softstate_t *softsp); -static void wrsm_handle_ce_error(struct wrsm_soft_state *softsp, - struct async_flt *ecc, int agent_type); -static void wrsm_handle_ue_error(struct wrsm_soft_state *softsp, - struct async_flt *ecc, int agent_type); - -static void wrsm_lc_sram_ecc_check(wrsm_softstate_t *softsp, - boolean_t do_shortterm); -static void wrsm_lc_restart_downlinks(wrsm_softstate_t *softsp); -static void wrsm_lc_check_paroli_hotplug(wrsm_softstate_t *softsp); -static void wrsm_lc_check_wcx_links(wrsm_softstate_t *softsp); -static void wrsm_lc_logevent(wrsm_softstate_t *softsp, - wrsm_sys_event_t eventtype, uint32_t local_link_num, char *reason); -#define NUM_PLATFORMS 7 - -typedef enum { - starcat_direct, /* starcat in direct connect topology */ - starcat_wcx, /* starcat in WCX topology */ - starcat_pt, /* starcat compute node in central switch */ - serengeti_direct, /* serengeti in direct connect topology */ - serengeti_wcx, /* serengeti in WCX topology */ - serengeti_pt, /* serengeti compute node in central switch */ - starcat_switch /* starcat as a central switch */ -} wrsm_platform_types_t; - - -#define SET_ROUTE(route_map, wnode, linknum) \ - switch (wnode) { \ - case 0: route_map.bit.node0_tlink = linknum; break; \ - case 1: route_map.bit.node1_tlink = linknum; break; \ - case 2: route_map.bit.node2_tlink = linknum; break; \ - case 3: route_map.bit.node3_tlink = linknum; break; \ - case 4: route_map.bit.node4_tlink = linknum; break; \ - case 5: route_map.bit.node5_tlink = linknum; break; \ - case 6: route_map.bit.node6_tlink = linknum; break; \ - case 7: route_map.bit.node7_tlink = linknum; break; \ - case 8: route_map.bit.node8_tlink = linknum; break; \ - case 9: route_map.bit.node9_tlink = linknum; break; \ - case 10: route_map.bit.node10_tlink = linknum; break; \ - case 11: route_map.bit.node11_tlink = linknum; break; \ - case 12: route_map.bit.node12_tlink = linknum; break; \ - case 13: route_map.bit.node13_tlink = linknum; break; \ - case 14: route_map.bit.node14_tlink = linknum; break; \ - case 15: route_map.bit.node15_tlink = linknum; break; \ - default: ASSERT(wnode < 15 && "illegal wnodeid/gnidid"); \ - } - -#define GET_ROUTE(linknum, route_map, wnode) \ - switch (wnode) { \ - case 0: linknum = route_map.bit.node0_tlink; break; \ - case 1: linknum = route_map.bit.node1_tlink; break; \ - case 2: linknum = route_map.bit.node2_tlink; break; \ - case 3: linknum = route_map.bit.node3_tlink; break; \ - case 4: linknum = route_map.bit.node4_tlink; break; \ - case 5: linknum = route_map.bit.node5_tlink; break; \ - case 6: linknum = route_map.bit.node6_tlink; break; \ - case 7: linknum = route_map.bit.node7_tlink; break; \ - case 8: linknum = route_map.bit.node8_tlink; break; \ - case 9: linknum = route_map.bit.node9_tlink; break; \ - case 10: linknum = route_map.bit.node10_tlink; break; \ - case 11: linknum = route_map.bit.node11_tlink; break; \ - case 12: linknum = route_map.bit.node12_tlink; break; \ - case 13: linknum = route_map.bit.node13_tlink; break; \ - case 14: linknum = route_map.bit.node14_tlink; break; \ - case 15: linknum = route_map.bit.node15_tlink; break; \ - default: ASSERT(wnode < 15 && "illegal wnodeid/gnidid"); \ - } - -#define CA_TIMEOUT_CONFIG_VAL_WCI2 0x00001000000100FFULL - -static gnid_t -wnode_to_gnid(wrsm_softstate_t *softsp, wnodeid_t wnode) -{ - gnid_t gnid; - - /* - * For a WCX, the wnode is always equal to the gnid - * so that mapping is not stored in the table. - */ - if (WRSM_GNID_IS_WCX(wnode)) - return (wnode); - - for (gnid = 0; gnid < WRSM_MAX_WNODES; gnid++) { - wnodeid_t wnode_tmp = softsp->gnid_to_wnode[gnid]; - /* Make sure this wnode is in a valid range */ - if (wnode_tmp >= WRSM_MAX_WNODES) { - continue; - } - /* See if gnid yielded the right wnode id */ - if (wnode_tmp == wnode) { - break; - } - } - return (gnid); -} - -linkid_t -wrsm_lc_get_route(wrsm_softstate_t *softsp, wnodeid_t wnode, int map) -{ - wci_route_map0_u route_map; - linkid_t link; - - if (map == 0) { - wrsm_lc_csr_read(softsp, ADDR_WCI_ROUTE_MAP0, - &(route_map.val)); - } else { - wrsm_lc_csr_read(softsp, ADDR_WCI_ROUTE_MAP1, - &(route_map.val)); - } - GET_ROUTE(link, route_map, wnode); - DPRINTF(LC_DEBUG_EXTRA, (CE_NOTE, "wrsm_lc_get_route: " - "wnode %d map %d link %u val %lx", wnode, map, - link, route_map.val)); - - return (link); -} - -void -wrsm_lc_set_route(wrsm_softstate_t *softsp, wnodeid_t wnode, linkid_t linknum, - int map) -{ - gnid_t gnid; - wci_route_map0_u route_map0; - wci_route_map1_u route_map1; - wci_gnid_map0_u gnid_map0; - wci_gnid_map1_u gnid_map1; - - gnid = wnode_to_gnid(softsp, wnode); - if (gnid >= WRSM_MAX_WNODES) { - DPRINTF(LC_WARN, (CE_WARN, "Invalid gnid_to_wnode, wnode %u", - wnode)); - return; - } - - if (map == 0) { - wrsm_lc_csr_read(softsp, ADDR_WCI_ROUTE_MAP0, - &(route_map0.val)); - SET_ROUTE(route_map0, wnode, linknum); - wrsm_lc_csr_write(softsp, ADDR_WCI_ROUTE_MAP0, route_map0.val); - DPRINTF(LC_DEBUG_EXTRA, (CE_NOTE, "lc_set_route0 wnode %d " - "link %d map %d new val %lx", wnode, linknum, map, - route_map0.val)); - if (softsp->wci_rev >= 30) { - /* also update wci_gnid_map0 for wci 3 */ - wrsm_lc_csr_read(softsp, ADDR_WCI_GNID_MAP0, - &(gnid_map0.val)); - SET_ROUTE(gnid_map0, gnid, linknum); - wrsm_lc_csr_write(softsp, ADDR_WCI_GNID_MAP0, - gnid_map0.val); - } - } else { - wrsm_lc_csr_read(softsp, ADDR_WCI_ROUTE_MAP1, - &(route_map1.val)); - SET_ROUTE(route_map1, wnode, linknum); - wrsm_lc_csr_write(softsp, ADDR_WCI_ROUTE_MAP1, route_map1.val); - DPRINTF(LC_DEBUG_EXTRA, (CE_NOTE, "lc_set_route1 wnode %d " - "link %d map %d new val %lx", wnode, linknum, map, - route_map0.val)); - if (softsp->wci_rev >= 30) { - /* also update wci_gnid_map1 for wci 3 */ - wrsm_lc_csr_read(softsp, ADDR_WCI_GNID_MAP1, - &(gnid_map1.val)); - SET_ROUTE(gnid_map1, gnid, linknum); - wrsm_lc_csr_write(softsp, ADDR_WCI_GNID_MAP1, - gnid_map1.val); - } - } -} - -static void -wrsm_lc_link_bringup(wrsm_softstate_t *softsp, uint32_t local_link_num) -{ - wrsm_link_req_state_t link_state; - ASSERT(softsp != NULL); - ASSERT(softsp->config != NULL); - ASSERT(local_link_num < WRSM_LINKS_PER_WCI); - ASSERT(MUTEX_HELD(&softsp->lc_mutex)); - - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_link_bringup wci %d link %d", - softsp->portid, local_link_num)); - - softsp->links[local_link_num].user_down_requested = B_FALSE; - - link_state = softsp->links[local_link_num].link_req_state; - - if ((link_state == lc_down) || - (link_state == sc_wait_errdown) || - (link_state == sc_wait_down) || - (link_state == sc_wait_up) || - (link_state == lc_up)) { - if (link_state != lc_up) { - /* - * lc_up links are config confirmation requests, - * hence shouldn't change to sc_wait_up state. - */ - softsp->links[local_link_num].link_req_state = - sc_wait_up; - } - softsp->links[local_link_num].num_requested_bringups++; - softsp->links[local_link_num].waiting_count = 0; - (void) wrsmplat_uplink(softsp->portid, - (linkid_t)local_link_num, - softsp->local_gnid, - softsp->ctlr_config->fmnodeid, - softsp->ctlr_config->version_stamp, - softsp->ctlr_config->controller_id, - B_FALSE /* loopback */); -#ifdef DEBUG - } else { - DPRINTF(LC_DEBUG, (CE_WARN, "unexpected link state %d for " - "for wrsm%d link %d wci %d wci", - link_state, - softsp->instance, - local_link_num, softsp->portid)); -#endif /* DEBUG */ - } -} - -int -wrsm_lc_loopback_enable(wrsm_softstate_t *softsp, uint32_t local_link_num) -{ - int rc; - wci_sw_config_u sw_config; - - if (local_link_num >= WRSM_LINKS_PER_WCI) - return (EINVAL); - - if ((rc = wrsm_cf_claim_wci(WRSM_LOOPBACK_ID, softsp->portid)) != 0) - return (rc); - - wrsm_lc_csr_read(softsp, ADDR_WCI_SW_CONFIG, &sw_config.val); - - softsp->links[local_link_num].loopback_test_mode = B_TRUE; - (void) wrsmplat_uplink(softsp->portid, (linkid_t)local_link_num, - sw_config.bit.gnid, 0, 0, 0, B_TRUE); - - return (0); -} - -int -wrsm_lc_loopback_disable(wrsm_softstate_t *softsp, uint32_t local_link_num) -{ - int i; - boolean_t release; - - if (local_link_num >= WRSM_LINKS_PER_WCI) - return (EINVAL); - - if (wrsm_cf_wci_owner(softsp->portid) != WRSM_LOOPBACK_ID) - return (EACCES); - - (void) wrsmplat_downlink(softsp->portid, (linkid_t)local_link_num, - B_TRUE); - softsp->links[local_link_num].loopback_test_mode = B_FALSE; - - /* - * If no other links on this wci are in loopback test mode - * then release the wci for general use - */ - release = B_TRUE; - for (i = 0; i < WRSM_LINKS_PER_WCI; ++i) { - if (softsp->links[i].loopback_test_mode) { - release = B_FALSE; - break; - } - } - if (release) - wrsm_cf_release_wci(softsp->portid); - - return (0); -} - -int -wrsm_lc_linktest(wrsm_softstate_t *softsp, wrsm_linktest_arg_t *linktest) -{ - if (wrsm_cf_wci_owner(softsp->portid) != WRSM_LOOPBACK_ID) - return (EACCES); - - return (wrsmplat_linktest(softsp->portid, linktest)); -} - -/* - * Take down link, and record that this is a user-requested takedown. - */ -int -wrsm_lc_user_linkdown(wrsm_softstate_t *softsp, int linkno) -{ - if ((linkno < 0) || (linkno >= WRSM_LINKS_PER_WCI)) { - return (EINVAL); - } - - mutex_enter(&softsp->lc_mutex); - wrsm_lc_link_takedown(softsp, linkno, B_FALSE, B_TRUE); - mutex_exit(&softsp->lc_mutex); - return (0); -} - -/* - * Unset user takedown boolean, and attempt to bring it up link. - */ -int -wrsm_lc_user_linkup(wrsm_softstate_t *softsp, int linkno) -{ - if ((linkno < 0) || (linkno >= WRSM_LINKS_PER_WCI)) { - return (EINVAL); - } - - mutex_enter(&softsp->lc_mutex); - - if ((softsp->config == NULL) || - !softsp->config->links[linkno].present) { - mutex_exit(&softsp->lc_mutex); - return (ENODEV); - } - - wrsm_lc_link_bringup(softsp, linkno); - mutex_exit(&softsp->lc_mutex); - - return (0); -} - -void -lc_link_takedown_all(wrsm_softstate_t *softsp, uint32_t link) -{ - int i; - gnid_t remote_gnid; - wnodeid_t remote_wnode; - - ASSERT(softsp); - ASSERT(link < WRSM_LINKS_PER_WCI); - - remote_wnode = softsp->links[link].remote_wnode; - remote_gnid = wnode_to_gnid(softsp, remote_wnode); - - DPRINTF(LC_DEBUG, (CE_CONT, "lc_link_takedown_all: wci %d link %d " - "remote_wnode %d remote_gnid %d", softsp->portid, link, - remote_wnode, remote_gnid)); - - if (WRSM_GNID_IS_WCX(remote_gnid)) { - int gnids = softsp->links[link].remote_gnids_active; - for (i = 0; i < WRSM_MAX_WNODES; ++i) { - if ((gnids & (1 << i)) && - (softsp->gnid_to_wnode[i] <= WRSM_MAX_WNODES)) { - wrsm_mh_link_is_down(softsp->nc, link, - softsp->gnid_to_wnode[i]); - } - } - softsp->links[link].remote_gnids_active = 0; - } else { - wrsm_mh_link_is_down(softsp->nc, link, remote_wnode); - } -} - -static void -wrsm_lc_link_takedown(wrsm_softstate_t *softsp, uint32_t local_link_num, - boolean_t linkerr, boolean_t user_requested) -{ - wrsm_link_req_state_t link_state; - - ASSERT(softsp != NULL); - ASSERT(local_link_num < WRSM_LINKS_PER_WCI); - ASSERT(MUTEX_HELD(&softsp->lc_mutex)); - - if (user_requested) { - softsp->links[local_link_num].user_down_requested = B_TRUE; - } - - link_state = softsp->links[local_link_num].link_req_state; - - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_link_takedown: wci %d link %d " - "linkerr %d user %d remote_wnode %d state %d", softsp->portid, - local_link_num, linkerr, user_requested, - softsp->links[local_link_num].remote_wnode, link_state)); - - if ((link_state != lc_up) && linkerr) { - /* - * ignore any request for link takedown due to linkerr - * unless the current link state is up. (A linkerr - * takedown is only generated when the link was up, but - * because the lock is dropped, this may not be the state - * by the time we get here.) - */ - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_link_takedown: " - "link %d not up, state = %d", local_link_num, - link_state)); - return; - } - - if ((link_state == lc_up) || (link_state == sc_wait_up)) { - - DPRINTF(LC_DEBUG, (CE_CONT, "in wrsm_lc_link_takedown" - " up/setstate/waitup link %d wci %d", - local_link_num, softsp->portid)); - - ASSERT(softsp); - ASSERT(local_link_num < WRSM_LINKS_PER_WCI); - - softsp->links[local_link_num].link_req_state = - sc_wait_down; - - if (link_state == lc_up) { - /* Notify MH that link is going down */ - if (softsp->links[local_link_num].tell_mh_link_is_up) { - lc_link_takedown_all(softsp, local_link_num); - } - - /* - * check for a linkerr reason for links in lc_up state - */ - if (linkerr) { - /* - * Link takedown request is due to link - * errors. Change state to sc_wait_errdown. - */ - DPRINTF(LC_DEBUG, (CE_CONT, - "in wrsm_lc_link_takedown: linkerr")); - - softsp->links[local_link_num].link_req_state = - sc_wait_errdown; - - if (!softsp->links[local_link_num]. - tell_mh_link_is_up) { - /* - * Link error occured on an up link - * after a link_bringup that was - * requested by lc_installconfig. - * mh_link_is_up has not been - * called yet because - * tell_mh_link_is_up is still - * false. Increment - * newlink_waitup_cnt since we must - * now wait for this link to come - * back up - again. - */ - softsp->newlink_waitup_cnt++; - } - } else { - /* - * link_takedown request was intentially - * unconfigured. log system event. - */ - wrsm_lc_logevent(softsp, link_down, - local_link_num, "unconfigured"); - } - } - - (void) wrsmplat_downlink(softsp->portid, - (linkid_t)local_link_num, B_FALSE); - - } else if (link_state == sc_wait_errdown) { - /* - * lc_cleanconfig or user requested link takedown while - * link was already coming down due to link error. - * Change state so link does not come back up automatically. - */ - DPRINTF(LC_DEBUG, (CE_CONT, "in wrsm_lc_link_takedown" - " errdown state link %d wci %d linkerr true", - local_link_num, softsp->portid)); - softsp->links[local_link_num].link_req_state = - sc_wait_down; - (void) wrsmplat_downlink(softsp->portid, - (linkid_t)local_link_num, B_FALSE); - - } - softsp->links[local_link_num].waiting_count = 0; - - /* - * ignore link down request if link is already down - */ -} - -void -wrsm_lc_logevent(wrsm_softstate_t *softsp, wrsm_sys_event_t eventtype, - uint32_t local_link_num, char *reason) -{ - nvlist_t *attr_list; - int err = DDI_SUCCESS; - uint32_t rsm_ctlr_id; - - ASSERT(softsp); - - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_logevent: link %d wci %d", - local_link_num, softsp->portid)); - - rsm_ctlr_id = wrsm_nr_getcontroller_id(softsp->nc); - if ((err = nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, - KM_SLEEP)) == DDI_SUCCESS) { - err = nvlist_add_uint32(attr_list, "controller", - rsm_ctlr_id); - if (err == DDI_SUCCESS) { - err = nvlist_add_uint32(attr_list, "portid", - softsp->portid); - } - if (err == DDI_SUCCESS) { - err = nvlist_add_uint32(attr_list, "link", - local_link_num); - } - - switch (eventtype) { - case link_up: - cmn_err(CE_NOTE, "wci %d link %d up", - softsp->portid, local_link_num); - if (err == DDI_SUCCESS) { - err = ddi_log_sysevent(softsp->dip, - DDI_VENDOR_SUNW, WRSM_CLASS, - WRSM_SUBCLASS_LINKUP, - attr_list, NULL, DDI_SLEEP); - } - break; - case link_down: - cmn_err(CE_NOTE, "wci %d link %d down: %s", - softsp->portid, local_link_num, reason); - if (err == DDI_SUCCESS) { - err = nvlist_add_string(attr_list, "reason", - reason); - } - if (err == DDI_SUCCESS) { - err = ddi_log_sysevent(softsp->dip, - DDI_VENDOR_SUNW, WRSM_CLASS, - WRSM_SUBCLASS_LINKDOWN, - attr_list, NULL, DDI_SLEEP); - } - break; - default: - break; - } - - nvlist_free(attr_list); - } -#ifdef DEBUG - if (err != DDI_SUCCESS) { - DPRINTF(LC_WARN, (CE_WARN, "ERROR LOGGING system event")); - } -#endif /* DEBUG */ -} -/* - * This function is only called by the Mbox message handler function. - * it is called when the SC has completed discovery. - * The purpose of this functions is to confirm the remote config data before - * the hardware knows the link is physically 'connected' that is, the wci - * register has link_state = in-use. Once lc_phys_link_up confirms that remote - * data is correct, it will put in a request for the SC to set the link_state - * to in-use - */ -/* ARGSUSED */ -void -wrsm_lc_phys_link_up(safari_port_t local_port, uint32_t local_link_num, - fmnodeid_t remote_fmnodeid, gnid_t remote_gnid, - uint32_t remote_link_num, safari_port_t remote_port, uint64_t - remote_partition_version, uint32_t remote_partition_id) -{ - wrsm_softstate_t *softsp; - wrsm_linkbadconfig_reasons_t badconfig; - boolean_t badconfigcaught = B_FALSE; - - badconfig.val = 0; - - softsp = wrsm_cf_lookup_wci(local_port); - - if ((softsp == NULL) || (local_link_num >= WRSM_LINKS_PER_WCI)) { - /* - * since data is invalid, we are not sure - * how to send a stop discovery message - */ - DPRINTF(LC_WARN, (CE_WARN, "wrsm_lc_phys_link_up: " - "Invalid args wrsm%d link %d", - softsp?softsp->instance:-1, local_link_num)); - return; - } - - DPRINTF(LC_DEBUG, (CE_CONT, "in wrsm_lc_phys_link_up link %d " - "wci %d", local_link_num, softsp->portid)); - - mutex_enter(&softsp->lc_mutex); - softsp->links[local_link_num].num_completed_bringups++; - if ((softsp->config == NULL) || - (softsp->ctlr_config == NULL) || - (softsp->suspended) || - (!softsp->config->links[local_link_num].present) || - (softsp->links[local_link_num].link_req_state != sc_wait_up && - softsp->links[local_link_num].link_req_state != lc_up)) { - mutex_exit(&softsp->lc_mutex); - return; - } - - /* verify args */ - if (softsp->ctlr_config->version_stamp != - remote_partition_version) { - badconfig.reasons.bad_ctlr_version = B_TRUE; - badconfigcaught = B_TRUE; - cmn_err(CE_WARN, "wci %d link %d bad remote configuration: " - "got controller version %ld expected %ld", - softsp->portid, local_link_num, - remote_partition_version, - softsp->ctlr_config->version_stamp); - } else { - if (softsp->ctlr_config->controller_id != - remote_partition_id) { - badconfig.reasons.bad_ctlr_id = B_TRUE; - badconfigcaught = B_TRUE; - cmn_err(CE_WARN, - "wci %d link %d bad remote configuration: " - "got controller id %d expected %d", - softsp->portid, local_link_num, - remote_partition_id, - softsp->ctlr_config->controller_id); - } - if (softsp->config->links[local_link_num]. - remote_gnid != remote_gnid) { - badconfig.reasons.bad_gnid = B_TRUE; - badconfigcaught = B_TRUE; - cmn_err(CE_WARN, - "wci %d link %d bad remote configuration: " - "got gnid %d expected %d", softsp->portid, - local_link_num, remote_gnid, - softsp->config->links[local_link_num]. - remote_gnid); - } - if (softsp->config->links[local_link_num]. - remote_link_num != remote_link_num) { - badconfig.reasons.bad_linknum = B_TRUE; - badconfigcaught = B_TRUE; - cmn_err(CE_WARN, - "wci %d link %d bad remote configuration: " - "got link # %d expected %d", softsp->portid, - local_link_num, remote_link_num, - softsp->config->links[local_link_num]. - remote_link_num); - } - if (softsp->config->links[local_link_num].remote_port - != remote_port) { - badconfig.reasons.bad_safari_port_id = B_TRUE; - badconfigcaught = B_TRUE; - cmn_err(CE_WARN, - "wci %d link %d bad remote configuration: " - "got safari port id %d expected %d", - softsp->portid, local_link_num, remote_port, - softsp->config->links[local_link_num].remote_port); - } - } - /* Update softstate struct with badconfig reasons */ - softsp->links[local_link_num].badconfig_reasons.val = badconfig.val; - - if (badconfigcaught) { - softsp->links[local_link_num].num_cfg_takedown++; - wrsm_lc_link_takedown(softsp, local_link_num, - B_FALSE, B_FALSE); - mutex_exit(&softsp->lc_mutex); - wrsm_lc_logevent(softsp, link_down, local_link_num, - "badconfig"); - return; - } - - /* If we weren't waiting for the link to come up, just bail */ - if (softsp->links[local_link_num].link_req_state != sc_wait_up) { - mutex_exit(&softsp->lc_mutex); - return; - } - - softsp->links[local_link_num].link_req_state = lc_up; - if (WRSM_GNID_IS_WCX(remote_gnid)) - softsp->links[local_link_num].remote_wnode = remote_gnid; - else - softsp->links[local_link_num].remote_wnode = - softsp->gnid_to_wnode[remote_gnid]; - *softsp->links[local_link_num].wrsm_link_err_cnt_addr = 0; - - /* Is it OK to tell MH link is up? */ - if (WRSM_GNID_IS_WCX(remote_gnid)) { - softsp->links[local_link_num].remote_gnids_active = 0; - softsp->links[local_link_num].poll_reachable = B_TRUE; - wrsm_lc_logevent(softsp, link_up, local_link_num, - NULL); - mutex_exit(&softsp->lc_mutex); - return; - } else if (softsp->links[local_link_num].tell_mh_link_is_up) { - wnodeid_t remote_wnode = - softsp->links[local_link_num].remote_wnode; - mutex_exit(&softsp->lc_mutex); - /* LINTED: E_NOP_IF_STMT */ - if (remote_wnode >= WRSM_MAX_WNODES) { - DPRINTF(LC_WARN, (CE_WARN, - "Bad remote wnode for wci %d link %d: %d", - softsp->portid, local_link_num, - softsp->links[local_link_num].remote_wnode)); - } else { - wrsm_mh_link_is_up(softsp->nc, local_link_num, - softsp->links[local_link_num].remote_wnode); - wrsm_lc_logevent(softsp, link_up, - local_link_num, NULL); - } - return; - } else { - /* - * newlink_waitup_cnt is how we keep track of - * bringup link on a new link requested - * initiated by NR via lc_installconfig. - * In this case, link is up but the NR has - * not as of yet called lc_enableconfig - */ - softsp->newlink_waitup_cnt--; - ASSERT(softsp->newlink_waitup_cnt >= 0); - wrsm_lc_logevent(softsp, link_up, - local_link_num, NULL); - if (softsp->newlink_waitup_cnt == 0) { - /* - * All new links are up and MH doesn't - * know - tell NR so that it will call - * lc_enableconfig - */ - mutex_exit(&softsp->lc_mutex); - wrsm_nr_all_links_up(softsp->nc); - return; - } - } - mutex_exit(&softsp->lc_mutex); -} - - -/* - * this function is only called by the mbox message handler function. - * this function processes responses from the SC (via the SBBC mailbox) - * that a link is down. - * - * This may also be called when we bring down a link in loopback mode. - * it is harmless, as the lc state is marked as down and the call is ignored - */ -void -wrsm_lc_phys_link_down(safari_port_t local_port, uint32_t local_link_num) -{ - wrsm_softstate_t *softsp; - - softsp = wrsm_cf_lookup_wci(local_port); - - if ((softsp == NULL) || (local_link_num >= WRSM_LINKS_PER_WCI)) { - /* invalid args */ - DPRINTF(LC_WARN, (CE_WARN, "wrsm_lc_phys_link_down: " - "Invalid args wrsm%d link %d", - softsp->instance, local_link_num)); - return; - } - - DPRINTF(LC_DEBUG, (CE_CONT, "in wrsm_lc_phys_link_down link %d " - "wci %d", local_link_num, softsp->portid)); - - mutex_enter(&softsp->lc_mutex); - if (softsp->suspended) { - mutex_exit(&softsp->lc_mutex); - return; - } - - softsp->links[local_link_num].poll_reachable = B_FALSE; - if (softsp->links[local_link_num].link_req_state == sc_wait_down) { - - softsp->links[local_link_num].link_req_state = lc_down; - - if (((softsp->config == NULL) || - !softsp->config->links[local_link_num].present) && - (softsp->oldlink_waitdown_cnt != 0)) { - /* - * If oldlink_waitdown_cnt is set, lc_installconfig - * is waiting for all links not in the config to - * come down. Decrement oldlink_waitdown_cnt here - * to reflect that another link has come down. - */ - ASSERT(softsp->oldlink_waitdown_cnt >= 0 && - softsp->oldlink_waitdown_cnt <= - WRSM_LINKS_PER_WCI); - softsp->oldlink_waitdown_cnt--; - if (softsp->oldlink_waitdown_cnt == 0) { - /* - * All all requested links are down, so - * signal installconfig() to go. - */ - DPRINTF(LC_DEBUG, (CE_CONT, - "wrsm_lc_phys_link_down signal" - " lc_installconfig")); - cv_signal(&softsp->goinstallconfig); - } - - } else if (!softsp->links[local_link_num].user_down_requested) { - /* - * Link takedown must have been due to - * a config error being caught. Set timer to - * bring up link later if one isn't already set. - */ - if (softsp->restart_timeout_id == 0) { - if (softsp->suspended) { - softsp->need_restart_timeout = B_TRUE; - } else { - softsp->restart_timeout_id = - timeout((void (*)(void *)) - wrsm_lc_restart_downlinks, softsp, - wrsm_restart_hz); - DPRINTF(LC_DEBUG, (CE_CONT, - "RESTART LINK " - "timeout STARTED wci %d", - softsp->portid)); - } - } - } - - } else if (softsp->links[local_link_num].link_req_state == - sc_wait_errdown) { - /* - * If a new config is being installed which doesn't - * include this link, don't bring it back up. - */ - if ((softsp->config == NULL) || - !softsp->config->links[local_link_num].present) { - softsp->links[local_link_num].link_req_state = lc_down; - } else { - /* - * Link take down was due to link error. - * Immediately try bringing link back up, - * unless this link has had errors on the - * last LC_MAX_CONT_ERRS link error checks. - */ - if (softsp->links[local_link_num].cont_errs < - LC_MAX_CONT_ERRS) { - wrsm_lc_link_bringup(softsp, local_link_num); - } else { - /* - * Set timer to bring up link later if one - * isn't already set. - */ - softsp->links[local_link_num].link_req_state = - lc_down; - softsp->links[local_link_num].cont_errs = 0; - if (softsp->restart_timeout_id == 0) { - if (softsp->suspended) { - softsp->need_restart_timeout = - B_TRUE; - } else { - softsp->restart_timeout_id = - timeout((void (*)(void *)) - wrsm_lc_restart_downlinks, - softsp, - wrsm_restart_hz); - DPRINTF(LC_DEBUG, (CE_CONT, - "RESTART LINK " - "timeout STARTED wci %d", - softsp->portid)); - } - } - } - } - } - - mutex_exit(&softsp->lc_mutex); -} - - -/* - * one time setup for timeout speeds - */ -void -wrsm_lc_setup_timeout_speeds() -{ - wrsm_poll_hz = drv_usectohz(WRSM_POLL_TIMEOUT_USEC); - wrsm_restart_hz = drv_usectohz(WRSM_RESTART_TIMEOUT_USEC); - wrsm_shortterm_hz = drv_usectohz(WRSM_SHORTTERM_USEC); - DPRINTF(LC_POLL, (CE_CONT, "lc_setup_timeout: " - "poll = 0x%x restart = 0x%x shortterm = 0x%x", - wrsm_poll_hz, wrsm_restart_hz, wrsm_shortterm_hz)); -} - -static int -wrsm_lc_get_wci_rev(uint64_t jtag_id) -{ - int rev; - - switch (jtag_id) { - case WCI_ID_WCI1: - rev = 10; - break; - case WCI_ID_WCI2: - rev = 20; - break; - case WCI_ID_WCI3: - rev = 30; - break; - case WCI_ID_WCI31: - rev = 31; - break; - case WCI_ID_WCI4: - rev = 40; - break; - case WCI_ID_WCI41: - rev = 41; - break; - default: - rev = 99; - DPRINTF(LC_WARN, (CE_WARN, "unrecognized WCI jtag id 0x%lx" - " assuming equivalent to WCI 4.1", jtag_id)); - break; - } - return (rev); -} - -typedef struct { - uint32_t offset; - uint32_t mask_hi; - uint32_t mask_lo; - uint32_t shift; - uint32_t array_entries; - uint32_t plat_values[NUM_PLATFORMS]; -} wrsm_platform_csr_t; - -/* - * Create a wrsm_platform_csr_t entry - */ -#define TABLE(name, field, v1, v2, v3, v4, v5, v6, v7) \ -{ ADDR_ ## name, MASK_ ## name ## _ ## field, 1, v1, v2, v3, v4, v5, v6, v7 } - -/* - * Create a wrsm_platform_csr_t entry for a register array - */ -#define TABLE_A(name, field, v1, v2, v3, v4, v5, v6, v7) \ -{ ADDR_ ## name, MASK_ ## name ## _ ## field, ENTRIES_ ## name, \ -v1, v2, v3, v4, v5, v6, v7 } - -/* - * Create a wrsm_platform_csr_t entry using the same value for all - * platforms. - */ -#define TABLE_S(name, field, v) \ -{ ADDR_ ## name, MASK_ ## name ## _ ## field, 1, v, v, v, v, v, v, v } - -/* - * Platform specific CSRs - * - * The following is a list of all the WCI CSRs which may need to have - * different settings based on the platform type of the local node - * and/or the network topology. - * - * 0x00180 wci_error_pause_timer_hold - * 0x200e0 wci_ca_timeout_config - * 0x201a0 wci_ca_timeout_config_2 - * 0x001c0 wci_csra_timeout_config - * 0x500c0 wci_sa_timeout_config - * 0x31100 wci_ra_timeout_config - * 0x400e0 wci_ha_timeout_config - * 0x201e0 wci_qlim_config_cag - * 0x34080 wci_qlim_config_piq - * 0x340a0 wci_qlim_config_niq - * 0x340c0 wci_qlim_config_ciq - * 0x00040 wci_config - * 0x20100 wci_ca_config - * - * 0x34040 wci_qlim_3req_priority - * 0x34060 wci_qlim_2req_priority - * 0x64160 wci_qlim_sort_ciq - * 0x64140 wci_qlim_sort_niq - * 0x64120 wci_qlim_sort_piq - */ - -/* - * These CSR values come from the "Programming the Timeouts", "RSM - * Sorting and Bandwidth Balancing" and "Setting the WC{I,X} - * Network Timeouts: a programmer's guide" sections of the WCI 3 PRM. - * The seven field values correspond to the the seven platform types - * as specified by the wrsm_platform_types_t enumeration. - */ -wrsm_platform_csr_t plat_csr_values[] = { - -/* Programming the Timeouts */ -TABLE_S(WCI_ERROR_PAUSE_TIMER_HOLD, CA_APHASE, 0), -TABLE_S(WCI_ERROR_PAUSE_TIMER_HOLD, CA_DPHASE, 0), -TABLE_S(WCI_ERROR_PAUSE_TIMER_HOLD, CA_REUSE, 1), -TABLE_S(WCI_ERROR_PAUSE_TIMER_HOLD, RA_CLUSTER_PRIMARY, 1), -TABLE_S(WCI_ERROR_PAUSE_TIMER_HOLD, RA_SSM_PRIMARY, 0), -TABLE_S(WCI_ERROR_PAUSE_TIMER_HOLD, HA_PRIMARY, 0), -TABLE_S(WCI_ERROR_PAUSE_TIMER_HOLD, SA_PRIMARY, 0), - -TABLE_S(WCI_CA_TIMEOUT_CONFIG, DPHASE_DISABLE, 0), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, DPHASE_FREEZE, 0), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, DPHASE_DEST_MAG, 3), -TABLE(WCI_CA_TIMEOUT_CONFIG, DPHASE_DEST_VAL, 13, 13, 20, 18, 18, 18, 13), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, DPHASE_PASS_MAG, 3), -TABLE(WCI_CA_TIMEOUT_CONFIG, DPHASE_PASS_VAL, 13, 13, 20, 18, 18, 18, 13), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, APHASE_DISABLE, 0), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, APHASE_FREEZE, 0), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, APHASE_MAG, 2), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, APHASE_VAL, 32), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, REUSE_DISABLE, 0), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, REUSE_FREEZE, 0), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, REUSE_MAG, 0), -TABLE_S(WCI_CA_TIMEOUT_CONFIG, REUSE_VAL, 9), - -TABLE_S(WCI_CA_TIMEOUT_CONFIG_2, SFI_TARGID_TIMEOUT_DISABLE, 0), -TABLE_S(WCI_CA_TIMEOUT_CONFIG_2, SFI_TARGID_TIMEOUT_SEL, 3), -TABLE_S(WCI_CA_TIMEOUT_CONFIG_2, LOC_REUSE_MAG, 0), -TABLE_S(WCI_CA_TIMEOUT_CONFIG_2, LOC_REUSE_VAL, 32), - -TABLE_S(WCI_CSRA_TIMEOUT_CONFIG, PULL_TARGID_FAIL_FAST_ENABLE, 0), -TABLE_S(WCI_CSRA_TIMEOUT_CONFIG, PULL_FAIL_FAST_ENABLE, 1), -TABLE_S(WCI_CSRA_TIMEOUT_CONFIG, DISABLE, 0), -TABLE_S(WCI_CSRA_TIMEOUT_CONFIG, FREEZE, 0), -TABLE_S(WCI_CSRA_TIMEOUT_CONFIG, MAGNITUDE, 0), -TABLE_S(WCI_CSRA_TIMEOUT_CONFIG, RD_TIMEOUT, 8), -TABLE_S(WCI_CSRA_TIMEOUT_CONFIG, WR_TIMEOUT, 8), - -TABLE_S(WCI_SA_TIMEOUT_CONFIG, SSM_DISABLE, 1), -TABLE_S(WCI_SA_TIMEOUT_CONFIG, SSM_FREEZE, 0), - -TABLE_S(WCI_RA_TIMEOUT_CONFIG, CLUS_DISABLE, 0), -TABLE_S(WCI_RA_TIMEOUT_CONFIG, CLUS_FREEZE, 0), -TABLE_S(WCI_RA_TIMEOUT_CONFIG, CLUS_APHASE_MAG, 2), -TABLE(WCI_RA_TIMEOUT_CONFIG, CLUS_APHASE_VAL, 50, 50, 39, 50, 50, 50, 39), -TABLE_S(WCI_RA_TIMEOUT_CONFIG, CLUS_DPHASE_MAG, 0), -TABLE_S(WCI_RA_TIMEOUT_CONFIG, CLUS_DPHASE_VAL, 8), -TABLE_S(WCI_RA_TIMEOUT_CONFIG, SSM_DISABLE, 1), -TABLE_S(WCI_RA_TIMEOUT_CONFIG, SSM_FREEZE, 0), - -TABLE_S(WCI_HA_TIMEOUT_CONFIG, SSM_DISABLE, 1), -TABLE_S(WCI_HA_TIMEOUT_CONFIG, SSM_FREEZE, 0), - -TABLE_S(WCI_QLIM_CONFIG_CAG, FREEZE, 1), -TABLE_S(WCI_QLIM_CONFIG_CAG, DISABLE, 1), -TABLE(WCI_QLIM_CONFIG_CAG, MAX_DISCARD, 0x1fff, 0x1fff, 0x1fff, 0x1fff, - 0x1fff, 0x1fff, 0x1fff), -TABLE_S(WCI_QLIM_CONFIG_CAG, NUM2DISCARD, 16), -TABLE_S(WCI_QLIM_CONFIG_CAG, TMIN_MAG, 5), -TABLE_S(WCI_QLIM_CONFIG_CAG, HWMARK_EXP, 4), - -TABLE_S(WCI_QLIM_CONFIG_PIQ, FREEZE, 1), -TABLE_S(WCI_QLIM_CONFIG_PIQ, DISABLE, 1), -TABLE_S(WCI_QLIM_CONFIG_PIQ, DISCARD_CNT_TIMER_EN, 1), -TABLE(WCI_QLIM_CONFIG_PIQ, DISCARD_CNT_TIMER_MAG, 5, 5, 5, 6, 6, 6, 5), -TABLE_S(WCI_QLIM_CONFIG_PIQ, DISCARD_CNT_TIMER_VAL, 1), -TABLE(WCI_QLIM_CONFIG_PIQ, MAX_DISCARD, 0x1fff, 0x1fff, 0x1fff, 0x1fff, - 0x1fff, 0x1fff, 0x1fff), -TABLE_S(WCI_QLIM_CONFIG_PIQ, NUM2DISCARD, 16), -TABLE_S(WCI_QLIM_CONFIG_PIQ, DECAY, 1), -TABLE(WCI_QLIM_CONFIG_PIQ, TMIN_MAG, 30, 30, 30, 47, 47, 47, 65), -TABLE_S(WCI_QLIM_CONFIG_PIQ, HWMARK_EXP, 4), - -TABLE_S(WCI_QLIM_CONFIG_NIQ, FREEZE, 1), -TABLE_S(WCI_QLIM_CONFIG_NIQ, DISABLE, 1), -TABLE_S(WCI_QLIM_CONFIG_NIQ, DISCARD_CNT_TIMER_EN, 1), -TABLE_S(WCI_QLIM_CONFIG_NIQ, DISCARD_CNT_TIMER_MAG, 5), -TABLE(WCI_QLIM_CONFIG_NIQ, DISCARD_CNT_TIMER_VAL, 1, 1, 1, 2, 2, 2, 1), -TABLE(WCI_QLIM_CONFIG_NIQ, MAX_DISCARD, 0x1fff, 0x1fff, 0x1fff, 0x1fff, - 0x1fff, 0x1fff, 0x1fff), -TABLE_S(WCI_QLIM_CONFIG_NIQ, NUM2DISCARD, 16), -TABLE_S(WCI_QLIM_CONFIG_NIQ, DECAY, 1), -TABLE(WCI_QLIM_CONFIG_NIQ, TMIN_MAG, 30, 30, 30, 36, 36, 36, 59), -TABLE_S(WCI_QLIM_CONFIG_NIQ, HWMARK_EXP, 4), - -TABLE_S(WCI_QLIM_CONFIG_CIQ, FREEZE, 1), -TABLE_S(WCI_QLIM_CONFIG_CIQ, DISABLE, 1), -TABLE_S(WCI_QLIM_CONFIG_CIQ, DISCARD_CNT_TIMER_EN, 1), -TABLE_S(WCI_QLIM_CONFIG_CIQ, DISCARD_CNT_TIMER_MAG, 6), -TABLE_S(WCI_QLIM_CONFIG_CIQ, DISCARD_CNT_TIMER_VAL, 1), -TABLE(WCI_QLIM_CONFIG_CIQ, MAX_DISCARD, 2048, 2048, 2048, 1024, 1024, - 1024, 2048), -TABLE_S(WCI_QLIM_CONFIG_CIQ, NUM2DISCARD, 16), -TABLE_S(WCI_QLIM_CONFIG_CIQ, DECAY, 1), -TABLE(WCI_QLIM_CONFIG_CIQ, TMIN_MAG, 30, 30, 30, 36, 36, 36, 59), -TABLE_S(WCI_QLIM_CONFIG_CIQ, HWMARK_EXP, 4), - -TABLE_S(WCI_CONFIG, SAFARI_COMPLIANT_TARGID, 1), -TABLE_S(WCI_CONFIG, CLUSTER_EARLY_REUSE_EN, 1), - -TABLE_S(WCI_CA_CONFIG, REUSE_TIMEOUT_LIMIT, 15), - -/* RSM Sorting and Bandwidth Balancing */ -TABLE(WCI_QLIM_3REQ_PRIORITY, NUM_SLOTS, 7, 7, 7, 1, 1, 1, 14), -TABLE(WCI_QLIM_3REQ_PRIORITY, ARB_SLOTS, 0xaaa7, 0xaaa7, 0xaaa7, 0xb, - 0xb, 0xb, 0xaaa9aaab), - -TABLE(WCI_QLIM_2REQ_PRIORITY, CIQ_NIQ_NUM_SLOTS, 7, 7, 7, 1, 1, 1, 14), -TABLE(WCI_QLIM_2REQ_PRIORITY, PIQ_CIQ_NUM_SLOTS, 0, 0, 0, 0, 0, 0, 1), -TABLE(WCI_QLIM_2REQ_PRIORITY, NIQ_PIQ_NUM_SLOTS, 0, 0, 0, 0, 0, 0, 14), -TABLE(WCI_QLIM_2REQ_PRIORITY, CIQ_NIQ_ARB_SLOTS, 1, 1, 1, 1, 1, 0, 1), -TABLE(WCI_QLIM_2REQ_PRIORITY, PIQ_CIQ_ARB_SLOTS, 0, 0, 0, 0, 0, 0, 1), -TABLE(WCI_QLIM_2REQ_PRIORITY, NIQ_PIQ_ARB_SLOTS, 1, 1, 1, 0, 0, 0, 0x7ffe), - -TABLE(WCI_QLIM_SORT_CIQ, DEV_ID_VEC, 0xf000030f, 0xf000030f, - 0xf000030f, 0xffffffff, 0xffffffff, 0xffffffff, 0xf000010f), - -TABLE(WCI_QLIM_SORT_NIQ, DEV_ID_VEC, 0xffffcf0, 0xffffcf0, 0xffffcf0, - 0, 0, 0, 0xffffcf0), - -TABLE(WCI_QLIM_SORT_PIQ, DEV_ID_VEC, 0xf0000000, 0xf0000000, - 0xf0000000, 0, 0, 0, 0xf0000200), - -/* Setting the WC{I,X} Network Timeouts: a programmer's guide */ -TABLE_A(WCI_SW_LINK_CONTROL, REXMIT_FREEZE, 0, 0, 0, 0, 0, 0, 0), -TABLE_A(WCI_SW_LINK_CONTROL, REXMIT_MAG, 3, 3, 3, 3, 3, 3, 3), -TABLE_A(WCI_SW_LINK_CONTROL, REXMIT_VAL, 5, 84, 5, 5, 84, 5, 5), -TABLE_A(WCI_SW_LINK_CONTROL, REXMIT_SHUTDOWN_EN, 1, 1, 1, 1, 1, 1, 1), - -TABLE_S(WCI_DIF_TIMEOUT_CNTL, TIMEOUT_DISABLE, 0), -TABLE_S(WCI_DIF_TIMEOUT_CNTL, TIMEOUT_FREEZE, 0), -TABLE_S(WCI_DIF_TIMEOUT_CNTL, TIMEOUT_MAG, 3), -TABLE_S(WCI_DIF_TIMEOUT_CNTL, TIMEOUT_VAL, 0), - -{ 0 } -}; - - -/* - * lc_wciinit may ONLY be called from lc_replaceconfig - * lc_wciinit sets the softstate struct with the local_cnode - * local_wnode, and initializes several different registers - * routemap0 and routemap1, wci_brd2cnid_array. - * enables cluster_disable in wci_ca_config. - */ -static void -wrsm_lc_wciinit(wrsm_softstate_t *softsp, cnodeid_t local_cnode, - wnodeid_t local_wnode) -{ - int i; - uint64_t offset; - uint64_t entry; - wci_id_u wci_id; /* determine wci partid - wci1, wci2, wci3 */ - wci_cluster_error_status_array_u cesr; - wci_ca_timeout_config_u ca_timeout_config; - wci_ra_timeout_config_u ra_timeout_config; - wci_ra_esr_mask_u ra_mask; - wci_ca_esr_mask_u ca_mask; - wci_hli_esr_mask_u hli_mask; - wci_csra_esr_mask_u csra_mask; - wci_sfi_esr_mask_u sfi_mask; - wci_dc_esr_mask_u dc_mask; - wci_sfq_esr_mask_u sfq_mask; - wci_link_esr_mask_u link_mask; - wci_sw_esr_mask_u sw_mask; - wci_ha_esr_mask_u ha_mask; - wci_sa_esr_mask_u sa_mask; - wci_cci_esr_mask_u cci_mask; - wci_sw_config_u sw_config; - wci_config_u wci_config_tmp; /* where w.node_id is defined */ - wci_board2cnid_control_u wci_brd2cnid_control; - wci_board2cnid_array_u wci_brd2cnid_array_tmp; - wci_ca_config_u wci_ca_config_tmp; /* where cluster_disable defined */ - wci_sram_config_u sram_config; - wci_error_inducement_u wci_error_inducement; - wrsm_cmmu_t cmmu; - - DPRINTF(LC_DEBUG, (CE_CONT, "in wrsm_lc_wciinit wci %d", - softsp->portid)); - ASSERT(softsp != NULL); - ASSERT(local_wnode < 16); - - - softsp->restart_timeout_id = 0; - softsp->shortterm_start = ddi_get_lbolt(); - - /* set striping bits to no striping */ - wrsm_lc_csr_read(softsp, ADDR_WCI_CONFIG, &wci_config_tmp.val); - wci_config_tmp.bit.stripe_bits = WCI_STRIPE_NONE; - wci_config_tmp.bit.enable_inid = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_CONFIG, wci_config_tmp.val); - - /* - * set up the wci_error_inducement to reset state - * this must be done before writing to SRAM (CMMU) - */ - wci_error_inducement.val = 0; - wci_error_inducement.bit.sram_ecc_xor_2_select = 0x3F; - wci_error_inducement.bit.sram_ecc_xor_1_select = 0x3F; - - wrsm_lc_csr_write(softsp, ADDR_WCI_ERROR_INDUCEMENT, - wci_error_inducement.val); - - /* clear all CMMU entries in SRAM */ - wrsm_lc_clear_cmmu(softsp); - - /* - * Entry 1 of the CMMU is reserved during cmmu_init() to - * be used for clearing cluster write lockout. Here we - * initialized it to a sensible value. - */ - cmmu.entry_0.val = 0; - cmmu.entry_1.val = 0; - cmmu.entry_0.bit.writable = 0; - cmmu.entry_0.bit.from_all = 1; - cmmu.entry_0.bit.from_node = 255; - cmmu.entry_0.bit.valid = 1; - cmmu.entry_0.bit.type = CMMU_TYPE_CACHEABLE; - wrsm_lc_cmmu_update(softsp, &cmmu, 1, CMMU_UPDATE_ALL); - - - /* clear wci_nc_slice_config_array */ - for (i = 0; i < ENTRIES_WCI_NC_SLICE_CONFIG_ARRAY; i++) { - offset = ADDR_WCI_NC_SLICE_CONFIG_ARRAY + - i * STRIDE_WCI_NC_SLICE_CONFIG_ARRAY; - wrsm_lc_csr_write(softsp, offset, 0); - } - - /* clear wci_cluster_error_count */ - wrsm_lc_csr_write(softsp, ADDR_WCI_CLUSTER_ERROR_COUNT, 0); - /* clear inid2dnid array */ - for (i = 0; i < ENTRIES_WCI_INID2DNID_ARRAY; i++) { - offset = ADDR_WCI_INID2DNID_ARRAY + - i * STRIDE_WCI_INID2DNID_ARRAY; - wrsm_lc_csr_write(softsp, offset, 0); - } - /* Clear cluster members bits */ - for (i = 0; i < ENTRIES_WCI_CLUSTER_MEMBERS_BITS; i++) { - offset = ADDR_WCI_CLUSTER_MEMBERS_BITS + - i * STRIDE_WCI_CLUSTER_MEMBERS_BITS; - wrsm_lc_csr_write(softsp, offset, 0); - } - /* clear wci_sw_link_error_count */ - for (i = 0; i < ENTRIES_WCI_SW_LINK_ERROR_COUNT; i++) - *softsp->links[i].wrsm_link_err_cnt_addr = 0; - /* set wci revisions - to determine if wci 2 or 3 */ - wrsm_lc_csr_read(softsp, ADDR_WCI_ID, &wci_id.val); - softsp->wci_rev = wrsm_lc_get_wci_rev(wci_id.val); - - cesr.val = 0; - cesr.bit.disable_fail_fast = 1; - for (i = 0; i < ENTRIES_WCI_CLUSTER_ERROR_STATUS_ARRAY; i++) { - offset = ADDR_WCI_CLUSTER_ERROR_STATUS_ARRAY + - i * STRIDE_WCI_CLUSTER_ERROR_STATUS_ARRAY; - wrsm_lc_csr_write(softsp, offset, cesr.val); - } - - /* Clear the write lockout bits */ - for (i = 0; i < ENTRIES_WCI_CLUSTER_WRITE_LOCKOUT; ++i) { - offset = ADDR_WCI_CLUSTER_WRITE_LOCKOUT + - i * STRIDE_WCI_CLUSTER_WRITE_LOCKOUT; - wrsm_lc_csr_write(softsp, offset, 0); - } - /* clear write lockout status */ - wrsm_lc_csr_write(softsp, ADDR_WCI_RA_WRITE_LOCKOUT_STATUS, 0); - - /* - * disable all slave and home agent instances - they are - * not used in cluster mode. - */ - wrsm_lc_csr_write(softsp, ADDR_WCI_SA_FREEZE, 0xff); - wrsm_lc_csr_write(softsp, ADDR_WCI_HA_FREEZE, 0xffff); - - /* wci_dco_ce_count must be set before wci_dc_esr register */ - wrsm_lc_csr_write(softsp, ADDR_WCI_DCO_CE_COUNT, CE_CNTMAX); - wrsm_lc_csr_write(softsp, ADDR_WCI_CA_FREEZE, 0); - - /* Clear any previous freeze bits set in prior configs */ - wrsm_lc_csr_write(softsp, ADDR_WCI_RA_FREEZE, 0); - /* the following ESR registers require a TOGGLE to reset bit */ - wrsm_lc_csr_read(softsp, ADDR_WCI_CSRA_ESR, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_CSRA_ESR, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_CCI_ESR, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_CCI_ESR, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_DC_ESR, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_DC_ESR, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_HLI_ESR, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_HLI_ESR, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_SFQ_ESR, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_SFQ_ESR, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_CA_ESR_0, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_CA_ESR_0, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_CA_ESR_1, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_CA_ESR_1, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_RA_ESR_0, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_RA_ESR_0, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_RA_ESR_1, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_RA_ESR_1, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_HA_ESR_0, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_HA_ESR_0, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_HA_ESR_1, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_HA_ESR_1, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_SA_ESR_0, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_SA_ESR_0, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_SFI_ESR, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_SFI_ESR, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_LINK_ESR, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_LINK_ESR, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_SW_ESR, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_SW_ESR, entry); - wrsm_lc_csr_read(softsp, ADDR_WCI_SRAM_STATUS, &entry); - wrsm_lc_csr_write(softsp, ADDR_WCI_SRAM_STATUS, entry); - - /* - * mask/unmask ESR registers as outlined in PRM doc - * this step should always follow reseting esr - */ - ra_mask.val = MASKALL; - ra_mask.bit.wrong_safari_command = 0; - ra_mask.bit.unexpected_send_ack = 0; - ra_mask.bit.unexpected_receive_ack = 0; - ra_mask.bit.hw_protocol_error = 0; - ra_mask.bit.hw_fifo_ovfl_unfl = 0; - ra_mask.bit.cluster_local_timeout = 0; - ra_mask.bit.mtag_mismatch_between_hcls = 0; - ra_mask.bit.mtag_mismatch_within_hcl = 0; - ra_mask.bit.mtag_not_gm = 0; - ra_mask.bit.uncorrectable_mtag_error = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_RA_ESR_MASK, ra_mask.val); - - ca_mask.val = MASKALL; - ca_mask.bit.atomic_map_mismatch = 0; - ca_mask.bit.mtag_mismatch_between_hcls = 0; - ca_mask.bit.mtag_mismatch_within_hcl = 0; - ca_mask.bit.dstat_inconsistent = 0; - ca_mask.bit.uncorrectable_mtag_error = 0; - ca_mask.bit.internal_error = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_CA_ESR_MASK, ca_mask.val); - - hli_mask.val = MASKALL; - hli_mask.bit.slq_perr = 0; - hli_mask.bit.hmq_perr = 0; - hli_mask.bit.strange_pkt = 0; - hli_mask.bit.bq_unfl = 0; - hli_mask.bit.hmq_unfl = 0; - hli_mask.bit.hmq_ovfl = 0; - hli_mask.bit.slq_ovfl = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_HLI_ESR_MASK, hli_mask.val); - - csra_mask.val = MASKALL; - csra_mask.bit.timeout = 0; - csra_mask.bit.pull_targid_timeout = 0; - csra_mask.bit.pull_timeout = 0; - csra_mask.bit.mtag_not_gm = 0; - csra_mask.bit.mtag_mismatch = 0; - csra_mask.bit.uncorrectable_data_error = 0; - csra_mask.bit.uncorrectable_mtag_error = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_CSRA_ESR_MASK, csra_mask.val); - - sfi_mask.val = MASKALL; - sfi_mask.bit.targid_timeout = 0; - sfi_mask.bit.nc2nid_misconfig = 0; - sfi_mask.bit.addr_pty = 0; - sfi_mask.bit.incoming_prereq_conflict = 0; - sfi_mask.bit.modcam_clr_set_conflict = 0; - sfi_mask.bit.modcam_multi_hit = 0; - sfi_mask.bit.modcam_set_set = 0; - sfi_mask.bit.unexpected_incoming = 0; - sfi_mask.bit.unexpected_targarbgnt = 0; - sfi_mask.bit.transid_unalloc_released = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_SFI_ESR_MASK, sfi_mask.val); - - cci_mask.val = MASKALL; - cci_mask.bit.sram_ae = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_CCI_ESR_MASK, cci_mask.val); - - /* - * The PRM recommends unmasking dco_data_parity_error. - * However, due to some firmware and/or hardware problems, - * these errors happen all the time, so we have to mask it. - */ - dc_mask.val = MASKALL; - dc_mask.bit.dif_timeout = 0; - dc_mask.bit.dco_map_error = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_DC_ESR_MASK, dc_mask.val); - - sfq_mask.val = MASKALL; - sfq_mask.bit.sfq_perr = 0; - sfq_mask.bit.sfq_ovfl = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_SFQ_ESR_MASK, sfq_mask.val); - - link_mask.val = MASKALL; - wrsm_lc_csr_write(softsp, ADDR_WCI_LINK_ESR_MASK, link_mask.val); - - sw_mask.val = MASKALL; - sw_mask.bit.error_pause_broadcast = 0; - sw_mask.bit.addr_lpbk_fifo_ovf = 0; - sw_mask.bit.data_lpbk_fifo_ovf = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_SW_ESR_MASK, sw_mask.val); - - /* - * although the ha (home agent) and sa (slave agent) are only used - * in a SSM configured wci, it was recommended that the mask be - * set correctly in the wrsm driver so that illegal ssm transactions - * can be caught. - */ - ha_mask.val = MASKALL; - ha_mask.bit.wrong_cmd = 0; - ha_mask.bit.not_expected_compl = 0; - ha_mask.bit.address_not_mapped = 0; - ha_mask.bit.gnr_err = 0; - ha_mask.bit.timeout = 0; - ha_mask.bit.unexpected_mtag = 0; - ha_mask.bit.mtag_mismatch_between_hcls = 0; - ha_mask.bit.mtag_mismatch_within_hcl = 0; - ha_mask.bit.dstat_inconsistent = 0; - ha_mask.bit.mtag_not_gm = 0; - ha_mask.bit.uncorrectable_mtag_error = 0; - ha_mask.bit.hw_err = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_HA_ESR_MASK, ha_mask.val); - - sa_mask.val = MASKALL; - sa_mask.bit.wrong_demand = 0; - sa_mask.bit.ga2lpa_ecc_error = 0; - sa_mask.bit.address_not_owned = 0; - sa_mask.bit.address_not_mapped = 0; - sa_mask.bit.rip_multi_hit = 0; - sa_mask.bit.timeout = 0; - sa_mask.bit.unexpected_mtag = 0; - sa_mask.bit.mtag_mismatch_between_hcls = 0; - sa_mask.bit.mtag_mismatch_within_hcl = 0; - sa_mask.bit.uncorrectable_mtag_error = 0; - sa_mask.bit.hw_err = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_SA_ESR_MASK, sa_mask.val); - - wrsm_lc_csr_read(softsp, ADDR_WCI_SW_CONFIG, &sw_config.val); - sw_config.bit.error_pause_shutdown_en = 1; - sw_config.bit.max_errors = MAXERRORS; - sw_config.bit.gnid = softsp->local_gnid; - wrsm_lc_csr_write(softsp, ADDR_WCI_SW_CONFIG, sw_config.val); - - wrsm_lc_csr_write(softsp, ADDR_WCI_ERROR_PAUSE_TIMER_HOLD, 0); - - wrsm_lc_csr_read(softsp, ADDR_WCI_SRAM_CONFIG, &sram_config.val); - sram_config.bit.ecc_disable = 0; - sram_config.bit.parity_disable = 1; - sram_config.bit.ecc_writeback_disable = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_SRAM_CONFIG, sram_config.val); - - /* - * On timeout config registers, Hien Nguyen suggests the - * following settings. - * - * Tru(cag) = wci_ca_timeout_config.reuse_timeout - * Tdp(rag) = wci_ra_timeout_config.primary_cluster_wr_timeout - * T(cpu) = Cheetah timeout value - * T(rag) = wci_ra_timeout_config.primary_cluster_rd_timeout - * T(cag) = wci_ca_timeout_config.primary_timeout - * - * T(cag) < T(rag) < Tcpu < Tdp(rag) < Tru(cag) - * - * Here is a suggestion without much analysis. - * Tru(cag) = 256*2^24 cycles (max) - * Tdp(rag) = 32*2^24 cycles - * T(cpu) = 16*2^24 cycles (Is 2^28 the default?) - * T(rag) = 2*2^24 cycles - * T(cag) = 1*2^24 cycles - * - * These numbers are ok for small clusters. When we have larger - * machines, we will have to make some adjustments. - */ - ca_timeout_config.val = 0; - /* - * the position of the reuse_mag and reuse_val change between wci2 - * wci3. Since our driver is compiled to deal with > wci 3 headers - * the values for wci 2 fields must be set manually. - * reuse_val; wci 2 0-7 th bit, wci 3 0-10 bit - * reuse_mag; wci 2 8th and 9th bit, wci 3 11 and 12 - */ - - if (softsp->wci_rev < 30) { - /* reuse_mag already 0 since config.val = 0 above */ - ca_timeout_config.val = CA_TIMEOUT_CONFIG_VAL_WCI2; - } else { /* wci 3 or later revision */ - ca_timeout_config.bit.reuse_mag = 0; - ca_timeout_config.bit.reuse_val = 255; - ca_timeout_config.bit.dphase_dest_val = 1; - ca_timeout_config.bit.aphase_val = 1; - } - - wrsm_lc_csr_write(softsp, ADDR_WCI_CA_TIMEOUT_CONFIG, - ca_timeout_config.val); - - ra_timeout_config.val = 0; - ra_timeout_config.bit.ssm_disable = 1; - ra_timeout_config.bit.clus_aphase_val = 2; - ra_timeout_config.bit.clus_dphase_val = 32; - wrsm_lc_csr_write(softsp, ADDR_WCI_RA_TIMEOUT_CONFIG, - ra_timeout_config.val); - - /* set routemap 0 and routemap 1 to local */ - wrsm_lc_csr_write(softsp, ADDR_WCI_ROUTE_MAP0, ROUTEMAPRESET); - wrsm_lc_csr_write(softsp, ADDR_WCI_ROUTE_MAP1, ROUTEMAPRESET); - - /* Perforance counters settings - expand to bit fields later */ - wrsm_lc_csr_write(softsp, ADDR_WCI_CLUSTER_CTR_CTL, 0xff); - wrsm_lc_csr_write(softsp, ADDR_WCI_SFI_CTR0_MASK, 0); - wrsm_lc_csr_write(softsp, ADDR_WCI_SFI_CTR0_MATCH, 0); - wrsm_lc_csr_write(softsp, ADDR_WCI_SFI_CTR0_MATCH_TRANSACTION, 0); - wrsm_lc_csr_write(softsp, ADDR_WCI_SFI_CTR1_MASK, 0); - wrsm_lc_csr_write(softsp, ADDR_WCI_SFI_CTR1_MATCH, 0); - wrsm_lc_csr_write(softsp, ADDR_WCI_SFI_CTR1_MATCH_TRANSACTION, 0); - /* Set wci_misc_ctr_ctl to cluster agent */ - wrsm_lc_csr_write(softsp, ADDR_WCI_MISC_CTR_CTL, 0x440); - wrsm_lc_csr_write(softsp, ADDR_WCI_MISC_CTR, 0); - wrsm_lc_csr_write(softsp, ADDR_WCI_LPBK_CTR_CTL, 0x60001); - wrsm_lc_csr_write(softsp, ADDR_WCI_LPBK_CTR, 0); - wrsm_lc_csr_write(softsp, ADDR_WCI_LINK_CTR_CTL, 0x100006); - wrsm_lc_csr_write(softsp, ADDR_WCI_LINK_CTR, 0); - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, "routemap0 = 0x%"PRIx64" ", - *((uint64_t *)(softsp->wrsm_regs + ADDR_WCI_ROUTE_MAP0)))); - - /* set first element in board2cnid */ - wrsm_lc_csr_read(softsp, ADDR_WCI_BOARD2CNID_ARRAY, - &wci_brd2cnid_array_tmp.val); - wci_brd2cnid_array_tmp.bit.data = local_cnode; - /* - * This write to wci_board2dnid_array will be ignored on a Starcat - * system if jtag-wr_only bit is set in wci_csr_control. - */ - wrsm_lc_csr_write(softsp, ADDR_WCI_BOARD2CNID_ARRAY, - wci_brd2cnid_array_tmp.val); - - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, "brd2cnid.data = 0x%"PRIx64, - *((uint64_t *)(softsp->wrsm_regs + ADDR_WCI_BOARD2CNID_ARRAY)))); - - /* Disable board2cnid */ - wrsm_lc_csr_read(softsp, ADDR_WCI_BOARD2CNID_CONTROL, - &wci_brd2cnid_control.val); - wci_brd2cnid_control.bit.board2cnid_enable = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_BOARD2CNID_CONTROL, - wci_brd2cnid_control.val); - - /* set wnode in wci_config register */ - wrsm_lc_csr_read(softsp, ADDR_WCI_CONFIG, &wci_config_tmp.val); - wci_config_tmp.bit.node_id = local_wnode; - wrsm_lc_csr_write(softsp, ADDR_WCI_CONFIG, wci_config_tmp.val); - /* turn-off cluster_disable -- that is, allow transactions */ - wrsm_lc_csr_read(softsp, ADDR_WCI_CA_CONFIG, &wci_ca_config_tmp.val); - wci_ca_config_tmp.bit.cluster_disable = 0; - wci_ca_config_tmp.bit.reuse_timeout_limit = 0x1F; - wrsm_lc_csr_write(softsp, ADDR_WCI_CA_CONFIG, wci_ca_config_tmp.val); - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, - "wciINIT ca_config = 0x%"PRIx64, - *((uint64_t *)(softsp->wrsm_regs + ADDR_WCI_CA_CONFIG)))); -#ifdef DEBUG - wrsm_lc_csr_write(softsp, ADDR_WCI_CLUSTER_CTR_CTL, 0); - wrsm_lc_csr_write(softsp, ADDR_WCI_LPBK_CTR_CTL, 0); - wrsm_lc_csr_write(softsp, ADDR_WCI_MISC_CTR_CTL, 0); -#endif - - /* Initialize CSRs new to WCI-3 */ - if (softsp->wci_rev >= 30) { - wrsm_lc_csr_write(softsp, - ADDR_WCI_INT_DEST_BUSY_COUNT, 0); - wrsm_lc_csr_write(softsp, - ADDR_WCI_OS_CLUSTER_DISABLE, 0); - wrsm_lc_csr_write(softsp, - ADDR_WCI_SC_CLUSTER_DISABLE, 0); - /* Initialize GNID maps for loopback */ - wrsm_lc_csr_write(softsp, - ADDR_WCI_GNID_MAP0, (uint64_t)0x6db6db6db6db); - wrsm_lc_csr_write(softsp, - ADDR_WCI_GNID_MAP1, (uint64_t)0x6db6db6db6db); - } - - - softsp->local_cnode = local_cnode; - softsp->local_wnode = local_wnode; - softsp->num_sram_ecc_errors = 0; - softsp->last_sram_ecc_errors = 0; - softsp->max_sram_ecc_errors = 0; - softsp->avg_sram_ecc_errors = 0; - - wrsm_lc_platform_wciinit(softsp); - - /* Enable the QDL for WCI-3.1 and later */ - if (softsp->wci_rev >= 31) { - wci_qlim_config_cag_u cag; - wci_qlim_config_piq_u piq; - wci_qlim_config_ciq_u ciq; - wci_qlim_config_niq_u niq; - - wrsm_lc_csr_read(softsp, ADDR_WCI_QLIM_CONFIG_CAG, &cag.val); - cag.bit.freeze = 0; - cag.bit.disable = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_QLIM_CONFIG_CAG, cag.val); - - wrsm_lc_csr_read(softsp, ADDR_WCI_QLIM_CONFIG_PIQ, &piq.val); - piq.bit.freeze = 0; - piq.bit.disable = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_QLIM_CONFIG_PIQ, cag.val); - - wrsm_lc_csr_read(softsp, ADDR_WCI_QLIM_CONFIG_CIQ, &ciq.val); - ciq.bit.freeze = 0; - ciq.bit.disable = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_QLIM_CONFIG_CIQ, ciq.val); - - wrsm_lc_csr_read(softsp, ADDR_WCI_QLIM_CONFIG_NIQ, &niq.val); - niq.bit.freeze = 0; - niq.bit.disable = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_QLIM_CONFIG_NIQ, niq.val); - } - - /* - * error polling needs to be started here in order to check - * esr registers even if no physical links are up. an error - * may appear during initialization or a loopback transaction - */ - - /* already holding lc_mutex */ - if (softsp->suspended) { - softsp->need_err_timeout = B_TRUE; - } else { - softsp->err_timeout_id = timeout((void (*)(void *)) - wrsm_lc_poll_timeout, softsp, wrsm_poll_hz); - } - - DPRINTF(LC_DEBUG, (CE_CONT, "POLLING STARTED" - " wci %d", softsp->portid)); -} - - -static void -lc_platform_csr_init(wrsm_softstate_t *softsp, wrsm_platform_csr_t * - csr, wrsm_platform_types_t type) -{ - uint64_t val; - uint64_t mask; - int i; - - mask = (uint64_t)csr->mask_hi << 32 | (uint64_t)csr->mask_lo; - DPRINTF(LC_DEBUG_PLAT, (CE_CONT, "platform_csr_init: offset %lx " - "mask %lx shift %d value %d entries %d type %d", csr->offset, - mask, csr->shift, csr->plat_values[type], csr->array_entries, - type)); - - for (i = 0; i < csr->array_entries; ++i) { - uint64_t offset = csr->offset + (STRIDE_WCI_SRAM_ARRAY * i); - - wrsm_lc_csr_read(softsp, offset, &val); - val = (val & ~mask) | - (((uint64_t)csr->plat_values[type] << csr->shift) & mask); - wrsm_lc_csr_write(softsp, offset, val); - } -} - -/* - * Set up WCI CSRs that depend on the cluster node type and/or the - * network topology. - */ -static void -wrsm_lc_platform_wciinit(wrsm_softstate_t *softsp) -{ - int i; - uint_t nentries; - int *conf_values; - wrsm_platform_csr_t *conf_plat_array; - wrsm_platform_types_t plat_type; - wrsm_node_types_t node_type; - wrsm_topology_t net_type; - - node_type = wrsmplat_get_node_type(); - ASSERT(softsp->config); - net_type = softsp->config->topology_type; - - switch (node_type) { - case wrsm_node_serengeti: - case wrsm_node_wssm: - switch (net_type) { - case topology_distributed_switch: - plat_type = serengeti_direct; - break; - case topology_san_switch: - plat_type = serengeti_wcx; - break; - case topology_central_switch: - plat_type = serengeti_pt; - break; - } - break; - case wrsm_node_starcat: - switch (net_type) { - case topology_distributed_switch: - plat_type = starcat_direct; - break; - case topology_san_switch: - plat_type = starcat_wcx; - break; - case topology_central_switch: - plat_type = starcat_pt; - break; - } - } - - if (wrsm_cf_cnode_is_switch(softsp->ctlr_config)) { - plat_type = starcat_switch; - } - - if (softsp->wci_rev >= 30) { - for (i = 0; plat_csr_values[i].offset; ++i) - lc_platform_csr_init(softsp, - &plat_csr_values[i], plat_type); - } - - /* - * Give the wrsmplat module an oportunity to make CSR settings - * specific to this platform. - */ - wrsmplat_wci_init(softsp->wrsm_regs); - - /* - * CSR settings which over-ride the defaults can be encoded in - * the driver .conf file using the "wci_csr" property. This - * property is array of integers where each set of 12 ints - * represents one wrsm_platform_csr_t struct. This section - * should be performed last in WCI initialization so that - * settings in the .conf file take priority to those - * hard-coded in the driver. - */ - if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, softsp->dip, - DDI_PROP_DONTPASS, "wci_csr", &conf_values, &nentries) == - DDI_PROP_SUCCESS) { - uint32_t num_regs; - - DPRINTF(LC_DEBUG, (CE_CONT, "wciinit: got wci_csr % entries", - nentries)); - /* - * The number of int in the array must be a multiple - * of the size of the wrsm_platform_csr_t struct. - */ - num_regs = (nentries * sizeof (int)) / - sizeof (wrsm_platform_csr_t); - - if ((num_regs * sizeof (wrsm_platform_csr_t)) == - (nentries * sizeof (int))) { - - conf_plat_array = (wrsm_platform_csr_t *)conf_values; - for (i = 0; i < num_regs; ++i) - lc_platform_csr_init(softsp, - &conf_plat_array[i], plat_type); - } else { - cmn_err(CE_WARN, "wrsm_lc_wciinit: illegal array " - "length for wci_csr property: %d", - nentries); - } - - ddi_prop_free(conf_values); - } -} - - -/* - * lc_wcifini can ONLY be called by lc_installconfig. - * lc_wcifini resets some register values to 'clean' values - * ie. WCI_ROUTE_MAP= LOOPBACK, wci_ca_config.cluster_disable - * is disabled - that is set BACK to 1, clears cmmu, etc. - */ -static void -wrsm_lc_wcifini(wrsm_softstate_t *softsp) -{ - wci_ca_config_u wci_ca_config_tmp; /* set cluster_disable */ - wci_config_u wci_config_tmp; /* where node_id (wnodeid) is defined */ - wci_board2cnid_array_u wci_brd2cnid_array_tmp; /* local cnode */ - timeout_id_t err_timeout_id; /* timeout handle for link polling */ - ASSERT(softsp != NULL); - - mutex_enter(&softsp->lc_mutex); - - err_timeout_id = softsp->err_timeout_id; - softsp->err_timeout_id = 0; - - mutex_exit(&softsp->lc_mutex); - - /* LINTED: E_NOP_IF_STMT */ - if (untimeout(err_timeout_id) == -1) { - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_wcifini" - " err_timeout_id not valid")); - } - - DPRINTF(LC_DEBUG, (CE_CONT, "in wrsm_lc_wcifini wci %d", - softsp->portid)); - - /* Clear CMMU to make all entries invalid */ - wrsm_lc_clear_cmmu(softsp); - - /* Reset route maps */ - wrsm_lc_csr_write(softsp, ADDR_WCI_ROUTE_MAP0, ROUTEMAPRESET); - wrsm_lc_csr_write(softsp, ADDR_WCI_ROUTE_MAP1, ROUTEMAPRESET); - - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, "routemap0 = 0x%"PRIx64" ", - *((uint64_t *)(softsp->wrsm_regs + ADDR_WCI_ROUTE_MAP0)))); - - /* enable cluster_disable */ - wci_ca_config_tmp.val = *((uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_CA_CONFIG)); - wci_ca_config_tmp.bit.cluster_disable = 1; - *((uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_CA_CONFIG)) = wci_ca_config_tmp.val; - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, "wcifini ca_config = 0x%"PRIx64"", - *((uint64_t *)(softsp->wrsm_regs + ADDR_WCI_CA_CONFIG)))); - - /* set wnode in wci_config register to reset value */ - wrsm_lc_csr_read(softsp, ADDR_WCI_CONFIG, &wci_config_tmp.val); - wci_config_tmp.bit.node_id = 0; - wrsm_lc_csr_write(softsp, ADDR_WCI_CONFIG, wci_config_tmp.val); - - /* set first element in board2cnid to 'cleared' value */ - wrsm_lc_csr_read(softsp, ADDR_WCI_BOARD2CNID_ARRAY, - &wci_brd2cnid_array_tmp.val); - wci_brd2cnid_array_tmp.bit.data = 0; - /* - * This write to wci_board2dnid_array will be ignored on a Starcat - * system if jtag-wr_only bit is set in wci_csr_control. - */ - wrsm_lc_csr_write(softsp, ADDR_WCI_BOARD2CNID_ARRAY, - wci_brd2cnid_array_tmp.val); - softsp->nc = NULL; -} - -/* - * lc_verifyconfig must be called before any calls to lc_replaceconfig - * verifies that a new configuration for existing links is not a mismatch - * returns TRUE if config is GOOD - */ -boolean_t -wrsm_lc_verifyconfig(wrsm_softstate_t *softsp, wrsm_wci_data_t *config) -{ - int i; - boolean_t config_ok = B_TRUE; /* init to config is good */ - wnodeid_t locwnode_new; /* local wnode - new configuration */ - - ASSERT(softsp != NULL); - ASSERT(softsp->config != NULL); - ASSERT(config != NULL); - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, "in wrsm_lc_verifyconfig")); - - /* For WCI2, gnids must equal wnodes */ - if (softsp->wci_rev < 30) { - for (i = 0; i < WRSM_MAX_WNODES; i++) { - wnodeid_t wnode = config->gnid_to_wnode[i]; - if (wnode < WRSM_MAX_WNODES && - wnode != i) { - DPRINTF(LC_WARN, (CE_WARN, "For wci2 " - "gnids must equal wnodes")); - config_ok = B_FALSE; - } - } - } - - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - if (softsp->config->links[i].present && - config->links[i].present) { - /* a valid link that is part of a config */ - gnid_t rgnid_old; - gnid_t rgnid_new; - wnodeid_t rwnid_old; - wnodeid_t rwnid_new; - - rgnid_old = softsp->config->links[i].remote_gnid; - rgnid_new = config->links[i].remote_gnid; - - if (rgnid_old != rgnid_new) { - /* - * Remote gnid changes. To support changing - * gnids, must bring down links. Not yet - * supported. - */ - config_ok = B_FALSE; - cmn_err(CE_WARN, "attempt to change gnid " - "for wrsm%d link %d", softsp->instance, i); - continue; - } - - if (WRSM_GNID_IS_WCX(rgnid_old)) { - /* - * We already know remote gnid isn't - * changing. If remote gnid is a switch, - * don't need to check for changes in - * cnodeids. - */ - continue; - } - - rwnid_old = softsp->config->gnid_to_wnode[rgnid_old]; - rwnid_new = config->gnid_to_wnode[rgnid_new]; - - if (rwnid_new >= WRSM_MAX_WNODES) { - config_ok = B_FALSE; - cmn_err(CE_WARN, "wci %d link %d: remote gnid " - "%d not in reachable list", - softsp->instance, i, rgnid_new); - } else if (rwnid_old != rwnid_new) { - /* remote wnodeid mismatch */ - config_ok = B_FALSE; - cmn_err(CE_WARN, "attempt to change wnodeid " - "for wrsm%d link %d", softsp->instance, i); - } else { - if (!(config->wnode_reachable[rwnid_new]) || - !(softsp->config->wnode_reachable - [rwnid_old]) || - ((softsp->config->reachable[rwnid_old]) - != (config->reachable[rwnid_new]))) { - config_ok = B_FALSE; - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_" - "verifyconfig bad remote-cnode" - " link %d", i)); - cmn_err(CE_WARN, "Invalid" - " remote_cnode for wrsm%d link" - " %d", softsp->instance, i); - } - } - } - } - locwnode_new = config->local_wnode; - if (softsp->local_wnode == locwnode_new) { - if (!(config->wnode_reachable[locwnode_new]) || - !(softsp->config->wnode_reachable[softsp->local_wnode]) || - ((softsp->local_cnode) != - (config->reachable[locwnode_new]))) { - config_ok = B_FALSE; - cmn_err(CE_WARN, "Invalid local_cnode for wrsm%d link" - " %d", softsp->instance, i); - } - } else { /* wnode mismatch */ - config_ok = B_FALSE; - DPRINTF(LC_WARN, (CE_WARN, "wrsm_lc_verify" - "bad config local-wnode link %d", i)); - cmn_err(CE_WARN, "Invalid local_wnode" - "for wrsm%d link %d", softsp->instance, i); - } - return (config_ok); -} - - - -/* - * lc_replaceconfig must be called before a call to lc_cleanconfig - * and lc_installconfig. lc_verify_config must be called prior to - * lc_replaceconfig. responsible for initialization required before link - * takedown and bringup request can be made. - */ -void -wrsm_lc_replaceconfig(wrsm_softstate_t *softsp, ncwci_handle_t nc, - wrsm_wci_data_t *config, wrsm_controller_t *ctlr_config) -{ - uint64_t i; - wnodeid_t local_wnode; - wrsm_wci_data_t *old_config; - - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, "in wrsm_lc_replaceconfig - wci %d", - softsp->portid)); - - ASSERT(softsp != NULL); - softsp->nc = nc; - mutex_enter(&softsp->lc_mutex); - - /* - * newlink_waitup_cnt is used to count the number of installconfig - * initiated link_bringup requests. It is decremented when a link - * reaches lc_up state. - * - * old_link_waitdown_cnt is used to count the number of cleanconfig - * initiated link_takedown request. It is decremented when a link - * reaches lc_down state. - */ - softsp->newlink_waitup_cnt = 0; - softsp->oldlink_waitdown_cnt = 0; - softsp->ctlr_config = ctlr_config; - old_config = softsp->config; - softsp->config = config; - if ((old_config == NULL) && (config != NULL)) { - /* first time only initialize links */ - local_wnode = config->local_wnode; - ASSERT(config->wnode_reachable[local_wnode]); - /* - * tell_mh_link_is_up is needed so that the LC knows when - * it is allowed to call mh_link_is_up. On new request, the - * LC must wait until lc_enableconfig is called, - * lc_enableconfig sets tell_mh_link_is_up to TRUE, and TRUE - * is the value that tell_mh_link_is_up remains until - * another 'new' bringup link request is made in - * lc_installconfig. - */ - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - softsp->links[i].tell_mh_link_is_up = B_TRUE; - } - wrsm_lc_wciinit(softsp, config->reachable[local_wnode], - local_wnode); - - } - if (config != NULL) { - /* Save local gnid, gnid_to_wnode map for later */ - softsp->local_gnid = config->local_gnid; - for (i = 0; i < WRSM_MAX_WNODES; i++) { - softsp->gnid_to_wnode[i] = config->gnid_to_wnode[i]; - } - - /* Update WCI-3 with local gnid and setup dnid2gnid */ - if (softsp->wci_rev >= 30) { - wci_dnid2gnid_u dnid2gnid; - wnodeid_t *gnid2dnid; - wci_sw_config_u sw_config; - - wrsm_lc_csr_read(softsp, ADDR_WCI_SW_CONFIG, - &sw_config.val); - sw_config.bit.gnid = softsp->local_gnid; - sw_config.bit.partner_gnid = softsp->local_gnid; - wrsm_lc_csr_write(softsp, ADDR_WCI_SW_CONFIG, - sw_config.val); - - dnid2gnid.val = 0; - gnid2dnid = softsp->config->gnid_to_wnode; - for (i = 0; i < WRSM_MAX_WNODES; ++i) { - if (gnid2dnid[i] < WRSM_MAX_WNODES) - dnid2gnid.val |= i << - (gnid2dnid[i] * 4); - } - wrsm_lc_csr_write(softsp, ADDR_WCI_DNID2GNID, - dnid2gnid.val); - } - } - - mutex_exit(&softsp->lc_mutex); -} - - -/* - * initiates takedown link request for any links where the config pointer - * in the softstate struct is NULL, or the link is marked as not - * present in the new configuration. - */ -void -wrsm_lc_cleanconfig(wrsm_softstate_t *softsp) -{ - int i; - - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, "in wrsm_lc_cleanconfig - wci %d", - softsp->portid)); - ASSERT(softsp->oldlink_waitdown_cnt == 0); - - /* - * Take down all links not in the config. - */ - mutex_enter(&softsp->lc_mutex); - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - if ((softsp->config == NULL) || - !softsp->config->links[i].present) { - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_cleanconfig - " - "takedown link %d wci %d", i, softsp->portid)); - wrsm_lc_link_takedown(softsp, i, - B_FALSE, B_FALSE); - /* - * All user link down states are discarded when a - * link is removed from a config. - */ - softsp->links[i].interval_count = 0; - softsp->links[i].user_down_requested = B_FALSE; - softsp->links[i].cont_errs = 0; - softsp->links[i].num_err_takedown = 0; - softsp->links[i].last_err_takedown = 0; - softsp->links[i].max_err_takedown = 0; - softsp->links[i].avg_err_takedown = 0; - softsp->links[i].num_disconnected_takedown = 0; - softsp->links[i].num_cfg_takedown = 0; - softsp->links[i].num_requested_bringups = 0; - softsp->links[i].num_completed_bringups = 0; - softsp->links[i].num_errors = 0; - softsp->links[i].shortterm_errsum = 0; - softsp->links[i].shortterm_last_errors = 0; - softsp->links[i].shortterm_max_errors = 0; - softsp->links[i].shortterm_avg_errors = 0; - softsp->links[i].longterm_errsum = 0; - softsp->links[i].longterm_last_errors = 0; - softsp->links[i].longterm_max_errors = 0; - softsp->links[i].longterm_avg_errors = 0; - } - } - - /* - * Calculate which links not in the config are not down yet, and - * need to be waited for. - */ - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - if ((softsp->config == NULL) || - !softsp->config->links[i].present) { - if ((softsp->links[i].link_req_state != lc_down) && - (softsp->links[i].link_req_state != lc_not_there)) { - softsp->oldlink_waitdown_cnt++; - } - } - } - mutex_exit(&softsp->lc_mutex); -} - -/* - * lc_installconfig waits for all takedown request to be fully completed. - * This function will bringup up new links and confirms existing link - * connections. - */ -void -wrsm_lc_installconfig(wrsm_softstate_t *softsp) -{ - int i; - - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, "in wrsm_lc_installconfig - wci %d", - softsp->portid)); - - /* - * wait for old links to come down - */ - mutex_enter(&softsp->lc_mutex); - while (softsp->oldlink_waitdown_cnt != 0) { - DPRINTF(LC_DEBUG, (CE_CONT, "INSTALL IS WAITING")); - cv_wait(&softsp->goinstallconfig, &softsp->lc_mutex); - } - - /* - * Cancel timeout initiated link bringup - any links we want to - * bring for the new config will be brought up now. - */ - if (softsp->restart_timeout_id != 0) { - timeout_id_t restart_timeout_id; - - restart_timeout_id = softsp->restart_timeout_id; - softsp->restart_timeout_id = 0; - mutex_exit(&softsp->lc_mutex); - - /* LINTED: E_NOP_IF_STMT */ - if (untimeout(restart_timeout_id) == -1) { - DPRINTF(LC_DEBUG, (CE_CONT, - "wrsm_lc_link_installconfig" - " restart_timeout_id not valid")); - } - } else { - mutex_exit(&softsp->lc_mutex); - } - - if (softsp->config == NULL) { - /* no new config; clean up and return */ - wrsm_lc_wcifini(softsp); - return; - } - - /* - * bring up links in new config - */ - - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - - mutex_enter(&softsp->lc_mutex); - - if (softsp->config->links[i].present) { - /* - * It is important to attempt to bringup links in - * sc_wait_down state to allow for uniform - * treatment of down states. Links in - * sc_wait_errdown state will already come back up. - */ - if ((softsp->links[i].link_req_state == lc_down) || - (softsp->links[i].link_req_state == sc_wait_down)) { - /* - * For any link that is not currently up, - * the LC is not allowed to call - * mh_link_is_up for this link until - * lc_enableconfig is called. - */ - softsp->links[i].tell_mh_link_is_up = B_FALSE; - softsp->newlink_waitup_cnt++; - - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, - "lc_installconfig: new link %d" - " newlink_waitup_cnt = %d", i, - softsp->newlink_waitup_cnt)); - - wrsm_lc_link_bringup(softsp, i); - - } else if (softsp->links[i].link_req_state == lc_up) { - /* verify remote config data */ - DPRINTF(LC_DEBUG, (CE_CONT, "confirm" - " remote config on old link %d", i)); - wrsm_lc_link_bringup(softsp, i); - } - } - mutex_exit(&softsp->lc_mutex); - } -} - -/* - * calls mh_link_is_up() for each new link requested up in - * lc_installconfig - */ -void -wrsm_lc_enableconfig(wrsm_softstate_t *softsp) -{ - int i; - wrsm_gnid_t remote_gnid; - wnodeid_t remote_wnode; - - DPRINTF(LC_DEBUG_EXTRA, (CE_CONT, "in wrsm_lc_enableconfig - wci %d", - softsp->portid)); - - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - - mutex_enter(&softsp->lc_mutex); - - if ((softsp->links[i].link_req_state == lc_up) && - (!softsp->links[i].tell_mh_link_is_up)) { - ASSERT(softsp->config->links[i].present); - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_enableconfig:" - " enable wci %d link %d", softsp->portid, i)); - softsp->links[i].tell_mh_link_is_up = B_TRUE; - mutex_exit(&softsp->lc_mutex); - remote_gnid = softsp->config->links[i].remote_gnid; - remote_wnode = softsp->links[i].remote_wnode; - /* LINTED: E_NOP_IF_STMT */ - if (WRSM_GNID_IS_WCX(remote_gnid)) { - DPRINTF(LC_DEBUG, (CE_CONT, "lc_enableconfig" - " enable link %d to wcx %d", i, - remote_gnid)); - /* LINTED: E_NOP_IF_STMT */ - } else if (remote_wnode >= WRSM_MAX_WNODES) { - DPRINTF(LC_WARN, (CE_WARN, - "Bad remote wnode for wci %d link %d: %d", - softsp->portid, i, remote_wnode)); - } else { - wrsm_mh_link_is_up(softsp->nc, i, - remote_wnode); - } - } else { - softsp->links[i].tell_mh_link_is_up = B_TRUE; - mutex_exit(&softsp->lc_mutex); - } - } - - /* - * We no longer care about newlink_waitup_cnt. The purpose of - * this count is to determine ahead of time that all the - * requested links are up and then call nr_all_links_up which will - * force the NR into calling lc_enableconfig earlier - */ - softsp->newlink_waitup_cnt = 0; -} - -safari_port_t -wrsm_lc_get_safid(wrsm_softstate_t *softsp) -{ - ASSERT(softsp != NULL); - return (softsp->portid); -} - -int -wrsm_lc_get_instance(wrsm_softstate_t *softsp) -{ - ASSERT(softsp != NULL); - return (softsp->instance); -} - -/* - * given dev_id (and box_id from wci_config) get index into cesr - */ -static uint32_t -get_index(wrsm_softstate_t *softsp, uint32_t dev_id) -{ - wci_config_u wci_config_tmp; - int box_id; - int index = 0; - - wrsm_lc_csr_read(softsp, ADDR_WCI_CONFIG, &wci_config_tmp.val); - box_id = (uint32_t)wci_config_tmp.bit.box_id; - /* - * Hardware defines the index into the CESR as follows: - * cesr index bit [0] = dev_id bit [0] - * cesr index bit [1] = dev_id bit [1] - * cesr index bit [2] = dev_id bit [3] | box_id bit [0] - * cesr index bit [3] = dev_id bit [4] | box_id bit [1] - * cesr index bit [4] = dev_id bit [2] | box_id bit [2] - * cesr index bit [5] = box_id bit [3] - * cesr index bit [6] = box_id bit [4] - * cesr index bit [7] = box_id bit [5] - */ - index = (dev_id & 0x3) | ((box_id & 0x3f) << 2); - index |= BIT(dev_id, 3) << 2; - index |= BIT(dev_id, 4) << 3; - index |= BIT(dev_id, 2) << 4; - return (index); -} - -/* - * returns entire contents of cesr[index] in entry - */ -void -wrsm_lc_cesr_read(wrsm_softstate_t *softsp, safari_port_t dev_id, - uint64_t *entry) -{ - uint32_t index; - index = get_index(softsp, dev_id); - - ASSERT(index <= ENTRIES_WCI_CLUSTER_ERROR_STATUS_ARRAY); - *entry = *((uint64_t *)(softsp->wrsm_regs + - ADDR_WCI_CLUSTER_ERROR_STATUS_ARRAY + (index - * STRIDE_WCI_CLUSTER_ERROR_STATUS_ARRAY))); - DPRINTF(LC_CESR, (CE_NOTE, "read cesr at index=%d, entry = " - "0x%"PRIx64, index, *entry)); -} - -/* - * writes entire entry to cesr[index] - */ -void -wrsm_lc_cesr_write(wrsm_softstate_t *softsp, safari_port_t dev_id, - uint64_t entry) -{ - uint32_t index; - index = get_index(softsp, dev_id); - - ASSERT(index <= ENTRIES_WCI_CLUSTER_ERROR_STATUS_ARRAY); - *((uint64_t *)(softsp->wrsm_regs + ADDR_WCI_CLUSTER_ERROR_STATUS_ARRAY - + (index * STRIDE_WCI_CLUSTER_ERROR_STATUS_ARRAY))) = entry; - DPRINTF(LC_CESR, (CE_NOTE, "write cesr at index=%d, entry is" - " 0x%"PRIx64"", index, entry)); -} - -/* - * reads from register at reg_offset and returns entire register contents - * in entry - */ -void -wrsm_lc_csr_read(wrsm_softstate_t *softsp, uint64_t reg_offset, - uint64_t *entry) -{ - /* check for valid offset */ - ASSERT((reg_offset & REGMASK) == 0); - ASSERT(softsp); - ASSERT(softsp->wrsm_regs); - *entry = *((uint64_t *)(softsp->wrsm_regs + reg_offset)); - - DPRINTF(LC_CSR_READ_DEBUG, (CE_NOTE, "read csr at reg_offset=" - "0x%"PRIx64", entry = 0x%"PRIx64, reg_offset, *entry)); -} - -/* - * write entire contents of entry at register at reg_offset - */ -void -wrsm_lc_csr_write(wrsm_softstate_t *softsp, uint64_t reg_offset, - uint64_t entry) -{ - volatile uint64_t *vaddr = (uint64_t *) - (softsp->wrsm_regs + reg_offset); - /* LINTED: E_FUNC_SET_NOT_USED */ - volatile uint64_t readback; - - /* check for valid offset */ - ASSERT((reg_offset & REGMASK) == 0); - - DPRINTF(LC_CSR_WRITE_DEBUG, (CE_NOTE, "write to csr at reg_offset=" - "0x%"PRIx64", value of 0x%"PRIx64"", reg_offset, entry)); - - /* Write to the CSR */ - *vaddr = entry; - - /* Read back to ensure it's stuck in hardware */ - readback = *vaddr; -} - -static void -wrsm_lc_poll_timeout(wrsm_softstate_t *softsp) -{ - int link; - static uint32_t max_wait_count = WRSM_LINK_MAX_WAIT_COUNT; - boolean_t do_shortterm = B_FALSE; - clock_t time_now; - - DPRINTF(LC_POLL, (CE_CONT, "in wrsm_lc_poll_timeout")); - - time_now = ddi_get_lbolt(); - if ((time_now - softsp->shortterm_start) >= wrsm_shortterm_hz) { - DPRINTF(LC_POLL, - (CE_CONT, "lc_poll_timeout: do_shortterm")); - softsp->shortterm_start = time_now; - do_shortterm = B_TRUE; - } - - wrsm_lc_err_cnt(softsp, do_shortterm); - wrsm_lc_check_lockout(softsp); - wrsm_lc_check_paroli_hotplug(softsp); - wrsm_lc_check_wcx_links(softsp); - - wrsm_lc_ecc_check(softsp); - wrsm_lc_sram_ecc_check(softsp, do_shortterm); - - mutex_enter(&softsp->lc_mutex); - - /* Retry send link bringup request periodically */ - if (softsp->ctlr_config) { - for (link = 0; link < WRSM_LINKS_PER_WCI; link++) { - switch (softsp->links[link].link_req_state) { - case sc_wait_up: - softsp->links[link].waiting_count++; - if (softsp->links[link].waiting_count < - max_wait_count) { - break; - } - DPRINTF(LC_DEBUG, (CE_CONT, - "wrsm_lc_poll_timeout: " - "retrying link bringup for " - "wci %d link %d\n", softsp->portid, link)); - wrsm_lc_link_bringup(softsp, link); - break; - case sc_wait_down: - softsp->links[link].waiting_count++; - if (softsp->links[link].waiting_count < - max_wait_count) { - break; - } - DPRINTF(LC_DEBUG, (CE_CONT, - "wrsm_lc_poll_timeout: " - "retrying link takedown for " - "wci %d link %d\n", softsp->portid, link)); - wrsm_lc_link_takedown(softsp, link, B_FALSE, - B_FALSE); - break; - case sc_wait_errdown: - softsp->links[link].waiting_count++; - if (softsp->links[link].waiting_count < - max_wait_count) { - break; - } - DPRINTF(LC_DEBUG, (CE_CONT, - "wrsm_lc_poll_timeout: " - "retrying link takedown on errors for " - "wci %d link %d\n", softsp->portid, link)); - wrsm_lc_link_takedown(softsp, link, B_TRUE, - B_FALSE); - break; - } - } - } - if (softsp->err_timeout_id) { - softsp->err_timeout_id = timeout((void (*)(void *)) - wrsm_lc_poll_timeout, softsp, wrsm_poll_hz); - } - mutex_exit(&softsp->lc_mutex); -} - - -/* - * Bring back up any links in the config that have been brought down due to - * prolonged link errors or bad configs. - */ -static void -wrsm_lc_restart_downlinks(wrsm_softstate_t *softsp) -{ - int i; - - if (softsp->restart_timeout_id == 0) { - return; - } - softsp->restart_timeout_id = 0; - - mutex_enter(&softsp->lc_mutex); - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - if ((softsp->links[i].link_req_state == lc_down) && - !softsp->links[i].user_down_requested && - (softsp->config != NULL) && - (softsp->config->links[i].present)) { - wrsm_lc_link_bringup(softsp, i); - } - } - mutex_exit(&softsp->lc_mutex); -} - - -/* - * update error statistics used by status kstat - */ -static void -wrsm_lc_update_errstats(wrsm_softstate_t *softsp, int link, - uint64_t num_errs, boolean_t do_shortterm) -{ - /* update shortterm error monitor */ - softsp->links[link].num_errors += num_errs; - softsp->links[link].shortterm_errsum += num_errs; - if (do_shortterm) { - softsp->links[link].interval_count++; - softsp->links[link].last_err_takedown = - softsp->links[link].err_takedown_sum; - softsp->links[link].max_err_takedown = - MAX(softsp->links[link].max_err_takedown, - softsp->links[link].err_takedown_sum); - softsp->links[link].avg_err_takedown = - RUNNING_AVG(softsp->links[link].err_takedown_sum, - softsp->links[link].avg_err_takedown); - softsp->links[link].err_takedown_sum = 0; - - softsp->links[link].shortterm_last_errors = - softsp->links[link].shortterm_errsum; - softsp->links[link].shortterm_max_errors = - MAX(softsp->links[link].shortterm_max_errors, - softsp->links[link].shortterm_errsum); - softsp->links[link].shortterm_avg_errors = - RUNNING_AVG(softsp->links[link].shortterm_errsum, - softsp->links[link].shortterm_avg_errors); - - /* update longterm error monitor */ - softsp->links[link].longterm_shortterms++; - softsp->links[link].longterm_errsum += - softsp->links[link].shortterm_errsum; - if (softsp->links[link].longterm_shortterms == - wrsm_shorts_per_longterm) { - softsp->links[link].longterm_last_errors = - softsp->links[link].longterm_errsum; - softsp->links[link].longterm_max_errors = - MAX(softsp->links[link].longterm_max_errors, - softsp->links[link].longterm_errsum); - softsp->links[link].longterm_avg_errors = - RUNNING_AVG( - softsp->links[link].longterm_errsum, - softsp->links[link].longterm_avg_errors); - softsp->links[link].longterm_errsum = 0; - softsp->links[link].longterm_shortterms = 0; - - } - softsp->links[link].shortterm_errsum = 0; - } -} - - -/* - * wrsm_lc_err_cnt checks and clears the link error count register: - * wci_sw_link_error_count - * wrsm_sw_link_error_count is and array of NUM_LINKS = - * ENTRIES_WCI_SW_LINK_ERROR_COUNT = 3 - * SC controls: - * wci_sw_link_control_u.near_end_shutdown_lock (bit 4) should be set - * wci_sw_link_control_u.auto_shut_en set to enable hardware to shut - * down link. (bit 2) (default is NOT enabled) - */ -static void -wrsm_lc_err_cnt(wrsm_softstate_t *softsp, boolean_t do_shortterm) -{ - wci_sw_link_error_count_u reg; - wci_sw_esr_u sw_esr; - int i; - wci_sw_link_control_u sw_link_ctrl; - boolean_t acc_auto_shut[WRSM_LINKS_PER_WCI]; - wci_sw_link_status_u status; - uint64_t num_errs; - boolean_t takedown_link; - - - /* - * We enable auto link shutdown in cluster mode; because of this, - * we must check the accumulated auto_shut bits to test for a - * hardware shutdown. - * - * Read registers associated with HW shutdown. - */ - wrsm_lc_csr_read(softsp, ADDR_WCI_SW_ESR, &sw_esr.val); - wrsm_lc_csr_read(softsp, ADDR_WCI_SW_LINK_CONTROL, - &sw_link_ctrl.val); - acc_auto_shut[0] = sw_esr.bit.acc_link_0_auto_shut; - acc_auto_shut[1] = sw_esr.bit.acc_link_1_auto_shut; - acc_auto_shut[2] = sw_esr.bit.acc_link_2_auto_shut; - - - /* - * Because this is a toggle/write register, in order to only set - * the bit field in question we must first set all fields to 0 so - * that we don't inadvertently toggle write a bit field other than - * the one(s) in question. - */ - sw_esr.val = 0; - - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - - mutex_enter(&softsp->lc_mutex); - wrsm_lc_csr_read(softsp, (ADDR_WCI_SW_LINK_STATUS + - (i * STRIDE_WCI_SW_LINK_STATUS)), &status.val); - /* only check on links that are already up */ - if (softsp->links[i].link_req_state != lc_up) { - wrsm_lc_update_errstats(softsp, i, 0, do_shortterm); - mutex_exit(&softsp->lc_mutex); - continue; - } - - takedown_link = B_FALSE; - - /* - * Check if link has been auto-shutdown. If so, we still - * need to turn off lasers, etc, so still must call - * wrsm_lc_link_takedown(). - */ - if (acc_auto_shut[i]) { - - softsp->links[i].cont_errs++; - if (status.bit.paroli_present != WCI_PAROLI_PRESENT) { - /* paroli removed while in use */ - cmn_err(CE_NOTE, "wci %d link %d " - "removed from service while in use", - softsp->portid, i); - lc_link_takedown_all(softsp, i); - softsp->links[i].link_req_state = lc_not_there; - } else { - takedown_link = B_TRUE; - } - /* - * If link is configured and session is in - * progress, report this link down event. - * Otherwise don't; the link_down reason will be - * reported as unconfigured. - */ - if ((softsp->config != NULL) && - (softsp->config->links[i].present)) { - if ((softsp->links[i].remote_wnode >= - WRSM_MAX_WNODES) || - wrsm_nr_session_up(softsp->nc, - softsp->links[i].remote_wnode)) { - wrsm_lc_logevent(softsp, - link_down, i, - "hardware-shutdown"); - softsp->links[i].num_err_takedown++; - softsp->links[i].err_takedown_sum++; - } else { - /* - * no session, link was probably - * shutdown at remote end - */ - wrsm_lc_logevent(softsp, - link_down, i, - "disconnected-shutdown"); - softsp->links[i]. - num_disconnected_takedown++; - } - } - - /* - * We clear the acc_auto_shut bit in wci_sw_esr so - * that the LC can use it to detect the next - * hardware shutdown. This register is a - * toggle/write register, so we must write 1 in - * order to clear the bit. - * - * reset - bit fields are not arrays: - * acc_link_0 bit field 20 - * acc_link_1 bit field 21 - * acc_link_2 bit field 22 - */ - sw_esr.val |= ((uint64_t)1 << (20 + i)); - } - - /* - * Check the link error counter to see if link - * should be shutdown by hand, and to clear - * any errors. - */ - - reg.val = *softsp->links[i].wrsm_link_err_cnt_addr; - num_errs = reg.bit.error_count; - softsp->wci_common_softst. - wci_sw_link_error_count_sum[i] += num_errs; - - if (!takedown_link && (num_errs >= MAXERRORS) && - (softsp->links[i].link_req_state == lc_up)) { - DPRINTF(LC_WARN, (CE_WARN, - "wrsm%d: err cnt = %"PRIx64" too high" - " on link %d", softsp->instance, - num_errs, i)); - softsp->links[i].cont_errs++; - /* - * If link is configured, report this link down - * event. Otherwise don't; the link_down reason - * will be reported as unconfigured. - */ - if ((softsp->config != NULL) && - (softsp->config->links[i].present)) { - if ((softsp->links[i].remote_wnode >= - WRSM_MAX_WNODES) || - wrsm_nr_session_up(softsp->nc, - softsp->links[i].remote_wnode)) { - wrsm_lc_logevent(softsp, - link_down, i, - "link-errors"); - softsp->links[i].num_err_takedown++; - softsp->links[i].err_takedown_sum++; - } else { - /* - * no session, link was probably - * shutdown at remote end - */ - wrsm_lc_logevent(softsp, - link_down, i, - "disconnected-shutdown"); - softsp->links[i]. - num_disconnected_takedown++; - } - } - takedown_link = B_TRUE; - } - - if (!takedown_link) { - /* - * No link problem during this - * round. - */ - softsp->links[i].cont_errs = 0; - } - - /* take down link if needed */ - if (takedown_link) { - wrsm_lc_link_takedown(softsp, i, - B_TRUE, B_FALSE); - } - - /* - * Link error counter and error status registers - * must be cleared if any link errors have occured. - */ - if (num_errs > 0) { - reg.bit.error_count = 0; - *softsp->links[i].wrsm_link_err_cnt_addr = reg.val; - - /* write back to clear error bits */ - wrsm_lc_csr_write(softsp, (ADDR_WCI_SW_LINK_STATUS + - (i * STRIDE_WCI_SW_LINK_STATUS)), status.val); - if (wrsm_log_link_errors) { - cmn_err(CE_NOTE, "wci %u link %d, " - "wci_sw_link_error_count = %lu, " - "wci_sw_link_error_sum = %lu, " - "crc = %d, framing = %d, clocking = %d", - softsp->portid, i, num_errs, - softsp->wci_common_softst. - wci_sw_link_error_count_sum[i], - status.bit.crc_error, - status.bit.framing_error, - status.bit.clocking_error); - } - } - - if (takedown_link) { - /* - * Don't count links errors that caused a link - * takedown in link_errors counter; they are - * counted in the takedown counters. - */ - num_errs = 0; - } - wrsm_lc_update_errstats(softsp, i, num_errs, do_shortterm); - mutex_exit(&softsp->lc_mutex); - } - - /* Toggle auto_shut bits back to reset mode */ - wrsm_lc_csr_write(softsp, ADDR_WCI_SW_ESR, sw_esr.val); -} - -static void -wrsm_lc_check_lockout(wrsm_softstate_t *softsp) -{ - wci_ra_esr_1_u ra_esr_1; - wci_ra_write_lockout_status_u status; - - wrsm_lc_csr_read(softsp, ADDR_WCI_RA_ESR_1, &ra_esr_1.val); - if (ra_esr_1.bit.acc_write_lockout) { - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_check_lockout ra_esr_1" - " 0x%"PRIx64, ra_esr_1.val)); - - /* First clear the esr bit */ - wrsm_lc_csr_read(softsp, ADDR_WCI_RA_WRITE_LOCKOUT_STATUS, - &status.val); - ra_esr_1.val = 0; - ra_esr_1.bit.acc_write_lockout = 1; - wrsm_lc_csr_write(softsp, ADDR_WCI_RA_ESR_1, ra_esr_1.val); - - /* Next do the special read from page 1 */ - wrsm_nr_clear_lockout(softsp->nc, - (ncslice_t)status.bit.nc_slice); - - /* clear the esr again, if necessary */ - wrsm_lc_csr_read(softsp, ADDR_WCI_RA_ESR_1, &ra_esr_1.val); - if (ra_esr_1.bit.acc_write_lockout) { - ra_esr_1.val = 0; - ra_esr_1.bit.acc_write_lockout = 1; - wrsm_lc_csr_write(softsp, ADDR_WCI_RA_ESR_1, - ra_esr_1.val); - } - -#ifdef DEBUG - wrsm_lc_csr_read(softsp, ADDR_WCI_RA_WRITE_LOCKOUT_STATUS, - &status.val); - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_check_lockout: status" - " slice %lu stripe %lu", status.bit.nc_slice, - status.bit.link_stripe)); -#endif - /* For good measure, clear the status register too */ - wrsm_lc_csr_write(softsp, ADDR_WCI_RA_WRITE_LOCKOUT_STATUS, 0); - } -} - - -/* - * In the event the SC should crash while messages were between - * the SC and the mailbox, the SC will have no way of knowing what - * messages were lost. In this event, the SC sends a 'I am Here" - * message. When the LC gets this it knows the SC crashed. This function - * resends all messages in the sc_waitxxx state to the SC, and resends - * request to set LEDs off or On depending on if the link is lc_down or lc_up - */ -void -wrsm_lc_sc_crash(wrsm_softstate_t *softsp) -{ - int i; - - if (softsp == NULL) { - /* invalid arg */ - DPRINTF(LC_WARN, (CE_WARN, "wrsm_lc_sc_crash " - "invalid softsp")); - return; - } - mutex_enter(&softsp->lc_mutex); - if (softsp->suspended) { - mutex_exit(&softsp->lc_mutex); - return; - } - - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - if (softsp->links[i].link_req_state == sc_wait_up) { - DPRINTF(LC_DEBUG, (CE_CONT, "crash UPLINK")); - softsp->links[i].num_requested_bringups++; - softsp->links[i].waiting_count = 0; - (void) wrsmplat_uplink(softsp->portid, - (linkid_t)i, softsp->local_gnid, - softsp->ctlr_config->fmnodeid, - softsp->ctlr_config->version_stamp, - softsp->ctlr_config->controller_id, - B_FALSE /* loopback */); - } else if ((softsp->links[i].link_req_state == - sc_wait_down) || (softsp->links[i].link_req_state - == sc_wait_errdown)) { - DPRINTF(LC_DEBUG, (CE_CONT, "crash DOWNLINK")); - softsp->links[i].waiting_count = 0; - (void) wrsmplat_downlink(softsp->portid, - (linkid_t)i, B_FALSE); - } - } - mutex_exit(&softsp->lc_mutex); -} - -static void -wrsm_lc_clear_cmmu(wrsm_softstate_t *softsp) -{ - int i; - wrsm_cmmu_t cmmu; - const int numcmmu_entries = wrsm_lc_num_cmmu_entries_get(softsp); -#ifdef DEBUG - const uint32_t debug_flags = wrsm_lc_debug; /* Save original state */ - wrsm_lc_debug &= ~LC_CMMU; /* Turn off the LC_CMMU flag, if it's set */ -#endif /* DEBUG */ - - cmmu.entry_0.val = 0; - cmmu.entry_1.val = 0; - for (i = 0; i < numcmmu_entries; i++) { - wrsm_lc_cmmu_update(softsp, &cmmu, i, - CMMU_UPDATE_WRITEONLY); - } - -#ifdef DEBUG - wrsm_lc_debug = debug_flags; /* Restore to original settings */ -#endif /* DEBUG */ -} - -void -wrsm_lc_cmmu_update(wrsm_softstate_t *softsp, wrsm_cmmu_t *entry, - uint32_t index, wrsm_cmmu_flags_t flags) -{ - wrsm_cmmu_t tmp_entry; - uint64_t entry0_addr; - uint64_t entry1_addr; - boolean_t prev_valid_bit_value; /* previous value for valid bit */ - volatile uint64_t *cluster_syncp; - wci_cluster_sync_u cluster_sync; - /* LINTED: E_FUNC_SET_NOT_USED */ - volatile uint64_t readback; - - ASSERT(softsp != NULL); - - DPRINTF(LC_CMMU, (CE_NOTE, - "lc_cmmu_update(wci %d, index=%u, entry0=0x%08lX, " - "entry1=0x%08lX, flags=0x%04X)", softsp->portid, - index, entry->entry_0.val, entry->entry_1.val, flags)); - - /* Don't write off the end of the CMMU sram */ - if (index >= wrsm_lc_num_cmmu_entries_get(softsp)) { - return; - } - - /* - * Note cmmu_entry0 and cmmu_entry1 are interleaved. - * Because of this each Index for an entry is spaced 0x40 - * apart from the previous one. - * The initial physical address starts where cmmu_entry0 begins, - * because of the cmmu_entry1 must always be offset by an - * additional 20 from the base of softsp->cmmu_addr - */ - entry0_addr = (uint64_t)((softsp->wrsm_sram) + - (index * 2 * STRIDE_WCI_SRAM_ARRAY)); - entry1_addr = entry0_addr + STRIDE_WCI_SRAM_ARRAY; - - /* used to inject SRAM ECC errors into CMMU entries by cmmu injector */ - if (flags & CMMU_UPDATE_WRITEONLY) { - /* write full values */ - STOREPHYS(entry->entry_1.val, entry1_addr); - STOREPHYS(entry->entry_0.val, entry0_addr); - DPRINTF(LC_CMMU, (CE_NOTE, "wrsm_lc_cmmu_update(index=%u) " - "clean write to cmmu, no read back", index)); - return; - } - if (flags & CMMU_UPDATE_WRITE_0) { - /* write full value 0 */ - STOREPHYS(entry->entry_0.val, entry0_addr); - DPRINTF(LC_CMMU, (CE_NOTE, "wrsm_lc_cmmu_update(index=%u) " - "clean write to cmmu entry 1, no read back", index)); - return; - } - if (flags & CMMU_UPDATE_WRITE_1) { - /* write full value 1 */ - STOREPHYS(entry->entry_1.val, entry1_addr); - DPRINTF(LC_CMMU, (CE_NOTE, "wrsm_lc_cmmu_update(index=%u) " - "clean write to cmmu entry 0, no read back", index)); - return; - } - - /* store value for entry 0 in tmp_entry */ - LOADPHYS(tmp_entry.entry_0.val, entry0_addr); - - - /* - * Set the cmmu entry to invalid so that the separate update of each - * half of the entry doesn't end up creating a strange state. - * - * Only need to clear the valid bit IF both entries need to change - * and the valid bit was set and the user error bit wasn't. - */ - prev_valid_bit_value = tmp_entry.entry_0.bit.valid; /* needed later */ - if (tmp_entry.entry_0.bit.valid && - !tmp_entry.entry_0.bit.user_err) { - tmp_entry.entry_0.bit.valid = B_FALSE; - STOREPHYS(tmp_entry.entry_0.val, entry0_addr); - } - - LOADPHYS(tmp_entry.entry_1.val, entry1_addr); - - - if (flags == CMMU_UPDATE_ALL) { - /* - * Use passed in values for all fields. - * - * Set entry 1, then entry 0 of the cmmu entry to the - * passed in values. Entry 0 is updated second in order to - * leave the valid bit set to false until the update of - * both halves is complete. - */ - STOREPHYS(entry->entry_1.val, entry1_addr); - STOREPHYS(entry->entry_0.val, entry0_addr); - DPRINTF(LC_CMMU, (CE_NOTE, "lc_cmmu_update entry1" - " addr 0x%"PRIx64", entry value = 0x%"PRIx64, - (uint64_t)(entry1_addr), entry->entry_1.val)); - DPRINTF(LC_CMMU, (CE_NOTE, "lc_cmmu_update entry0" - " addr 0x%"PRIx64", entry value = 0x%"PRIx64, - (uint64_t)(entry0_addr), entry->entry_0.val)); - } else { - /* - * Update tmp_entry with the appropriate fields, then set - * entry 1 followed by entry 0 of the cmmu entry to the - * values in tmp_entry. Entry 0 is updated second in order - * to leave the valid bit set to false until the update of - * both halves is complete. - */ - if (flags & CMMU_UPDATE_MONDO) { - tmp_entry.entry_1.intr.mondo = - entry->entry_1.intr.mondo; - } - if (flags & CMMU_UPDATE_FROMNODE) { - tmp_entry.entry_0.bit.from_node = - entry->entry_0.bit.from_node; - } - if (flags & CMMU_UPDATE_TYPE) { - tmp_entry.entry_0.bit.type = entry->entry_0.bit.type; - } - if (flags & CMMU_UPDATE_WRITABLE) { - tmp_entry.entry_0.bit.writable = - entry->entry_0.bit.writable; - } - if (flags & CMMU_UPDATE_USERERROR) { - tmp_entry.entry_0.bit.user_err = - entry->entry_0.bit.user_err; - } - if (flags & CMMU_UPDATE_FROMALL) { - tmp_entry.entry_0.bit.from_all = - entry->entry_0.bit.from_all; - } - if (flags & CMMU_UPDATE_LARGEPAGE) { - tmp_entry.entry_0.bit.large_page = - entry->entry_0.bit.large_page; - } - if (flags & CMMU_UPDATE_ENABLEPERF) { - tmp_entry.entry_0.bit.count_enable = - entry->entry_0.bit.count_enable; - } - if (flags & CMMU_UPDATE_VALID) { - tmp_entry.entry_0.bit.valid = entry->entry_0.bit.valid; - } else { /* set back to original value */ - tmp_entry.entry_0.bit.valid = prev_valid_bit_value; - } - - /* - * Only allowed to set either the LPA or the INTRDEST fields, - * but not both. (These fields overlap.) - */ - ASSERT(!((flags & CMMU_UPDATE_LPA) && - flags & CMMU_UPDATE_INTRDEST)); - if (flags & CMMU_UPDATE_LPA) { - tmp_entry.entry_1.addr.lpa_page = - entry->entry_1.addr.lpa_page; - } else if (flags & CMMU_UPDATE_INTRDEST) { - tmp_entry.entry_1.intr.lpa_page_2 = - entry->entry_1.intr.lpa_page_2; - } - STOREPHYS(tmp_entry.entry_1.val, entry1_addr); - STOREPHYS(tmp_entry.entry_0.val, entry0_addr); - DPRINTF(LC_CMMU, (CE_NOTE, "lc_cmmu_update entry1" - "addr 0x%"PRIx64", entry value = 0x%"PRIx64, - (uint64_t)(entry1_addr), tmp_entry.entry_1.val)); - DPRINTF(LC_CMMU, (CE_NOTE, "lc_cmmu_update entry0" - " addr 0x%"PRIx64", entry value = 0x%"PRIx64, - (uint64_t)(entry0_addr), tmp_entry.entry_0.val)); - } - - /* readback to assure the write to hardware occured */ - LOADPHYS(readback, entry0_addr); - LOADPHYS(readback, entry1_addr); - - - if (flags & CMMU_UPDATE_FLUSH) { - - /* grab lock so only one thread at a time has access */ - mutex_enter(&softsp->cmmu_mutex); - cluster_syncp = (uint64_t *) - (softsp->wrsm_regs + ADDR_WCI_CLUSTER_SYNC); - cluster_sync.val = *cluster_syncp; - - /* - * setting sync_in_progress tells the hardware to do - * CMMU flush. once the hardware has set sync_in_progress - * back to 0 AND there aren't any cag_busy bits set - * we can considered the CMMU successfully FLUSHED. - */ - cluster_sync.bit.sync_in_progress = 1; - cluster_sync.bit.cag_busy = 0; - *cluster_syncp = cluster_sync.val; - while (cluster_sync.val) { - DPRINTF(LC_CMMU, (CE_NOTE, "lc_cmmu_update " - " CMMU_UPDATE_FLUSH addr %p wci_cluster_sync " - "0x%lx has is waiting on hardware to respond", - (void *)cluster_syncp, cluster_sync.val)); - - cluster_sync.val = *cluster_syncp; - }; - mutex_exit(&softsp->cmmu_mutex); - } -} - -void -wrsm_lc_cmmu_read(wrsm_softstate_t *softsp, wrsm_cmmu_t *cmmu_entry, - uint32_t index) -{ - uint64_t entry0_offset; - uint64_t entry1_offset; - - ASSERT(softsp != NULL); - - /* Don't read beyond the end of the CMMU sram */ - if (index >= wrsm_lc_num_cmmu_entries_get(softsp)) { - cmmu_entry->entry_0.val = 0; - cmmu_entry->entry_1.val = 0; - return; - } - - /* - * Note cmmu_entry0 and cmmu_entry1 are interleaved. - * Because of this each Index for an entry is spaced 0x40 - * apart from the previous one. - * The initial physical address starts where cmmu_entry0 begins, - * because of the cmmu_entry1 must always be offset by an - * additional 20 from the base of softsp->cmmu_addr - */ - entry0_offset = index * 2 * STRIDE_WCI_SRAM_ARRAY; - entry1_offset = STRIDE_WCI_SRAM_ARRAY + - (index * 2 * STRIDE_WCI_SRAM_ARRAY); - LOADPHYS(cmmu_entry->entry_0.val, softsp->wrsm_sram + entry0_offset); - LOADPHYS(cmmu_entry->entry_1.val, softsp->wrsm_sram + entry1_offset); - - DPRINTF(LC_CMMU, (CE_NOTE, "wrsm_lc_cmmu_read(index=%u) = " - "0x%016lX 0x%016lX", index, cmmu_entry->entry_0.val, - cmmu_entry->entry_1.val)); - - if (cmmu_entry->entry_0.bit.error) { - cmn_err(CE_WARN, "wci %d sram uncorrectable error " - "(0x%016lX) index %u entry 0", softsp->portid, - cmmu_entry->entry_0.val, index); - } - if (cmmu_entry->entry_1.addr.error) { - cmn_err(CE_WARN, "wci %d sram uncorrectable error " - "(0x%016lX) index %u entry 1", softsp->portid, - cmmu_entry->entry_1.val, index); - } -} - -int -wrsm_lc_num_cmmu_entries_get(wrsm_softstate_t *softsp) -{ - int num_entries; - int max_usable_entries = wrsm_cmmu_max_entries; - ASSERT(softsp != NULL); - - num_entries = min(max_usable_entries, - ((int)softsp->sramsize) / ((int)(2 * STRIDE_WCI_SRAM_ARRAY))); - return (num_entries); -} - - -/* The following is for the interrupt trap handler only */ -caddr_t -wrsm_lc_get_sram_paddr(wrsm_softstate_t *softsp) -{ - /* phsyical addr used to access wci */ - return ((caddr_t)softsp->wrsm_sram); -} - -/* - * The following function is used to emulate a response from the sc - */ -void -get_remote_config_data(safari_port_t wci_id, uint32_t link_num, - fmnodeid_t *remote_fmnodeid, gnid_t *remote_gnid, linkid_t *remote_link, - safari_port_t *remote_port, volatile uchar_t **wrsm_regs) -{ - wrsm_softstate_t *softsp = NULL; - boolean_t simwci; - - softsp = wrsm_cf_lookup_wci(wci_id); - if (softsp == NULL) { - DPRINTF(LC_WARN, (CE_CONT, "get_remote_config_data: " - "could not get softsp")); - return; - } - - simwci = (boolean_t)ddi_getprop(DDI_DEV_T_ANY, softsp->dip, - DDI_PROP_DONTPASS, "simwci", 0); - - DPRINTF(LC_DEBUG, (CE_CONT, - "get_remote_config_data: wci %d sim %d regs %p", - wci_id, simwci, (void *)softsp->wrsm_regs)); - - if (softsp->config != NULL && softsp->ctlr_config != NULL) { - *remote_fmnodeid = softsp->ctlr_config->fmnodeid; - *remote_gnid = softsp->config->links[link_num].remote_gnid; - *remote_link = softsp->config->links[link_num].remote_link_num; - *remote_port = softsp->config->links[link_num].remote_port; - } - if (simwci) - *wrsm_regs = NULL; - else - *wrsm_regs = softsp->wrsm_regs; -} - -/* - * lc_check_paroli_hotplug is called from wrsm_lc_poll_timeout to check - * occasionally if a paroli has been hot pluged. - */ -static void -wrsm_lc_check_paroli_hotplug(wrsm_softstate_t *softsp) -{ - int i; - wci_sw_link_status_u wci_sw_link_status; - - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - wrsm_lc_csr_read(softsp, (ADDR_WCI_SW_LINK_STATUS + - (i * STRIDE_WCI_SW_LINK_STATUS)), &wci_sw_link_status.val); - /* - * if state is both not_there and a paroli has been detected - * this is hotpluged link. Check if part of a config - * and try to bring up. - */ - if ((softsp->links[i].link_req_state == - lc_not_there) && (wci_sw_link_status.bit.paroli_present - == WCI_PAROLI_PRESENT)) { - /* - * No check for simwci needed since we don't use the - * not_there state for simwci's. - */ - mutex_enter(&softsp->lc_mutex); - softsp->links[i].link_req_state = lc_down; - - if ((softsp->config != NULL) && - (softsp->config->links[i].present)) { - DPRINTF(LC_WARN, (CE_NOTE, - "lc_check_paroli_hotplug: paroli detected" - ": wrsm%d port id#%u, link#%d", - softsp->instance, softsp->portid, i)); - /* link is part of a config - bring it up */ - wrsm_lc_link_bringup(softsp, i); - } - mutex_exit(&softsp->lc_mutex); - } - } -} - -static void -wrsm_lc_check_wcx_links(wrsm_softstate_t *softsp) -{ - int i, gnid; - wci_sw_link_status_u link_status; - uint16_t active_diff; - link_t *link; - - /* If WCI is not part of a controller, abort */ - if (softsp->config == NULL) { - return; - } - - for (i = 0; i < WRSM_LINKS_PER_WCI; ++i) { - link = &softsp->links[i]; - - DPRINTF(LC_POLL, (CE_CONT, "check_wcx_links: link %d " - "state %d remote wnode %d", i, link->link_req_state, - link->remote_wnode)); - - /* - * Look for links that are up and connected to a WCX - */ - if ((link->link_req_state != lc_up) || - (!WRSM_GNID_IS_WCX(softsp->links[i].remote_wnode))) - continue; - - DPRINTF(LC_POLL, (CE_CONT, "check_wcx_links: link %d " - "tell_mh %d", i, link->tell_mh_link_is_up)); - - /* - * If it's not ok to call mh, just skip this link, - * the status bits will still be there later. - */ - if (!link->tell_mh_link_is_up) - continue; - - /* - * farend_ustat1 contains a bitmask of other gnids which - * are reachable through the WCX at the remote end of this link - */ - wrsm_lc_csr_read(softsp, ADDR_WCI_SW_LINK_STATUS + - (i * STRIDE_WCI_SW_LINK_STATUS), &link_status.val); - active_diff = link->remote_gnids_active ^ - link_status.bit.farend_ustat_1; - - DPRINTF(LC_POLL, (CE_CONT, "check_wcx_links: ustat1 %d", - link_status.bit.farend_ustat_1)); - - if (active_diff) { - - DPRINTF(LC_DEBUG, (CE_CONT, "check_wcx_links: " - "changed reachable 0x%x old 0x%x", active_diff, - link->remote_gnids_active)); - - for (gnid = 0; gnid < WRSM_MAX_WNODES; ++gnid) { - uint16_t mask = 1<<gnid; - wnodeid_t remote_wnode; - - if (gnid == softsp->local_gnid) - continue; - - if (!(active_diff & mask)) - continue; - - remote_wnode = softsp->gnid_to_wnode[gnid]; - /* - * Make sure that the indicated gnid is - * actually in the current config. - */ - if (remote_wnode >= WRSM_MAX_WNODES) { - DPRINTF(LC_DEBUG, (CE_CONT, - "check_wcx_links: bad active " - "gnid from switch %d", gnid)); - continue; - } - - /* new gnid reachable */ - if (link_status.bit.farend_ustat_1 & mask) { - wrsm_mh_link_is_up(softsp->nc, i, - remote_wnode); - link->remote_gnids_active |= mask; - continue; - } - - /* previously reachable gnid now gone */ - if (link->remote_gnids_active & mask) { - wrsm_mh_link_is_down(softsp->nc, i, - remote_wnode); - link->remote_gnids_active &= ~mask; - continue; - } - } - } - } -} - -/* - * Checks and handles ECC errors noted by the driver - * - * correctable errors are noted and if possible corrected - * uncorrectable errors cause a trap - * - */ -void -wrsm_lc_ecc_check(wrsm_softstate_t *softsp) -{ - - wci_dco_ce_count_u wci_dco_ce_count; - wci_dc_esr_u wci_dc_esr, wci_dc_esr_clear; - wci_dco_state_u wci_dco_state; - - wci_ra_esr_1_u wci_ra_esr_1, wci_ra_esr_1_clear; - wci_ca_esr_0_u wci_ca_esr_0, wci_ca_esr_0_clear; - - wci_ra_ecc_address_u wci_ra_ecc_addr; - wci_ca_ecc_address_u wci_ca_ecc_addr; - - struct async_flt ecc; - - wci_dco_ce_count.val = *softsp->wci_dco_ce_cnt_vaddr; - wci_dc_esr.val = *softsp->wci_dc_esr_vaddr; - wci_dco_state.val = (uint64_t)*softsp->wci_dco_state_vaddr; - - wci_ra_esr_1.val = *softsp->wci_ra_esr_1_vaddr; - wci_ca_esr_0.val = *softsp->wci_ca_esr_0_vaddr; - - wci_ra_esr_1_clear.val = 0; - wci_ca_esr_0_clear.val = 0; - wci_dc_esr_clear.val = 0; - - wci_ra_ecc_addr.val = *softsp->wci_ra_ecc_addr_vaddr; - wci_ca_ecc_addr.val = *softsp->wci_ca_ecc_addr_vaddr; - - /* - * Request Agent Mtag UE - * - * need to check that there is an uncorrectable error, - * and the address logged is not data [mtag], - * and the address logged is for ue [not ce] - */ - if (wci_ra_esr_1.bit.acc_uncorrectable_mtag_error && - !wci_ra_ecc_addr.bit.data && wci_ra_ecc_addr.bit.ue) { - - DPRINTF(LC_ECC, (CE_NOTE, "wrsm %d: RA Mtag UE error caught", - softsp->instance)); - - if (((wci_dco_state.bit.mtag_ecc_error_aid & - REQ_CLUSTER_MASK) == REQUEST_AGENT_MASK) && - wci_dco_state.bit.mtag_ecc_ue) { - ecc.flt_synd = WCI_MTAG_SYNDROME(wci_dco_state); - } else { - ecc.flt_synd = NO_SYNDROME; - } - - /* - * wci_ra_ecc_addr_tmp.bit.addr <42:4> is over - * bit 31 boundary (32/64 bit). - */ - ecc.flt_addr = wci_ra_ecc_addr.bit.addr << 4; - ecc.flt_stat = RA_ECC_MTAG_UE; - wrsm_handle_ue_error(softsp, &ecc, REQUEST_AGENT); - /* - * clear wci_ra_esr_1 acc_uncorrectable_mtag_error bit - * The bit type is RW1TX, i.e.toggle, thus it needs to be - * set 1 to be cleared. - * - */ - wci_ra_esr_1_clear.bit.acc_uncorrectable_mtag_error = 1; - } - - /* Request Agent Data UE */ - if (wci_ra_esr_1.bit.acc_uncorrectable_data_error && - wci_ra_ecc_addr.bit.data && wci_ra_ecc_addr.bit.ue) { - - DPRINTF(LC_ECC, (CE_NOTE, "wrsm %d: RA Data UE error caught", - softsp->instance)); - - if (((wci_dco_state.bit.data_ecc_error_aid & - REQ_CLUSTER_MASK) == REQUEST_AGENT_MASK) && - wci_dco_state.bit.data_ecc_ue) { - ecc.flt_synd = WCI_DATA_SYNDROME(wci_dco_state); - } else { - ecc.flt_synd = NO_SYNDROME; - } - /* - * Address bits [42:4] of the transaction that caused the - * first UE error. - */ - ecc.flt_addr = wci_ra_ecc_addr.bit.addr << 4; - ecc.flt_stat = RA_ECC_DATA_UE; - wrsm_handle_ue_error(softsp, &ecc, REQUEST_AGENT); - /* clear wci_ra_esr_1 acc_uncorrectable_data_error bit */ - wci_ra_esr_1_clear.bit.acc_uncorrectable_data_error = 1; - - } - - /* Request Agent Mtag CE */ - if (wci_ra_esr_1.bit.acc_correctable_mtag_error && - !wci_ra_ecc_addr.bit.data && !wci_ra_ecc_addr.bit.ue) { - - DPRINTF(LC_ECC, (CE_NOTE, "wrsm %d: RA Mtag CE error caught", - softsp->instance)); - - if (((wci_dco_state.bit.mtag_ecc_error_aid & - REQ_CLUSTER_MASK) == REQUEST_AGENT_MASK) && - !wci_dco_state.bit.mtag_ecc_ue) { - ecc.flt_synd = WCI_MTAG_SYNDROME(wci_dco_state); - } else { - ecc.flt_synd = NO_SYNDROME; - } - /* - * Address bits [42:4] of the transaction that caused the - * first CE error. - */ - ecc.flt_addr = wci_ra_ecc_addr.bit.addr << 4; - ecc.flt_stat = RA_ECC_MTAG_CE; - wrsm_handle_ce_error(softsp, &ecc, REQUEST_AGENT); - /* - * clear wci_ra_esr_1 acc_correctable_mtag_error bit - * The bit type is RW1TX (toggle), thus needs to be - * set 1 to be cleared. - * - */ - wci_ra_esr_1_clear.bit.acc_correctable_mtag_error = 1; - } - - /* Request Agent Data CE */ - if (wci_ra_esr_1.bit.acc_correctable_data_error && - wci_ra_ecc_addr.bit.data && !wci_ra_ecc_addr.bit.ue) { - - DPRINTF(LC_ECC, (CE_NOTE, "wrsm %d: RA Data CE error caught", - softsp->instance)); - - if (((wci_dco_state.bit.data_ecc_error_aid & - REQ_CLUSTER_MASK) == REQUEST_AGENT_MASK) && - !wci_dco_state.bit.data_ecc_ue) { - ecc.flt_synd = WCI_DATA_SYNDROME(wci_dco_state); - } else { - ecc.flt_synd = NO_SYNDROME; - } - - /* - * Address bits [42:4] of the transaction that caused the - * first CE error. - */ - ecc.flt_addr = wci_ra_ecc_addr.bit.addr << 4; - ecc.flt_stat = RA_ECC_DATA_CE; - wrsm_handle_ce_error(softsp, &ecc, REQUEST_AGENT); - /* clear wci_ra_esr_1 acc_correctable_data_error bit */ - wci_ra_esr_1_clear.bit.acc_correctable_data_error = 1; - } - - /* Cluster Agent Mtag UE */ - if (wci_ca_esr_0.bit.acc_uncorrectable_mtag_error && - wci_ca_ecc_addr.bit.ue && !wci_ca_ecc_addr.bit.data) { - - DPRINTF(LC_ECC, (CE_NOTE, "wssm %d: CA Mtag UE error caught", - softsp->instance)); - - if (((wci_dco_state.bit.mtag_ecc_error_aid & - REQ_CLUSTER_MASK) == CLUSTER_AGENT_MASK) && - wci_dco_state.bit.mtag_ecc_ue) { - ecc.flt_synd = WCI_MTAG_SYNDROME(wci_dco_state); - } else { - ecc.flt_synd = NO_SYNDROME; - } - - /* - * Address bits [36:0] of the transaction that caused the - * first CE error. - */ - ecc.flt_addr = wci_ca_ecc_addr.bit.addr << 6; - ecc.flt_stat = CA_ECC_MTAG_UE; - /* mark if it was passthru request */ - if (!wci_ca_ecc_addr.bit.passthru) - ecc.flt_stat |= CA_ECC_NOTPASS; - wrsm_handle_ue_error(softsp, &ecc, CLUSTER_AGENT); - /* clear wci_ca_esr_0 acc_uncorrectable_mtag_error bit */ - wci_ca_esr_0_clear.bit.acc_uncorrectable_mtag_error = 1; - } - - /* Cluster Agent Data UE */ - if (wci_ca_esr_0.bit.acc_uncorrectable_data_error && - wci_ca_ecc_addr.bit.ue && wci_ca_ecc_addr.bit.data) { - - DPRINTF(LC_ECC, (CE_NOTE, "wrsm %d: CA Data UE error caught", - softsp->instance)); - - if (((wci_dco_state.bit.data_ecc_error_aid & - REQ_CLUSTER_MASK) == CLUSTER_AGENT_MASK) && - wci_dco_state.bit.data_ecc_ue) { - ecc.flt_synd = WCI_DATA_SYNDROME(wci_dco_state); - } else { - ecc.flt_synd = NO_SYNDROME; - } - - /* - * Address bits [36:0] of the transaction that caused the - * first CE error. - */ - ecc.flt_addr = wci_ca_ecc_addr.bit.addr << 6; - ecc.flt_stat = CA_ECC_DATA_UE; - /* mark if it was passthru request */ - if (!wci_ca_ecc_addr.bit.passthru) - ecc.flt_stat |= CA_ECC_NOTPASS; - wrsm_handle_ue_error(softsp, &ecc, CLUSTER_AGENT); - /* clear wci_ca_esr_0 acc_uncorrectable_data_error bit */ - wci_ca_esr_0_clear.bit.acc_uncorrectable_data_error = 1; - } - - /* Cluster Agent Mtag CE */ - if (wci_ca_esr_0.bit.acc_correctable_mtag_error && - !wci_ca_ecc_addr.bit.data && !wci_ca_ecc_addr.bit.ue) { - - DPRINTF(LC_ECC, (CE_NOTE, "wrsm %d: CA Mtag CE error caught", - softsp->instance)); - - if (((wci_dco_state.bit.mtag_ecc_error_aid & - REQ_CLUSTER_MASK) == CLUSTER_AGENT_MASK) && - !wci_dco_state.bit.mtag_ecc_ue) { - ecc.flt_synd = WCI_MTAG_SYNDROME(wci_dco_state); - } else { - ecc.flt_synd = NO_SYNDROME; - } - /* - * Address bits [36:0] of the transaction that caused the - * first CE error. - */ - ecc.flt_addr = wci_ca_ecc_addr.bit.addr << 6; - ecc.flt_stat = CA_ECC_MTAG_CE; - /* mark if it was passthru request */ - if (!wci_ca_ecc_addr.bit.passthru) - ecc.flt_stat |= CA_ECC_NOTPASS; - wrsm_handle_ce_error(softsp, &ecc, CLUSTER_AGENT); - /* clear wci_ca_esr_0 acc_correctable_mtag_error bit */ - wci_ca_esr_0_clear.bit.acc_correctable_mtag_error = 1; - - } - - /* Cluster Agent Data CE */ - if (wci_ca_esr_0.bit.acc_correctable_data_error && - wci_ca_ecc_addr.bit.data && !wci_ca_ecc_addr.bit.ue) { - - DPRINTF(LC_ECC, (CE_NOTE, "wrsm %d: CA Data CE error caught", - softsp->instance)); - - if (((wci_dco_state.bit.data_ecc_error_aid & - REQ_CLUSTER_MASK) == CLUSTER_AGENT_MASK) && - !wci_dco_state.bit.data_ecc_ue) { - ecc.flt_synd = WCI_DATA_SYNDROME(wci_dco_state); - } else { - ecc.flt_synd = NO_SYNDROME; - } - - /* - * Address bits [36:0] of the transaction that caused the - * first CE error. - */ - ecc.flt_addr = wci_ca_ecc_addr.bit.addr << 6; - ecc.flt_stat = CA_ECC_DATA_CE; - /* mark if it was passthru request */ - if (!wci_ca_ecc_addr.bit.passthru) - ecc.flt_stat |= CA_ECC_NOTPASS; - wrsm_handle_ce_error(softsp, &ecc, CLUSTER_AGENT); - /* clear wci_ca_esr_0 acc_correctable_data_error bit */ - wci_ca_esr_0_clear.bit.acc_correctable_data_error = 1; - } - - if (wci_dco_ce_count.bit.ce_count != ECC_MAX_CNT) { - DPRINTF(LC_ECC, (CE_NOTE, "wrsm %d: " - "ECC error(s) caught and handled " - "number of CE errors recorded: %d", softsp->instance, - (ECC_MAX_CNT - wci_dco_ce_count.bit.ce_count))); - - /* reset the W1X esr registers */ - *softsp->wci_ra_esr_1_vaddr = wci_ra_esr_1_clear.val; - *softsp->wci_ca_esr_0_vaddr = wci_ca_esr_0_clear.val; - - /* wci_dco_ce_count counts down from ECC_MAX_CNT */ - wci_dco_ce_count.bit.ce_count = ECC_MAX_CNT; - *softsp->wci_dco_ce_cnt_vaddr = wci_dco_ce_count.val; - - /* !! bit type is RW1TX toggle */ - wci_dc_esr_clear.bit.acc_dco_ce = wci_dc_esr.bit.acc_dco_ce; - wci_dc_esr_clear.bit.dco_ce = wci_dc_esr.bit.dco_ce; - *softsp->wci_dc_esr_vaddr = wci_dc_esr_clear.val; - - /* clear syndrome */ - *softsp->wci_dco_state_vaddr = 0; - - /* reset ca,ra address regs */ - *softsp->wci_ra_ecc_addr_vaddr = 0; - *softsp->wci_ca_ecc_addr_vaddr = 0; - - DPRINTF(LC_ECC, (CE_NOTE, "wrsm_check_ecc reg CLEARED:" - "wci_dco.ce.cnt = %lld," - "wci_dc_esr.bit.acc_dco_ce = %lld," - "wci_dc_esr.bit.dco_ce = %lld,\n" - "*softsp->wci_dco_state_vaddr = 0x%llx,\n" - "*softsp->wci_ra_ecc_addr_vaddr = 0x%llx," - "*softsp->wci_ca_ecc_addr_vaddr = 0x%llx\n", - wci_dco_ce_count.bit.ce_count, - wci_dc_esr.bit.acc_dco_ce, - wci_dc_esr.bit.dco_ce, - *softsp->wci_dco_state_vaddr, - *softsp->wci_ra_ecc_addr_vaddr, - *softsp->wci_ca_ecc_addr_vaddr)); - } -} - -/* - * WRSM Correctable ecc error trap handler - * - */ -/* ARGSUSED */ -static void -wrsm_handle_ce_error(struct wrsm_soft_state *softsp, - struct async_flt *ecc, int agent_type) -{ - DPRINTF(LC_ECC, (CE_NOTE, "Enter wrsm_handle_ce_error")); - - ecc->flt_id = gethrtime(); - ecc->flt_pc = 0; - ecc->flt_func = wci_log_ce_error; - ecc->flt_inst = softsp->instance; - ecc->flt_status = ECC_WCI; - ecc->flt_class = CPU_FAULT; - ecc->flt_prot = AFLT_PROT_NONE; - ecc->flt_priv = 0; - ecc->flt_panic = 0; - ecc->flt_tl = 0; - ecc->flt_core = 0; - - ecc->flt_bus_id = softsp->portid; - - DPRINTF(LC_ECC, (CE_NOTE, "ecc->flt_inst = %d agent_type = %d," - " syndrome = %x", ecc->flt_inst, agent_type, ecc->flt_synd)); - - /* - * We can only scrub if the error comes from CA and it was not - * a passthru transaction. This is already marked in flt_stat - */ - if (ecc->flt_stat & CA_ECC_NOTPASS) { - ecc->flt_stat &= ~CA_ECC_NOTPASS; /* remove the mark */ - ecc->flt_in_memory = 1; - DPRINTF(LC_ECC, (CE_NOTE, "detected ce error in CA," - "ecc->flt_in_memory = 1")); - } else { - /* RA or CA in passthru */ - ecc->flt_in_memory = 0; - DPRINTF(LC_ECC, (CE_NOTE, "RA or CA in passthru," - "ecc->flt_in_memory = 0")); - } - ce_scrub(ecc); - errorq_dispatch(ce_queue, ecc, sizeof (*ecc), ERRORQ_ASYNC); -} - -/* - * WRSM Uncorrectable ecc error trap handler - */ -/* ARGSUSED */ -static void -wrsm_handle_ue_error(struct wrsm_soft_state *softsp, - struct async_flt *ecc, int agent_type) -{ -#ifdef DEBUG - int level = CE_WARN; -#else - int level = CE_PANIC; -#endif - - cmn_err(level, "wci %d uncorrectable ECC error " - "agent_type %d, fault address 0x%08x.%08x", - softsp->portid, agent_type, (uint32_t)(ecc->flt_addr>>32), - (uint32_t)ecc->flt_addr); -} - -/* - * Examines the state of wci SRAM in wrsm (CMMU) - */ -static void -wrsm_lc_sram_ecc_check(wrsm_softstate_t *softsp, boolean_t do_shortterm) -{ - wci_cci_esr_u wci_cci_esr; - wci_sram_ce_count_u wci_sram_ce_count; - wci_sram_ecc_address_u wci_sram_ecc_address; - - wci_ca_esr_1_u wci_ca_esr_1; - wci_csra_esr_u wci_csra_esr; - wci_csra_status_u wci_csra_status; - - wrsm_seprom_data_t seprom; - - uint32_t num_ce_errors; - - wci_cci_esr.val = *softsp->wci_cci_esr_vaddr; - - if (!wci_cci_esr.val) { - /* no errors found */ - return; - } - - DPRINTF(LC_ECC, (CE_NOTE, "SRAM ECC ERROR CAUGHT")); - - /* map relevant registers */ - wrsm_lc_csr_read(softsp, ADDR_WCI_SRAM_CE_COUNT, - &wci_sram_ce_count.val); - wrsm_lc_csr_read(softsp, ADDR_WCI_SRAM_ECC_ADDRESS, - &wci_sram_ecc_address.val); - - seprom.type = WRSM_WIB_SEPROM_TYPE_ECCERR; - seprom.data.eccerr.ce = wci_sram_ecc_address.bit.ce; - seprom.data.eccerr.address = wci_sram_ecc_address.bit.address; - seprom.data.eccerr.syndrome = wci_sram_ecc_address.bit.syndrome; - - cmn_err(CE_WARN, "wci %d: SRAM ECC error: ce=%u, addr=0x%X, " - "syndrome=0x%X", - softsp->portid, seprom.data.eccerr.ce, - seprom.data.eccerr.address, seprom.data.eccerr.syndrome); - - (void) wrsmplat_set_seprom(softsp->portid, (uchar_t *)&seprom, - sizeof (seprom)); - - if (wci_cci_esr.bit.acc_sram_ue) { /* uncorrectable SRAM ECC error */ - /* - * Note that the CMMU remains disabled after we log the error - */ - - wrsm_lc_csr_read(softsp, ADDR_WCI_CA_ESR_1, &wci_ca_esr_1.val); - wrsm_lc_csr_read(softsp, ADDR_WCI_CSRA_ESR, &wci_csra_esr.val); - wrsm_lc_csr_read(softsp, ADDR_WCI_CSRA_STATUS, - &wci_csra_status.val); - - /* - * The ecc is calculated from 34 bits of data + - * 2 parity bits taken from the address. - * We are here knowing that at least one of the address - * bits was corrupted - */ - if (wci_cci_esr.bit.acc_sram_ae) { - cmn_err(CE_WARN, "wci %d uncorrectable sram error: " - "address", softsp->portid); - } - - if (wci_ca_esr_1.bit.acc_cmmu_ecc_error) { - cmn_err(CE_WARN, "wci %d uncorrectable sram error: " - " CAG", softsp->portid); - wci_ca_esr_1.val = 0; - wci_ca_esr_1.bit.acc_cmmu_ecc_error = 1; - wrsm_lc_csr_write(softsp, ADDR_WCI_CA_ESR_1, - wci_ca_esr_1.val); - } - - if (wci_csra_esr.bit.acc_sram_error) { - cmn_err(CE_WARN, "wci %d uncorrectable sram error: " - "CSRA, wci_csra_esr_status 0x%08x.%08x", - softsp->portid, - (uint32_t)(wci_csra_status.val>>32), - (uint32_t)wci_csra_status.val); - wci_csra_esr.val = 0; - wci_csra_esr.bit.acc_sram_error = 1; - wrsm_lc_csr_write(softsp, ADDR_WCI_CSRA_ESR, - wci_csra_esr.val); - wrsm_lc_csr_write(softsp, ADDR_WCI_CSRA_STATUS, 0); - } - /* note it for kstats */ - softsp->uc_sram_ecc_error = 1; - } - - if (wci_cci_esr.bit.acc_sram_ce) { /* correctable SRAM ECC error */ - - num_ce_errors = 0xFF - wci_sram_ce_count.val; - - DPRINTF(LC_ECC, (CE_NOTE, "wrsm %d: wci %d SRAM " - "correctable error, " - "with%s address, total number of CE errors: %d", - softsp->instance, softsp->portid, - (wci_sram_ecc_address.bit.ce?"":"out"), - num_ce_errors)); - - /* note count for kstats */ - softsp->num_sram_ecc_errors += num_ce_errors; - softsp->sram_ecc_errsum += num_ce_errors; - if (do_shortterm) { - softsp->last_sram_ecc_errors = - softsp->sram_ecc_errsum; - softsp->max_sram_ecc_errors = - MAX(softsp->max_sram_ecc_errors, - softsp->sram_ecc_errsum); - softsp->avg_sram_ecc_errors = - RUNNING_AVG(softsp->sram_ecc_errsum, - softsp->avg_sram_ecc_errors); - softsp->sram_ecc_errsum = 0; - } - } - - /* clean up */ - wrsm_lc_csr_write(softsp, ADDR_WCI_SRAM_ECC_ADDRESS, 0x0); - /* reset the count */ - wrsm_lc_csr_write(softsp, ADDR_WCI_SRAM_CE_COUNT, ECC_MAX_CNT); - /* reset the wci_cci_esr (write 1 to toggle) */ - *softsp->wci_cci_esr_vaddr = wci_cci_esr.val; -} - -/* Handles ioctls to read/modify WCI registers */ -/* ARGSUSED */ -int -wrsm_lc_register_ioctl(wrsm_softstate_t *softsp, int cmd, intptr_t arg, - int flag, cred_t *cred_p, int *rval_p) -{ - wrsm_cmmu_t cmmu_tmp; - int retval = 0; - int num_entries; /* number of cmmu entries */ - uint64_t args[4]; - - /* Only allow privileged users to do this */ - if ((retval = secpolicy_sys_config(cred_p, B_FALSE)) != 0) - return (retval); - - if (ddi_copyin((void *)arg, args, 4 * sizeof (uint64_t), flag) != 0) - return (EFAULT); - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_register_ioctl\n")); - - switch (cmd) { - - case WRSM_LC_READCSR: - if (((args[0] & REGMASK) != 0) || (args[0] > - ADDR_LAST_CSR)) { - retval = EINVAL; - break; - } - wrsm_lc_csr_read(softsp, args[0], &args[1]); - if (ddi_copyout(args, (void*)arg, 2 * sizeof (uint64_t), - flag) != 0) - retval = EFAULT; - break; - - case WRSM_LC_WRITECSR: - if (((args[0] & REGMASK) != 0) || (args[0] > - ADDR_LAST_CSR)) { - retval = EINVAL; - break; - } - wrsm_lc_csr_write(softsp, args[0], args[1]); - break; - - case WRSM_LC_READCESR: - if (args[0] > ENTRIES_WCI_CLUSTER_ERROR_STATUS_ARRAY) { - retval = EINVAL; - break; - } - wrsm_lc_cesr_read(softsp, (safari_port_t)args[0], &args[1]); - if (ddi_copyout(args, (void*)arg, 2 * sizeof (uint64_t), - flag) != 0) - retval = EFAULT; - break; - - case WRSM_LC_WRITECESR: - if (args[0] > ENTRIES_WCI_CLUSTER_ERROR_STATUS_ARRAY) { - retval = EINVAL; - break; - } - wrsm_lc_cesr_write(softsp, (safari_port_t)args[0], args[1]); - break; - - case WRSM_LC_UPDATECMMU: - num_entries = wrsm_lc_num_cmmu_entries_get(softsp); - if (args[2] > num_entries) { - retval = EINVAL; - break; - } - cmmu_tmp.entry_0.val = args[0]; - cmmu_tmp.entry_1.val = args[1]; - - wrsm_lc_cmmu_update(softsp, &cmmu_tmp, args[2], - (wrsm_cmmu_flags_t)args[3]); - break; - - case WRSM_LC_READCMMU: - num_entries = wrsm_lc_num_cmmu_entries_get(softsp); - if (args[2] > num_entries) { - retval = EINVAL; - break; - } - wrsm_lc_cmmu_read(softsp, &cmmu_tmp, args[2]); - args[0] = cmmu_tmp.entry_0.val; - args[1] = cmmu_tmp.entry_1.val; - if (ddi_copyout(args, (void*)arg, 2 * sizeof (uint64_t), - flag) != 0) - retval = EFAULT; - break; - - default: - return (EINVAL); - } - - return (retval); -} - - - - -/* - * cancel all timeouts as part of DDI_SUSPEND - */ -void -wrsm_lc_suspend(wrsm_softstate_t *softsp) -{ - timeout_id_t restart_tmoid = 0; - timeout_id_t err_tmoid = 0; - - ASSERT(softsp); - - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_suspend wci %d\n", - softsp->portid)); - - mutex_enter(&softsp->lc_mutex); - - if (softsp->suspended) { - mutex_exit(&softsp->lc_mutex); - return; - } - - softsp->suspended = B_TRUE; - - if (softsp->restart_timeout_id) { - restart_tmoid = softsp->restart_timeout_id; - softsp->restart_timeout_id = 0; - softsp->need_restart_timeout = B_TRUE; - } - - - if (softsp->err_timeout_id) { - err_tmoid = softsp->err_timeout_id; - softsp->err_timeout_id = 0; - softsp->need_err_timeout = B_TRUE; - } - - mutex_exit(&softsp->lc_mutex); - - if (restart_tmoid) - (void) untimeout(restart_tmoid); - - if (err_tmoid) - (void) untimeout(err_tmoid); - - wrsmplat_suspend(softsp->portid); -} - - - -/* - * restart any timeouts cancelled for a DDI_SUSPEND - */ -void -wrsm_lc_resume(wrsm_softstate_t *softsp) -{ - ASSERT(softsp); - - DPRINTF(LC_DEBUG, (CE_CONT, "wrsm_lc_resume wci %d\n", - softsp->portid)); - - mutex_enter(&softsp->lc_mutex); - - if (!softsp->suspended) { - mutex_exit(&softsp->lc_mutex); - return; - } - - softsp->suspended = B_FALSE; - wrsmplat_resume(softsp->portid); - - if (softsp->need_restart_timeout) { - softsp->need_restart_timeout = B_FALSE; - softsp->restart_timeout_id = timeout((void (*)(void *)) - wrsm_lc_restart_downlinks, softsp, wrsm_restart_hz); - } - if (softsp->need_err_timeout) { - softsp->need_err_timeout = B_FALSE; - softsp->err_timeout_id = timeout((void (*)(void *)) - wrsm_lc_poll_timeout, softsp, wrsm_poll_hz); - } - - mutex_exit(&softsp->lc_mutex); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_memseg.c b/usr/src/uts/sun4u/io/wrsm/wrsm_memseg.c deleted file mode 100644 index 7e408dbd3a..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_memseg.c +++ /dev/null @@ -1,326 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file manages generic RSMPI memory segment management, setup and - * teardown. - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/systm.h> -#include <sys/vmsystm.h> -#include <sys/errno.h> -#include <sys/kmem.h> -#include <vm/seg_kmem.h> -#include <vm/page.h> -#include <sys/sunddi.h> -#include <sys/ddimapreq.h> -#include <sys/taskq.h> - -#include <sys/rsm/rsmpi.h> - -#include <sys/wrsm_common.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_session.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_memseg_impl.h> -#include <sys/wrsm_intr.h> - - -#ifdef DEBUG -#define DBG_MEMSEG 0x001 -#define DBG_MEMSEG_EXTRA 0x010 - -static uint_t wrsm_memseg_debug = DBG_MEMSEG; - -#define DPRINTF(a, b) { if (wrsm_memseg_debug & a) wrsmdprintf b; } - -#else /* DEBUG */ -#define DPRINTF(a, b) { } -#endif /* DEBUG */ - - -/* Non-pageable kernel memory is allocated from the wrsm_arena. */ -static vmem_t *wrsm_arena; - -static boolean_t -memseg_sess_teardown(wrsm_node_t *node) -{ - boolean_t teardown_complete = B_TRUE; - - DPRINTF(DBG_MEMSEG, (CE_CONT, "ctlr %d: memseg_sess_teardown node %d\n", - node->network->rsm_ctlr_id, node->config->cnodeid)); - /* - * it is presumed that at this point the node was removed from the - * cluster_members_bits registers in all wcis - */ - - mutex_enter(&node->memseg->lock); - - /* - * clean up exports to the remote node - */ - if (!exportseg_sess_teardown(node)) { - teardown_complete = B_FALSE; - } - - /* - * clean up iseginfos imported from remote node - */ - if (!iseginfo_sess_teardown(node)) { - teardown_complete = B_FALSE; - } - - mutex_exit(&node->memseg->lock); - - return (teardown_complete); -} - - - -static boolean_t -memseg_sess_notify(wrsm_network_t *network, cnodeid_t cnodeid, - wrsm_sess_state state) -{ - boolean_t teardown_complete = B_TRUE; - - switch (state) { - /* - * nothing to do on SESSION_UP - */ - case SESSION_DOWN: - teardown_complete = memseg_sess_teardown( - network->nodes[cnodeid]); - break; - } - - return (teardown_complete); -} - -/* - * - * driver initialization functions - * - */ - -void -wrsm_memseg_node_init(wrsm_node_t *node) -{ - struct wrsm_node_memseg *memseg; - - DPRINTF(DBG_MEMSEG_EXTRA, (CE_CONT, "wrsm_memseg_node_init(cnode %d)\n", - node->config->cnodeid)); - - memseg = (struct wrsm_node_memseg *)kmem_zalloc( - sizeof (struct wrsm_node_memseg), KM_SLEEP); - mutex_init(&memseg->lock, NULL, MUTEX_DRIVER, NULL); - memseg->removing_session = B_FALSE; - node->memseg = memseg; -} - -void -wrsm_memseg_node_fini(wrsm_node_t *node) -{ -#ifdef DEBUG - int i; -#endif - DPRINTF(DBG_MEMSEG_EXTRA, (CE_CONT, "wrsm_memseg_node_fini(cnode %d)\n", - node->config->cnodeid)); - -#ifdef DEBUG - /* verify that the segment is really not in use */ - ASSERT(node->memseg->connected == NULL); - ASSERT(node->memseg->wait_for_unmaps == 0); - - mutex_enter(&node->memseg->lock); - for (i = 0; i < WRSM_SEGID_HASH_SIZE; i++) { - ASSERT(node->memseg->iseginfo_hash[i] == NULL); - } - mutex_exit(&node->memseg->lock); -#endif - mutex_destroy(&node->memseg->lock); - kmem_free(node->memseg, sizeof (wrsm_node_memseg_t)); - node->memseg = NULL; -} - -void -wrsm_memseg_network_init(wrsm_network_t *network) -{ - DPRINTF(DBG_MEMSEG_EXTRA, (CE_CONT, "wrsm_memseg_init(ctlr %d)\n", - network->rsm_ctlr_id)); - - /* this initiates all variables to 0 */ - network->memseg = kmem_zalloc(sizeof (wrsm_memseg_t), KM_SLEEP); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_CONNECT, - wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr); - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_CONNECT_RESPONSE, - wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SMALLPUTMAP, - wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr); - (void) wrsm_tl_add_handler(network, - WRSM_MSG_SEGMENT_SMALLPUTMAP_RESPONSE, - wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_BARRIERMAP, - wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr); - (void) wrsm_tl_add_handler(network, - WRSM_MSG_SEGMENT_BARRIERMAP_RESPONSE, - wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SEGMAP, - wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr); - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SEGMAP_RESPONSE, - wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_DISCONNECT, - wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_UNPUBLISH, - wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr); - (void) wrsm_tl_add_handler(network, - WRSM_MSG_SEGMENT_UNPUBLISH_RESPONSE, - wrsm_tl_txhandler_sessionid, wrsm_tl_rxhandler_sessionid); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_ACCESS, - wrsm_tl_txhandler_sessionid, wrsm_memseg_msg_hdlr); - - /* - * Register for session teardown calls - */ - wrsm_sess_register(network, memseg_sess_notify); -} - -void -wrsm_memseg_network_fini(wrsm_network_t *network) -{ - DPRINTF(DBG_MEMSEG_EXTRA, (CE_CONT, "wrsm_memseg_fini(ctlr %d)\n", - network->rsm_ctlr_id)); - - - /* - * If there are importsegs or exportsegs left around which a client - * did not destroy prior to doing release controller, destroy them - * now. - */ - wrsm_free_exportsegs(network); - wrsm_free_importsegs(network); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_CONNECT, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_CONNECT_RESPONSE, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SMALLPUTMAP, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - (void) wrsm_tl_add_handler(network, - WRSM_MSG_SEGMENT_SMALLPUTMAP_RESPONSE, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_BARRIERMAP, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - (void) wrsm_tl_add_handler(network, - WRSM_MSG_SEGMENT_BARRIERMAP_RESPONSE, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SEGMAP, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_SEGMAP_RESPONSE, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_DISCONNECT, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_UNPUBLISH, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - (void) wrsm_tl_add_handler(network, - WRSM_MSG_SEGMENT_UNPUBLISH_RESPONSE, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - - (void) wrsm_tl_add_handler(network, WRSM_MSG_SEGMENT_ACCESS, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - - wrsm_sess_unregister(network, memseg_sess_notify); - - kmem_free(network->memseg, sizeof (wrsm_memseg_t)); -} - - -void -wrsm_memseg_init(void) -{ - mutex_init(&all_exportsegs_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&all_importsegs_lock, NULL, MUTEX_DRIVER, NULL); - wrsm_arena = vmem_create("wrsm_arena", NULL, 0, - PAGESIZE, vmem_alloc, vmem_free, - static_arena, PAGESIZE, VM_SLEEP); -} - - -void -wrsm_memseg_fini(void) -{ - vmem_destroy(wrsm_arena); - mutex_destroy(&all_exportsegs_lock); - mutex_destroy(&all_importsegs_lock); -} - -void -wrsm_memseg_stat(wrsm_network_t *network, wrsm_memseg_stat_data_t *data) -{ - mutex_enter(&network->lock); - data->export_count = network->memseg->export_count; - data->export_published = network->memseg->export_published; - data->export_connected = network->memseg->export_connected; - data->bytes_bound = network->memseg->bytes_bound; - data->import_count = network->memseg->import_count; - mutex_exit(&network->lock); -} - - -/* - * wrsm alloc routine used in place of kmem_{z}alloc() - * as it allocates memory from the non-relocatable heap arena - */ -void * -wrsm_alloc(size_t size, int flags) -{ - return (vmem_alloc(wrsm_arena, size, flags)); -} - -/* - * wrsm free routine used in place of kmem_{z}alloc() - * as it frees memory to the non-relocatable heap arena - */ -void -wrsm_free(void *addr, size_t size) -{ - vmem_free(wrsm_arena, addr, size); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_memseg_export.c b/usr/src/uts/sun4u/io/wrsm/wrsm_memseg_export.c deleted file mode 100644 index c25020d3c8..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_memseg_export.c +++ /dev/null @@ -1,3290 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file implements the RSMPI export side memory segment functions - * for the Wildcat RSM driver. - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/systm.h> -#include <sys/vmsystm.h> -#include <sys/errno.h> -#include <sys/kmem.h> -#include <sys/buf.h> -#include <vm/seg_kmem.h> -#include <vm/page.h> -#include <sys/sunddi.h> -#include <sys/ddi.h> -#include <sys/ddimapreq.h> - -#include <sys/rsm/rsmpi.h> - -#include <sys/wrsm_common.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_session.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_memseg_impl.h> -#include <sys/wrsm_intr.h> - -#ifdef DEBUG -#define DBG_WARN 0x001 -#define DBG_EXPORT 0x002 -#define DBG_EXPORT_EXTRA 0x040 - -static uint_t wrsm_export_memseg_debug = DBG_WARN; - -#define DPRINTF(a, b) { if (wrsm_export_memseg_debug & a) wrsmdprintf b; } - -#else /* DEBUG */ -#define DPRINTF(a, b) { } -#endif /* DEBUG */ - -static int wrsm_hw_protection = 0; - - -/* - * lock hierarchy: - * network->lock - * all_exportsegs_lock - * exportseg->lock - * node->memseg->lock - * - * Note: it is always safe to take all_exportsegs_lock. - * It is also safe to take network->lock: the network must - * unregister (unregister_controller), which it can't do - * until clients all release the network (release_controller). - * If a client accesses these functions after doing a release - * controller, all bets are off. - */ - - -static exportseg_t *all_exportsegs_hash[WRSM_PTR_HASH_SIZE]; - - - -/* - * Find the right starting cmmugrp for offset <off>. <sz> is the size of - * the region starting at <off> that falls within this cmmugrp. <ci> is - * the index of the cmmu entry within the entire cmmugrp's tuples array of - * the entry for this offset. - */ -static void -get_start_cmmugrp(cmmugrp_t **grpp, size_t off, unsigned *ci, size_t *sz) -{ - off_t remainder; - - while ((*grpp)->offset + (*grpp)->len < off) { - (*grpp) = (*grpp)->next; - ASSERT(grpp); - } - ASSERT((*grpp)->offset <= off); - ASSERT((*grpp)->offset + (*grpp)->len > off); - remainder = off - (*grpp)->offset; - ASSERT(remainder < (*grpp)->len); - *sz = (*grpp)->len - remainder; - *ci = remainder / (*grpp)->pgbytes; -} - - -/* - * Get the next cmmugrp. <cc> is the index into the new cmmugrp's tuples - * array. <ci> is the cmmu entry within the tuple. (Both are set to 0.) - */ -static void -get_next_cmmugrp(cmmugrp_t **grpp, unsigned *cc, unsigned *ci, size_t *sz, - wrsm_cmmu_tuple_t **tp) -{ - *grpp = (*grpp)->next; - ASSERT(*grpp); - *sz = (*grpp)->len; - *cc = 0; - *ci = 0; - *tp = &((*grpp)->tuples[(*cc)]); -} - - -/* - * Get the starting tuple and index into this tuple within cmmugrp <grp> - * for this offset. <cc> is the index into the cmmugrp's tuples array. - * <tp> is the tuple. The index into the cmmgrup for this offset is passed - * in through <ci>. <ci> is modified to contain the cmmu entry within the tuple - * for this offset. - */ -static void -get_start_entry(cmmugrp_t *grp, wrsm_cmmu_tuple_t **tp, unsigned *cc, - unsigned *ci) -{ - (*cc) = 0; - *tp = &(grp->tuples[(*cc)]); - while ((*tp)->count <= *ci) { - *ci -= (*tp)->count; - (*cc)++; - ASSERT((*cc) < grp->num_tuples); - (*tp) = &(grp->tuples[(*cc)]); - ASSERT((*tp)); - ASSERT(*ci < (*tp)->count); - } - - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "get_start_entry: tuple_index %d " - "cmmu_index %d\n", *cc, *ci)); -} - - -/* - * Get next entry from this tuple. If no more entries from this tuple, use - * entries from next tuple. <cc> is the index into the tuples array. <tp> - * is the tuple. <ci> is the cmmu entry within the tuple for this offset. - */ -void -get_next_entry(wrsm_cmmu_tuple_t *tuple_list, wrsm_cmmu_tuple_t **tp, - unsigned *cc, unsigned *ci) -{ - (*ci)++; - if ((*ci) == (*tp)->count) { - (*cc)++; - (*tp) = &(tuple_list[(*cc)]); - (*ci) = 0; - } - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "get_next_entry: tuple_index %d " - "cmmu_index %d\n", *cc, *ci)); -} - - -/* - * Get the number of entries in this cmmugrp needed to cover region of size - * <len>, or the maximum number of entries. <sz> is the size in bytes of - * the cmmugrp. <pgbytes> is the number of bytes covered by each entry. - * <num> returns the number of entries. - */ -static void -get_num_entries(size_t *len, unsigned *num, size_t sz, size_t pgbytes) -{ - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "get_num_entries start: len 0x%lx " - "num %d sz 0x%lx pgbytes 0x%lx\n", *len, *num, sz, pgbytes)); - if ((*len) > sz) { - (*num) = sz / pgbytes; - (*len) -= sz; - } else { - ASSERT((*len) % pgbytes == 0); - (*num) = (*len) / pgbytes; - (*len) = 0; - } - ASSERT((*num) >= 1); - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "get_num_entries end: len 0x%lx " - "num %d sz 0x%lx pgbytes 0x%lx\n", *len, *num, sz, pgbytes)); -} - - - - -/* - * Find exportseg structure in network exportseg hash from segment id. - */ -static exportseg_t * -segid_to_exportseg(wrsm_network_t *network, rsm_memseg_id_t segid) -{ - int index; - exportseg_t *exportseg; - - ASSERT(MUTEX_HELD(&network->lock)); - - index = WRSM_SEGID_HASH_FUNC(segid); - ASSERT(index < WRSM_SEGID_HASH_SIZE); - exportseg = network->memseg->exportseg_hash[index]; - while (exportseg) { - if (exportseg->segid == segid) - return (exportseg); - exportseg = exportseg->segid_next; - } - - return (NULL); -} - - - -/* - * Set segid of exportseg, add to network hash table. - */ -static int -exportseg_set_segid(exportseg_t *exportseg, rsm_memseg_id_t segid) -{ - wrsm_network_t *network = exportseg->network; - int index; - boolean_t found = B_FALSE; - exportseg_t *expsg; - - ASSERT(MUTEX_HELD(&exportseg->lock)); - - /* - * release exportseg lock in order to take network lock - */ - index = WRSM_PTR_HASH_FUNC(exportseg); - mutex_exit(&exportseg->lock); - mutex_enter(&network->lock); - mutex_enter(&all_exportsegs_lock); - - expsg = all_exportsegs_hash[index]; - while (expsg) { - if (expsg == exportseg) { - mutex_enter(&exportseg->lock); - found = B_TRUE; - break; - } - expsg = expsg->all_next; - } - mutex_exit(&all_exportsegs_lock); - if (!found) { - mutex_exit(&network->lock); - return (RSMERR_BAD_SEG_HNDL); - } - - if (exportseg->state != memseg_unpublished) { - /* segment is already published */ - mutex_exit(&network->lock); - return (RSMERR_SEG_ALREADY_PUBLISHED); - } - - if (segid_to_exportseg(network, segid)) { - /* segment id already in use */ - mutex_exit(&network->lock); - return (RSMERR_SEGID_IN_USE); - } - - exportseg->segid = segid; - exportseg->state = memseg_published; - network->memseg->export_published++; - - /* - * add to hash - */ - - index = WRSM_SEGID_HASH_FUNC(segid); - ASSERT(index < WRSM_SEGID_HASH_SIZE); - exportseg->segid_next = network->memseg->exportseg_hash[index]; - network->memseg->exportseg_hash[index] = exportseg; - - mutex_exit(&network->lock); - - return (RSM_SUCCESS); -} - - -/* - * Stop using current segment id, and remove exportseg structure from - * network hash. Note: exportseg is prevented from disappearing until - * exportseg->state is unpublished. - */ -static void -exportseg_unset_segid(exportseg_t *exportseg, rsm_memseg_id_t segid) -{ - wrsm_network_t *network = exportseg->network; - exportseg_t **exportsegp; - int index; - - index = WRSM_SEGID_HASH_FUNC(segid); - ASSERT(index < WRSM_SEGID_HASH_SIZE); - - mutex_enter(&network->lock); - - /* - * find and remove exportseg from hash table - */ - exportsegp = &(network->memseg->exportseg_hash[index]); - - while (*exportsegp != NULL && *exportsegp != exportseg) { - exportsegp = &((*exportsegp)->segid_next); - } - - if (*exportsegp == NULL) { - /* someone else already unpublished this segment */ - DPRINTF(DBG_EXPORT, (CE_NOTE, "exportseg %p (segid %d) not " - "in hash table", (void *) exportseg, exportseg->segid)); - mutex_exit(&network->lock); - return; - } - - /* - * Found exportseg; remove from segid hash table. - * If exportseg is in segid hash table, it cannot - * be in unpublished state. - */ - mutex_enter(&exportseg->lock); - *exportsegp = (*exportsegp)->segid_next; - network->memseg->export_published--; - mutex_exit(&network->lock); - - ASSERT(exportseg->state != memseg_unpublished); - exportseg->state = memseg_unpublished; - mutex_exit(&exportseg->lock); -} - - -/* - * Find an exportseg with specified segid in network's exportseg hash and - * lock it. - */ -static exportseg_t * -find_and_lock_exportseg(wrsm_network_t *network, rsm_memseg_id_t segid) -{ - exportseg_t *exportseg = NULL; - mutex_enter(&network->lock); - exportseg = segid_to_exportseg(network, segid); - if (exportseg) - mutex_enter(&exportseg->lock); - mutex_exit(&network->lock); - - return (exportseg); -} - - - - -/* - * Make sure this exportseg is still in all_exportsegs_hash. - */ -static int -lock_exportseg(exportseg_t *exportseg) -{ - exportseg_t *expsg; - uint_t index; - int err = RSMERR_BAD_SEG_HNDL; - - index = WRSM_PTR_HASH_FUNC(exportseg); - ASSERT(index < WRSM_PTR_HASH_SIZE); - - mutex_enter(&all_exportsegs_lock); - expsg = all_exportsegs_hash[index]; - while (expsg) { - if (expsg == exportseg) { - mutex_enter(&exportseg->lock); - err = RSM_SUCCESS; - break; - } - expsg = expsg->all_next; - } - mutex_exit(&all_exportsegs_lock); - - /* - * make sure exportseg is not currently being removed - */ - if ((err == RSM_SUCCESS) && (exportseg->valid == B_FALSE)) { - mutex_exit(&exportseg->lock); - err = RSMERR_BAD_SEG_HNDL; - } - -#ifdef DEBUG - if (err == RSMERR_BAD_SEG_HNDL) { - DPRINTF(DBG_EXPORT, (CE_CONT, "lock_exportseg - " - "invalid memseg 0x%p\n", (void *)exportseg)); - } -#endif - return (err); -} - - - - - -/* - * Free all cmmu entries for this exported segment. - */ -static void -mseg_free_cmmus(exportseg_t *exportseg) -{ - cmmugrp_t *cmmugrp, *ocmmugrp; - wrsm_cmmu_t cmmu; - wrsm_cmmu_index_t index; - unsigned count; - unsigned i, j; - - DPRINTF(DBG_EXPORT, (CE_CONT, "mseg_free_cmmus() exportseg 0x%p\n", - (void *)exportseg)); - - cmmu.entry_0.bit.valid = B_FALSE; - - cmmugrp = exportseg->cmmugrps; - while (cmmugrp != NULL) { - /* - * invalidate and free cmmu entries - */ - for (i = 0; i < cmmugrp->num_tuples; i++) { - index = cmmugrp->tuples[i].index; - count = cmmugrp->tuples[i].count; - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, - "mseg_free_cmmus() freeing tuples %d - %d\n", - index, index + count - 1)); - for (j = 0; j < count; j++) { - wrsm_cmmu_update(exportseg->network, &cmmu, - index, CMMU_UPDATE_VALID); - index++; - } - } - - wrsm_cmmu_free(exportseg->network, cmmugrp->num_tuples, - cmmugrp->tuples); - - /* - * free cmmugrp structures - */ - ocmmugrp = cmmugrp; - cmmugrp = cmmugrp->next; - kmem_free(ocmmugrp, sizeof (cmmugrp_t)); - } - - exportseg->cmmugrps = NULL; -} - - - - -/* - * In the cmmu entries in the range specifed by <seg_offset, len>, set or - * unset the valid field and set or unset the writable field as specified - * by <flag>. - */ -static void -update_cmmu_fields(exportseg_t *exportseg, size_t seg_offset, size_t len, - memseg_cmmufield_t flag) -{ - wrsm_network_t *network = exportseg->network; - cmmugrp_t *cmmugrp = exportseg->cmmugrps; - size_t cmmugrp_size; - unsigned cmmutuples; - unsigned cmmu_index; - unsigned num_entries; - unsigned pfn_index; - wrsm_cmmu_tuple_t *tuple; - wrsm_cmmu_t cmmu; - wrsm_cmmu_flags_t cmmu_flag; - - DPRINTF(DBG_EXPORT, (CE_CONT, "update_cmmu_fields() - " - "seg_offset 0x%lx len 0x%lx flag %s\n", seg_offset, len, - CMMU_UPDATE_STR(flag))); - - ASSERT(MUTEX_HELD(&exportseg->lock)); - - if (exportseg->size == 0) { - /* nothing to do */ - return; - } - - /* - * Update the valid field; also update the writable field if this - * was requested. - */ - cmmu_flag = CMMU_UPDATE_VALID; - if (flag == memseg_set_writeable) { - cmmu.entry_0.bit.writable = 1; - cmmu_flag |= CMMU_UPDATE_WRITABLE; - } else if (flag == memseg_unset_writeable) { - cmmu.entry_0.bit.writable = 0; - cmmu_flag |= CMMU_UPDATE_WRITABLE; - } else if (flag == memseg_unset_valid) { - cmmu_flag |= CMMU_UPDATE_FLUSH; - } - - pfn_index = seg_offset >> MMU_PAGESHIFT; - - /* - * Find the right cmmugrp structure, tuple, and cmmu entry within - * the tuple (as indicated by cmmu_index) for <seg_offset>. - */ - get_start_cmmugrp(&cmmugrp, seg_offset, &cmmu_index, &cmmugrp_size); - get_start_entry(cmmugrp, &tuple, &cmmutuples, &cmmu_index); - - while (len > 0) { - /* - * Calculate the number of entries from this cmmugrp that - * should be reset, and subtract covered bytes from len. - */ - get_num_entries(&len, &num_entries, cmmugrp_size, - cmmugrp->pgbytes); - - while (num_entries) { - - /* - * If writable field is being updated, the valid - * field also set to true if there is memory - * backing the cmmu entry. - */ - if (flag == memseg_unset_valid || - exportseg->pfn_list[pfn_index] == PFN_INVALID) { - cmmu.entry_0.bit.valid = 0; - } else { - cmmu.entry_0.bit.valid = 1; - } - wrsm_cmmu_update(network, &cmmu, - tuple->index + cmmu_index, cmmu_flag); - DPRINTF(DBG_EXPORT, (CE_CONT, "updated " - "index %d\n", tuple->index + cmmu_index)); - - /* get next CMMU entry in this cmmugrp */ - get_next_entry(cmmugrp->tuples, &tuple, &cmmutuples, - &cmmu_index); - num_entries--; - pfn_index += cmmugrp->pgbytes >> MMU_PAGESHIFT; - } - - if (len == 0) - break; - - get_next_cmmugrp(&cmmugrp, &cmmutuples, &cmmu_index, - &cmmugrp_size, &tuple); - } -} - - - -/* - * The lpa fields in cmmu entries in the range specified by <seg_offset, - * len> are no longer valid. Set the valid field of all cmmu entries in - * this range to invalid, and set the affected entries in the pfn_list to - * PFN_INVALID. - */ -static int -clear_lpa_fields(exportseg_t *exportseg, size_t seg_offset, size_t len, - boolean_t mapping_required) -{ - wrsm_network_t *network = exportseg->network; - cmmugrp_t *cmmugrp = exportseg->cmmugrps; - size_t cmmugrp_size; - unsigned cmmutuples; - unsigned cmmu_index; - unsigned num_entries; - unsigned pfn_index; - wrsm_cmmu_tuple_t *tuple; - wrsm_cmmu_t cmmu; - int i; - - DPRINTF(DBG_EXPORT, (CE_CONT, "clear_lpa_fields() - " - "seg_offset 0x%lx len 0x%lx\n", seg_offset, len)); - - /* - * Check if any pfn fields are not valid. Fail with - * RSMERR_MEM_NOT_BOUND if it is required that they be valid. - */ - pfn_index = seg_offset >> MMU_PAGESHIFT; - if (mapping_required) { - for (i = 0; i < (len >> MMU_PAGESHIFT); i++) { - if (exportseg->pfn_list[pfn_index + i] == PFN_INVALID) { - return (RSMERR_MEM_NOT_BOUND); - } - } - } - - /* - * Invalidate all affected entries in the pfn list. - */ - for (i = pfn_index; i < ((seg_offset + len) >> MMU_PAGESHIFT); i++) { - if (exportseg->pfn_list[i] != PFN_INVALID) { - network->memseg->bytes_bound -= MMU_PAGESIZE; - } - exportseg->pfn_list[i] = PFN_INVALID; - } - - /* - * Set all cmmu entries in range to invalid if segment is published. - * Otherwise, they are already set to invalid. - */ - if (exportseg->state != memseg_published) { - return (WRSM_SUCCESS); - } - - cmmu.entry_0.bit.valid = 0; - - /* - * Find the right cmmugrp structure, tuple, and cmmu entry within - * the tuple (as indicated by cmmu_index) for <seg_offset>. - */ - get_start_cmmugrp(&cmmugrp, seg_offset, &cmmu_index, &cmmugrp_size); - get_start_entry(cmmugrp, &tuple, &cmmutuples, &cmmu_index); - - while (len > 0) { - /* - * Calculate the number of entries from this cmmugrp that - * should be cleared, and subtract covered bytes from len. - */ - get_num_entries(&len, &num_entries, cmmugrp_size, - cmmugrp->pgbytes); - - while (num_entries) { - wrsm_cmmu_update(network, - &cmmu, - tuple->index + cmmu_index, - CMMU_UPDATE_VALID); - - /* get next CMMU entry in this cmmugrp */ - get_next_entry(cmmugrp->tuples, &tuple, &cmmutuples, - &cmmu_index); - num_entries--; - } - - if (len == 0) - break; - - get_next_cmmugrp(&cmmugrp, &cmmutuples, &cmmu_index, - &cmmugrp_size, &tuple); - } - - return (WRSM_SUCCESS); -} - - - - -/* - * Set up the cmmu lpa fields to point to the physical memory backing the - * region pointed to by <as, vaddr> or to the pages in the pagelist - * starting with <startpp>. Use as many entries as needed to map <len> - * bytes. - * - * For each physical page backing the region, update the lpa fields of as - * many cmmu entries as are needed to map the page -- either one cmmu entry - * if the passed in page size matches the CMMU entry page size, or multiple - * cmmu entries if a large page is passed in but small page cmmu entries - * are being used. Also record the pfn for each 8k region in the segment - * pfn_list, and set the entry to valid if it is published. - * - * Update the cmmu entries in cmmugrp/tuple sequential order starting with - * the entry specified by <seg_offset>. - */ -static int -set_lpa_fields(exportseg_t *exportseg, size_t seg_offset, size_t len, - struct as *as, caddr_t vaddr, page_t *startpp) -{ - int err = 0; - int pgbytes; - size_t bytesleft; - size_t used_in_group; - pfn_t pfn, pfn_8k; - wrsm_network_t *network = exportseg->network; - cmmugrp_t *cmmugrp = exportseg->cmmugrps; - size_t cmmugrp_size; - unsigned cmmutuples; - unsigned cmmu_index; - unsigned num_entries; - unsigned pfn_index; - wrsm_cmmu_tuple_t *tuple; - wrsm_cmmu_t cmmu; - off_t cur_offset = 0; - page_t *pp = startpp; - int i; - - DPRINTF(DBG_EXPORT, (CE_CONT, "set_lpa_fields() - " - "seg_offset 0x%lx len 0x%lx\n", seg_offset, len)); - - ASSERT(cmmugrp); - - - /* - * If any pfn entries are already valid, fail with - * RSMERR_MEM_ALREADY_BOUND. - */ - pfn_index = seg_offset >> MMU_PAGESHIFT; - for (i = 0; i < (len >> MMU_PAGESHIFT); i++) { - if (exportseg->pfn_list[pfn_index + i] != PFN_INVALID) { - return (RSMERR_MEM_ALREADY_BOUND); - } - } - - /* - * Set cmmu entries to valid if segment has been published. - */ - if (exportseg->state == memseg_published) { - cmmu.entry_0.bit.valid = 1; - } else { - cmmu.entry_0.bit.valid = 0; - } - - /* - * Find the right cmmugrp structure, tuple, and cmmu entry within - * the tuple (as indicated by cmmu_index) for <seg_offset>. - */ - get_start_cmmugrp(&cmmugrp, seg_offset, &cmmu_index, &cmmugrp_size); - get_start_entry(cmmugrp, &tuple, &cmmutuples, &cmmu_index); - - used_in_group = 0; - - while (len > 0) { - - /* - * Get the pfn and size of the next page. - */ - if (startpp) { - /* - * Get the pfn for next page in pagelist. This is - * guaranteed to be real memory, as we have been - * given page structures. - */ - if (!pp) { - err = RSMERR_NO_BACKING_MEM; - goto bad_memory; - } - pfn = page_pptonum(pp); - pgbytes = PAGESIZE; /* same as bp_mapin */ - page_unlock(pp); - pp = pp->p_next; - } else { - /* - * Get the pfn for the page backing <as, vaddr + - * cur_offset>. Make sure this is real memory. - * Grab AS_LOCK to make sure as mappings don't - * change. - */ - - AS_LOCK_ENTER(as, &as->a_lock, RW_READER); - pfn = hat_getpfnum(as->a_hat, vaddr + cur_offset); - AS_LOCK_EXIT(as, &as->a_lock); - - if (pfn == PFN_INVALID) { - err = RSMERR_NO_BACKING_MEM; - goto bad_memory; - } - if (!pf_is_memory(pfn)) { - err = RSMERR_NOT_MEM; - goto bad_memory; - } - pgbytes = MMU_PAGESIZE; - } - - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, - "mapping page with pfn 0x%lx size 0x%x\n", - pfn, pgbytes)); - - ASSERT(pgbytes == MMU_PAGESIZE || pgbytes == MMU_PAGESIZE4M); - ASSERT(pgbytes >= cmmugrp->pgbytes); - - pfn_8k = pfn; - bytesleft = pgbytes; - - /* - * If we've already allocated all the entries from the - * current cmmugrp, move to the next one. - */ - if (used_in_group >= cmmugrp_size) { - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, - "set_lpa_fields used all in one group" - " used_in_group = %lx, size = %lx\n", - used_in_group, cmmugrp_size)); - - get_next_cmmugrp(&cmmugrp, &cmmutuples, &cmmu_index, - &cmmugrp_size, &tuple); - - used_in_group = 0; - } - - while (bytesleft > 0) { - - /* - * Calculate the number of cmmu entries from this - * cmmugrp that will be used to map this page, and - * subtract covered bytes from bytesleft. - */ - get_num_entries(&bytesleft, &num_entries, - cmmugrp_size, cmmugrp->pgbytes); - - while (num_entries) { - /* - * record lpa for this region of the page - */ - cmmu.entry_1.addr.lpa_page = pfn; - wrsm_cmmu_update(network, &cmmu, - tuple->index + cmmu_index, - CMMU_UPDATE_LPA | CMMU_UPDATE_VALID); - DPRINTF(DBG_EXPORT_EXTRA, - (CE_CONT, "set_lpa_fields " - "cmmu index %d pfn 0x%lx valid %ld\n", - tuple->index + cmmu_index, - cmmu.entry_1.addr.lpa_page, - cmmu.entry_0.bit.valid)); - - /* get next CMMU entry */ - get_next_entry(cmmugrp->tuples, &tuple, - &cmmutuples, &cmmu_index); - num_entries--; - - /* - * If cmmu entries are for small pages, - * get physaddr (pfn) for next 8k page. - */ - if (cmmugrp->pgbytes == MMU_PAGESIZE) - pfn += MMU_PAGESIZE >> MMU_PAGESHIFT; - } - - if (bytesleft == 0) - break; - - get_next_cmmugrp(&cmmugrp, &cmmutuples, &cmmu_index, - &cmmugrp_size, &tuple); - used_in_group = 0; - } - - /* - * record the 8k-based pfns for this page in pfn_list - */ - for (i = 0; i < (pgbytes >> MMU_PAGESHIFT); i++) { - exportseg->pfn_list[pfn_index + i] = pfn_8k; - pfn_8k += MMU_PAGESIZE >> MMU_PAGESHIFT; - } - pfn_index += pgbytes >> MMU_PAGESHIFT; - - used_in_group += pgbytes; - cur_offset += pgbytes; - network->memseg->bytes_bound += pgbytes; - len -= pgbytes; - ASSERT(len >= 0); - } - return (WRSM_SUCCESS); - - -bad_memory: - /* - * There was a problem with the backing memory. Tear down - * previously set up stuff, and return error. - */ - pfn_index = seg_offset >> MMU_PAGESHIFT; - for (i = 0; i < (cur_offset >> MMU_PAGESHIFT); i++) { - exportseg->pfn_list[pfn_index + i] = PFN_INVALID; - } - (void) clear_lpa_fields(exportseg, seg_offset, cur_offset, B_FALSE); - return (err); -} - - - - -/* - * Allocate <num_entries> cmmu entries of <pgbytes> page size from the cmmu - * allocator. Create a cmmugrp entry to store info about these entries. - */ -static int -alloc_cmmu_tuples(exportseg_t *exportseg, int num_entries, off_t seg_offset, - int pgbytes, cmmugrp_t **cmmugrpp, boolean_t sleep) -{ - wrsm_network_t *network = exportseg->network; - int err = WRSM_SUCCESS; - size_t cmmu_page_size; - cmmugrp_t *cmmugrp; - wrsm_cmmu_t cmmu; - wrsm_cmmu_index_t index; - boolean_t lg_page; - int i, j; - - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "alloc_cmmu_tuples() - " - "num_entries %d seg_offset 0x%lx pgbytes 0x%x\n", - num_entries, seg_offset, pgbytes)); - - cmmugrp = (cmmugrp_t *)kmem_zalloc(sizeof (cmmugrp_t), - KM_SLEEP); - cmmugrp->offset = seg_offset; - cmmugrp->len = num_entries * pgbytes; - cmmugrp->pgbytes = pgbytes; - cmmu_page_size = (pgbytes == MMU_PAGESIZE) ? - CMMU_PAGE_SIZE_SMALL : CMMU_PAGE_SIZE_LARGE; - lg_page = (pgbytes == MMU_PAGESIZE4M) ? B_TRUE : B_FALSE; - - - if ((err = wrsm_cmmu_alloc(network, cmmu_page_size, num_entries, - &cmmugrp->tuples, &cmmugrp->num_tuples, sleep)) != - WRSM_SUCCESS) { - if (cmmu_page_size == CMMU_PAGE_SIZE_LARGE) { - /* - * try allocating cmmu entries for small pages - */ - lg_page = B_FALSE; - cmmugrp->pgbytes = MMU_PAGESIZE; - cmmu_page_size = CMMU_PAGE_SIZE_SMALL; - num_entries *= MMU_PAGESIZE4M >> MMU_PAGESHIFT; - if ((err = wrsm_cmmu_alloc(network, - cmmu_page_size, num_entries, - &cmmugrp->tuples, &cmmugrp->num_tuples, sleep)) != - WRSM_SUCCESS) { - kmem_free(cmmugrp, sizeof (cmmugrp_t)); - /* return RSMPI complaint error code */ - return (RSMERR_INSUFFICIENT_RESOURCES); - } - } else { - /* give up */ - kmem_free(cmmugrp, sizeof (cmmugrp_t)); - return (err); - } - } - - /* - * Update each CMMU entry to reflect how it is being used - */ - cmmu.entry_0.val = 0; - cmmu.entry_0.bit.count_enable = B_FALSE; - cmmu.entry_0.bit.large_page = lg_page; - cmmu.entry_0.bit.user_err = B_FALSE; - cmmu.entry_0.bit.writable = B_FALSE; - cmmu.entry_0.bit.from_all = B_TRUE; - cmmu.entry_0.bit.from_node = 255; - cmmu.entry_0.bit.valid = B_FALSE; - cmmu.entry_0.bit.type = CMMU_TYPE_CACHEABLE; - - cmmu.entry_1.val = 0; - - for (i = 0; i < cmmugrp->num_tuples; i++) { - index = cmmugrp->tuples[i].index; - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, - "alloc_cmmu_tuples() alloced tuples %d - %d\n", - index, index + cmmugrp->tuples[i].count - 1)); - for (j = 0; j < cmmugrp->tuples[i].count; j++) { - wrsm_cmmu_update(network, &cmmu, index, - CMMU_UPDATE_ALL); - index++; - } - } - - exportseg->total_tuples += cmmugrp->num_tuples; - exportseg->num_cmmugrps++; - *cmmugrpp = cmmugrp; - - return (WRSM_SUCCESS); -} - - - - -/* - * Allocate enough cmmu entries for a segment of size <size>. Allocate - * large pages where possible. Set up mappings to any passed in memory. - */ -static int -alloc_seg_cmmu_entries(exportseg_t *exportseg, rsm_memory_local_t *memory, - size_t size, boolean_t allow_lg_pages, boolean_t sleep) -{ - int pgbytes, opgbytes, num_entries, need_entries; - off_t seg_offset; - cmmugrp_t **cmmugrp_nextp; - size_t nbytes = 0; - pfn_t pfn; - page_t *pp; - page_t *startpp = NULL; - struct buf *bp = NULL; - struct as *as = NULL; - off_t offset = 0; - void *vaddr = NULL; - /* LINTED: E_FUNC_SET_NOT_USED */ - int err; -#ifdef DEBUG - pfn = 0; -#endif - - if (memory->ms_type == RSM_MEM_BUF) { - bp = memory->ms_bp; - - DPRINTF(DBG_EXPORT, (CE_CONT, "alloc_seg_cmmu_entries() - " - "bp 0x%p size 0x%lx\n", (void *)bp, size)); - - ASSERT(bp); - ASSERT(SEMA_HELD(&bp->b_sem)); - - nbytes = bp->b_bcount; - - if (bp->b_flags & B_PAGEIO) { - if (!bp->b_pages) { - return (RSMERR_NO_BACKING_MEM); - } else { - pp = startpp = bp->b_pages; - } - } else { - vaddr = (void *)bp->b_un.b_addr; - if (bp->b_flags & B_PHYS) { - if (bp->b_proc == NULL || - (as = bp->b_proc->p_as) == NULL) - as = &kas; - } else { - as = &kas; - } - } - - } else { - ASSERT(memory->ms_type == RSM_MEM_VADDR); - - as = memory->ms_as; - if (as == NULL) { - as = &kas; - } - vaddr = memory->ms_vaddr; - nbytes = memory->ms_length; - - DPRINTF(DBG_EXPORT, (CE_CONT, "alloc_seg_cmmu_entries() - " - "as 0x%p vaddr 0x%p length 0x%lx size 0x%lx\n", (void *)as, - vaddr, nbytes, size)); - } - - if ((uint64_t)vaddr & (uint64_t)MMU_PAGEOFFSET) { - /* vaddr must be propertly aligned */ - DPRINTF(DBG_EXPORT, (CE_CONT, "vaddr 0x%p not aligned\n", - (void *)vaddr)); - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - if (nbytes > size) { - /* size range can't exceed segment size */ - DPRINTF(DBG_EXPORT, (CE_CONT, "nbytes %ld > size %ld\n", - nbytes, size)); - return (RSMERR_BAD_LENGTH); - } - - if (nbytes & MMU_PAGEOFFSET) { - /* size must be an aligned number of bytes */ - DPRINTF(DBG_EXPORT, (CE_CONT, "nbytes %ld not 64 byte round\n", - nbytes)); - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - size -= nbytes; /* size of region not backed by memory */ - pgbytes = opgbytes = MMU_PAGESIZE; - num_entries = 0; - seg_offset = 0; - cmmugrp_nextp = &exportseg->cmmugrps; - ASSERT(*cmmugrp_nextp == NULL); - - /* - * Use large page CMMU entries for all large physical pages if - * allowed and available. We could try seeing if the small pages - * happen to be allocated consecutively, but the caller apparently - * didn't care enough to use large pages, so don't bother. - */ - - while (nbytes > 0) { - if (startpp) { - if (!pp) { - mseg_free_cmmus(exportseg); - DPRINTF(DBG_EXPORT, - (CE_CONT, "invalid buf pp\n")); - return (RSMERR_NO_BACKING_MEM); - } - - pgbytes = PAGESIZE; /* same as bp_mapin */ - pp = pp->p_next; - - } else { - - /* - * make sure the next region of the vaddr range - * points to valid physical memory. Grab AS_LOCK - * to make sure as mappings don't change. - */ - - AS_LOCK_ENTER(as, &as->a_lock, RW_READER); - pfn = hat_getpfnum(as->a_hat, (caddr_t)vaddr + - offset); - AS_LOCK_EXIT(as, &as->a_lock); - - if (pfn == PFN_INVALID) { - /* not backed by anything! */ - mseg_free_cmmus(exportseg); - DPRINTF(DBG_EXPORT, (CE_CONT, "vaddr 0x%p " - "not backed by memory\n", - (void *)((caddr_t)vaddr + offset))); - return (RSMERR_NO_BACKING_MEM); - } - if (!pf_is_memory(pfn)) { - /* tear down previously set up stuff */ - mseg_free_cmmus(exportseg); - DPRINTF(DBG_EXPORT, (CE_CONT, "IO " - "pfn 0x%lx at vaddr 0x%p\n", pfn, - (void *)((caddr_t)vaddr + offset))); - return (RSMERR_NOT_MEM); - } - pgbytes = MMU_PAGESIZE; - offset += pgbytes; - } - - ASSERT(pgbytes == MMU_PAGESIZE || pgbytes == MMU_PAGESIZE4M); - - if (pgbytes == MMU_PAGESIZE4M && !allow_lg_pages) { - /* - * large pages not allowed: translate to small pages - */ - DPRINTF(DBG_EXPORT, (CE_CONT, "no large pages; convert " - "pages from size %d to %d (MMU_PAGESIZE)\n", - pgbytes, MMU_PAGESIZE)); - ASSERT((pgbytes & MMU_PAGEOFFSET) == 0); - need_entries = pgbytes >> MMU_PAGESHIFT; - pgbytes = MMU_PAGESIZE; - } else { - need_entries = 1; - } - - nbytes -= pgbytes; - - if (pgbytes != opgbytes) { - /* - * a different page size is being used - */ - if (num_entries != 0) { - /* - * Allocate cmmu entries for the num_entries - * previous pages. - */ - if ((alloc_cmmu_tuples(exportseg, - num_entries, seg_offset, opgbytes, - cmmugrp_nextp, sleep)) != WRSM_SUCCESS) { - mseg_free_cmmus(exportseg); - DPRINTF(DBG_EXPORT, (CE_CONT, - "couldn't alloc cmmu tuples to " - "back memory\n")); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - cmmugrp_nextp = &((*cmmugrp_nextp)->next); - - /* - * record the physical addresses of this - * range of memory into the LPA fields in - * the cmmu entries - */ - err = set_lpa_fields(exportseg, seg_offset, - num_entries * opgbytes, as, - (caddr_t)vaddr + seg_offset, startpp); - ASSERT(err == WRSM_SUCCESS); - seg_offset += num_entries * opgbytes; - - if (startpp) { - startpp = pp; - ASSERT(startpp || nbytes == 0); - } - opgbytes = pgbytes; - num_entries = 0; - } - } - - num_entries += need_entries; - } - - ASSERT(nbytes == 0); - - - /* - * allocate tuples for last set of physical pages - */ - - if (num_entries != 0) { - ASSERT(pgbytes == MMU_PAGESIZE || pgbytes == MMU_PAGESIZE4M); - if (num_entries != 0) { - if ((alloc_cmmu_tuples(exportseg, num_entries, - seg_offset, pgbytes, cmmugrp_nextp, sleep)) != - WRSM_SUCCESS) { - mseg_free_cmmus(exportseg); - DPRINTF(DBG_EXPORT, (CE_CONT, - "couldn't alloc cmmu tuples for " - "last set of backing memory\n")); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - cmmugrp_nextp = &((*cmmugrp_nextp)->next); - - err = set_lpa_fields(exportseg, seg_offset, - num_entries * pgbytes, as, - (caddr_t)vaddr + seg_offset, startpp); - ASSERT(err == WRSM_SUCCESS); - seg_offset += num_entries * pgbytes; - } - } - - /* - * Allocate tuples for the end of the segment if some of it - * has no memory backing it. Allocate small pages for this - * part, as we don't know what memory will eventually back it. - */ - - if (size != 0) { - num_entries = size >> MMU_PAGESHIFT; - ASSERT(num_entries != 0); - if ((alloc_cmmu_tuples(exportseg, num_entries, - seg_offset, MMU_PAGESIZE, cmmugrp_nextp, sleep)) - != WRSM_SUCCESS) { - mseg_free_cmmus(exportseg); - DPRINTF(DBG_EXPORT, (CE_CONT, - "couldn't alloc cmmu tuples for unbacked " - " memory\n")); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - } - - - return (WRSM_SUCCESS); -} - - -/* - * Parse the passed in access list, calculate new per node access - * permissions (based on the old and new permissions), store the new - * permissions, and apply the access permissions for an exported segment - * to the appropriate cmmu entries. - */ -static int -apply_access_list(exportseg_t *exportseg, - rsm_access_entry_t access_list[], uint_t access_list_length) -{ - rsm_addr_t addr; - wrsm_network_t *network; - cnodeid_t cnodeid; - cnode_bitmask_t bitmask; - rsm_permission_t perms = RSM_PERM_NONE; - uint_t i; - int j; - boolean_t changed[WRSM_MAX_CNODES]; - boolean_t old_import_vals[WRSM_MAX_CNODES]; - rsm_permission_t old_perms_vals[WRSM_MAX_CNODES]; - - DPRINTF(DBG_EXPORT, (CE_CONT, "apply_access_list()\n")); - - ASSERT(MUTEX_HELD(&exportseg->lock)); - - WRSMSET_ZERO(bitmask); - network = exportseg->network; - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - changed[i] = B_FALSE; - } - - - /* - * If no access list, assume default of all nodes, with a - * permission of RSM_PERM_RDWR. If the access list's first entry - * specifies single hardware address of RSM_ACCESS_PUBLIC, apply - * the specified permission to all nodes. Otherwise, parse the - * access list. - */ - - if (access_list == NULL || - access_list[0].ae_addr == RSM_ACCESS_PUBLIC) { - perms = access_list ? access_list[0].ae_permission : - RSM_PERM_RDWR; - - if ((perms & ~RSM_PERM_RDWR) != 0) { - return (RSMERR_BAD_ACL); - } - - /* all nodes are allowed to import this segment */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (network->nodes[i]) { - exportseg->nodes[i].allow_import = B_TRUE; - exportseg->nodes[i].perms = perms; - WRSMSET_ADD(bitmask, i); - } - } - - } else { - for (i = 0; i < access_list_length; i++) { - /* - * wrsm hardware addresses must be cnodeids. - * Only allowed bits in perms are RSM_PERM_READ - * and RSM_PERM_WRITE - */ - addr = access_list[i].ae_addr; - if ((addr >= WRSM_MAX_CNODES) || - !network->nodes[addr] || - ((access_list[i].ae_permission & - ~RSM_PERM_RDWR) != 0)) { - /* - * invalid hardware address or perms -- - * reinstate old settings, then fail - */ - for (j = 0; j < i; j++) { - if (changed[j]) { - exportseg->nodes[j]. - allow_import = - old_import_vals[j]; - exportseg->nodes[j].perms = - old_perms_vals[j]; - } - } - return (RSMERR_BAD_ACL); - } - cnodeid = access_list[i].ae_addr; - WRSMSET_ADD(bitmask, cnodeid); - - changed[cnodeid] = B_TRUE; - old_import_vals[cnodeid] = - exportseg->nodes[cnodeid].allow_import; - old_perms_vals[cnodeid] = - exportseg->nodes[cnodeid].perms; - exportseg->nodes[cnodeid].allow_import = B_TRUE; - exportseg->nodes[cnodeid].perms = - access_list[i].ae_permission; - - /* - * make sure perms is set to the most permissive - * of each node's old and new permissions. - * perms starts out as RSM_PERM_NONE, and gets - * changed if the current node has greater - * permissions. - */ - switch (exportseg->nodes[cnodeid].perms) { - case RSM_PERM_RDWR: - case RSM_PERM_WRITE: - perms = RSM_PERM_RDWR; - break; - case RSM_PERM_READ: - if (perms == RSM_PERM_NONE) - perms = RSM_PERM_READ; - break; -#ifdef DEBUG - default: - ASSERT(exportseg->nodes[cnodeid].perms - == RSM_PERM_NONE); - break; -#endif - } - switch (exportseg->nodes[cnodeid].actual_perms) { - case RSM_PERM_RDWR: - case RSM_PERM_WRITE: - perms = RSM_PERM_RDWR; - break; - case RSM_PERM_READ: - if (perms == RSM_PERM_NONE) - perms = RSM_PERM_READ; - break; -#ifdef DEBUG - default: - ASSERT(exportseg->nodes[cnodeid].actual_perms - == RSM_PERM_NONE); - break; -#endif - } - } - } - - /* - * Make sure the actual per node perms are the max permissions of - * previous actual perms and the newly installed perms. - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - switch (exportseg->nodes[i].perms) { - case RSM_PERM_RDWR: - case RSM_PERM_WRITE: - exportseg->nodes[i].actual_perms = RSM_PERM_RDWR; - break; - case RSM_PERM_READ: - if (exportseg->nodes[i].actual_perms == RSM_PERM_NONE) - exportseg->nodes[i].actual_perms = - RSM_PERM_READ; - break; - } - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "cnode %d: allow_import %d " - "perms 0x%x actual perms 0x%x\n", - i, - exportseg->nodes[i].allow_import, - exportseg->nodes[i].perms, - exportseg->nodes[i].actual_perms)); - } - - if (!wrsm_hw_protection) { - - /* - * Set all CMMU entries to valid (if they have a valid - * lpa). Set writeable to true if any node is allowed - * write permission, or if there were previous permissions - * that allowed writing. (This handles the case of - * republish calling this function with stricter - * permissions.) - */ - /* LINTED: E_PRECEDENCE_CONFUSION */ - if ((perms == RSM_PERM_RDWR) || (perms == RSM_PERM_WRITE) || - exportseg->writeable) { - exportseg->writeable = B_TRUE; - update_cmmu_fields(exportseg, 0, exportseg->size, - memseg_set_writeable); - } else { - exportseg->writeable = B_FALSE; - update_cmmu_fields(exportseg, 0, exportseg->size, - memseg_unset_writeable); - } - } - - WRSMSET_COPY(bitmask, exportseg->import_bitmask); - return (RSM_SUCCESS); -} - - - -/* - * Enable the small page interrupt cmmu entry for this exportseg. - */ -static void -enable_smallput_intr_page(exportseg_t *exportseg) -{ - wrsm_cmmu_t cmmu; - wrsm_cmmu_index_t index; - - index = exportseg->small_put_intr.tuple->index; - cmmu.entry_0.bit.valid = B_TRUE; - wrsm_cmmu_update(exportseg->network, &cmmu, index, CMMU_UPDATE_VALID); -} - - - -/* - * Disable the small page interrupt cmmu entry for this exportseg. - */ -static void -disable_smallput_intr_page(exportseg_t *exportseg) -{ - wrsm_cmmu_t cmmu; - wrsm_cmmu_index_t index; - - index = exportseg->small_put_intr.tuple->index; - cmmu.entry_0.bit.valid = B_FALSE; - wrsm_cmmu_update(exportseg->network, &cmmu, index, - CMMU_UPDATE_VALID | CMMU_UPDATE_FLUSH); - - /* make sure any in-process interrupts have completed */ - wrsm_intr_flush_recvq(exportseg->small_put_intr.recvq); -} - - - - -/* - * Translate an exportseg's stored cmmu entry information into the format - * needed for connection messages. - */ -static void -cmmutuple_to_ncslicetuple(wrsm_network_t *network, wrsm_cmmu_tuple_t *cmmutuple, - import_ncslice_t *ncslicetuple, size_t seg_offset, size_t cmmu_page_size, - cnodeid_t cnodeid) -{ - int i; -#ifdef DEBUG - boolean_t found_ncslice = B_FALSE; -#endif - ncslice_t ncslice; - ncslicetuple->seg_offset = seg_offset; - ncslice = cmmutuple->ncslice; - /* set ncslice to the equivalent ncslice imported by this node */ - for (i = 0; i < WRSM_NODE_NCSLICES; i++) { - if (network->exported_ncslices.id[i] == ncslice) { -#ifdef DEBUG - found_ncslice = B_TRUE; -#endif - ncslicetuple->ncslice = network->nodes[cnodeid]-> - config->imported_ncslices.id[i]; - break; - } - } -#ifdef DEBUG - ASSERT(found_ncslice); -#endif - ncslicetuple->ncslice_offset = (off_t)cmmutuple->offset; - ncslicetuple->len = cmmutuple->count * cmmu_page_size; -} - -/* - * Send requestor information about a published exported segment. - */ -void -wrsm_connect_msg_evt(void *arg) -{ - wrsm_network_t *network = ((wrsm_memseg_evt_args_t *)arg)->network; - wrsm_message_t *msg = &((wrsm_memseg_evt_args_t *)arg)->msg; - cnodeid_t cnodeid = msg->header.source_cnode; - connect_msg_t args; - wrsm_node_t *node = network->nodes[msg->header.source_cnode]; - wrsm_raw_message_t msgbuf; - wrsm_message_t *respmsg = (wrsm_message_t *)&msgbuf; - connect_resp_t respargs; - exportseg_t *exportseg; - connect_info_t *connected; - int connection = 0; - - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: connect_msg_evt() " - "node %d\n", network->rsm_ctlr_id, cnodeid)); - - if (node == NULL) { - /* non-existent node */ - return; - } - - if (wrsm_tl_rxhandler_sessionid(network, msg) == B_FALSE) { - /* session must not be valid */ - return; - } - - bcopy(&msg->body, &args, sizeof (args)); - - respmsg->header.message_type = WRSM_MSG_SEGMENT_CONNECT_RESPONSE; - - /* - * does segment exist? - */ - exportseg = find_and_lock_exportseg(network, args.segid); - if (exportseg == NULL) { - respargs.err = ENOENT; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - - /* - * is segment published? - */ - if (exportseg->state != memseg_published) { - mutex_exit(&exportseg->lock); - respargs.err = ENOENT; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - - /* - * does requesting node have permission to connect to it? - */ - if (!WRSM_IN_SET(exportseg->import_bitmask, cnodeid)) { - mutex_exit(&exportseg->lock); - respargs.err = EACCES; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - - if (exportseg->nodes[cnodeid].inuse != B_TRUE) { - /* - * add to list of segments the remote node is importing - */ - exportseg->nodes[cnodeid].inuse = B_TRUE; - connection = 1; - mutex_enter(&node->memseg->lock); - connected = kmem_zalloc(sizeof (connect_info_t), KM_SLEEP); - connected->exportseg = exportseg; - connected->next = node->memseg->connected; - node->memseg->connected = connected; - mutex_exit(&node->memseg->lock); -#ifdef DEBUG - } else { - DPRINTF(DBG_WARN, (CE_WARN, - "unexpected connect request from node %d " - "for segment id %d\n", cnodeid, args.segid)); -#endif - } - - respargs.perms = exportseg->nodes[cnodeid].perms; - respargs.size = exportseg->size; - respargs.num_seg_tuples = exportseg->total_tuples; - respargs.err = RSM_SUCCESS; - mutex_exit(&exportseg->lock); - - /* - * Transport Layer tears down the session if there is a message - * delivery failure. - */ - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - - - mutex_enter(&network->lock); - network->memseg->export_connected += connection; - mutex_exit(&network->lock); - - /* We're done, deallocate our incoming args struct and the message */ - kmem_free(arg, sizeof (wrsm_memseg_evt_args_t)); - -} - - -/* - * Send requestor small put interrupt page mapping information for a - * published exported segment. - */ -void -wrsm_smallputmap_msg_evt(void *arg) -{ - wrsm_network_t *network = ((wrsm_memseg_evt_args_t *)arg)->network; - wrsm_message_t *msg = &((wrsm_memseg_evt_args_t *)arg)->msg; - cnodeid_t cnodeid = msg->header.source_cnode; - smallputmap_msg_t args; - wrsm_node_t *node = network->nodes[msg->header.source_cnode]; - wrsm_raw_message_t msgbuf; - wrsm_message_t *respmsg = (wrsm_message_t *)&msgbuf; - smallputmap_resp_t respargs; - exportseg_t *exportseg; - - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: smallputmap_msg_evt() " - "node %d\n", network->rsm_ctlr_id, cnodeid)); - - if (node == NULL) { - /* non-existent node */ - return; - } - - if (wrsm_tl_rxhandler_sessionid(network, msg) == B_FALSE) { - /* session must not be valid */ - return; - } - - bcopy(&msg->body, &args, sizeof (args)); - - respmsg->header.message_type = WRSM_MSG_SEGMENT_SMALLPUTMAP_RESPONSE; - - /* - * does segment exist? - */ - exportseg = find_and_lock_exportseg(network, args.segid); - if (exportseg == NULL) { - respargs.err = ENOENT; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - - respargs.err = RSM_SUCCESS; - /* - * is segment published? - */ - if (exportseg->state != memseg_published) { - respargs.err = ENOENT; - } - /* - * does requesting node have permission to connect to it? - */ - else if (!WRSM_IN_SET(exportseg->import_bitmask, cnodeid)) { - respargs.err = EACCES; - } - /* - * 0 length segment -- no small put page to report - */ - else if (exportseg->size == 0) { - respargs.err = EINVAL; - } - - if (respargs.err != RSM_SUCCESS) { - mutex_exit(&exportseg->lock); - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - -#ifdef DEBUG - if (exportseg->nodes[cnodeid].inuse != B_TRUE) { - DPRINTF(DBG_WARN, (CE_WARN, "ctlr %d: smallputmap_msg_evt() " - "unexpected smallputmap request from node %d " - "for segment id %d\n", cnodeid, args.segid)); - } -#endif - - cmmutuple_to_ncslicetuple(network, exportseg->small_put_intr.tuple, - &respargs.small_put_tuple, 0, MMU_PAGESIZE, cnodeid); - - mutex_exit(&exportseg->lock); - - /* - * Transport Layer tears down the session if there is a message - * delivery failure. - */ - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - - - /* We're done, deallocate our incoming args struct and the message */ - kmem_free(arg, sizeof (wrsm_memseg_evt_args_t)); - -} - - -/* - * Send requestor barrier page mapping information for a published exported - * segment. - */ -void -wrsm_barriermap_msg_evt(void *arg) -{ - wrsm_network_t *network = ((wrsm_memseg_evt_args_t *)arg)->network; - wrsm_message_t *msg = &((wrsm_memseg_evt_args_t *)arg)->msg; - cnodeid_t cnodeid = msg->header.source_cnode; - barriermap_msg_t args; - wrsm_node_t *node = network->nodes[msg->header.source_cnode]; - wrsm_raw_message_t msgbuf; - wrsm_message_t *respmsg = (wrsm_message_t *)&msgbuf; - barriermap_resp_t respargs; - exportseg_t *exportseg; - - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: barriermap_msg_evt() " - "node %d\n", network->rsm_ctlr_id, cnodeid)); - - if (node == NULL) { - /* non-existent node */ - return; - } - - if (wrsm_tl_rxhandler_sessionid(network, msg) == B_FALSE) { - /* session must not be valid */ - return; - } - - bcopy(&msg->body, &args, sizeof (args)); - - respmsg->header.message_type = WRSM_MSG_SEGMENT_BARRIERMAP_RESPONSE; - - /* - * does segment exist? - */ - exportseg = find_and_lock_exportseg(network, args.segid); - if (exportseg == NULL) { - respargs.err = ENOENT; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - - respargs.err = RSM_SUCCESS; - - /* - * is segment published? - */ - if (exportseg->state != memseg_published) { - respargs.err = ENOENT; - } - /* - * does requesting node have permission to connect to it? - */ - else if (!WRSM_IN_SET(exportseg->import_bitmask, cnodeid)) { - respargs.err = EACCES; - } - /* - * 0 length segment -- no small put page to report - */ - else if (exportseg->size == 0) { - respargs.err = EINVAL; - } - - if (respargs.err != RSM_SUCCESS) { - mutex_exit(&exportseg->lock); - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - -#ifdef DEBUG - if (exportseg->nodes[cnodeid].inuse != B_TRUE) { - DPRINTF(DBG_WARN, (CE_WARN, - "unexpected barriermap request from node %d " - "for segment id %d\n", cnodeid, args.segid)); - } -#endif - - cmmutuple_to_ncslicetuple(network, exportseg->barrier_page.tuple, - &respargs.barrier_tuple, 0, MMU_PAGESIZE, cnodeid); - - mutex_exit(&exportseg->lock); - - /* - * Transport Layer tears down the session if there is a message - * delivery failure. - */ - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - - /* We're done, deallocate our incoming args struct and the message */ - kmem_free(arg, sizeof (wrsm_memseg_evt_args_t)); - -} - - -/* - * Send segment mapping information for a published exported segment. - */ -void -wrsm_segmap_msg_evt(void *arg) -{ - wrsm_network_t *network = ((wrsm_memseg_evt_args_t *)arg)->network; - wrsm_message_t *msg = &((wrsm_memseg_evt_args_t *)arg)->msg; - segmap_msg_t args; - cnodeid_t cnodeid = msg->header.source_cnode; - wrsm_node_t *node = network->nodes[msg->header.source_cnode]; - wrsm_raw_message_t msgbuf; - wrsm_message_t *respmsg = (wrsm_message_t *)&msgbuf; - segmap_resp_t respargs; - exportseg_t *exportseg; - int i, j; - cmmugrp_t *cmmugrp; - uint64_t tuple_offset; - int tuple_index; - - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: segmap_msg_evt() " - "node %d\n", network->rsm_ctlr_id, cnodeid)); - - if (node == NULL) { - /* non-existent node */ - return; - } - - if (wrsm_tl_rxhandler_sessionid(network, msg) == B_FALSE) { - /* session must not be valid */ - return; - } - - bcopy(&msg->body, &args, sizeof (args)); - - respmsg->header.message_type = WRSM_MSG_SEGMENT_SEGMAP_RESPONSE; - - /* - * does segment exist? - */ - exportseg = find_and_lock_exportseg(network, args.segid); - if (exportseg == NULL) { - respargs.err = ENOENT; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - - /* - * is segment published? - */ - if (exportseg->state != memseg_published) { - mutex_exit(&exportseg->lock); - respargs.err = ENOENT; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - /* - * does requesting node have permission to connect to it? - */ - if (!WRSM_IN_SET(exportseg->import_bitmask, cnodeid)) { - mutex_exit(&exportseg->lock); - respargs.err = EACCES; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - -#ifdef DEBUG - if (exportseg->nodes[cnodeid].inuse != B_TRUE) { - DPRINTF(DBG_WARN, (CE_WARN, - "unexpected map request from node %d " - "for segment id %d\n", cnodeid, args.segid)); - } -#endif - - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: segmap_msg_evt() " - "tuple_index %d\n", network->rsm_ctlr_id, args.tuple_index)); - - tuple_index = args.tuple_index; - if (tuple_index >= exportseg->total_tuples) { - mutex_exit(&exportseg->lock); - /* bad message */ - respargs.err = EINVAL; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - - /* - * find the cmmugrp containing the desired starting tuple - */ - i = 0; - cmmugrp = exportseg->cmmugrps; - while (i < tuple_index && ((i + cmmugrp->num_tuples) <= tuple_index)) { - i += cmmugrp->num_tuples; - cmmugrp = cmmugrp->next; - ASSERT(cmmugrp); - } - - /* calculate index within the cmmugrp */ - i = tuple_index - i; - - /* - * If this is not the first cmmu tuple in a cmmugrp, then - * compute its offset. - */ - tuple_offset = 0; - if (i > 0) { - for (j = 0; j < i; j++) { - tuple_offset += (cmmugrp->tuples[j].count * - cmmugrp->pgbytes); - } - } - - j = 0; - - /* - * copy as many tuples as possible into the response message - */ - while (j < MAP_MSG_TUPLES && tuple_index < exportseg->total_tuples) { - - cmmutuple_to_ncslicetuple(network, &(cmmugrp->tuples[i]), - &(respargs.tuples[j]), - cmmugrp->offset + tuple_offset, - cmmugrp->pgbytes, cnodeid); - - tuple_offset += (cmmugrp->tuples[i].count * - cmmugrp->pgbytes); - i++; - j++; - tuple_index++; - - if (tuple_index == exportseg->total_tuples) - break; - - if (i == cmmugrp->num_tuples) { - cmmugrp = cmmugrp->next; - ASSERT(cmmugrp); - i = 0; - tuple_offset = 0; - } - } - - respargs.num_tuples = j; - respargs.err = RSM_SUCCESS; - - mutex_exit(&exportseg->lock); - - /* - * Transport Layer tears down the session if there is a message - * delivery failure. - */ - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - - /* We're done, deallocate our incoming args struct and the message */ - kmem_free(arg, sizeof (wrsm_memseg_evt_args_t)); - -} - - - -/* - * Mark this exportseg as no longer imported by node sending this message. - */ -void -wrsm_disconnect_msg_evt(void *arg) -{ - wrsm_network_t *network = ((wrsm_memseg_evt_args_t *)arg)->network; - wrsm_message_t *msg = &((wrsm_memseg_evt_args_t *)arg)->msg; - disconnect_msg_t args; - cnodeid_t cnodeid = msg->header.source_cnode; - wrsm_node_t *node = network->nodes[msg->header.source_cnode]; - exportseg_t *exportseg; - connect_info_t **connpp, *connp; - - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: disconnect_msg_evt() " - "node %d\n", network->rsm_ctlr_id, cnodeid)); - - if (node == NULL) { - /* non-existent node */ - return; - } - - if (wrsm_tl_rxhandler_sessionid(network, msg) == B_FALSE) { - /* session must not be valid */ - return; - } - - /* - * does segment exist? - */ - bcopy(&msg->body, &args, sizeof (args)); - exportseg = find_and_lock_exportseg(network, args.segid); - if (exportseg == NULL) { - /* ignore */ - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: unexpected disconnect " - "from node %d for non-existent segment %d\n", - network->rsm_ctlr_id, node->config->cnodeid, args.segid)); - return; - } - - if (exportseg->nodes[cnodeid].inuse == B_FALSE) { - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: unexpected disconnect " - "from disconnected node %d for segment %d\n", - network->rsm_ctlr_id, node->config->cnodeid, args.segid)); - mutex_exit(&exportseg->lock); - return; - } - - /* - * remove from list of segments the remote node is importing - */ - exportseg->nodes[cnodeid].inuse = B_FALSE; - - mutex_enter(&node->memseg->lock); - for (connpp = &node->memseg->connected; *connpp != NULL; - connpp = &((*connpp)->next)) { - if ((*connpp)->exportseg == exportseg) { - connp = *connpp; - *connpp = (*connpp)->next; - kmem_free(connp, sizeof (*connp)); - break; - } - } - mutex_exit(&node->memseg->lock); - - if (exportseg->wait_for_disconnects > 0) { - DPRINTF(DBG_EXPORT, (CE_CONT, "disconnect_evt: " - "wait_for_disconnects %d\n", - exportseg->wait_for_disconnects)); - exportseg->wait_for_disconnects--; - } - - mutex_exit(&exportseg->lock); - - mutex_enter(&network->lock); - network->memseg->export_connected--; - mutex_exit(&network->lock); - - /* We're done, deallocate our incoming args struct and the message */ - kmem_free(arg, sizeof (wrsm_memseg_evt_args_t)); - -} - - - - -/* - * Send specified node a message indicating the the exported segment - * is no longer published. Record based on the response message whether - * the node has released all connections to the segment. Function - * returns 1 if it received a disconnect response from the remote - * node, otherwise it returns 0. - */ -static int -send_unpublish_msg(wrsm_node_t *node, exportseg_t *exportseg) -{ - wrsm_raw_message_t msgbuf; - wrsm_message_t *msg = (wrsm_message_t *)&msgbuf; - unpublish_msg_t args; - wrsm_raw_message_t recvmsgbuf; - wrsm_message_t *recvmsg = (wrsm_message_t *)&recvmsgbuf; - wrsm_network_t *network = node->network; - unpublish_resp_t recvargs; - connect_info_t **connpp, *connp; - int disconnect = 0; - - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: send_unpublish_msg() " - "node %d\n", network->rsm_ctlr_id, node->config->cnodeid)); - - /* LINTED */ - ASSERT(sizeof (unpublish_msg_t) <= WRSM_MESSAGE_BODY_SIZE); - - msg->header.message_type = WRSM_MSG_SEGMENT_UNPUBLISH; - args.segid = exportseg->segid; - - bcopy(&args, &msg->body, sizeof (args)); - if (wrsm_tl_rpc(network, node->config->cnodeid, msg, recvmsg) - != WRSM_SUCCESS) { - /* - * This node is not responding (message not - * delivered or response not received). (Transport - * Layer tears down the session if there is a - * message delivery failure). - * - * Assume session teardown will remove all accesses - * to this segment. - */ - return (0); - } - -#ifdef DEBUG - if (wrsm_export_memseg_debug & DBG_EXPORT_EXTRA) - wrsm_tl_dump_message("UNPUBLISH_RESPONSE: ", recvmsg); -#endif - if (recvmsg->header.message_type != - WRSM_MSG_SEGMENT_UNPUBLISH_RESPONSE) { - DPRINTF(DBG_EXPORT, (CE_WARN, - "send_unpublish_msg got invalid response\n")); - return (0); - } - - bcopy(&recvmsg->body, &recvargs, sizeof (recvargs)); - - - if (recvargs.status == WC_DISCONNECTED) { - disconnect = 1; - - /* - * remove from list of segments the remote node is - * importing - */ - mutex_enter(&node->memseg->lock); - for (connpp = &node->memseg->connected; *connpp != NULL; - connpp = &((*connpp)->next)) { - if ((*connpp)->exportseg == exportseg) { - connp = *connpp; - *connpp = (*connpp)->next; - kmem_free(connp, sizeof (*connp)); - break; - } - } - mutex_exit(&node->memseg->lock); - } - - return (disconnect); -} - - - - -/* - * Send the specified node a message indicating new access permissions - * for the exported segment. - */ -static void -send_access_msg(wrsm_node_t *node, rsm_memseg_id_t segid, - rsm_permission_t perms) -{ - wrsm_raw_message_t msgbuf; - wrsm_message_t *msg = (wrsm_message_t *)&msgbuf; - access_msg_t args; - wrsm_raw_message_t recvmsgbuf; - wrsm_message_t *recvmsg = (wrsm_message_t *)&recvmsgbuf; - wrsm_network_t *network = node->network; - - DPRINTF(DBG_EXPORT, (CE_CONT, "ctlr %d: send_access_msg() " - "node %d\n", network->rsm_ctlr_id, node->config->cnodeid)); - - /* LINTED */ - ASSERT(sizeof (access_msg_t) <= WRSM_MESSAGE_BODY_SIZE); - - msg->header.message_type = WRSM_MSG_SEGMENT_ACCESS; - args.segid = segid; - args.perms = perms; - - bcopy(&args, &msg->body, sizeof (args)); - if (wrsm_tl_rpc(network, node->config->cnodeid, msg, recvmsg) - != WRSM_SUCCESS) { - /* - * This node is not responding (message not - * delivered or response not received). (Transport - * Layer tears down the session if there is a - * message delivery failure). - * - * Assume session teardown will remove all accesses - * to this segment. - */ - return; - } - -#ifdef DEBUG - if (wrsm_export_memseg_debug & DBG_EXPORT_EXTRA) - wrsm_tl_dump_message("ACCESS_RESPONSE: ", recvmsg); -#endif -} - - - - -/* - * The session to the specified node has been torn down. Clean up - * references by this node to any exported segments. - */ -boolean_t -exportseg_sess_teardown(wrsm_node_t *node) -{ - exportseg_t *exportseg; - rsm_memseg_id_t segid; - connect_info_t *connp; - int disconnects = 0; - wrsm_network_t *network = node->network; - - DPRINTF(DBG_EXPORT, (CE_CONT, "exportseg_sess_teardown")); - - /* - * it is presumed that at this point the node was removed from the - * cluster_members_bits registers in all wcis - */ - - ASSERT(MUTEX_HELD(&node->memseg->lock)); - - /* - * clean up exports to the remote node - */ - while (node->memseg->connected) { - connp = node->memseg->connected; - exportseg = connp->exportseg; - segid = exportseg->segid; - node->memseg->connected = node->memseg->connected->next; - kmem_free(connp, sizeof (*connp)); - mutex_exit(&node->memseg->lock); - /* - * Must release node->memseg->lock in order to take - * exportseg lock; meanwhile, exportseg could disappear, so - * use find_and_lock_exportseg to verify it's still around. - */ - exportseg = find_and_lock_exportseg(node->network, segid); - if (exportseg) { - if (exportseg->nodes[node->config->cnodeid].inuse) { - exportseg->nodes[node->config->cnodeid].inuse = - B_FALSE; - disconnects++; - if (exportseg->wait_for_disconnects > 0) { - exportseg->wait_for_disconnects--; - } - } - mutex_exit(&exportseg->lock); - } - mutex_enter(&network->lock); - network->memseg->export_connected -= disconnects; - mutex_exit(&network->lock); - disconnects = 0; - mutex_enter(&node->memseg->lock); - } - - - return (B_TRUE); -} - - - -/* - * Allocate and set up cmmu entries for the segment. - * The exportseg lock is not needed because segment is not yet visible to - * other threads. - */ -static int -setup_segment_memory(exportseg_t *exportseg, int flags, - rsm_memory_local_t *memory, boolean_t sleep) -{ - wrsm_network_t *network = exportseg->network; - boolean_t allow_lg_pages = B_TRUE; - int i; - int err; - - DPRINTF(DBG_EXPORT, (CE_CONT, "setup segment memory\n")); - - exportseg->num_pages = exportseg->size >> MMU_PAGESHIFT; - ASSERT(exportseg->num_pages != 0); - exportseg->pfn_list = kmem_zalloc( - exportseg->num_pages * sizeof (pfn_t), KM_SLEEP); - for (i = 0; i < exportseg->num_pages; i++) { - exportseg->pfn_list[i] = PFN_INVALID; - } - - - /* - * Allocate CMMU entries for this segment. We can't use 4 Meg - * entries if we don't export a 4 meg ncslice, if REBIND is - * permitted, or if there is no memory backing the segment. - * - * If backing memory was provided, calculate the physical address - * for each CMMU entry, and store it in the CMMU's LPA field. Note: - * there is no guarantee that a buf struct will hang around, so can't - * just save a pointer to it. Similarly, there is no guarantee - * that the particular address space mapping will remain the same - * (although it must be mapped somewhere and locked down). - * - * If we need the physical addresses for any reason (such as to - * create HW based per node entries), the LPA can be read from the - * CMMU entry or found in the pfn_list. (The LPA field is - * RW.) - */ - - if (!network->have_lg_page_ncslice || - (flags & RSM_ALLOW_UNBIND_REBIND)) { - allow_lg_pages = B_FALSE; - } - - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "setup seg cmmu entries\n")); - - if (memory == NULL) { - /* use small page CMMU entries */ - if ((alloc_cmmu_tuples(exportseg, exportseg->num_pages, 0, - MMU_PAGESIZE, &exportseg->cmmugrps, sleep)) != - WRSM_SUCCESS) { - kmem_free(exportseg->pfn_list, - exportseg->num_pages * sizeof (pfn_t)); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - - } else if (memory->ms_type == RSM_MEM_VADDR || - memory->ms_type == RSM_MEM_BUF) { - if ((err = alloc_seg_cmmu_entries(exportseg, memory, - exportseg->size, allow_lg_pages, sleep)) != WRSM_SUCCESS) { - kmem_free(exportseg->pfn_list, - exportseg->num_pages * sizeof (pfn_t)); - return (err); - } - - } else { - kmem_free(exportseg->pfn_list, - exportseg->num_pages * sizeof (pfn_t)); - return (RSMERR_BAD_MSTYPE); - } - - return (RSM_SUCCESS); -} - -/* - * Invalidate and remove cmmu entries for the segment. - */ -static void -teardown_segment_memory(exportseg_t *exportseg) -{ - /* - * Unbind all pages, free CMMU entries. - */ - (void) clear_lpa_fields(exportseg, 0, exportseg->size, B_FALSE); - mseg_free_cmmus(exportseg); - kmem_free(exportseg->pfn_list, exportseg->num_pages * sizeof (pfn_t)); -} - - - -/* - * Allocate and set up cmmu entry for the smallput interrupt page. - * The exportseg lock is not needed because segment is not yet visible to - * other threads. - */ -static int -setup_smallput_interrupt(exportseg_t *exportseg, boolean_t sleep) -{ - wrsm_network_t *network = exportseg->network; - unsigned num_tuples; - int err; - int flags; - - DPRINTF(DBG_EXPORT, (CE_CONT, "setup smallput interrupt\n")); - - /* - * Set up an interrupt page for small puts. Allocate a CMMU entry, - * then create a receive queue. - */ - if ((err = wrsm_cmmu_alloc(network, CMMU_PAGE_SIZE_SMALL, 1, - &(exportseg->small_put_intr.tuple), &num_tuples, sleep)) != - WRSM_SUCCESS) { - ASSERT(err != ENOSPC); - return (RSMERR_INSUFFICIENT_RESOURCES); - - } - ASSERT(exportseg->small_put_intr.tuple->ncslice == - network->nodes[network->cnodeid]->config->comm_ncslice); - - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "smallput interrupt: index %d\n", - exportseg->small_put_intr.tuple->index)); - - - /* - * wrsm_intr_create_recvq() sets up the cmmu entry - identified by - * the passed in cmmu index. Create the recvq with the invalid - * flag set, and sleep waiting for resources if the caller set - * the sleep flag. - */ - flags = WRSM_CREATE_RECVQ_INVALID; - if (sleep) { - flags |= WRSM_CREATE_RECVQ_SLEEP; - } - err = wrsm_intr_create_recvq(network, - WRSM_SMPUT_INTR_TYPE, - WRSM_SMPUT_PACKETRING_SIZE, - exportseg->small_put_intr.tuple->index, - &(exportseg->small_put_intr.recvq), - 0, /* from_node - N/A for memsegs */ - exportseg, - flags); - if (err != WRSM_SUCCESS) { - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "smallput interrupt: " - "freeing index %d\n", - exportseg->small_put_intr.tuple->index)); - - wrsm_cmmu_free(network, 1, exportseg->small_put_intr.tuple); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - - DPRINTF(DBG_EXPORT, (CE_CONT, "small put recvq 0x%p\n", - (void *)exportseg->small_put_intr.recvq)); - - return (RSM_SUCCESS); -} - -/* - * Invalidate and remove cmmu entry for the smallput interrupt page. - */ -static void -teardown_smallput_interrupt(exportseg_t *exportseg) -{ - wrsm_network_t *network = exportseg->network; - - /* - * Release the small put interrupt page recvq - * and free the cmmu entry. - */ - wrsm_intr_destroy_recvq(network, - exportseg->small_put_intr.recvq); - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "teardown_smallput interrupt: " - "freeing index %d\n", - exportseg->small_put_intr.tuple->index)); - wrsm_cmmu_free(network, 1, exportseg->small_put_intr.tuple); -} - - - -/* - * Allocate and set up cmmu entry for the barrier page. - * The exportseg lock is not needed because segment is not yet visible to - * other threads. - */ -static int -setup_barrier_page(exportseg_t *exportseg, boolean_t sleep) -{ - wrsm_network_t *network = exportseg->network; - unsigned num_tuples; - caddr_t aligned_vaddr; - wrsm_cmmu_t cmmu; - pfn_t pfn; - /* LINTED: E_FUNC_SET_NOT_USED */ - int err; - - DPRINTF(DBG_EXPORT, (CE_CONT, "setup barrier page\n")); - - /* - * Set up a barrier page: allocate a page of memory, allocate a - * cmmu entry, and point the cmmu entry at the memory page. - */ - - /* - * Need an aligned page, so allocate 2 pages. - */ - exportseg->barrier_page.vaddr = wrsm_alloc(MMU_PAGESIZE * 2, VM_SLEEP); - bzero(exportseg->barrier_page.vaddr, (MMU_PAGESIZE * 2)); - - if ((err = wrsm_cmmu_alloc(network, CMMU_PAGE_SIZE_SMALL, 1, - &(exportseg->barrier_page.tuple), &num_tuples, sleep)) != - WRSM_SUCCESS) { - ASSERT(err != ENOSPC); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - ASSERT(exportseg->barrier_page.tuple->ncslice == - network->nodes[network->cnodeid]->config->comm_ncslice); - - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "setup_barrier interrupt: " - "index %d\n", - exportseg->barrier_page.tuple->index)); - - cmmu.entry_0.val = 0; - cmmu.entry_0.bit.count_enable = B_FALSE; - cmmu.entry_0.bit.large_page = B_FALSE; - cmmu.entry_0.bit.user_err = B_FALSE; - cmmu.entry_0.bit.writable = B_TRUE; - cmmu.entry_0.bit.from_all = B_TRUE; - cmmu.entry_0.bit.from_node = 255; - cmmu.entry_0.bit.valid = B_TRUE; - cmmu.entry_0.bit.type = CMMU_TYPE_CACHEABLE; - - cmmu.entry_1.val = 0; - aligned_vaddr = (caddr_t) - ((uint64_t)((caddr_t)exportseg->barrier_page.vaddr + - MMU_PAGEOFFSET) & (uint64_t)MMU_PAGEMASK); - pfn = hat_getpfnum(kas.a_hat, aligned_vaddr); - cmmu.entry_1.addr.lpa_page = pfn; - - DPRINTF(DBG_EXPORT, (CE_CONT, "setup barrier cmmu entry to " - "point to paddr 0x%lx (pfn 0x%lx)\n", va_to_pa(aligned_vaddr), - pfn)); - - wrsm_cmmu_update(network, &cmmu, exportseg->barrier_page.tuple->index, - CMMU_UPDATE_ALL); - - return (RSM_SUCCESS); -} - -/* - * Invalidate and remove cmmu entry for the barrier page. - */ -static void -teardown_barrier_page(exportseg_t *exportseg) -{ - wrsm_network_t *network = exportseg->network; - wrsm_cmmu_t cmmu; - - /* - * Invalidate and free barrier page cmmu entry, and free the - * barrier page memory. - */ - cmmu.entry_0.bit.valid = B_FALSE; - wrsm_cmmu_update(network, &cmmu, exportseg->barrier_page.tuple->index, - CMMU_UPDATE_VALID); - DPRINTF(DBG_EXPORT_EXTRA, (CE_CONT, "teardown_barrier interrupt: " - "freeing index %d\n", - exportseg->barrier_page.tuple->index)); - wrsm_cmmu_free(network, 1, exportseg->barrier_page.tuple); - wrsm_free(exportseg->barrier_page.vaddr, MMU_PAGESIZE * 2); -} - - - - -/* - * Free exportsegs when network is being removed. Will only happen - * if client does a release_controller without first releasing - * exported segments. - */ -void -wrsm_free_exportsegs(wrsm_network_t *network) -{ - exportseg_t *exportseg; - exportseg_t **exportsegp; - int i; - - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsm_free_exportseg: ctlr %d\n", - network->rsm_ctlr_id)); - - mutex_enter(&network->lock); - if (network->memseg->export_count == 0) { - mutex_exit(&network->lock); - return; - } - - mutex_enter(&all_exportsegs_lock); - for (i = 0; i < WRSM_SEGID_HASH_SIZE; i++) { - exportsegp = &(all_exportsegs_hash[i]); - while (*exportsegp != NULL) { - exportseg = *exportsegp; - if (exportseg->network == network) { - /* - * remove exportseg from all_exportsegs_hash - * and destroy it - */ - *exportsegp = exportseg->all_next; - mutex_destroy(&exportseg->lock); - if (exportseg->size > 0) { - teardown_segment_memory(exportseg); - teardown_smallput_interrupt(exportseg); - teardown_barrier_page(exportseg); - } - kmem_free(exportseg, sizeof (exportseg_t)); - ASSERT(network->memseg->export_count > 0); - network->memseg->export_count--; - } else { - exportsegp = &((*exportsegp)->all_next); - } - } - } - mutex_exit(&all_exportsegs_lock); -#ifdef DEBUG - if (network->memseg->export_count > 0) { - DPRINTF(DBG_WARN, (CE_WARN, "wrsm_free_exportseg: network " - "exportseg count %d after exportseg cleanup\n", - network->memseg->export_count)); - } -#endif - mutex_exit(&network->lock); -} - - - -/* - * - * RSMPI entry points - * - */ - - -/* ARGSUSED */ -int -wrsmrsm_seg_create(rsm_controller_handle_t controller, - rsm_memseg_export_handle_t *memsegp, - size_t size, uint_t flags, rsm_memory_local_t *memory, - rsm_resource_callback_t callback, - rsm_resource_callback_arg_t callback_arg) -{ - wrsm_network_t *network = (wrsm_network_t *)controller; - exportseg_t *exportseg; - int err; - int i; - int index; - boolean_t sleep = B_FALSE; - - - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsmrsm_seg_create(ctlr %d)\n", - network->rsm_ctlr_id)); - - if (callback != RSM_RESOURCE_SLEEP && - callback != RSM_RESOURCE_DONTWAIT) { - /* we don't support callbacks */ - return (RSMERR_CALLBACKS_NOT_SUPPORTED); - } - - if (callback == RSM_RESOURCE_SLEEP) - sleep = B_TRUE; - - if ((size & MMU_PAGEOFFSET) != 0) { - /* size must be full pages */ - DPRINTF(DBG_WARN, (CE_WARN, "seg_create: bad size 0x%lx\n", - size)); - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - /* - * ddi_map() in sun4u's rootnex.c limits us to 4GB of total - * mappable space per segment. - */ - if (size > (uint64_t)UINT_MAX) { - DPRINTF(DBG_WARN, (CE_WARN, "seg_create: bad size 0x%llx\n", - size)); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - - exportseg = kmem_zalloc(sizeof (exportseg_t), KM_SLEEP); - exportseg->network = network; - exportseg->size = size; - exportseg->state = memseg_unpublished; - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsmrsm_seg_create: exportseg 0x%p " - "(8k) size 0x%lx\n", (void *)exportseg, exportseg->size)); - - if (exportseg->size > 0) { - - if ((err = setup_segment_memory(exportseg, flags, memory, - sleep)) != RSM_SUCCESS) { - kmem_free(exportseg, sizeof (exportseg_t)); - return (err); - } - - if ((err = setup_smallput_interrupt(exportseg, sleep)) - != RSM_SUCCESS) { - teardown_segment_memory(exportseg); - kmem_free(exportseg, sizeof (exportseg_t)); - return (err); - } - - if ((err = setup_barrier_page(exportseg, sleep)) - != RSM_SUCCESS) { - teardown_segment_memory(exportseg); - teardown_smallput_interrupt(exportseg); - kmem_free(exportseg, sizeof (exportseg_t)); - return (err); - } - } - - mutex_init(&exportseg->lock, NULL, MUTEX_DRIVER, NULL); - exportseg->valid = B_TRUE; - - /* save flags */ - if (flags & RSM_ALLOW_UNBIND_REBIND) { - exportseg->allow_rebind = B_TRUE; - } - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - exportseg->nodes[i].perms = RSM_PERM_NONE; - exportseg->nodes[i].actual_perms = RSM_PERM_NONE; - } - - /* - * add exportseg to all_exportsegs_hash - */ - index = WRSM_PTR_HASH_FUNC(exportseg); - mutex_enter(&network->lock); - network->memseg->export_count++; - mutex_exit(&network->lock); - mutex_enter(&all_exportsegs_lock); - exportseg->all_next = all_exportsegs_hash[index]; - all_exportsegs_hash[index] = exportseg; - mutex_exit(&all_exportsegs_lock); - - - *memsegp = (rsm_memseg_export_handle_t)exportseg; - - ASSERT(MUTEX_NOT_HELD(&exportseg->lock)); - return (RSM_SUCCESS); -} - - - - - -int -wrsmrsm_seg_destroy(rsm_memseg_export_handle_t handle) -{ - exportseg_t *exportseg = (exportseg_t *)handle; - exportseg_t **exportsegp; - wrsm_network_t *network; - boolean_t found_exportseg; - int err; - int index; - - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsmrsm_seg_destroy(0x%p)\n", - (void *)exportseg)); - - if ((err = lock_exportseg(exportseg)) != RSM_SUCCESS) { - return (err); - } - - /* - * make sure segment is not published - */ - if (exportseg->state != memseg_unpublished) { - DPRINTF(DBG_EXPORT, - (CE_CONT, "seg_destroy - memseg 0x%p is published " - "with segid %d\n", (void *)exportseg, exportseg->segid)); - mutex_exit(&exportseg->lock); - return (RSMERR_SEG_PUBLISHED); - } - - network = exportseg->network; - - /* - * Remove exportseg from all_exportsegs_hash. exportseg->lock - * can't be held prior to taking all_exportsegs_lock, so mark - * exportseg as invalid until it is actually removed from the hash. - * Searching for exportseg in the hash fails when exportseg->valid - * is B_FALSE. - */ - exportseg->valid = B_FALSE; - mutex_exit(&exportseg->lock); - - index = WRSM_PTR_HASH_FUNC(exportseg); - mutex_enter(&all_exportsegs_lock); - found_exportseg = B_FALSE; - for (exportsegp = &(all_exportsegs_hash[index]); - *exportsegp != NULL; - exportsegp = &((*exportsegp)->all_next)) { - /* make sure no one else got here first */ - if ((*exportsegp == exportseg) && - (exportseg->valid == B_FALSE)) { - *exportsegp = exportseg->all_next; - found_exportseg = B_TRUE; - break; - } - } - mutex_exit(&all_exportsegs_lock); - - if (found_exportseg) { - - mutex_enter(&network->lock); - network->memseg->export_count--; - mutex_exit(&network->lock); - - mutex_destroy(&exportseg->lock); - - if (exportseg->size > 0) { - teardown_segment_memory(exportseg); - teardown_smallput_interrupt(exportseg); - teardown_barrier_page(exportseg); - } - - kmem_free(exportseg, sizeof (exportseg_t)); - } - - return (RSM_SUCCESS); -} - - - -/* ARGSUSED */ -int -wrsmrsm_bind(rsm_memseg_export_handle_t memseg, - off_t offset, - rsm_memory_local_t *memory, - rsm_resource_callback_t callback, - rsm_resource_callback_arg_t callback_arg) -{ - exportseg_t *exportseg = (exportseg_t *)memseg; - size_t nbytes; - struct buf *bp; - page_t *startpp = NULL; - struct as *as = NULL; - void *vaddr = NULL; - int err; - - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsmrsm_bind(0x%p)\n", - (void *)exportseg)); - - if (callback != RSM_RESOURCE_SLEEP && - callback != RSM_RESOURCE_DONTWAIT) { - /* we don't support callbacks */ - return (RSMERR_CALLBACKS_NOT_SUPPORTED); - } - - if (offset & (off_t)MMU_PAGEOFFSET) { - /* can only bind starting at page boundaries */ - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - if ((err = lock_exportseg(exportseg)) != RSM_SUCCESS) { - return (err); - } - - if (memory->ms_type == RSM_MEM_BUF) { - bp = memory->ms_bp; - - ASSERT(bp); - ASSERT(SEMA_HELD(&bp->b_sem)); - - nbytes = bp->b_bcount; - - if (bp->b_flags & B_PAGEIO) { - if (!bp->b_pages) { - mutex_exit(&exportseg->lock); - return (RSMERR_NO_BACKING_MEM); - } else { - startpp = bp->b_pages; - } - } else { - vaddr = (void *)bp->b_un.b_addr; - if (bp->b_flags & B_PHYS) { - if (bp->b_proc == NULL || - (as = bp->b_proc->p_as) == NULL) - as = &kas; - } else { - as = &kas; - } - } - } else if (memory->ms_type == RSM_MEM_VADDR) { - nbytes = memory->ms_length; - as = memory->ms_as; - vaddr = memory->ms_vaddr; - } else { - mutex_exit(&exportseg->lock); - return (RSMERR_BAD_MSTYPE); - } - - if (nbytes + offset > exportseg->size) { - mutex_exit(&exportseg->lock); - return (RSMERR_BAD_LENGTH); - } - - if (nbytes & MMU_PAGEOFFSET) { - mutex_exit(&exportseg->lock); - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - if ((uint64_t)vaddr & MMU_PAGEOFFSET) { - mutex_exit(&exportseg->lock); - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - if (exportseg->size == 0) { - /* don't touch cmmu entries if a 0 length segment */ - mutex_exit(&exportseg->lock); - return (RSM_SUCCESS); - } - - /* - * set up cmmu entries to point at the specified memory - */ - err = set_lpa_fields(exportseg, offset, nbytes, as, vaddr, - startpp); - - mutex_exit(&exportseg->lock); - return (err); -} - - - -int -wrsmrsm_unbind(rsm_memseg_export_handle_t memseg, off_t offset, - size_t length) -{ - exportseg_t *exportseg = (exportseg_t *)memseg; - int err; - - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsmrsm_unbind(0x%p)\n", - (void *)exportseg)); - - if (offset & MMU_PAGEOFFSET) { - /* can only unbind starting at page boundaries */ - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - if (length & MMU_PAGEOFFSET) { - /* can only unbind page aligned regions */ - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - if ((err = lock_exportseg(exportseg)) != RSM_SUCCESS) { - return (err); - } - - if (!exportseg->allow_rebind) { - mutex_exit(&exportseg->lock); - return (RSMERR_UNBIND_REBIND_NOT_ALLOWED); - } - - if (offset + length > exportseg->size) { - mutex_exit(&exportseg->lock); - return (RSMERR_BAD_LENGTH); - } - - if (exportseg->size == 0) { - /* don't touch cmmu entries if a 0 length segment */ - mutex_exit(&exportseg->lock); - return (RSM_SUCCESS); - } - - /* - * modify cmmu entries to no longer point to this memory - */ - err = clear_lpa_fields(exportseg, offset, length, B_TRUE); - mutex_exit(&exportseg->lock); - return (err); -} - - -/* ARGSUSED */ -int -wrsmrsm_rebind(rsm_memseg_export_handle_t memseg, off_t offset, - rsm_memory_local_t *memory, rsm_resource_callback_t callback, - rsm_resource_callback_arg_t callback_arg) -{ - exportseg_t *exportseg = (exportseg_t *)memseg; - size_t nbytes; - struct buf *bp; - page_t *startpp = NULL; - struct as *as = NULL; - void *vaddr = NULL; - int err; - - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsmrsm_rebind(0x%p)\n", - (void *)exportseg)); - - if (callback != RSM_RESOURCE_SLEEP && - callback != RSM_RESOURCE_DONTWAIT) { - /* we don't support callbacks */ - return (RSMERR_CALLBACKS_NOT_SUPPORTED); - } - - if (offset & MMU_PAGEOFFSET) { - /* can only rebind starting at page boundaries */ - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - if ((err = lock_exportseg(exportseg)) != RSM_SUCCESS) { - return (err); - } - - if (!exportseg->allow_rebind) { - mutex_exit(&exportseg->lock); - return (RSMERR_UNBIND_REBIND_NOT_ALLOWED); - } - - if (memory->ms_type == RSM_MEM_BUF) { - bp = memory->ms_bp; - - ASSERT(bp); - ASSERT(SEMA_HELD(&bp->b_sem)); - - nbytes = bp->b_bcount; - - if (bp->b_flags & B_PAGEIO) { - if (!bp->b_pages) { - mutex_exit(&exportseg->lock); - return (RSMERR_NO_BACKING_MEM); - } else { - startpp = bp->b_pages; - } - } else { - vaddr = (void *)bp->b_un.b_addr; - if (bp->b_flags & B_PHYS) { - if (bp->b_proc == NULL || - (as = bp->b_proc->p_as) == NULL) - as = &kas; - } else { - as = &kas; - } - } - - } else if (memory->ms_type == RSM_MEM_VADDR) { - nbytes = memory->ms_length; - as = memory->ms_as; - vaddr = memory->ms_vaddr; - } else { - mutex_exit(&exportseg->lock); - return (RSMERR_BAD_MSTYPE); - } - - if (nbytes + offset > exportseg->size) { - mutex_exit(&exportseg->lock); - return (RSMERR_BAD_LENGTH); - } - - if (nbytes & MMU_PAGEOFFSET) { - mutex_exit(&exportseg->lock); - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - if ((uint64_t)vaddr & MMU_PAGEOFFSET) { - mutex_exit(&exportseg->lock); - return (RSMERR_BAD_MEM_ALIGNMENT); - } - - if (exportseg->size == 0) { - /* don't touch cmmu entries if a 0 length segment */ - mutex_exit(&exportseg->lock); - return (RSM_SUCCESS); - } - - /* - * modify cmmu entries to remove old mappings - */ - if ((err = clear_lpa_fields(exportseg, offset, nbytes, B_FALSE)) != - WRSM_SUCCESS) { - mutex_exit(&exportseg->lock); - return (err); - } - - /* - * modify cmmu entries to point to new memory - */ - err = set_lpa_fields(exportseg, offset, nbytes, as, vaddr, - startpp); - - mutex_exit(&exportseg->lock); - return (err); -} - - -/* ARGSUSED */ -int -wrsmrsm_publish(rsm_memseg_export_handle_t memseg, - rsm_access_entry_t access_list[], - uint_t access_list_length, - rsm_memseg_id_t segid, - rsm_resource_callback_t callback, - rsm_resource_callback_arg_t callback_arg) -{ - exportseg_t *exportseg = (exportseg_t *)memseg; - int err; - - - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsmrsm_publish(0x%p)\n", - (void *)exportseg)); - - if (callback != RSM_RESOURCE_SLEEP && - callback != RSM_RESOURCE_DONTWAIT) { - /* we don't support callbacks */ - return (RSMERR_CALLBACKS_NOT_SUPPORTED); - } - - if ((err = lock_exportseg(exportseg)) != RSM_SUCCESS) { - return (err); - } - - if ((err = exportseg_set_segid(exportseg, segid)) != RSM_SUCCESS) { - if (err != RSMERR_BAD_SEG_HNDL) { - mutex_exit(&exportseg->lock); - } - return (err); - } - - - if ((err = apply_access_list(exportseg, access_list, - access_list_length)) != RSM_SUCCESS) { - mutex_exit(&exportseg->lock); - exportseg_unset_segid(exportseg, segid); - return (err); - } - - if (exportseg->size > 0) { - enable_smallput_intr_page(exportseg); - } - - mutex_exit(&exportseg->lock); - return (RSM_SUCCESS); -} - - - -int -wrsmrsm_unpublish(rsm_memseg_export_handle_t memseg) -{ - exportseg_t *exportseg = (exportseg_t *)memseg; - rsm_memseg_id_t segid; - wrsm_network_t *network; - int err; - int i; - int disconnects = 0; - int rcv_disconnect; - int num_waiting; - - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsmrsm_unpublish(0x%p)\n", - (void *)exportseg)); - - if ((err = lock_exportseg(exportseg)) != RSM_SUCCESS) { - return (err); - } - segid = exportseg->segid; - - if (exportseg->state == memseg_wait_for_disconnects) { - /* - * segment was already unpublished, but wasn't able - * to complete cleanup. Check whether cleanup has - * now completed. - */ - if (exportseg->wait_for_disconnects) { - mutex_exit(&exportseg->lock); - return (RSMERR_SEG_IN_USE); - } else { - mutex_exit(&exportseg->lock); - exportseg_unset_segid(exportseg, segid); - return (RSM_SUCCESS); - } - } - - if (exportseg->state != memseg_published) { - /* segment is not published */ - mutex_exit(&exportseg->lock); - return (RSMERR_SEG_NOT_PUBLISHED); - } - - network = exportseg->network; - - /* - * Set state to reflect we're doing an unpublish. - * - * update state prior to releasing lock, so subsequent publish or - * republish calls fail. - * - * exportseg->wait_for_disconnects is used as a reference count - * for the export_seg. The segment can't be freed until - * the count goes to zero. - * - * Note that the export segment lock is released prior - * to sending the RPC and thus the export seg state can change. - */ - exportseg->state = memseg_wait_for_disconnects; - exportseg->wait_for_disconnects = 0; - - /* - * Notify all importers that segment is being unpublished. - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - exportseg->nodes[i].allow_import = B_FALSE; - exportseg->nodes[i].perms = RSM_PERM_NONE; - exportseg->nodes[i].actual_perms = RSM_PERM_NONE; - - if (exportseg->nodes[i].inuse) { - exportseg->wait_for_disconnects++; - - mutex_exit(&exportseg->lock); - rcv_disconnect = send_unpublish_msg(network->nodes[i], - exportseg); - /* - * If a session teardown occurs while we are waiting - * for the reponse to the rpc, - * exportseg_sess_teardown(), while holding exportseg - * lock, will decrement wait_for_disconnects, - * decrement network->memseg->export_connected, - * and clear inuse. - * So, if inuse is cleared, we don't want to - * do those actions again here. - */ - mutex_enter(&exportseg->lock); - if (rcv_disconnect && exportseg->nodes[i].inuse) { - disconnects++; - exportseg->wait_for_disconnects--; - exportseg->nodes[i].inuse = B_FALSE; - } - } - } - - /* - * disable ability to write to segment - */ - exportseg->writeable = B_FALSE; - - /* only need to update cmmu entries if size > 0 */ - if (exportseg->size != 0) { - disable_smallput_intr_page(exportseg); - update_cmmu_fields(exportseg, 0, exportseg->size, - memseg_unset_valid); - } - - - /* - * Kernel agent on importer doesn't always release mappings - * (doesn't call rsm_unmap) in a timely fashion. So instead of - * waiting to complete the disconnect or tearing down the session, - * return RSMERR_SEG_IN_USE. - */ - num_waiting = exportseg->wait_for_disconnects; - mutex_exit(&exportseg->lock); - - mutex_enter(&network->lock); - network->memseg->export_connected -= disconnects; - mutex_exit(&network->lock); - - if (num_waiting) { - return (RSMERR_SEG_IN_USE); - } - - exportseg_unset_segid(exportseg, segid); - - return (RSM_SUCCESS); -} - - - - -/* ARGSUSED */ -int -wrsmrsm_republish(rsm_memseg_export_handle_t memseg, - rsm_access_entry_t access_list[], uint_t access_list_length, - rsm_resource_callback_t callback, rsm_resource_callback_arg_t callback_arg) -{ - exportseg_t *exportseg = (exportseg_t *)memseg; - int err; - int i; - - DPRINTF(DBG_EXPORT, (CE_CONT, "wrsmrsm_republish(0x%p)\n", - (void *)exportseg)); - - if (callback != RSM_RESOURCE_SLEEP && - callback != RSM_RESOURCE_DONTWAIT) { - /* we don't support callbacks */ - return (RSMERR_CALLBACKS_NOT_SUPPORTED); - } - - if ((err = lock_exportseg(exportseg)) != RSM_SUCCESS) { - return (err); - } - - if (exportseg->state != memseg_published) { - /* segment is not published */ - mutex_exit(&exportseg->lock); - return (RSMERR_SEG_NOT_PUBLISHED); - } - - /* - * apply new permissions - */ - if ((err = apply_access_list(exportseg, access_list, - access_list_length)) != RSM_SUCCESS) { - mutex_exit(&exportseg->lock); - return (err); - } - - /* - * Notify current importers of permission changes. - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (exportseg->nodes[i].inuse) { - mutex_exit(&exportseg->lock); - send_access_msg(exportseg->network->nodes[i], - exportseg->segid, - exportseg->nodes[i].perms); - mutex_enter(&exportseg->lock); - } - } - - mutex_exit(&exportseg->lock); - return (RSM_SUCCESS); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_memseg_import.c b/usr/src/uts/sun4u/io/wrsm/wrsm_memseg_import.c deleted file mode 100644 index 94adfb7035..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_memseg_import.c +++ /dev/null @@ -1,2449 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file implements the RSMPI import side memory segment functions - * for the Wildcat RSM driver. - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/systm.h> -#include <sys/vmsystm.h> -#include <sys/errno.h> -#include <sys/kmem.h> -#include <vm/seg_kmem.h> -#include <vm/page.h> -#include <sys/ddimapreq.h> -#include <sys/mkdev.h> -#include <sys/ddi.h> -#include <vm/hat_sfmmu.h> -#include <sys/sunddi.h> - -#include <sys/rsm/rsmpi.h> - -#include <sys/wrsm_common.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_session.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_memseg_impl.h> -#include <sys/wrsm_intr.h> -#include <sys/wrsm_plugin.h> - -#ifdef DEBUG -#define DBG_IMPORT 0x004 -#define DBG_IMPORT_EXTRA 0x040 -#define DBG_WARN 0x100 - -static uint_t wrsm_import_memseg_debug = DBG_WARN; - -#define DPRINTF(a, b) { if (wrsm_import_memseg_debug & a) wrsmdprintf b; } - -#else /* DEBUG */ -#define DPRINTF(a, b) { } -#endif /* DEBUG */ - - -/* - * lock hierarchy: - * network->lock - * all_importsegs_lock - * node->memseg->lock - * importseg->rw_lock - * iseginfo->lock - * iseginfo->network->errorpage_lock - * - * Note: it is always safe to take all_importsegs_lock. - * It is also safe to take network->lock: the network must - * unregister (unregister_controller), which it can't do - * until clients all release the network (release_controller). - * If a client accesses these functions after doing a release - * controller, all bets are off. - */ - - -static importseg_t *all_importsegs_hash[WRSM_PTR_HASH_SIZE]; - - -static void send_disconnect_msg(wrsm_node_t *node, iseginfo_t *iseginfo); - -static off_t next_smallput_stride = NULL; - - -/* - * Find iseginfo in exporting node's hash using segid. - */ -static iseginfo_t * -segid_to_iseginfo(wrsm_node_t *node, rsm_memseg_id_t segid) -{ - iseginfo_t *iseginfo; - int index; - - ASSERT(MUTEX_HELD(&node->memseg->lock)); - - index = WRSM_SEGID_HASH_FUNC(segid); - ASSERT(index < WRSM_SEGID_HASH_SIZE); - iseginfo = node->memseg->iseginfo_hash[index]; - DPRINTF(DBG_IMPORT_EXTRA, (CE_CONT, "node %d iseginfo_hash[%d]\n", - node->config->cnodeid, index)); - while (iseginfo) { - DPRINTF(DBG_IMPORT_EXTRA, (CE_CONT, "seg 0x%p segid %d\n", - (void *)iseginfo, iseginfo->segid)); - if (iseginfo->segid == segid) { - return (iseginfo); - } - iseginfo = iseginfo->segid_next; - } - return (NULL); -} - - -/* - * Create a new iseginfo structure, add to hash, lock it. - * - * If in the middle of tearing down the session to this node, return - * a null iseginfo. - */ -static int -new_iseginfo(wrsm_network_t *network, cnodeid_t cnodeid, - rsm_memseg_id_t segid, iseginfo_t **iseginfop, boolean_t *new) -{ - iseginfo_t *iseginfo, *oseginfo; - wrsm_node_t *node; - int index; - - /* allocate memory from our wrsm_arena and zero it */ - iseginfo = wrsm_alloc(sizeof (iseginfo_t), VM_SLEEP); - bzero(iseginfo, sizeof (iseginfo_t)); - - iseginfo->segid = segid; - iseginfo->send_disconnect = B_TRUE; - mutex_init(&iseginfo->lock, NULL, MUTEX_DRIVER, NULL); - - mutex_enter(&network->lock); - node = network->nodes[cnodeid]; - if (node == NULL) { - /* invalid node */ - mutex_exit(&network->lock); - mutex_destroy(&iseginfo->lock); - wrsm_free(iseginfo, sizeof (iseginfo_t)); - return (RSMERR_UNKNOWN_RSM_ADDR); - } - mutex_enter(&node->memseg->lock); - mutex_exit(&network->lock); - - iseginfo->cnodeid = node->config->cnodeid; - iseginfo->network = network; - - /* - * add to node's iseginfo_hash - */ - - if (node->memseg->removing_session) { - /* - * can't connect to a segment while the exporting - * node's session is in the process of being removed - */ - mutex_exit(&node->memseg->lock); - mutex_destroy(&iseginfo->lock); - wrsm_free(iseginfo, sizeof (iseginfo_t)); - DPRINTF(DBG_IMPORT, (CE_CONT, "new_iseginfo: " - "node %d is removing_session; wait_for_unmap %d\n", - node->config->cnodeid, node->memseg->wait_for_unmaps)); - return (RSMERR_CONN_ABORTED); - } - - oseginfo = segid_to_iseginfo(node, segid); - if (oseginfo) { - mutex_enter(&oseginfo->lock); - ASSERT(oseginfo->network->nodes[oseginfo->cnodeid] == - node); - - if (!oseginfo->unpublished) { - /* - * valid iseginfo already exists - return - * this segment locked - */ - mutex_exit(&node->memseg->lock); - mutex_destroy(&iseginfo->lock); - wrsm_free(iseginfo, sizeof (iseginfo_t)); - *iseginfop = oseginfo; - *new = B_FALSE; - return (WRSM_SUCCESS); - } else { - /* - * old iseginfo no longer valid -- can't connect to - * this segment id exported by this node until the - * old one has been cleaned up. (This could take a - * while if clients have mappings they aren't - * releasing.) - */ - - mutex_exit(&oseginfo->lock); - mutex_exit(&node->memseg->lock); - mutex_destroy(&iseginfo->lock); - wrsm_free(iseginfo, sizeof (iseginfo_t)); - - DPRINTF(DBG_IMPORT, (CE_CONT, "new_iseginfo: " - "iseginfo %d is unpublished\n", iseginfo->segid)); - return (RSMERR_CONN_ABORTED); - } - } - - /* - * new iseginfo - add to node's hash - */ - index = WRSM_SEGID_HASH_FUNC(segid); - mutex_enter(&iseginfo->lock); - iseginfo->segid_next = node->memseg->iseginfo_hash[index]; - node->memseg->iseginfo_hash[index] = iseginfo; - mutex_exit(&node->memseg->lock); - - *iseginfop = iseginfo; - *new = B_TRUE; - return (WRSM_SUCCESS); -} - - - -/* - * Remove iseginfo structure from exporting node's hash. Clean up no - * longer valid mapping information in iseginfo. - */ -static void -remove_iseginfo(iseginfo_t *iseginfo) -{ - wrsm_node_t *node = iseginfo->network->nodes[iseginfo->cnodeid]; - iseginfo_t **isinfop; - int index; - - DPRINTF(DBG_IMPORT_EXTRA, (CE_CONT, "ctlr %d: remove_iseginfo() " - "seg 0x%p segid %d node %d\n", node->network->rsm_ctlr_id, - (void *)iseginfo, iseginfo->segid, node->config->cnodeid)); - - ASSERT(MUTEX_HELD(&iseginfo->lock)); - ASSERT(node); - ASSERT(MUTEX_HELD(&node->memseg->lock)); - - /* - * if session was terminated, other side no longer expects - * a disconnect message - */ - if (iseginfo->send_disconnect == B_TRUE) { - send_disconnect_msg(node, iseginfo); - } - - /* - * remove iseginfo from node's hash - */ - - index = WRSM_SEGID_HASH_FUNC(iseginfo->segid); - ASSERT(index < WRSM_SEGID_HASH_SIZE); - isinfop = &(node->memseg->iseginfo_hash[index]); - - /* look for iseginfo in hash */ - while (*isinfop != NULL && *isinfop != iseginfo) { - isinfop = &((*isinfop)->segid_next); - } - - if (*isinfop) { - /* found iseginfo in hash; now remove it */ - *isinfop = iseginfo->segid_next; -#ifdef DEBUG - } else { - /* didn't find iseginfo in hash - should never happen */ - DPRINTF(DBG_WARN, (CE_WARN, - "iseginfo 0x%p (dev_t %d) not in hash table", - (void *)iseginfo, iseginfo->segid)); -#endif - } - - /* - * release resources used by iseginfo - */ - if (iseginfo->seg_tuples) { - kmem_free(iseginfo->seg_tuples, - iseginfo->num_seg_tuples * sizeof (import_ncslice_t)); - kmem_free(iseginfo->pfns, - iseginfo->num_seg_tuples * sizeof (pfn_t)); - } -} - -static void -remove_and_destroy_iseginfo(iseginfo_t *iseginfo) -{ - ASSERT(iseginfo->importsegs == NULL); - remove_iseginfo(iseginfo); - mutex_exit(&iseginfo->lock); - mutex_destroy(&iseginfo->lock); - wrsm_free(iseginfo, sizeof (iseginfo_t)); -} - - -/* - * Find an iseginfo with specified segid in exporting node's iseginfo hash. - * Lock both the node and iseginfo (if iseginfo is found). - */ -static iseginfo_t * -lock_node_and_iseginfo(wrsm_node_t *node, rsm_memseg_id_t segid) -{ - iseginfo_t *iseginfo; - - DPRINTF(DBG_IMPORT_EXTRA, (CE_CONT, "ctlr %d: lock_node_and_iseginfo() " - "segid %d node %d\n", node->network->rsm_ctlr_id, - segid, node->config->cnodeid)); - - mutex_enter(&node->memseg->lock); - iseginfo = segid_to_iseginfo(node, segid); - if (iseginfo) { - mutex_enter(&iseginfo->lock); - if (iseginfo->unpublished) { - mutex_exit(&iseginfo->lock); - iseginfo = NULL; - } - } - if (!iseginfo) { - mutex_exit(&node->memseg->lock); - } - return (iseginfo); -} - - -/* - * Find an unpublished iseginfo with specified segid in exporting node's - * iseginfo hash. Lock both the node and iseginfo (if iseginfo is found). - */ -static iseginfo_t * -lock_node_and_unpublished_iseginfo(wrsm_node_t *node, - rsm_memseg_id_t segid) -{ - iseginfo_t *iseginfo; - - DPRINTF(DBG_IMPORT_EXTRA, (CE_CONT, - "ctlr %d: lock_node_and_unpublished_iseginfo() " - "segid %d node %d\n", node->network->rsm_ctlr_id, - segid, node->config->cnodeid)); - - mutex_enter(&node->memseg->lock); - iseginfo = segid_to_iseginfo(node, segid); - if (iseginfo) { - mutex_enter(&iseginfo->lock); - if (!iseginfo->unpublished) { - mutex_exit(&iseginfo->lock); - iseginfo = NULL; - } - } - if (!iseginfo) { - mutex_exit(&node->memseg->lock); - } - return (iseginfo); -} - - - -/* - * Find an iseginfo with specified segid in exporting node's iseginfo hash - * and lock it. - */ -static iseginfo_t * -find_and_lock_iseginfo(wrsm_node_t *node, rsm_memseg_id_t segid) -{ - iseginfo_t *iseginfo; - - iseginfo = lock_node_and_iseginfo(node, segid); - if (iseginfo) { - mutex_exit(&node->memseg->lock); - } - return (iseginfo); -} - - - - - -/* - * Make sure this importseg is still in all_importsegs_hash and still valid - * (not being destroyed). - */ -int -wrsm_lock_importseg(importseg_t *importseg, krw_t rw) -{ - importseg_t *impsg; - int err = RSMERR_BAD_SEG_HNDL; - int index; - - index = WRSM_PTR_HASH_FUNC(importseg); - ASSERT(index < WRSM_PTR_HASH_SIZE); - - mutex_enter(&all_importsegs_lock); - impsg = all_importsegs_hash[index]; - while (impsg) { - if (impsg == importseg) { - rw_enter(&importseg->rw_lock, rw); - err = RSM_SUCCESS; - break; - } - impsg = impsg->all_next; - } - mutex_exit(&all_importsegs_lock); - - /* - * make sure importseg is not currently being removed - */ - if (!err && importseg->valid == B_FALSE) { - rw_exit(&importseg->rw_lock); - err = RSMERR_BAD_SEG_HNDL; - } -#ifdef DEBUG - if (err) { - DPRINTF(DBG_IMPORT, (CE_CONT, "lock_importseg - " - "invalid memseg 0x%p\n", (void *)importseg)); - } -#endif - return (err); -} - - - -/* - * Remove kernel mapping to segment. - */ -static void -release_segment_mapping(iseginfo_t *iseginfo) -{ - caddr_t kaddr; - size_t size; - - ASSERT(MUTEX_HELD(&iseginfo->lock)); - - if (iseginfo->size == 0) - return; - - if (iseginfo->kernel_mapping.seg) { - kaddr = iseginfo->kernel_mapping.seg; - size = iseginfo->size; - DPRINTF(DBG_IMPORT, (CE_CONT, "hat_unload(kas kaddr 0x%p " - "size 0x%lx paddr 0x%lx", (void *)kaddr, size, - va_to_pa((void *)kaddr))); - hat_unload(kas.a_hat, kaddr, size, HAT_UNLOAD_UNLOCK); - DPRINTF(DBG_IMPORT, (CE_CONT, "vmem_free(kaddr 0x%p " - "size 0x%lx)", (void *)kaddr, size)); - wrsm_free(kaddr, size); - iseginfo->kernel_mapping.seg = NULL; - } -} - - - - - -/* - * Remove kernel mappings to barrier page and small put interrupt page. - */ -static void -release_kernel_mappings(iseginfo_t *iseginfo) -{ - int i; - wrsm_network_t *network = iseginfo->network; - - ASSERT(MUTEX_HELD(&iseginfo->lock)); - - DPRINTF(DBG_IMPORT, (CE_CONT, "release_kernel_mappings() iseginfo %d\n", - iseginfo->segid)); - - if (iseginfo->size == 0) - return; - - /* - * release mapping to barrier page - */ - if (iseginfo->kernel_mapping.barrier_page) { - DPRINTF(DBG_IMPORT, (CE_CONT, "ddi_unmap_regs(kaddr 0x%p " - "size 0x%x", (void *)iseginfo->kernel_mapping.barrier_page, - MMU_PAGESIZE)); - ddi_unmap_regs(wrsm_ncslice_dip, - iseginfo->barrier_tuple.ncslice, - &iseginfo->kernel_mapping.barrier_page, - iseginfo->barrier_tuple.ncslice_offset, - MMU_PAGESIZE); - iseginfo->kernel_mapping.barrier_page = NULL; - } - - /* - * release mapping to small put interrupt page - */ - if (iseginfo->kernel_mapping.small_put_intr) { - ddi_unmap_regs(wrsm_ncslice_dip, - iseginfo->small_put_tuple.ncslice, - &iseginfo->kernel_mapping.small_put_intr, - iseginfo->small_put_tuple.ncslice_offset, - MMU_PAGESIZE); - iseginfo->kernel_mapping.small_put_intr = NULL; - } - - if (iseginfo->errorpages) { - for (i = 0; i < iseginfo->errorpages; i++) { - wrsm_cmmu_free(network, 1, - iseginfo->errorpage_info[i].tuple); - } - kmem_free(iseginfo->errorpage_info, - iseginfo->errorpages * sizeof (wrsm_errorpage_t)); - iseginfo->errorpages = 0; - } else { - mutex_enter(&network->errorpage_lock); - network->errorpage_mappings -= - ((iseginfo->size >> MMU_PAGESHIFT) + 2); - mutex_exit(&network->errorpage_lock); - } -} - -/* - * Create kernel mapping to segment. - */ -int -create_segment_mapping(iseginfo_t *iseginfo) -{ - caddr_t kaddr, kaddr8k; - uint_t seg_perms; - ddi_map_req_t mr; - import_ncslice_t *map_tuple; - int i; - int err; - size_t len8k, accumulated_len = 0; - pfn_t pfn8k; - - DPRINTF(DBG_IMPORT, (CE_CONT, "create_segment_mapping() iseginfo %d\n", - iseginfo->segid)); - - ASSERT(MUTEX_HELD(&iseginfo->lock)); - - if (iseginfo->size == 0) - return (WRSM_SUCCESS); - - /* - * This is not DDI compatible, but there is no DDI compatible way - * of mapping in a segment contiguously in the kernel virtual - * address space if it is backed by multiple physically - * discontiguous regions of "regspec" memory. - */ - - /* - * Allocate a large enough kernel virtual memory region for this - * segment - */ - ASSERT((iseginfo->size & MMU_PAGEOFFSET) == 0); - ASSERT(iseginfo->size > 0); - DPRINTF(DBG_IMPORT, (CE_CONT, "vmem_alloc(size 0x%lx)", - iseginfo->size)); - /* allocate memory from our wrsm_arena */ - kaddr = wrsm_alloc(iseginfo->size, VM_NOSLEEP); - if (kaddr == NULL) { - /* - * not enough space in kernel virtual memory to map - * this segment - */ - return (RSMERR_INSUFFICIENT_RESOURCES); - } - iseginfo->kernel_mapping.seg = kaddr; - - /* LINTED: E_PRECEDENCE_CONFUSION */ - if ((iseginfo->perms == RSM_PERM_RDWR) || - (iseginfo->perms == RSM_PERM_WRITE)) { - seg_perms = PROT_READ | PROT_WRITE; - } else { - seg_perms = PROT_READ; - } - - mr.map_op = DDI_MO_MAP_LOCKED; - mr.map_type = DDI_MT_RNUMBER; - mr.map_prot = seg_perms; - mr.map_flags = DDI_MF_DEVICE_MAPPING; - mr.map_handlep = NULL; - mr.map_vers = DDI_MAP_VERSION; - - for (i = 0; i < iseginfo->num_seg_tuples; i++) { - map_tuple = &(iseginfo->seg_tuples[i]); - mr.map_obj.rnumber = map_tuple->ncslice; - - /* - * get the physical address for this ncslice - */ - ASSERT((map_tuple->len & MMU_PAGEOFFSET) == 0); - accumulated_len += map_tuple->len; - ASSERT(accumulated_len <= iseginfo->size); - err = ddi_map(wrsm_ncslice_dip, &mr, map_tuple->ncslice_offset, - map_tuple->len, (caddr_t *)&(iseginfo->pfns[i])); - if (err) { - return (RSMERR_INSUFFICIENT_RESOURCES); - } - - /* - * set up mapping to segment - */ - /* - * Force 8k tte entries to be used, so that the error - * mapping (which also uses 8k pages) will work without - * trouble. (HAT_LOAD_REMAP doesn't handle switching - * from other page sizes to 8k pages.) - */ - kaddr8k = kaddr; - pfn8k = iseginfo->pfns[i]; - for (len8k = 0; len8k < map_tuple->len; len8k += MMU_PAGESIZE) { - DPRINTF(DBG_IMPORT_EXTRA, (CE_CONT, - "hat_devload(kas kaddr " - "0x%p size 0x%x paddr 0x%lx perms 0x%x flags 0x%x", - (void *)kaddr8k, MMU_PAGESIZE, - pfn8k, seg_perms | MEMSEG_DEVLOAD_ATTRS, - HAT_LOAD_LOCK)); - hat_devload(kas.a_hat, kaddr8k, MMU_PAGESIZE, - pfn8k, seg_perms | MEMSEG_DEVLOAD_ATTRS, - HAT_LOAD_LOCK); - kaddr8k += MMU_PAGESIZE; - pfn8k += (MMU_PAGESIZE >> MMU_PAGESHIFT); - } - - DPRINTF(DBG_IMPORT, (CE_CONT, "mapped seg offset 0x%lx " - "len 0x%lx to paddr 0x%lx (ncslice 0x%x, offset 0x%lx)\n", - map_tuple->seg_offset, - map_tuple->len, - (iseginfo->pfns[i] << MMU_PAGESHIFT), - map_tuple->ncslice, - map_tuple->ncslice_offset)); - - kaddr += map_tuple->len; - } - - return (RSM_SUCCESS); -} - - - - -/* - * Create kernel mappings to barrier page and small put interrupt page. - */ -static int -create_kernel_mappings(iseginfo_t *iseginfo) -{ - int err; - int i; - int pages; - wrsm_network_t *network = iseginfo->network; - - DPRINTF(DBG_IMPORT, (CE_CONT, "create_kernel_mappings() iseginfo %d\n", - iseginfo->segid)); - - ASSERT(MUTEX_HELD(&iseginfo->lock)); - - if (iseginfo->size == 0) - return (WRSM_SUCCESS); - - /* - * Reserve mappings to this controller's error page (enough for the - * segment, barrier page and interrupt page). The kernel only - * supports a fixed number of locked mappings from one address - * space to the same physical address, so if can't reserve enough - * mappings, allocate additional error pages (cmmu entries) for - * this segment. - */ - mutex_enter(&network->errorpage_lock); - if ((network->errorpage_mappings + - (iseginfo->size >> MMU_PAGESHIFT) + 2) < MAX_HBLK_LCKCNT) { - network->errorpage_mappings += - ((iseginfo->size >> MMU_PAGESHIFT) + 2); - mutex_exit(&network->errorpage_lock); - } else { - mutex_exit(&network->errorpage_lock); - /* - * Can't set up error mappings using default error page. - * Allocate one or more private error pages for this - * segment. - */ - pages = (iseginfo->size >> MMU_PAGESHIFT) + 2; - iseginfo->errorpages = (pages / MAX_HBLK_LCKCNT) + - ((pages % MAX_HBLK_LCKCNT) ? 1 : 0); - iseginfo->errorpage_info = kmem_zalloc(iseginfo->errorpages * - sizeof (wrsm_errorpage_t), KM_SLEEP); - - for (i = 0; i < iseginfo->errorpages; i++) { - if ((err = wrsm_nc_create_errorpage(network, - &(iseginfo->errorpage_info[i].tuple), - &(iseginfo->errorpage_info[i].pfn), - B_FALSE)) != WRSM_SUCCESS) { - int j; - for (j = 0; j < i; j++) { - wrsm_cmmu_free(network, 1, - iseginfo->errorpage_info[j].tuple); - } - kmem_free(iseginfo->errorpage_info, - iseginfo->errorpages * - sizeof (wrsm_errorpage_t)); - iseginfo->errorpages = 0; - - return (RSMERR_INSUFFICIENT_RESOURCES); - } - } - } - - - /* - * map in the barrier page - */ - err = ddi_map_regs(wrsm_ncslice_dip, - iseginfo->barrier_tuple.ncslice, - &iseginfo->kernel_mapping.barrier_page, - iseginfo->barrier_tuple.ncslice_offset, - MMU_PAGESIZE); - DPRINTF(DBG_IMPORT, (CE_CONT, "kaddr 0x%p = ddi_map_regs(size 0x%x)", - (void *)iseginfo->kernel_mapping.barrier_page, MMU_PAGESIZE)); - if (err) { - release_kernel_mappings(iseginfo); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - DPRINTF(DBG_IMPORT, (CE_CONT, "mapped barrier page " - "to paddr 0x%lx (ncslice 0x%x, offset 0x%lx)\n", - va_to_pa(iseginfo->kernel_mapping.barrier_page), - iseginfo->barrier_tuple.ncslice, - iseginfo->barrier_tuple.ncslice_offset)); - - - /* - * map in the interrupt page - */ - err = ddi_map_regs(wrsm_ncslice_dip, - iseginfo->small_put_tuple.ncslice, - &iseginfo->kernel_mapping.small_put_intr, - iseginfo->small_put_tuple.ncslice_offset, - MMU_PAGESIZE); - DPRINTF(DBG_IMPORT, (CE_CONT, "kaddr 0x%p = ddi_map_regs(size 0x%x)", - (void *)iseginfo->kernel_mapping.small_put_intr, MMU_PAGESIZE)); - if (err) { - release_kernel_mappings(iseginfo); - return (RSMERR_INSUFFICIENT_RESOURCES); - } - - /* - * assign each new segment a different stride in which to do - * small puts. Just one stride is used per segment to simplify - * flushing outstanding smallput interrupts. - */ - iseginfo->kernel_mapping.small_put_offset = - iseginfo->kernel_mapping.small_put_intr + - next_smallput_stride; - next_smallput_stride = - (next_smallput_stride + WCI_CLUSTER_STRIPE_STRIDE) & - WCI_CLUSTER_STRIPE_MASK; - - DPRINTF(DBG_IMPORT, (CE_CONT, "mapped small put page " - "to paddr 0x%lx (ncslice 0x%x, offset 0x%lx)\n", - va_to_pa(iseginfo->kernel_mapping.small_put_intr), - iseginfo->small_put_tuple.ncslice, - iseginfo->small_put_tuple.ncslice_offset)); - - return (WRSM_SUCCESS); -} - - -/* - * Modify kernel mappings to segment, barrier page and small put interrupt - * page so that they all point to the local loopback error page. - */ -static void -error_kernel_mappings(iseginfo_t *iseginfo) -{ - caddr_t kaddr; - wrsm_network_t *network = iseginfo->network; - off_t offset; - uint_t seg_perms; - pfn_t errorpage_pfn; - int i, mappings; - - DPRINTF(DBG_IMPORT, (CE_CONT, "error_kernel_mappings() iseginfo %d\n", - iseginfo->segid)); - - ASSERT(MUTEX_HELD(&iseginfo->lock)); - - if (iseginfo->size == 0) - return; - - /* LINTED: E_PRECEDENCE_CONFUSION */ - if ((iseginfo->perms == RSM_PERM_RDWR) || - (iseginfo->perms == RSM_PERM_WRITE)) { - seg_perms = PROT_READ | PROT_WRITE; - } else { - seg_perms = PROT_READ; - } - - /* - * Change segment mapping (if there is one) to point to loopback - * error page. Mappings to this page were reserved in - * create_kernel_mappings(). - */ - kaddr = iseginfo->kernel_mapping.seg; - mappings = 0; - i = 0; - errorpage_pfn = iseginfo->errorpages ? iseginfo->errorpage_info[0].pfn : - network->errorpage_pfn; - if (kaddr) { - offset = 0; - while (offset < iseginfo->size) { - DPRINTF(DBG_IMPORT_EXTRA, (CE_CONT, - "hat_devload(kas kaddr 0x%p " - "size 0x%x paddr 0x%lx perms 0x%x flags 0x%x", - (void *)kaddr, - MMU_PAGESIZE, - errorpage_pfn, - seg_perms | MEMSEG_DEVLOAD_ATTRS, - HAT_LOAD_REMAP)); - hat_devload(kas.a_hat, - kaddr, - MMU_PAGESIZE, - errorpage_pfn, - seg_perms | MEMSEG_DEVLOAD_ATTRS, - HAT_LOAD_REMAP); - - offset += MMU_PAGESIZE; - kaddr += MMU_PAGESIZE; - mappings++; - if (mappings == MAX_HBLK_LCKCNT) { - /* - * If there are more than MAX_HBLK_LCKCNT - * mappings, we must have allocated private - * error pages for it. - */ - i++; - ASSERT(i < iseginfo->errorpages); - errorpage_pfn = - iseginfo->errorpage_info[i].pfn; - mappings = 0; - } - } - } - - - /* - * change barrier page mapping to loopback error page - */ - if (iseginfo->kernel_mapping.barrier_page) { - DPRINTF(DBG_IMPORT_EXTRA, (CE_CONT, - "hat_devload(kas kaddr 0x%p " - "size 0x%x paddr 0x%lx perms 0x%x flags 0x%x", - (void *)iseginfo->kernel_mapping.barrier_page, - MMU_PAGESIZE, - errorpage_pfn, - PROT_READ | PROT_WRITE | MEMSEG_DEVLOAD_ATTRS, - HAT_LOAD_REMAP)); - hat_devload(kas.a_hat, - iseginfo->kernel_mapping.barrier_page, - MMU_PAGESIZE, - errorpage_pfn, - PROT_READ | PROT_WRITE | MEMSEG_DEVLOAD_ATTRS, - HAT_LOAD_REMAP); - } - - mappings++; - if (mappings == MAX_HBLK_LCKCNT) { - /* - * If there are more than MAX_HBLK_LCKCNT - * mappings, we must have allocated private - * error pages for it. - */ - i++; - ASSERT(i < iseginfo->errorpages); - errorpage_pfn = iseginfo->errorpage_info[i].pfn; - mappings = 0; - } - - /* - * change small put interrupt page mapping to loopback error page - */ - if (iseginfo->kernel_mapping.small_put_intr) { - DPRINTF(DBG_IMPORT_EXTRA, (CE_CONT, - "hat_devload(kas kaddr 0x%p " - "size 0x%x paddr 0x%lx perms 0x%x flags 0x%x", - (void *)iseginfo->kernel_mapping.small_put_intr, - MMU_PAGESIZE, - errorpage_pfn, - PROT_READ | PROT_WRITE | MEMSEG_DEVLOAD_ATTRS, - HAT_LOAD_REMAP)); - hat_devload(kas.a_hat, - iseginfo->kernel_mapping.small_put_intr, - MMU_PAGESIZE, - errorpage_pfn, - PROT_READ | PROT_WRITE | MEMSEG_DEVLOAD_ATTRS, - HAT_LOAD_REMAP); - } -} - - -/* - * Lost access to this iseginfo - tear down mappings and mark - * related importsegs as no longer valid. - */ -static void -lost_iseginfo(iseginfo_t *iseginfo) -{ - importseg_t *importseg; - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: lost_iseginfo() segid %d " - "node %d\n", iseginfo->network->rsm_ctlr_id, - iseginfo->segid, iseginfo->cnodeid)); - - ASSERT(MUTEX_HELD(&iseginfo->lock)); - - /* - * This iseginfo is no longer backed by the remote node's segment, - * so remove it from the remote node's list. However don't free it - * until the last importseg has been freed. - */ - if (iseginfo->unpublished) { - /* already cleaned up after this segment */ - return; - } - - iseginfo->unpublished = B_TRUE; - - if (iseginfo->kernel_users) { - /* change kernel mappings to use loopback error page */ - error_kernel_mappings(iseginfo); - } - - /* - * notify any clients that have done mappings that the - * mappings are no longer valid - */ - for (importseg = iseginfo->importsegs; importseg; - importseg = importseg->iseg_next) { - importseg->unpublished = B_TRUE; - if (importseg->mappings) { - /* - * Callback client to notify them mappings - * are no longer valid. - */ - if (importseg->mapping_callback) { - (*(importseg->mapping_callback))( - importseg->mapping_callback_arg); - } - } - } - - if (iseginfo->wait_for_unmaps == 0) { - /* - * All mappings to segment cleaned up. Segment is no longer - * valid (except for access from remaining importsegs). - */ - remove_iseginfo(iseginfo); - } -} - - - -/* - * Send message to specified node to collect information about segment. - */ -static int -send_connect_msg(wrsm_node_t *node, iseginfo_t *iseginfo) -{ - wrsm_network_t *network = node->network; - wrsm_raw_message_t msgbuf; - wrsm_message_t *msg = (wrsm_message_t *)&msgbuf; - connect_msg_t args; - wrsm_raw_message_t recvmsgbuf; - wrsm_message_t *recvmsg = (wrsm_message_t *)&recvmsgbuf; - connect_resp_t recvargs; - int err = WRSM_SUCCESS; - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: send_connect_msg() " - "node %d\n", network->rsm_ctlr_id, node->config->cnodeid)); - - /* LINTED */ - ASSERT(sizeof (connect_msg_t) <= WRSM_MESSAGE_BODY_SIZE); - - msg->header.message_type = WRSM_MSG_SEGMENT_CONNECT; - args.segid = iseginfo->segid; - - bcopy(&args, &(msg->body), sizeof (args)); - if (wrsm_tl_rpc(network, node->config->cnodeid, msg, recvmsg) - != WRSM_SUCCESS) { - /* - * This node is not responding (message not delivered or - * response not received). (Transport Layer tears down the - * session if there is a message delivery failure). - */ - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - -#ifdef DEBUG - if (wrsm_import_memseg_debug & DBG_IMPORT_EXTRA) { - wrsm_tl_dump_message("CONNECT_RESPONSE: ", recvmsg); - } -#endif - if (recvmsg->header.message_type != - WRSM_MSG_SEGMENT_CONNECT_RESPONSE) { - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - - bcopy(&recvmsg->body, &recvargs, sizeof (recvargs)); - - if (recvargs.err) { - switch (recvargs.err) { - case ENOENT: - err = RSMERR_SEG_NOT_PUBLISHED; - break; - case EACCES: - err = RSMERR_SEG_NOT_PUBLISHED_TO_RSM_ADDR; - break; - default: - err = RSMERR_SEG_NOT_PUBLISHED; - break; - } - return (err); - } - - /* - * save information in iseginfo - */ - iseginfo->perms = recvargs.perms; - iseginfo->size = recvargs.size; - iseginfo->num_seg_tuples = recvargs.num_seg_tuples; - iseginfo->seg_tuples = (import_ncslice_t *)kmem_zalloc( - iseginfo->num_seg_tuples * sizeof (import_ncslice_t), KM_SLEEP); - iseginfo->pfns = (pfn_t *)kmem_zalloc( - iseginfo->num_seg_tuples * sizeof (pfn_t), KM_SLEEP); - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: send_connect_msg() " - "got num_seg_tuples %d size 0x%lx perms 0x%x\n", - network->rsm_ctlr_id, iseginfo->num_seg_tuples, - iseginfo->size, iseginfo->perms)); - - return (WRSM_SUCCESS); -} - - - - -/* - * Send message to specified node to collect small put page mapping - * information for segment. - */ -static int -send_smallputmap_msg(wrsm_node_t *node, iseginfo_t *iseginfo) -{ - wrsm_network_t *network = node->network; - wrsm_raw_message_t msgbuf; - wrsm_message_t *msg = (wrsm_message_t *)&msgbuf; - smallputmap_msg_t args; - wrsm_raw_message_t recvmsgbuf; - wrsm_message_t *recvmsg = (wrsm_message_t *)&recvmsgbuf; - smallputmap_resp_t recvargs; - int err = WRSM_SUCCESS; - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: send_smallputmap_msg() " - "node %d\n", network->rsm_ctlr_id, node->config->cnodeid)); - - /* LINTED */ - ASSERT(sizeof (smallputmap_msg_t) <= WRSM_MESSAGE_BODY_SIZE); - - msg->header.message_type = WRSM_MSG_SEGMENT_SMALLPUTMAP; - args.segid = iseginfo->segid; - - bcopy(&args, &(msg->body), sizeof (args)); - if (wrsm_tl_rpc(network, node->config->cnodeid, msg, recvmsg) - != WRSM_SUCCESS) { - /* - * This node is not responding (message not delivered or - * response not received). (Transport Layer tears down the - * session if there is a message delivery failure). - */ - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - -#ifdef DEBUG - if (wrsm_import_memseg_debug & DBG_IMPORT_EXTRA) - wrsm_tl_dump_message("SMALLPUTMAP_RESPONSE: ", recvmsg); -#endif - if (recvmsg->header.message_type != - WRSM_MSG_SEGMENT_SMALLPUTMAP_RESPONSE) { - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - - bcopy(&recvmsg->body, &recvargs, sizeof (recvargs)); - - if (recvargs.err) { - switch (recvargs.err) { - case ENOENT: - err = RSMERR_SEG_NOT_PUBLISHED; - break; - case EACCES: - err = RSMERR_SEG_NOT_PUBLISHED_TO_RSM_ADDR; - break; - default: - err = RSMERR_SEG_NOT_PUBLISHED; - break; - } - return (err); - } - - /* - * save information in iseginfo - */ - iseginfo->small_put_tuple = recvargs.small_put_tuple; - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: send_smallputmap_msg() " - "got small put intr ncslice %d offset 0x%lx\n", - network->rsm_ctlr_id, iseginfo->small_put_tuple.ncslice, - iseginfo->small_put_tuple.ncslice_offset)); - - return (WRSM_SUCCESS); -} - - - - -/* - * Send message to specified node to collect barrier page mapping - * information for segment. - */ -static int -send_barriermap_msg(wrsm_node_t *node, iseginfo_t *iseginfo) -{ - wrsm_network_t *network = node->network; - wrsm_raw_message_t msgbuf; - wrsm_message_t *msg = (wrsm_message_t *)&msgbuf; - barriermap_msg_t args; - wrsm_raw_message_t recvmsgbuf; - wrsm_message_t *recvmsg = (wrsm_message_t *)&recvmsgbuf; - barriermap_resp_t recvargs; - int err = WRSM_SUCCESS; - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: send_barriermap_msg() " - "node %d\n", network->rsm_ctlr_id, node->config->cnodeid)); - - /* LINTED */ - ASSERT(sizeof (barriermap_msg_t) <= WRSM_MESSAGE_BODY_SIZE); - - msg->header.message_type = WRSM_MSG_SEGMENT_BARRIERMAP; - args.segid = iseginfo->segid; - - bcopy(&args, &(msg->body), sizeof (args)); - if (wrsm_tl_rpc(network, node->config->cnodeid, msg, recvmsg) - != WRSM_SUCCESS) { - /* - * This node is not responding (message not delivered or - * response not received). (Transport Layer tears down the - * session if there is a message delivery failure). - */ - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - -#ifdef DEBUG - if (wrsm_import_memseg_debug & DBG_IMPORT_EXTRA) - wrsm_tl_dump_message("BARRIERMAP_RESPONSE: ", recvmsg); -#endif - if (recvmsg->header.message_type != - WRSM_MSG_SEGMENT_BARRIERMAP_RESPONSE) { - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - - bcopy(&recvmsg->body, &recvargs, sizeof (recvargs)); - - if (recvargs.err) { - switch (recvargs.err) { - case ENOENT: - err = RSMERR_SEG_NOT_PUBLISHED; - break; - case EACCES: - err = RSMERR_SEG_NOT_PUBLISHED_TO_RSM_ADDR; - break; - default: - err = RSMERR_SEG_NOT_PUBLISHED; - break; - } - return (err); - } - - /* - * save information in iseginfo - */ - iseginfo->barrier_tuple = recvargs.barrier_tuple; - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: send_barriermap_msg() " - "got barrier_page ncslice %d offset 0x%lx\n", - network->rsm_ctlr_id, iseginfo->barrier_tuple.ncslice, - iseginfo->barrier_tuple.ncslice_offset)); - - return (WRSM_SUCCESS); -} - - - - - -/* - * Send message to specified node to collect segment mapping information - * for segment. - */ -static int -send_segmap_msg(wrsm_node_t *node, iseginfo_t *iseginfo) -{ - wrsm_raw_message_t msgbuf; - wrsm_message_t *msg = (wrsm_message_t *)&msgbuf; - segmap_msg_t args; - wrsm_raw_message_t recvmsgbuf; - wrsm_message_t *recvmsg = (wrsm_message_t *)&recvmsgbuf; - wrsm_network_t *network = node->network; - segmap_resp_t recvargs; - int err = WRSM_SUCCESS; - int tuple_index; - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: send_segmap_msg() " - "node %d\n", network->rsm_ctlr_id, node->config->cnodeid)); - - /* LINTED */ - ASSERT(sizeof (segmap_msg_t) <= WRSM_MESSAGE_BODY_SIZE); - - msg->header.message_type = WRSM_MSG_SEGMENT_SEGMAP; - args.segid = iseginfo->segid; - - tuple_index = 0; - while (tuple_index < iseginfo->num_seg_tuples) { - - args.tuple_index = tuple_index; - - bcopy(&args, &msg->body, sizeof (args)); - if (wrsm_tl_rpc(network, node->config->cnodeid, msg, recvmsg) - != WRSM_SUCCESS) { - /* - * This node is not responding (message not - * delivered or response not received). (Transport - * Layer tears down the session if there is a - * message delivery failure). - */ - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - -#ifdef DEBUG - if (wrsm_import_memseg_debug & DBG_IMPORT_EXTRA) - wrsm_tl_dump_message("SEGMAP_RESPONSE: ", recvmsg); -#endif - if (recvmsg->header.message_type != - WRSM_MSG_SEGMENT_SEGMAP_RESPONSE) { - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - - bcopy(&recvmsg->body, &recvargs, sizeof (recvargs)); - - if (recvargs.err) { - switch (recvargs.err) { - case ENOENT: - err = RSMERR_SEG_NOT_PUBLISHED; - break; - case EACCES: - /* tab oddly to make cstyle happy */ - err = RSMERR_SEG_NOT_PUBLISHED_TO_RSM_ADDR; - break; - default: - err = RSMERR_SEG_NOT_PUBLISHED; - break; - } - return (err); - } - - if (recvargs.num_tuples > MAP_MSG_TUPLES || - (recvargs.num_tuples + tuple_index) > - iseginfo->num_seg_tuples) { - /* - * number of tuples in map response can't really - * fit in buffer (bad msg?) or doesn't match the - * number we were told to expect in connect response - */ - DPRINTF(DBG_WARN, (CE_WARN, "send_segmap_msg: " - "received %d tuples > max (%d) per message or " - "> expected remaining (%d - %d)\n", - recvargs.num_tuples, (int)MAP_MSG_TUPLES, - iseginfo->num_seg_tuples, tuple_index)); - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - - /* - * save information in iseginfo - */ - bcopy(&(recvargs.tuples), &(iseginfo->seg_tuples[tuple_index]), - recvargs.num_tuples * sizeof (import_ncslice_t)); - - tuple_index += recvargs.num_tuples; - } - - return (WRSM_SUCCESS); -} - - - - - -/* - * Notify exporting node that this segment is no longer being accessed. - */ -static void -send_disconnect_msg(wrsm_node_t *node, iseginfo_t *iseginfo) -{ - wrsm_raw_message_t msgbuf; - wrsm_message_t *msg = (wrsm_message_t *)&msgbuf; - disconnect_msg_t args; - wrsm_network_t *network = node->network; - - ASSERT(iseginfo->send_disconnect); - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: " - "send_disconnect_msg() node %d\n", network->rsm_ctlr_id, - node->config->cnodeid)); - - /* LINTED */ - ASSERT(sizeof (disconnect_msg_t) <= WRSM_MESSAGE_BODY_SIZE); - - msg->header.message_type = WRSM_MSG_SEGMENT_DISCONNECT; - args.segid = iseginfo->segid; - - bcopy(&args, &msg->body, sizeof (args)); - (void) wrsm_tl_dg(network, node->config->cnodeid, msg); -} - - - - - - - -/* - * Segment is no longer being published. Attempt clean up after all - * connections. If there are no mappings to segment, notify sender - * that there are no longer any connections. - */ -void -wrsm_unpublish_msg_evt(void *arg) -{ - wrsm_network_t *network = ((wrsm_memseg_evt_args_t *)arg)->network; - wrsm_message_t *msg = &((wrsm_memseg_evt_args_t *)arg)->msg; - unpublish_msg_t args; -#ifdef DEBUG - cnodeid_t cnodeid = msg->header.source_cnode; -#endif - wrsm_node_t *node = network->nodes[msg->header.source_cnode]; - wrsm_raw_message_t msgbuf; - wrsm_message_t *respmsg = (wrsm_message_t *)&msgbuf; - unpublish_resp_t respargs; - iseginfo_t *iseginfo; - - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: unpublish_msg_evt() " - "node %d\n", network->rsm_ctlr_id, cnodeid)); - - if (node == NULL) { - /* non-existent node */ - return; - } - - if (wrsm_tl_rxhandler_sessionid(network, msg) == B_FALSE) { - /* session must not be valid */ - return; - } - - bcopy(&msg->body, &args, sizeof (args)); - - respmsg->header.message_type = WRSM_MSG_SEGMENT_UNPUBLISH_RESPONSE; - - /* - * does segment exist? - */ - iseginfo = lock_node_and_iseginfo(node, args.segid); - if (iseginfo == NULL || iseginfo->importsegs == NULL) { - /* - * no iseginfo, or no connections to iseginfo - */ - if (iseginfo) { - /* no connections to iseginfo -- free it */ - ASSERT(iseginfo->wait_for_unmaps == 0); - iseginfo->send_disconnect = B_FALSE; - remove_and_destroy_iseginfo(iseginfo); - mutex_exit(&node->memseg->lock); - } - DPRINTF(DBG_IMPORT, (CE_CONT, - "sending WC_DISCONNECTED response\n")); - respargs.status = WC_DISCONNECTED; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - return; - } - - /* - * We have some cleanup work to do. Let the other side - * know we got the message, but aren't finished cleaning up. - */ - DPRINTF(DBG_IMPORT, (CE_CONT, "sending WC_CONNECTED response\n")); - respargs.status = WC_CONNECTED; - bcopy(&respargs, &respmsg->body, sizeof (respargs)); - (void) wrsm_tl_rsp(network, msg, respmsg); - - /* - * Tear down mappings to this iseginfo. Notify remote node - * when all mappings have been torn down. - */ - lost_iseginfo(iseginfo); - - mutex_exit(&node->memseg->lock); - mutex_exit(&iseginfo->lock); - - /* We're done, deallocate our incoming args struct and the message */ - kmem_free(arg, sizeof (wrsm_memseg_evt_args_t)); -} - - - - - -/* - * Remember new permissions for segment. - */ -void -wrsm_access_msg_evt(void *arg) -{ - wrsm_network_t *network = ((wrsm_memseg_evt_args_t *)arg)->network; - wrsm_message_t *msg = &((wrsm_memseg_evt_args_t *)arg)->msg; - access_msg_t args; -#ifdef DEBUG - cnodeid_t cnodeid = msg->header.source_cnode; -#endif - wrsm_node_t *node = network->nodes[msg->header.source_cnode]; - wrsm_raw_message_t msgbuf; - wrsm_message_t *respmsg = (wrsm_message_t *)&msgbuf; - iseginfo_t *iseginfo; - - DPRINTF(DBG_IMPORT, (CE_CONT, "ctlr %d: access_msg_evt() " - "node %d\n", network->rsm_ctlr_id, cnodeid)); - - if (node == NULL) { - /* non-existent node */ - return; - } - - if (wrsm_tl_rxhandler_sessionid(network, msg) == B_FALSE) { - /* session must not be valid */ - return; - } - - bcopy(&msg->body, &args, sizeof (args)); - - /* - * Record new permissions - */ - - iseginfo = find_and_lock_iseginfo(node, args.segid); - - if (iseginfo) { - iseginfo->perms = args.perms; - mutex_exit(&iseginfo->lock); - } - - /* - * send acknowledgement - */ - - respmsg->header.message_type = WRSM_MSG_ACK; - (void) wrsm_tl_rsp(network, msg, respmsg); - - /* We're done, deallocate our incoming args struct and the message */ - kmem_free(arg, sizeof (wrsm_memseg_evt_args_t)); - -} - - - -/* - * Collect information about segmenet from exporting node. Verify that - * it is valid. - */ -static int -iseginfo_fetch_info(wrsm_node_t *node, iseginfo_t *iseginfo) -{ - int err; - int i, last_tuple; - size_t offset; - - ASSERT(MUTEX_HELD(&iseginfo->lock)); - - /* - * collect segment info from exporter - */ - if ((err = send_connect_msg(node, iseginfo)) != WRSM_SUCCESS) { - /* don't send disconnect message */ - iseginfo->send_disconnect = B_FALSE; - return (err); - } - - if (iseginfo->size == 0) { - /* - * no need to fetch mappings for a 0 length segment - */ - return (WRSM_SUCCESS); - } - - - - /* - * collect mapping info for small put interrupt from exporter - */ - if ((err = send_smallputmap_msg(node, iseginfo)) != WRSM_SUCCESS) { - return (err); - } - - if (iseginfo->small_put_tuple.ncslice != - node->config->exported_ncslices.id[0]) { - DPRINTF(DBG_WARN, (CE_WARN, "iseginfo_fetch_info: " - "received bad small_put_tuple ncslice %d tuple %d\n", - iseginfo->small_put_tuple.ncslice, - iseginfo->small_put_tuple.ncslice)); - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - - - /* - * collect mapping info for barrier page from exporter - */ - if ((err = send_barriermap_msg(node, iseginfo)) != WRSM_SUCCESS) { - return (err); - } - - if (iseginfo->barrier_tuple.ncslice != - node->config->exported_ncslices.id[0]) { - DPRINTF(DBG_WARN, (CE_WARN, "iseginfo_fetch_info: " - "received bad barrier_tuple ncslice %d tuple %d\n", - iseginfo->barrier_tuple.ncslice, - iseginfo->barrier_tuple.ncslice)); - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - - - /* - * collect mapping info for segment from exporter - */ - if ((err = send_segmap_msg(node, iseginfo)) != WRSM_SUCCESS) { - return (err); - } - - offset = 0; - last_tuple = 0; - for (i = 0; i < iseginfo->num_seg_tuples; i++) { - - /* - * verify that this ncslice is exported by the remote node - */ - if (iseginfo->seg_tuples[i].ncslice != - node->config->exported_ncslices.id[last_tuple]) { - for (last_tuple = 0; last_tuple < WRSM_NODE_NCSLICES; - last_tuple++) { - if (iseginfo->seg_tuples[i].ncslice == - node->config-> - exported_ncslices.id[last_tuple]) - break; - } - } - if (last_tuple == WRSM_NODE_NCSLICES) { - /* - * Node is claiming it exports an ncslice it doesn't! - * Something must be wrong with connection. - */ - DPRINTF(DBG_WARN, (CE_WARN, "iseginfo_fetch_info: " - "segmap received bad ncslice %d tuple %d\n", - iseginfo->seg_tuples[i].ncslice, i)); - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - - if (iseginfo->seg_tuples[i].seg_offset != offset) { - /* part of segment doesn't have a mapping! */ - DPRINTF(DBG_WARN, (CE_WARN, "iseginfo_fetch_info: " - "segmap received bad info in tuple %d\n", i)); - return (RSMERR_RSM_ADDR_UNREACHABLE); - } - offset += iseginfo->seg_tuples[i].len; - } - - return (WRSM_SUCCESS); -} - - - -/* - * The session to the specified node has been torn down. Clean up - * references to any segments imported from this node. - */ -boolean_t -iseginfo_sess_teardown(wrsm_node_t *node) -{ - iseginfo_t *iseginfo; - int i; - - DPRINTF(DBG_IMPORT, (CE_CONT, "iseginfo_sess_teardown")); - - /* - * it is presumed that at this point the node was removed from the - * cluster_members_bits registers in all wcis - */ - - ASSERT(MUTEX_HELD(&node->memseg->lock)); - - node->memseg->removing_session = B_TRUE; - - /* - * Clean up iseginfos imported from remote node. The node lock - * could be held for a long time, but seeing as the node is - * considered unreachable, this shouldn't really be a problem. - */ - for (i = 0; i < WRSM_SEGID_HASH_SIZE; i++) { - iseginfo = node->memseg->iseginfo_hash[i]; - while (iseginfo) { - mutex_enter(&iseginfo->lock); - iseginfo->send_disconnect = B_FALSE; - lost_iseginfo(iseginfo); - mutex_exit(&iseginfo->lock); - iseginfo = iseginfo->segid_next; - } - } - - if (node->memseg->wait_for_unmaps == 0) { - /* - * new session can be established once all mappings - * to node are torn down - */ - node->memseg->removing_session = B_FALSE; - } - - return (!node->memseg->removing_session); -} - - - -/* - * The controller is being removed -- all clients have called - * release_controller, so it should be ok to remove objects the client may - * not have bothered to clean up. - */ -void -wrsm_free_importsegs(wrsm_network_t *network) -{ - importseg_t *importseg; - importseg_t **importsegp, **impisegp; - iseginfo_t *iseginfo; - wrsm_node_t *node; - int i; - - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_free_importseg: ctlr %d\n", - network->rsm_ctlr_id)); - - mutex_enter(&network->lock); - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (node) { - mutex_enter(&node->memseg->lock); - if (node->memseg->removing_session == B_TRUE) { - /* assume mappings have been removed */ - wrsm_sess_unreferenced(network, i); - node->memseg->removing_session = B_FALSE; - } - mutex_exit(&node->memseg->lock); - } - } - - if (network->memseg->import_count == 0) { - mutex_exit(&network->lock); - return; - } - - mutex_enter(&all_importsegs_lock); - for (i = 0; i < WRSM_SEGID_HASH_SIZE; i++) { - importsegp = &(all_importsegs_hash[i]); - while (*importsegp != NULL) { - importseg = *importsegp; - if (importseg->network == network) { - /* - * remove importseg from all_importsegs_hash - */ - *importsegp = importseg->all_next; - rw_enter(&importseg->rw_lock, RW_WRITER); - /* - * remove importseg from iseginfo list - */ - iseginfo = importseg->iseginfo; - mutex_enter(&iseginfo->lock); - impisegp = &(iseginfo->importsegs); - while (*impisegp != importseg) { - impisegp = &((*impisegp)->iseg_next); - } - ASSERT(*impisegp); - *impisegp = importseg->iseg_next; - if (importseg->kernel_user) { - ASSERT(iseginfo->kernel_users); - iseginfo->kernel_users--; - if (iseginfo->kernel_users == 0) - release_segment_mapping( - iseginfo); - } - if (iseginfo->importsegs == NULL) { - release_kernel_mappings(iseginfo); - mutex_exit(&iseginfo->lock); - mutex_destroy(&iseginfo->lock); - kmem_free(iseginfo, - sizeof (iseginfo_t)); - } else { - mutex_exit(&iseginfo->lock); - } - rw_exit(&importseg->rw_lock); - kmem_free(importseg, sizeof (importseg_t)); - ASSERT(network->memseg->import_count > 0); - network->memseg->import_count--; - } else { - importsegp = &((*importsegp)->all_next); - } - } - } - mutex_exit(&all_importsegs_lock); - -#ifdef DEBUG - if (network->memseg->import_count > 0) { - DPRINTF(DBG_WARN, (CE_WARN, "wrsm_free_exportseg: network " - "importseg count %d after exportseg cleanup\n", - network->memseg->import_count)); - } -#endif - mutex_exit(&network->lock); -} - - - -/* - * - * RSM functions - * - */ - - - -int -wrsmrsm_connect(rsm_controller_handle_t controller, - rsm_addr_t addr, rsm_memseg_id_t segid, - rsm_memseg_import_handle_t *im_memseg) -{ - wrsm_network_t *network = (wrsm_network_t *)controller; - wrsm_node_t *node; - importseg_t *importseg; - iseginfo_t *iseginfo; - cnodeid_t cnodeid; - boolean_t new; - int index; - int err; - - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsmrsm_connect(ctlr %d cnode %ld " - "segid %d)\n", network->rsm_ctlr_id, addr, segid)); - - if (wrsm_nc_ctlr_to_network(network->rsm_ctlr_id) != network) { - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsmrsm_connect - " - "invalid network 0x%p\n", (void *)network)); - return (RSMERR_BAD_CTLR_HNDL); - } - - if (addr >= WRSM_MAX_CNODES) { - /* - * wrsm hardware addresses must be cnodeids - */ - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsmrsm_connect: bad rsm_addr " - "%ld\n", addr)); - return (RSMERR_UNKNOWN_RSM_ADDR); - } - cnodeid = addr; - node = network->nodes[cnodeid]; - - /* - * create importseg structure for this connection - */ - importseg = kmem_zalloc(sizeof (importseg_t), KM_SLEEP); - importseg->valid = B_TRUE; - rw_init(&importseg->rw_lock, NULL, RW_DRIVER, NULL); - importseg->barrier_mode = RSM_BARRIER_MODE_IMPLICIT; /* default */ - - - /* - * get existing or create new iseginfo for this <node, segid> - * and return it locked - */ - if ((err = new_iseginfo(network, cnodeid, segid, &iseginfo, &new)) != - WRSM_SUCCESS) { - rw_destroy(&importseg->rw_lock); - kmem_free(importseg, sizeof (importseg_t)); - return (err); - } - - if (new) { - /* - * First import of this <node, segid>: collect mapping - * information from the node exporting it. - */ - ASSERT(MUTEX_HELD(&iseginfo->lock)); - err = iseginfo_fetch_info(node, iseginfo); - if (err) { - /* had a problem collecting mapping info */ - iseginfo->unpublished = B_TRUE; - mutex_exit(&iseginfo->lock); - if (lock_node_and_unpublished_iseginfo(node, - segid) == iseginfo) { - remove_and_destroy_iseginfo(iseginfo); - mutex_exit(&node->memseg->lock); - kmem_free(importseg, sizeof (importseg_t)); - } - if (err == RSMERR_RSM_ADDR_UNREACHABLE) { - wrsm_sess_teardown(network, cnodeid); - } - return (err); - } - - /* set up mappings to interrupt and barrier pages */ - err = create_kernel_mappings(iseginfo); - if (err) { - /* had a problem setting up mappings */ - iseginfo->unpublished = B_TRUE; - mutex_exit(&iseginfo->lock); - if (lock_node_and_unpublished_iseginfo(node, - segid) == iseginfo) { - remove_and_destroy_iseginfo(iseginfo); - mutex_exit(&node->memseg->lock); - kmem_free(importseg, sizeof (importseg_t)); - } - return (err); - } - } - - - /* - * add importseg to list of importsegs for this iseginfo - */ - importseg->iseg_next = iseginfo->importsegs; - iseginfo->importsegs = importseg; - importseg->iseginfo = iseginfo; - importseg->network = iseginfo->network; - - mutex_exit(&iseginfo->lock); - - /* - * add to all_importsegs_hash - */ - index = WRSM_PTR_HASH_FUNC(importseg); - mutex_enter(&network->lock); - network->memseg->import_count++; - mutex_exit(&network->lock); - mutex_enter(&all_importsegs_lock); - importseg->all_next = all_importsegs_hash[index]; - all_importsegs_hash[index] = importseg; - mutex_exit(&all_importsegs_lock); - - *im_memseg = (rsm_memseg_import_handle_t)importseg; - return (RSM_SUCCESS); -} - - - - - -/* - * destroy this importseg handle - */ -int -wrsmrsm_disconnect(rsm_memseg_import_handle_t im_memseg) -{ - importseg_t *importseg = (importseg_t *)im_memseg; - importseg_t **importsegp; - iseginfo_t *iseginfo; - wrsm_network_t *network; - int err; - int index; - - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsmrsm_disconnect(0x%p)\n", - (void *)importseg)); - - if ((err = wrsm_lock_importseg(importseg, RW_WRITER)) != - RSM_SUCCESS) { - return (err); - } - - if (importseg->have_mappings) { - rw_exit(&importseg->rw_lock); - return (RSMERR_SEG_IN_USE); - } - - network = importseg->network; - importseg->valid = B_FALSE; - - /* - * remove from iseginfo importseg list - */ - iseginfo = importseg->iseginfo; - mutex_enter(&iseginfo->lock); - importsegp = &(iseginfo->importsegs); - while (*importsegp != importseg) { - importsegp = &((*importsegp)->iseg_next); - } - ASSERT(*importsegp); - *importsegp = (*importsegp)->iseg_next; - if (importseg->kernel_user) { - ASSERT(iseginfo->kernel_users); - iseginfo->kernel_users--; - if (iseginfo->kernel_users == 0) - release_segment_mapping(iseginfo); - } - - if (iseginfo->unpublished && iseginfo->importsegs == NULL) { - /* - * Just removed the last importseg from a no longer valid - * iseginfo. There are now no references to iseginfo, so - * it is safe to free it. - */ - release_kernel_mappings(iseginfo); - mutex_exit(&iseginfo->lock); - mutex_destroy(&iseginfo->lock); - DPRINTF(DBG_IMPORT, (CE_CONT, - "freeing unpublished iseginfo\n")); - kmem_free(iseginfo, sizeof (iseginfo_t)); - } else { - mutex_exit(&iseginfo->lock); - } - - - /* - * Remove from all_importsegs_hash. - * importseg->rw_lock can't be held prior to taking - * all_importsegs_lock. - */ - index = WRSM_PTR_HASH_FUNC(importseg); - rw_exit(&importseg->rw_lock); - mutex_enter(&all_importsegs_lock); - rw_enter(&importseg->rw_lock, RW_WRITER); - for (importsegp = &(all_importsegs_hash[index]); - *importsegp != NULL; - importsegp = &((*importsegp)->all_next)) { - if (*importsegp == importseg) { - *importsegp = importseg->all_next; - break; - } - } - mutex_exit(&all_importsegs_lock); - rw_exit(&importseg->rw_lock); - mutex_enter(&network->lock); - network->memseg->import_count--; - mutex_exit(&network->lock); - - rw_destroy(&importseg->rw_lock); - kmem_free(importseg, sizeof (importseg_t)); - - return (RSM_SUCCESS); -} - - - -int -wrsmrsm_map(rsm_memseg_import_handle_t im_memseg, off_t offset, - size_t len, size_t *map_len, dev_info_t **dipp, uint_t *dev_register, - off_t *dev_offset, rsm_resource_callback_t callback, - rsm_resource_callback_arg_t arg) -{ - importseg_t *importseg = (importseg_t *)im_memseg; - wrsm_node_t *node; - wrsm_network_t *network; - iseginfo_t *iseginfo; - import_ncslice_t *seg_tuples; - int num_seg_tuples, i; - cnodeid_t cnodeid; - int err; - - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsmrsm_map(0x%p)\n", - (void *)importseg)); - - - if (len <= 0) { - return (RSMERR_BAD_LENGTH); - } - - if ((err = wrsm_lock_importseg(importseg, RW_WRITER)) != - RSM_SUCCESS) { - return (err); - } - - /* segment size never changes, so check immediately */ - if ((offset + len) > importseg->iseginfo->size) { - rw_exit(&importseg->rw_lock); - return (RSMERR_BAD_LENGTH); - } - - /* - * Release the importseg lock, take the exporting node's lock, then - * retake the importseg lock. - */ - cnodeid = importseg->iseginfo->cnodeid; - network = importseg->iseginfo->network; - rw_exit(&importseg->rw_lock); - - mutex_enter(&network->lock); - if (!network->nodes[cnodeid]) { - mutex_exit(&network->lock); - return (RSMERR_CONN_ABORTED); - } - node = network->nodes[cnodeid]; - mutex_enter(&node->memseg->lock); - mutex_exit(&network->lock); - - if ((err = wrsm_lock_importseg(importseg, RW_WRITER)) != - RSM_SUCCESS) { - mutex_exit(&node->memseg->lock); - return (err); - } - - if (importseg->unpublished) { - /* - * new mappings not allowed on a segment that has - * been unpublished - */ - mutex_exit(&node->memseg->lock); - rw_exit(&importseg->rw_lock); - return (RSMERR_CONN_ABORTED); - } - - iseginfo = importseg->iseginfo; - - /* - * remember that map has been called on this segment - */ - - if (importseg->have_mappings == B_FALSE) { - importseg->have_mappings = B_TRUE; - - mutex_enter(&iseginfo->lock); - iseginfo->wait_for_unmaps++; - if (iseginfo->wait_for_unmaps == 1) { - node->memseg->wait_for_unmaps++; - } - - mutex_exit(&iseginfo->lock); - } - - mutex_exit(&node->memseg->lock); - - - /* - * Calculate the ncslice and offset within the slice that maps to - * the requested segment offset. Also determine the size of the - * contiguous region starting at this offset that maps to the - * segment. - */ - - num_seg_tuples = importseg->iseginfo->num_seg_tuples; - seg_tuples = importseg->iseginfo->seg_tuples; - - for (i = 0; i < num_seg_tuples; i++) { - if (offset < (seg_tuples[i].seg_offset + seg_tuples[i].len)) { - /* - * offset falls within this ncslice region - */ - *dev_register = seg_tuples[i].ncslice; - *dev_offset = seg_tuples[i].ncslice_offset + - (offset - seg_tuples[i].seg_offset); - *map_len = seg_tuples[i].len - - (offset - seg_tuples[i].seg_offset); - if (*map_len > len) { - *map_len = len; - } - break; - } - } - - /* It is not possible that the desired offset does not have a mapping */ - ASSERT(i < num_seg_tuples); - - *dipp = wrsm_ncslice_dip; - - - /* - * record the mapping-no-longer-valid callback and arg for this - * importseg. - */ - importseg->mapping_callback = callback; - importseg->mapping_callback_arg = arg; - - rw_exit(&importseg->rw_lock); - - return (RSM_SUCCESS); -} - - -/* - * one rsm_unmap() call cancels all previous rsm_map calls - */ -int -wrsmrsm_unmap(rsm_memseg_import_handle_t im_memseg) -{ - importseg_t *importseg = (importseg_t *)im_memseg; - wrsm_network_t *network; - wrsm_node_t *node; - iseginfo_t *iseginfo; - cnodeid_t cnodeid; - int err; - - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsmrsm_unmap(0x%p)\n", - (void *)importseg)); - - if ((err = wrsm_lock_importseg(importseg, RW_WRITER)) != - RSM_SUCCESS) { - return (err); - } - - /* - * Release the importseg lock, take the exporting node's lock, then - * retake the importseg lock. If this is the last mapping for the - * segment, and for this node, change segment/node states to - * reflect this. - */ - - cnodeid = importseg->iseginfo->cnodeid; - network = importseg->iseginfo->network; - rw_exit(&importseg->rw_lock); - - mutex_enter(&network->lock); - if (!network->nodes[cnodeid]) { - mutex_exit(&network->lock); - return (RSMERR_CONN_ABORTED); - } - node = network->nodes[cnodeid]; - mutex_enter(&node->memseg->lock); - mutex_exit(&network->lock); - - if ((err = wrsm_lock_importseg(importseg, RW_WRITER)) != - RSM_SUCCESS) { - return (err); - } - - iseginfo = importseg->iseginfo; - mutex_enter(&iseginfo->lock); - - if (!iseginfo->wait_for_unmaps) { - /* - * segment not mapped, so do nothing - */ - mutex_exit(&iseginfo->lock); - mutex_exit(&node->memseg->lock); - rw_exit(&importseg->rw_lock); - return (RSM_SUCCESS); - } - - importseg->have_mappings = B_FALSE; - iseginfo->wait_for_unmaps--; - - if (iseginfo->wait_for_unmaps == 0) { - if (iseginfo->unpublished) { - remove_iseginfo(iseginfo); - } - - node->memseg->wait_for_unmaps--; - if (node->memseg->wait_for_unmaps == 0) { - if (node->memseg->removing_session == B_TRUE) { - - /* - * Make sure session state reflects that - * there are no more references to this - * node. - */ - wrsm_sess_unreferenced(node->network, - node->config->cnodeid); - node->memseg->removing_session = B_FALSE; - } - } - } - mutex_exit(&node->memseg->lock); - mutex_exit(&iseginfo->lock); - - importseg->mapping_callback = NULL; - importseg->mapping_callback_arg = NULL; - - rw_exit(&importseg->rw_lock); - - return (RSM_SUCCESS); -} - -/* RSMAPI helper functions */ - -/* - * returns the locked iseginfo that corresponds to ctrl_num, - * remote_cnode, and segid. - * Returns RSM_SUCCESS upon successful completion. - * If an iseginfo is successfully returned, the CALLER must RELEASE - * the iseginfo->mutex. - */ -int -wrsm_memseg_remote_node_to_iseginfo(uint32_t ctrl_num, - cnodeid_t remote_cnode, rsm_memseg_id_t segid, - iseginfo_t **iseginfo) - -{ - wrsm_network_t *network; - wrsm_node_t *node; - - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_memseg_remote_node_to_iseginfo" - " controller num %d remote cnode %d", ctrl_num, remote_cnode)); - - network = wrsm_nc_ctlr_to_network(ctrl_num); - - if (network == NULL) { - return (ENXIO); - } - mutex_enter(&network->lock); - node = network->nodes[remote_cnode]; - - /* - * we know that the network can't be removed because we are using - * either an ioctl or mmap to call this function. The driver will - * not allow the network to be removed while in use, hence, we do - * not need to grab and hold wrsm_networks_lock - */ - if (node == NULL) { - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_memseg_remote_node_to" - "_iseginfo node NULL")); - mutex_exit(&network->lock); - return (EBADF); - } - - *iseginfo = find_and_lock_iseginfo(node, segid); - mutex_exit(&network->lock); - - if (*iseginfo == NULL) { - DPRINTF(DBG_IMPORT, (CE_WARN, - "wrsm_memseg_remote_node_to_iseginfo NO iseginfo found")); - return (EBADF); - } - - ASSERT ((*iseginfo)->cnodeid == remote_cnode); - return (RSM_SUCCESS); -} - - -/* ARGSUSED */ -int -wrsm_memseg_segmap(dev_t dev, off_t off, struct as *asp, caddr_t *addrp, - off_t len, unsigned int prot, unsigned int maxprot, - unsigned int flags, cred_t *cred) -{ - wrsm_plugin_offset_t pseudo_offset; - uint32_t rsm_ctrl_id; - iseginfo_t *iseginfo = NULL; - int error; - - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_segmap\n")); - if (len != WRSM_PAGESIZE) { - DPRINTF(DBG_IMPORT, (CE_WARN, "Invalid PAGESIZE\n")); - return (EINVAL); - } - /* minor number is the controller number */ - rsm_ctrl_id = getminor(dev); - - pseudo_offset.val = (int64_t)off; - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_memseg_segmap segment %d " - "for controller id %d export cnode %d ", - pseudo_offset.bit.segment_id, rsm_ctrl_id, - (cnodeid_t)pseudo_offset.bit.export_cnodeid)) - - /* - * Get iseginfo for this controller, cnodeid, and segment_id. - * iseginfo is returned locked. - */ - error = wrsm_memseg_remote_node_to_iseginfo(rsm_ctrl_id, - (cnodeid_t)pseudo_offset.bit.export_cnodeid, - pseudo_offset.bit.segment_id, &iseginfo); - - if (error != RSM_SUCCESS) { - cmn_err(CE_WARN, "wrsm_memseg_segmap: unable to find matching " - " segment for controller id %d export cnode %d\n", - rsm_ctrl_id, (cnodeid_t)pseudo_offset.bit.export_cnodeid); - return (error); - } - - /* - * page_type field represents the type of page trying to be mapped. - * those types are Interrupt, Barrier, barrier registers (CESR and - * wci_cluster_error_count mapped in via page 0 of ncslice) - * and Reconfiguration counter. - */ - - if (pseudo_offset.bit.page_type == WRSM_MMAP_RECONFIG) { - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_segmap RECONFIG")); - if (prot != (PROT_READ | PROT_USER)) { - DPRINTF(DBG_WARN, (CE_WARN, "wrsm_memseg_segmap failed:" - " Only read permission allowed with Reconfig" - " mapping cntrl %d, export_cnode %d, segment %d", - rsm_ctrl_id, pseudo_offset.bit.export_cnodeid, - pseudo_offset.bit.segment_id)); - mutex_exit(&iseginfo->lock); - return (EACCES); - } - } - mutex_exit(&iseginfo->lock); - return (devmap_setup(dev, off, asp, addrp, len, prot, - maxprot, flags, cred)); -} - -/* ARGSUSED */ -int -wrsm_memseg_devmap(dev_t dev, devmap_cookie_t handle, offset_t off, - size_t len, size_t *maplen, uint_t model) - -{ - - int error; - offset_t offset; - wrsm_plugin_offset_t pseudo_offset; - uint32_t rsm_ctrl_id; - iseginfo_t *iseginfo = NULL; - uint_t rnumber; - dev_info_t *dip; - - /* Set up data access attribute structure */ - struct ddi_device_acc_attr wrsm_acc_attr = { - DDI_DEVICE_ATTR_V0, - DDI_NEVERSWAP_ACC, - DDI_STRICTORDER_ACC - }; - - if (len != WRSM_PAGESIZE) { - return (EINVAL); - } - - pseudo_offset.val = (int64_t)off; - - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_devmap")); - rsm_ctrl_id = getminor(dev); - - - /* - * Get iseginfo for this controller, cnodeid, and segment_id. - * iseginfo is returned locked. - */ - error = wrsm_memseg_remote_node_to_iseginfo(rsm_ctrl_id, - (cnodeid_t)pseudo_offset.bit.export_cnodeid, - pseudo_offset.bit.segment_id, &iseginfo); - - if (error != RSM_SUCCESS) { - cmn_err(CE_WARN, "wrsm_devmap: unable to find matching segment" - " for controller id %d\n", rsm_ctrl_id); - return (error); - } - - switch (pseudo_offset.bit.page_type) { - case WRSM_MMAP_BARRIER_SCRATCH: - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_devmap barrier scratch" - " page for controller id %d", rsm_ctrl_id)); - - dip = wrsm_ncslice_dip; - offset = iseginfo->barrier_tuple.ncslice_offset; - rnumber = iseginfo->barrier_tuple.ncslice; - if (iseginfo->barrier_tuple.len != len) { - mutex_exit(&iseginfo->lock); - return (ENXIO); - } - break; - - case WRSM_MMAP_BARRIER_REGS: - /* - * From WCI-2 CESR, wci_cluster_error_count registers - * and write lockout registers are visible through page 0 of - * the remotes node's ncslice - */ - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_devmap barrier ncslice" - " for CRS's on controller id %d\n", rsm_ctrl_id)); - - dip = wrsm_ncslice_dip; - offset = 0; - rnumber = iseginfo->barrier_tuple.ncslice; - if (iseginfo->barrier_tuple.len != len) { - mutex_exit(&iseginfo->lock); - return (ENXIO); - } - break; - - case WRSM_MMAP_RECONFIG: - DPRINTF(DBG_IMPORT, (CE_CONT, "wrsm_devmap route_counter, " - "rerouting, and striping for controller id %d", - rsm_ctrl_id)); - /* - * special case of wrsm_devmap. maps kernel memory - * rather than device memory for the network->route_counter - * and the network->routing and striping. - * The plugin needs these counters to implement - * barriers. - */ - offset = 0; - if (iseginfo->network->dip == NULL) { - cmn_err(CE_WARN, "wrsm_devmap network dev_info_t not" - " defined for controller id %d", rsm_ctrl_id); - mutex_exit(&iseginfo->lock); - return (ENXIO); - } - /* Set up the kernel mapping */ - error = devmap_umem_setup(handle, iseginfo->network->dip, - NULL, iseginfo->network->route_cookie, offset, len, - PROT_READ | PROT_USER, 0, NULL); - *maplen = len; - mutex_exit(&iseginfo->lock); - if (error != 0) - return (EINVAL); - else - return (RSM_SUCCESS); - - default: - /* this case should NOT occur */ - cmn_err(CE_WARN, "wrsm_devmap invalid page_type" - " for controller id %d", rsm_ctrl_id); - mutex_exit(&iseginfo->lock); - return (ENXIO); - } - - /* Set up the device mapping */ - mutex_exit(&iseginfo->lock); - error = devmap_devmem_setup(handle, dip, NULL, rnumber, - offset, len, PROT_ALL, DEVMAP_DEFAULTS, &wrsm_acc_attr); - /* acknowledge the entire range */ - - *maplen = len; - if (error != 0) - return (EINVAL); - else - return (RSM_SUCCESS); - -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_mh.c b/usr/src/uts/sun4u/io/wrsm/wrsm_mh.c deleted file mode 100644 index 7becca1d87..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_mh.c +++ /dev/null @@ -1,484 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Multi-hop routing module of the WildCat RSM diver. - * This file manages the programming of WCI route maps based on link - * up and down events. - */ - -#include <sys/types.h> -#include <sys/kmem.h> -#include <sys/cmn_err.h> -#include <sys/sunddi.h> -#include <sys/debug.h> - -#include <sys/wrsm_common.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_nc_impl.h> -#include <sys/wrsm_lc.h> - -#ifdef DEBUG -#define DBG_MH 0x01 -#define DBG_MH_EXTRA 0x02 -#define DBG_WARN 0x04 -#define DBG_DUMP 0x08 - -static uint_t wrsm_mh_debug = DBG_WARN; -#define DPRINTF(a, b) { if (wrsm_mh_debug & a) wrsmdprintf b; } -#define DUMPWCI(m, w) { if (wrsm_mh_debug & DBG_DUMP) wrsm_mh_dump_wci(m, w); } -#else -#define DPRINTF(a, b) { } -#define DUMPWCI(m, w) { } -#endif /* DEBUG */ - -/* - * WCI specific definitions used to program the control registers. - */ -#define ROUTE_MAP_LOCAL 3 - -enum mh_link_state { - mh_link_down, - mh_link_up -}; - -struct wrsm_mh_reroute_state { - enum mh_link_state link_state[WRSM_LINKS_PER_WCI]; - wnode_bitmask_t using_link[WRSM_LINKS_PER_WCI]; - wrsm_mh_reachable_t reachable; -}; - - -static void set_route_nostripe(lcwci_handle_t lcwci, wnodeid_t wnode, - uint32_t linknum); -static void set_route_addstripe(lcwci_handle_t lcwci, wnodeid_t wnode, - uint32_t linknum); -static void set_route_unstripe(lcwci_handle_t lcwci, wnodeid_t wnode, - uint32_t linknum); - -#ifdef DEBUG -void -wrsm_mh_dump_wci(char *msg, struct wrsm_ncwci *wci) -{ - wnodeid_t wnode; - linkid_t link; - - cmn_err(CE_WARN, "%s", msg); - - for (wnode = 0; wnode < WRSM_MAX_WNODES; ++wnode) { - cmn_err(CE_NOTE, " wnode %d", wnode); - cmn_err(CE_NOTE, " first_hop = %d", - wci->mh_state->reachable.first_hop[wnode]); - cmn_err(CE_NOTE, " stripes = %d", - wci->mh_state->reachable.stripes[wnode]); - link = wrsm_lc_get_route(wci->lcwci, wnode, 0); - cmn_err(CE_NOTE, " map0 = %u", link); - link = wrsm_lc_get_route(wci->lcwci, wnode, 1); - cmn_err(CE_NOTE, " map1 = %u", link); - } - for (link = 0; link < 3; link++) { - cmn_err(CE_NOTE, " link %d", link); - cmn_err(CE_NOTE, " state = %d", - wci->mh_state->link_state[link]); - } -} -#endif /* DEBUG */ - -/* - * Called from NR when a new wci is brought into use so that the - * per-wci MH private data structures can be initialized. - */ -void -wrsm_mh_new_wci(wrsm_ncwci_t *wci) -{ - wrsm_mh_reroute_state_t *mh_state; - wnodeid_t local_wnode; - int i; - - ASSERT(wci); - ASSERT(wci->config); - local_wnode = wci->config->local_wnode; - - DPRINTF(DBG_MH, (CE_CONT, "mh_new_wci wci %d - add loopback route", - wci->config->port)); - - mh_state = kmem_zalloc(sizeof (wrsm_mh_reroute_state_t), - KM_SLEEP); - ASSERT(mh_state); - for (i = 0; i < WRSM_LINKS_PER_WCI; ++i) { - mh_state->link_state[i] = mh_link_down; - WRSMSET_ZERO(mh_state->using_link[i]); - } - for (i = 0; i < WRSM_MAX_WNODES; ++i) { - mh_state->reachable.nhops[i] = WNODE_UNREACHABLE; - mh_state->reachable.changed[i] = B_FALSE; - } - /* local wnode is for loopback to local node memory */ - mh_state->reachable.nhops[local_wnode] = 0; - mh_state->reachable.stripes[local_wnode] = 1; - mh_state->reachable.first_hop[local_wnode] = local_wnode; - mh_state->reachable.changed[local_wnode] = B_TRUE; - wci->mh_state = mh_state; - - wrsm_nr_mhdirect(wci, &(mh_state->reachable)); - mh_state->reachable.changed[wci->config->local_wnode] = B_FALSE; -} - -/* - * Called from NR when wci taken away so that resources allocated - * by wrsm_mh_new_wci() can be freed. - */ -void -wrsm_mh_remove_wci(wrsm_ncwci_t *wci) -{ - ASSERT(wci); - ASSERT(wci->mh_state); - ASSERT(wci->config); - - DPRINTF(DBG_MH, (CE_CONT, "mh_remove wci %d", wci->config->port)); - - wci->mh_state->reachable.nhops[wci->config->local_wnode] = - WNODE_UNREACHABLE; - wci->mh_state->reachable.stripes[wci->config->local_wnode] = 0; - wci->mh_state->reachable.changed[wci->config->local_wnode] = B_TRUE; - - /* force a full reroute analysis */ - wrsm_nr_mhreroute(wci, &(wci->mh_state->reachable)); - - kmem_free(wci->mh_state, sizeof (wrsm_mh_reroute_state_t)); - wci->mh_state = NULL; -} - - -/* - * Main entry point of the MH module used to initiate an - * reevaluation of the multihop subnet. - */ -boolean_t -wrsm_mh_reroute(wrsm_ncwci_t *wci) -{ - ASSERT(wci); - ASSERT(wci->config); - - DPRINTF(DBG_MH_EXTRA, (CE_CONT, "mh_reroute wci %d", - wci->config->port)); - - if (wci->reroute_state != wci_need_reroute && - wci->reroute_state != wci_force_reroute) { - /* - * If the wci is in the wrong state, return - * without calling wrsm_nr_mhreroute(). - */ - DPRINTF(DBG_WARN, (CE_WARN, "mh_reroute wci %d - bad " - "reroute state!", wci->config->port)); - return (B_FALSE); - } - - if (wci->mh_state == NULL || wci->lcwci == NULL) { - /* wci not attached */ - DPRINTF(DBG_MH, (CE_WARN, "mh_reroute wci %d - no " - "mh_state or lcwci!", wci->config->port)); - wci->reroute_state = wci_rerouted; - return (B_FALSE); - } - - wci->reroute_state = wci_in_reroute; - - /* Do the reroute now */ - wci->reroute_state = wci_rerouted; - - wrsm_nr_mhreroute(wci, &(wci->mh_state->reachable)); - return (B_TRUE); -} - - - -/* - * Called from the LC when a new link has been successfully - * brought up. Programs the WCI's route_map registers to - * start using that link for direct-connect communication. - */ -void -wrsm_mh_link_is_up(ncwci_handle_t ncwci, uint32_t local_linknum, - wnodeid_t remote_wnode) -{ - struct wrsm_ncwci *wci = (struct wrsm_ncwci *)ncwci; - wnodeid_t wnode; - ASSERT(wci); - ASSERT(wci->config); - ASSERT(wci->mh_state); - ASSERT(wci->lcwci); - ASSERT(local_linknum >= 0 && local_linknum < WRSM_LINKS_PER_WCI); - - DPRINTF(DBG_MH, (CE_CONT, "mh_link_is_up wci %d link %d wnode %d", - wci->config->port, local_linknum, remote_wnode)); - - DUMPWCI("Entering wrsm_mh_link_is_up", wci); - -#ifdef DEBUG - if (wci->mh_state->link_state[local_linknum] != mh_link_down) { - DPRINTF(DBG_MH, (CE_CONT, "mh_link_is_up: wci %d link % " - "already up state %d", wci->config->port, local_linknum, - wci->mh_state->link_state[local_linknum])); - } -#endif - - wci->mh_state->link_state[local_linknum] = mh_link_up; - - ASSERT(remote_wnode < WRSM_MAX_WNODES); - - /* - * Use the one hop route if the current route uses more hops, or - * if a loopback route (0 hops) is currently being used. The theory - * behind this is that there wouldn't be a 1 hop route to the - * local node in the configuration unless the configurer wanted - * it to be preferred over loopback. - */ - if (wci->mh_state->reachable.nhops[remote_wnode] == WNODE_UNREACHABLE || - wci->mh_state->reachable.nhops[remote_wnode] != 1) { - set_route_nostripe(wci->lcwci, remote_wnode, - local_linknum); - wci->mh_state->reachable.nhops[remote_wnode] = 1; - wci->mh_state->reachable.stripes[remote_wnode] = 1; - wci->mh_state->reachable.changed[remote_wnode] = B_TRUE; - wci->mh_state->reachable.first_hop[remote_wnode] = remote_wnode; - WRSMSET_ADD(wci->mh_state->using_link[local_linknum], - remote_wnode); - } else if (wci->mh_state->reachable.stripes[remote_wnode] == 1 && - wci->mh_state->reachable.nhops[remote_wnode] == 1) { - /* Enable route map striping */ - set_route_addstripe(wci->lcwci, remote_wnode, local_linknum); - wci->mh_state->reachable.stripes[remote_wnode] = 2; - WRSMSET_ADD(wci->mh_state->using_link[local_linknum], - remote_wnode); - DPRINTF(DBG_MH, (CE_NOTE, - "mh_link_is_up: enabling link striping")); - } - - wrsm_nr_mhdirect(wci, &(wci->mh_state->reachable)); - - for (wnode = 0; wnode < WRSM_MAX_WNODES; ++wnode) { - wci->mh_state->reachable.changed[wnode] = B_FALSE; - } - - DUMPWCI("Exiting wrsm_mh_link_is_up", wci); -} - -/* Sets both routemap entries to route over the given link */ -static void -set_route_nostripe(lcwci_handle_t lcwci, wnodeid_t wnode, uint32_t linknum) -{ - /* Write to route_map_0 */ - wrsm_lc_set_route(lcwci, wnode, linknum, 0); - - /* Write same value to route_map_1 */ - wrsm_lc_set_route(lcwci, wnode, linknum, 1); -} - -/* Changes route map entry 1 to route over the given link */ -static void -set_route_addstripe(lcwci_handle_t lcwci, wnodeid_t wnode, uint32_t linknum) -{ - /* Assume route_map0 contains original stripe, just change map1 */ - wrsm_lc_set_route(lcwci, wnode, linknum, 1); -} - -/* - * Determines which route map entry uses the link, and replaces it with - * the other route map entry. Returns ENOENT if the wnode was not using - * this link to stripe. - */ -static void -set_route_unstripe(lcwci_handle_t lcwci, wnodeid_t wnode, uint32_t linknum) -{ - uint32_t link0; - uint32_t link1; - - link0 = wrsm_lc_get_route(lcwci, wnode, 0); - link1 = wrsm_lc_get_route(lcwci, wnode, 1); - - DPRINTF(DBG_MH, (CE_CONT, "mh set_route_unstripe link %d wnode %d " - "link0 %d link1 %d", linknum, wnode, link0, link1)); - - /* Make sure both route map entries are in use, and not the same */ - ASSERT(link0 != ROUTE_MAP_LOCAL); - ASSERT(link1 != ROUTE_MAP_LOCAL); - ASSERT(link0 != link1); - - /* - * If the caller passed in link0, reprogram routemap to use link1 - * and vice versa. - */ - if (link0 == linknum) { - set_route_nostripe(lcwci, wnode, link1); - } else { - ASSERT(link1 == linknum); - set_route_nostripe(lcwci, wnode, link0); - } -} - -/* - * Called from the LC before a link is to be brought down or - * after it has detected an auto-shutdown of the link. Turns - * off routing through the unavailable link. - */ -void -wrsm_mh_link_is_down(ncwci_handle_t ncwci, uint32_t local_linknum, - wnodeid_t remote_wnode) -{ - struct wrsm_ncwci *wci = (struct wrsm_ncwci *)ncwci; - wnodeid_t wnode; - - ASSERT(wci); - ASSERT(wci->config); - ASSERT(wci->mh_state); - ASSERT(wci->lcwci); - ASSERT(local_linknum < WRSM_LINKS_PER_WCI); - ASSERT(remote_wnode < WRSM_MAX_WNODES); - - DPRINTF(DBG_MH, (CE_CONT, "mh_link_is_down wci %d link %d wnode %d", - wci->config->port, local_linknum, remote_wnode)); - - if (wci->mh_state->link_state[local_linknum] != mh_link_up) - return; - - DUMPWCI("Entering wrsm_mh_link_is_down", wci); - - /* - * Find all wnodes in the subnet which have routes - * using the link which is going down. - */ - for (wnode = 0; wnode < WRSM_MAX_WNODES; ++wnode) { - if (wci->mh_state->reachable.nhops[wnode] != - WNODE_UNREACHABLE && - wci->mh_state->reachable.first_hop[wnode] == remote_wnode) { - if (wci->mh_state->reachable.stripes[wnode] == 1) { - set_route_nostripe(wci->lcwci, wnode, - ROUTE_MAP_LOCAL); - wci->mh_state->reachable.changed[wnode] = - B_TRUE; - /* - * If this is the local wnode, switching to - * ROUTE_MAP_LOCAL means internal loopback - * is now being used for this wnode. In - * all other cases, using ROUTE_MAP_LOCAL - * will cause failures and is equivalent to - * not having a route. - */ - if (wnode == wci->config->local_wnode) { - wci->mh_state-> - reachable.nhops[wnode] = 0; - wci->mh_state-> - reachable.stripes[wnode] = 1; - } else { - wci->mh_state-> - reachable.nhops[wnode] = - WNODE_UNREACHABLE; - wci->mh_state-> - reachable.stripes[wnode] = 0; - } - WRSMSET_DEL(wci->mh_state-> - using_link[local_linknum], wnode); - /* - * Else, if we were striping, and this wnode was - * using this link in its striping, then stop - * striping. Checking for stripine level isn't enough; - * we have to check for the link being in use because - * there could be three links going to same remote - * wnode, and the link going down could be the one - * not being used. - */ - } else if ( - wci->mh_state->reachable.stripes[wnode] == 2 && - WRSM_IN_SET(wci->mh_state-> - using_link[local_linknum], wnode)) { - /* Fix route maps to be unstriped */ - set_route_unstripe(wci->lcwci, wnode, - local_linknum); - /* Turn off striping on that link */ - wci->mh_state->reachable.stripes[wnode] = 1; - WRSMSET_DEL(wci->mh_state-> - using_link[local_linknum], wnode); - DPRINTF(DBG_MH, (CE_NOTE, "mh_link_is_down: " - "wci %d link %d to wnode %d " - "disabling link striping", - wci->config->port, local_linknum, - wnode)); - } - } - } - - if (WRSMSET_ISNULL(wci->mh_state->using_link[local_linknum])) - wci->mh_state->link_state[local_linknum] = mh_link_down; - - wrsm_nr_mhdirect(wci, &(wci->mh_state->reachable)); - - for (wnode = 0; wnode < WRSM_MAX_WNODES; ++wnode) { - wci->mh_state->reachable.changed[wnode] = B_FALSE; - } - DUMPWCI("Exiting wrsm_mh_link_is_down", wci); -} - -/* - * For a given WCI and a remote wnodeid, find the link. - * This is used to populate the wrsm_route_kstat. - */ -int -wrsm_mh_wnode_to_link(ncwci_handle_t ncwci, int wnodeid) -{ - struct wrsm_ncwci *wci = (struct wrsm_ncwci *)ncwci; - int i; - - if (wci == NULL || wci->mh_state == NULL) { - return (-1); - } - - for (i = 0; i < WRSM_LINKS_PER_WCI; i++) { - if (WRSM_IN_SET(wci->mh_state->using_link[i], wnodeid)) { - return (i); - } - } - return (-1); -} - -/* - * For a given WCI, determine if the given link leads to given remode wnodeid - * This is used to populate the wrsm_route_kstat. - */ -boolean_t -wrsm_mh_link_to_wnode(ncwci_handle_t ncwci, int link, int wnodeid) -{ - struct wrsm_ncwci *wci = (struct wrsm_ncwci *)ncwci; - - if (wci == NULL || wci->mh_state == NULL) { - return (B_FALSE); - } - - return (boolean_t) - (WRSM_IN_SET(wci->mh_state->using_link[link], wnodeid)); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_nc.c b/usr/src/uts/sun4u/io/wrsm/wrsm_nc.c deleted file mode 100644 index a94a3d9942..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_nc.c +++ /dev/null @@ -1,2008 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file manages controllers (networks). It coordinate the network - * routing, session and transport modules. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/kmem.h> -#include <sys/tnf_probe.h> -#include <sys/cmn_err.h> -#include <sys/errno.h> -#include <sys/mutex.h> -#include <sys/debug.h> -#include <sys/systm.h> -#include <sys/sunddi.h> - -#include <sys/wrsm_config.h> -#include <sys/wrsm_cf.h> -#include <sys/wrsm_transport.h> -#include <sys/wrsm_cmmu.h> -#include <sys/wrsm_session.h> -#include <sys/wrsm_lc.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_nc_impl.h> -#include <sys/wrsm_plugin.h> - -#include <sys/wci_common.h> -#include <sys/rsm/rsmpi_driver.h> -#include <sys/wrsm_rsmpi.h> - - -#ifdef DEBUG -#define DBG_CONFIG 0x001 -#define DBG_WARN 0x002 -#define DBG_CONFIG_EXTRA 0x010 - -uint_t wrsm_nc_debug = DBG_WARN; -#define DPRINTF(a, b) { if (wrsm_nc_debug & a) wrsmdprintf b; } - -#else -#define DPRINTF(a, b) { } -#endif - -static wrsm_network_t *wrsm_networks = NULL; -static kmutex_t wrsm_networks_lock; - - -static wrsm_network_t *rsmctlr_to_network(uint32_t rsm_ctlr_id); -static int new_network(uint32_t rsm_ctlr_id, wrsm_network_t **networkp); -static void remove_network(wrsm_network_t *network); - - -static void remove_wrsm_node(wrsm_node_t *node); -static int new_wrsm_node(wrsm_network_t *network, wrsm_net_member_t *member, - wrsm_node_t **nodep); - -static int nc_enableconfig(wrsm_network_t *network, int reroute_cnt, - wci_ids_t *reconfig_wcis); - -static void add_wrsm_ctlr_kstat(wrsm_network_t *network); -static void del_wrsm_ctlr_kstat(wrsm_network_t *network); -static int ctlr_kstat_update(kstat_t *ksp, int rw); - - -/* - * The configuration functions (nc_replaceconfig(), nc_cleanconfig(), - * nc_installconfig(), nc_enableconfig(), nc_initialconfig(), - * nc_removeconfig()) and the newwci() and removewci() functions are all - * guaranteed by the config layer to be single threaded. The config layer - * is the only consumer of these functions, and it will never call a second - * function before the first is complete. The config layer also only - * calls each function in the apprpropriate order, but the functions - * still do a quick check to be sure the NC concept of this controller's - * state is appropriate. - */ - -/* - * set up driver communication path to new node - */ -static int -config_new_node(wrsm_node_t *node) -{ - cnodeid_t cnodeid = node->config->cnodeid; - wrsm_network_t *network = node->network; - int i; - int err; - ncslice_t id; - - ASSERT(network->nodes[cnodeid] == node); - - /* - * allow access to local node's memory through ncslices - * used by the remote node. - */ - ASSERT(node->config->imported_ncslices.id[0]); - /* - * Note: no lock is needed because config operations are single - * threaded, and only imported ncslices are managed during - * configuration. - */ - id = node->config->imported_ncslices.id[0]; - if (network->wrsm_ncslice_users[id] == 0) { - wrsm_ncsliceconfig_set(network, id, ncslice_small_page); -#ifdef DEBUG - } else { - ASSERT(wrsm_ncsliceconfig_get(network, id) == - ncslice_small_page); -#endif - } - network->wrsm_ncslice_users[id]++; - - - for (i = 1; i < WRSM_NODE_NCSLICES; i++) { - id = node->config->imported_ncslices.id[i]; - if (id != 0) { - /* - * Note: no lock is needed because config - * operations are single threaded, and only - * imported ncslices are managed during - * configuration. - */ - if (network->wrsm_ncslice_users[id] == 0) { - wrsm_ncsliceconfig_set(network, id, - ncslice_large_page); -#ifdef DEBUG - } else { - ASSERT(wrsm_ncsliceconfig_get(network, id) == - ncslice_large_page); -#endif - } - network->wrsm_ncslice_users[id]++; - } - } - - /* - * set up mapping to CESR registers for remote node - * They are visible through page 0 in the ncslice - * exported by the remote note. - */ - - ASSERT(wrsm_ncslice_dip); - if ((err = ddi_map_regs(wrsm_ncslice_dip, - (uint_t)node->config->comm_ncslice, - &(node->cesr_vaddr), 0, PAGESIZE)) != DDI_SUCCESS) { - /* - * can't allow access to this node if this - * page can't be mapped - */ - DPRINTF(DBG_WARN, (CE_WARN, "wrsm: ddi_map_regs err %d -- " - "can't set up mapping to ncslice %d cnode %d CESRs", - err, node->config->comm_ncslice, cnodeid)); - return (ENOENT); - } - - if ((err = ddi_map_regs(wrsm_ncslice_dip, - (uint_t)node->config->comm_ncslice, - &(node->lockout_vaddr), PAGESIZE, PAGESIZE)) != DDI_SUCCESS) { - /* - * can't allow access to this node if this - * page can't be mapped - */ - DPRINTF(DBG_WARN, (CE_WARN, "wrsm: ddi_map_regs err %d -- " - "can't set up mapping to ncslice %d cnode %d CESRs", - err, node->config->comm_ncslice, cnodeid)); - return (ENOENT); - } - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "mapped cesr page (ncslice %d) for " - "node %d into kernel vaddr 0x%p\n", node->config->comm_ncslice, - cnodeid, (void *)node->cesr_vaddr)); - - -#ifdef DEBUG - if (wrsm_nc_debug & DBG_CONFIG) { - pfn_t pfn; /* page frame number */ - uint64_t pa; /* Physical address */ - - pfn = hat_getpfnum(kas.a_hat, node->lockout_vaddr); - pa = (pfn << MMU_PAGESHIFT); - DPRINTF(DBG_CONFIG, (CE_CONT, - "mapped lockout page (ncslice %d)" - " for node %d into kernel vaddr 0x%p pa=0x%p\n", - node->config->comm_ncslice, cnodeid, - (void *)node->lockout_vaddr, (void *)pa)); - } -#endif - /* - * configure the transport to this node - */ - if ((err = wrsm_tl_newcnode(network, cnodeid)) != WRSM_SUCCESS) { - DPRINTF(DBG_WARN, (CE_WARN, - "wrsm: can't set up transport to cnode %d", cnodeid)); - - (void) ddi_unmap_regs(wrsm_ncslice_dip, - (uint_t)node->config->comm_ncslice, - &(node->cesr_vaddr), 0, PAGESIZE); - (void) ddi_unmap_regs(wrsm_ncslice_dip, - (uint_t)node->config->comm_ncslice, - &(node->lockout_vaddr), PAGESIZE, PAGESIZE); - node->cesr_vaddr = 0; - node->lockout_vaddr = 0; - return (err); - } - - return (WRSM_SUCCESS); -} - - -/* - * remove node's transport, CESR mapping, then remove node - */ -static void -remove_old_node(wrsm_node_t *node) -{ - int i; - wrsm_network_t *network = node->network; - ncslice_t id; - - if (node->cesr_vaddr) { - for (i = 0; i < WRSM_NODE_NCSLICES; i++) { - id = node->config->imported_ncslices.id[i]; - if (id != 0) { - network->wrsm_ncslice_users[id]--; - if (network->wrsm_ncslice_users[id] == 0) { - wrsm_ncsliceconfig_set(network, id, - ncslice_invalid); - } - } - } - - (void) wrsm_tl_removecnode(node->network, - (cnodeid_t)node->config->cnodeid); - (void) ddi_unmap_regs(wrsm_ncslice_dip, - (uint_t)node->config->comm_ncslice, - &(node->cesr_vaddr), 0, PAGESIZE); - (void) ddi_unmap_regs(wrsm_ncslice_dip, - (uint_t)node->config->comm_ncslice, - &(node->lockout_vaddr), PAGESIZE, PAGESIZE); - node->cesr_vaddr = NULL; - node->lockout_vaddr = NULL; - } - remove_wrsm_node(node); -} - - - -/* - * Save away new configuration information. - * Notify the NR so it can save the routing configuration and stop rerouting. - * - * On failure, restore old configuration. - */ -int -wrsm_nc_replaceconfig(uint_t rsm_ctlr_id, wrsm_controller_t *config, - dev_info_t *dip, int attached_cnt, wci_ids_t *attached_wcis) -{ - int i, cindex; - int j; - int old_availability; - wrsm_network_t *network; - wrsm_node_t *node; - int err = EINVAL; - cnodeid_t cnodeid; - wrsm_net_member_t *nmem, *cmem; - wrsm_net_member_t *oconfig[WRSM_MAX_CNODES]; - wrsm_node_ncslice_array_t o_exported_ncslices; - boolean_t o_lgpg_ncslice; - boolean_t initialnr = B_FALSE; - boolean_t got_localnode_config = B_FALSE; - wrsm_net_member_t *new_localnode_config; - - TNF_PROBE_0(wrsm_nc_replaceconfig, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_replaceconfig: rsm_ctlr_id %d, " - "local cnodeid %d, config_version %ld, attached_cnt %d\n", - rsm_ctlr_id, config->cnodeid, config->version_stamp, - attached_cnt)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) { - DPRINTF(DBG_WARN, (CE_WARN, "nc_replaceconfig: bad rsm " - "ctlr id\n")); - return (ENXIO); - } - - - if (config->cnodeid != network->cnodeid) { - DPRINTF(DBG_WARN, (CE_WARN, "nc_replaceconfig: bad cnode\n")); - return (EINVAL); - } - - if (config->version_stamp == network->version_stamp) { - DPRINTF(DBG_WARN, (CE_WARN, "nc_replaceconfig: matching " - "version stamp\n")); - return (EEXIST); - } - - if (network->availability != wrsm_disabled && - network->availability != wrsm_enabled) { - DPRINTF(DBG_WARN, (CE_WARN, "nc_replaceconfig: bad " - "availability\n")); - return (EBUSY); - } - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_replaceconfig: checking nodes\n")); - - /* - * check for invalid changes in node config info - */ - for (i = 0; i < config->nmembers; i++) { - cnodeid = config->members[i]->cnodeid; - if (cnodeid == network->cnodeid) { - new_localnode_config = config->members[i]; - got_localnode_config = B_TRUE; - } - - if (network->nodes[cnodeid] == NULL) - continue; - nmem = network->nodes[cnodeid]->config; - cmem = config->members[i]; - - /* - * all ncslices in old config must also be in new config - */ - for (j = 0; j < WRSM_NODE_NCSLICES; j++) { - if ((cmem->exported_ncslices.id[j] != 0) && - (nmem->exported_ncslices.id[j] != - cmem->exported_ncslices.id[j])) { - DPRINTF(DBG_CONFIG, (CE_CONT, - "nc_replaceconfig: exported ncslice " - "change in new " - "config for node cnodeid %d\n", cnodeid)); - return (EINVAL); - } - } - - /* - * check that other configuration stuff hasn't changed - */ - if ((nmem->fmnodeid != cmem->fmnodeid) || - strcmp(nmem->hostname, cmem->hostname) || - (nmem->comm_ncslice != cmem->comm_ncslice) || - (nmem->comm_offset != cmem->comm_offset) || - (nmem->local_offset != cmem->local_offset)) { - /* these configuration changes not allowed */ - DPRINTF(DBG_WARN, (CE_WARN, - "nc_replaceconfig: bad node ncslice info " - " cnodeid %d\n", cnodeid)); - return (EINVAL); - } - } - - if ((config->nmembers != 0) && !got_localnode_config) { - DPRINTF(DBG_WARN, (CE_WARN, - "nc_replaceconfig: no routing config for local node\n")); - return (EINVAL); - } - - /* - * check that routing configuration is valid - */ - if ((err = wrsm_nr_verifyconfig(network, config, attached_cnt, - attached_wcis)) != WRSM_SUCCESS) - return (err); - - - - /* - * configuration looks reasonable - * set new state - */ - old_availability = network->availability; - network->availability = wrsm_disabled; - network->dip = dip; - o_exported_ncslices = network->exported_ncslices; - o_lgpg_ncslice = network->have_lg_page_ncslice; - if (got_localnode_config) { - network->exported_ncslices = - new_localnode_config->exported_ncslices; - } else { - WRSMSET_ZERO(network->exported_ncslices); - } - - network->have_lg_page_ncslice = B_FALSE; - for (i = 1; i < WRSM_NODE_NCSLICES; i++) { - if (network->exported_ncslices.id[i] != 0) { - network->have_lg_page_ncslice = B_TRUE; - break; - } - } - - - /* - * add new nodes; disable old nodes - */ - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_replaceconfig: adding nodes, " - "config->nmembers %d\n", config->nmembers)); - -#ifdef DEBUG - for (i = 1; i < config->nmembers; i++) { - ASSERT(config->members[i]->cnodeid > - config->members[i-1]->cnodeid); - } -#endif - i = 0; - for (cindex = 0; cindex < WRSM_MAX_CNODES; cindex++) { - oconfig[cindex] = NULL; - node = network->nodes[cindex]; - - /* - * the list of nodes in config->members is ordered by cnodeid - */ - if (i < config->nmembers && - config->members[i]->cnodeid == (cnodeid_t)cindex) { - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_replaceconfig: " - "have a config node - cnodeid %d, i %d\n", - cindex, i)); - - /* - * this is a valid node in new config - */ - if (node == NULL) { - /* - * new node - */ - if ((err = new_wrsm_node(network, - config->members[i], &node)) - != WRSM_SUCCESS) - goto err_cleanup; - } else { - /* - * node already existed - update config - * info - */ - ASSERT(node->availability == wrsm_enabled); - oconfig[cindex] = node->config; - node->config = config->members[i]; - } - - i++; - - } else { - /* - * this node is not valid in the new config - */ - if (node) { - node->availability = wrsm_disabled; - err = wrsm_sess_disable(network, cindex); - if (err) { - goto err_cleanup; - } - } - } - } - ASSERT(i == config->nmembers); - - - /* - * configure communication to the new nodes - */ - initialnr = wrsm_nr_initialconfig(network, attached_cnt, - attached_wcis); - - /* - * add routing info - */ - if ((err = wrsm_nr_replaceconfig(network, config, attached_cnt, - attached_wcis)) != WRSM_SUCCESS) { - goto err_cleanup; - } - - network->version_stamp = config->version_stamp; - wrsm_nr_logevent(network, NULL, new_config, NULL); - return (WRSM_SUCCESS); - - -err_cleanup: - network->exported_ncslices = o_exported_ncslices; - network->have_lg_page_ncslice = o_lgpg_ncslice; - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (network->nodes[i] == NULL) - continue; - - node = network->nodes[i]; - if (node->availability == wrsm_pending) { - node->availability = wrsm_disabled; - remove_wrsm_node(node); - } else if (node->availability == wrsm_disabled) { - node->availability = wrsm_enabled; - } else if (oconfig[i]) { - node->config = oconfig[i]; - } - } - - if (initialnr) - wrsm_nr_removeconfig(network); - - network->availability = old_availability; - - DPRINTF(DBG_WARN, (CE_WARN, "nc_replaceconfig: failed with " - "error %d\n", err)); - return (err); -} - - - -/* - * Reconfig transport and other layers to stop supporting old nodes. - * Turn off communication to nodes only in old configuration. - * Initiate link bringdown on links only in old configuration. - * Set up loopback route for local node. - */ -int -wrsm_nc_cleanconfig(uint32_t rsm_ctlr_id, int reroute_cnt, - wci_ids_t *reroute_wcis) -{ - int i; - wrsm_network_t *network; - wrsm_node_t *node; - int err; - - TNF_PROBE_0(wrsm_nc_cleanconfig, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_cleanconfig: rsm_ctlr_id %d\n", - rsm_ctlr_id)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) - return (ENXIO); - - if (network->availability != wrsm_disabled) - return (EBUSY); - - - network->availability = wrsm_pending; - - /* - * Clean up old routing configuration - use intersection - * of old and new configurations. - */ - if (err = wrsm_nr_cleanconfig(network, reroute_cnt, reroute_wcis)) { - return (err); - } - - - /* - * remove all nodes that are no longer part of the network - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (network->nodes[i] == NULL) - continue; - - node = network->nodes[i]; - - if (node->availability == wrsm_disabled) { - /* - * tear down communication path to all nodes that - * are no longer part of network - */ - remove_old_node(node); - } - } - - return (WRSM_SUCCESS); -} - - - -/* - * Wait for all old resources to stop being used. - * Bring up new links. - */ -int -wrsm_nc_installconfig(uint32_t rsm_ctlr_id) -{ - wrsm_network_t *network; - wrsm_node_t *node; - int err = WRSM_SUCCESS; - int i; - - TNF_PROBE_0(wrsm_nc_installconfig, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_installconfig: rsm_ctlr_id %d\n", - rsm_ctlr_id)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) { - DPRINTF(DBG_WARN, (CE_WARN, "nc_installconfig: bad " - "rsm ctlr id\n")); - return (ENXIO); - } - - if (network->availability != wrsm_pending) { - DPRINTF(DBG_WARN, (CE_WARN, "nc_installconfig: bad " - "availability\n")); - return (EBUSY); - } - - - /* - * Configure each node for communication and set up error - * pages. Skip local node, which has already been configured. - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (i == network->cnodeid) - continue; - node = network->nodes[i]; - if (node && node->availability == wrsm_pending) { - if ((err = config_new_node(node)) != WRSM_SUCCESS) - return (err); - } - } - - /* - * Wait for NR to complete old config clean and to - * start new link bringup - */ - err = wrsm_nr_installconfig(network); - - network->availability = wrsm_installed; - - return (err); -} - - -/* - * check whether all links are up yet - */ -boolean_t -wrsm_nc_is_installed_up(uint_t rsm_ctlr_id) -{ - wrsm_network_t *network; - - TNF_PROBE_0(wrsm_nc_checkconfig, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_checkconfig: rsm_ctlr_id %d\n", - rsm_ctlr_id)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) { - DPRINTF(DBG_WARN, (CE_WARN, "nc_checkconfig: bad rsm " - "ctlr id\n")); - return (B_FALSE); - } - - if (network->availability == wrsm_installed_up) - return (B_TRUE); - else - return (B_FALSE); -} - - - -/* - * start using new routes - */ -int -wrsm_nc_enableconfig(uint_t rsm_ctlr_id, int reroute_cnt, - wci_ids_t *reconfig_wcis) -{ - wrsm_network_t *network; - - TNF_PROBE_0(wrsm_nc_enableconfig, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_enableconfig: rsm_ctlr_id %d\n", - rsm_ctlr_id)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) { - DPRINTF(DBG_WARN, (CE_WARN, "nc_enableconfig: bad rsm " - "ctlr id\n")); - return (ENXIO); - } - - /* Increment num_reconfigs */ - network->num_reconfigs++; - - /* cancel enable timeout thread (or wait until it is finished) */ - if (network->enable_timeout_id) { - (void) untimeout(network->enable_timeout_id); - } - - if (network->availability == wrsm_enabled) { - /* timeout thread must have enabled network already */ - return (WRSM_SUCCESS); - } - - return (nc_enableconfig(network, reroute_cnt, reconfig_wcis)); -} - - - -/* - * internal version of nc_enableconfig() -- may be called from - * enable timeout thread - */ -static int -nc_enableconfig(wrsm_network_t *network, int reroute_cnt, - wci_ids_t *reconfig_wcis) -{ - int i; - int err = WRSM_SUCCESS; - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (network->nodes[i] == NULL) - continue; - network->nodes[i]->availability = wrsm_enabled; - } - - /* - * enable local routing - */ - err = wrsm_nr_enableconfig(network, reroute_cnt, reconfig_wcis); - - network->availability = wrsm_enabled; - - return (err); -} - - -int -wrsm_nc_create_errorpage(wrsm_network_t *network, - wrsm_cmmu_tuple_t **errorpage_tuplep, pfn_t *errorpage_pfnp, - boolean_t sleep) -{ - caddr_t errorpage_vaddr; - wrsm_cmmu_t cmmu; - uint_t num_tuples; - int err; - - if ((err = wrsm_cmmu_alloc(network, CMMU_PAGE_SIZE_SMALL, 1, - errorpage_tuplep, &num_tuples, sleep)) != WRSM_SUCCESS) { - DPRINTF(DBG_WARN, (CE_WARN, "no cmmu entry for loopback " - "error page on controller %d\n", network->rsm_ctlr_id)); - ASSERT(num_tuples == 1); - return (err); - } - - /* - * set up page to accept transactions, but return user error - * on all transactions - */ - cmmu.entry_0.bit.count_enable = B_FALSE; - cmmu.entry_0.bit.large_page = B_FALSE; - cmmu.entry_0.bit.user_err = B_TRUE; - cmmu.entry_0.bit.writable = B_TRUE; - cmmu.entry_0.bit.from_all = B_FALSE; - cmmu.entry_0.bit.valid = B_TRUE; - cmmu.entry_0.bit.type = CMMU_TYPE_CACHEABLE; - cmmu.entry_0.bit.from_node = network->cnodeid; - - wrsm_cmmu_update(network, &cmmu, - (*errorpage_tuplep)->index, CMMU_UPDATE_ALL); - - ASSERT(wrsm_ncslice_dip); - if ((err = ddi_map_regs(wrsm_ncslice_dip, - (uint_t)network->nodes[network->cnodeid]->config->comm_ncslice, - &errorpage_vaddr, (off_t)(*errorpage_tuplep)->offset, - PAGESIZE)) != DDI_SUCCESS) { - /* - * can't allow access to this node if this - * page can't be mapped - */ - DPRINTF(DBG_WARN, (CE_WARN, "wrsm: ddi_map_regs err %d -- " - "can't set up mapping to ncslice %d loopback error " - "page on controller %d\n", - err, - network->nodes[network->cnodeid]->config->comm_ncslice, - network->rsm_ctlr_id)); - err = EINVAL; - return (err); - } - - *errorpage_pfnp = va_to_pfn(errorpage_vaddr); - - ddi_unmap_regs(wrsm_ncslice_dip, - (uint_t)network->nodes[network->cnodeid]->config->comm_ncslice, - &errorpage_vaddr, (off_t)(*errorpage_tuplep)->offset, - PAGESIZE); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "loopback " - "error page pfn 0x%lx\n", *errorpage_pfnp)); - - return (0); -} - - - -/* - * install and enable a configuration for a new RSM network - */ -int -wrsm_nc_initialconfig(uint32_t rsm_ctlr_id, wrsm_controller_t *config, - dev_info_t *dip, int attached_cnt, wci_ids_t *attached_wcis) -{ - wrsm_network_t *network; - int err; - - TNF_PROBE_0(wrsm_nc_initialconfig, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_initialconfig: rsm_ctlr_id %d, " - "local cnodeid %d, attached_cnt %d\n", rsm_ctlr_id, - config->cnodeid, attached_cnt)); - - if ((err = new_network(rsm_ctlr_id, &network)) != WRSM_SUCCESS) - return (err); - - network->cnodeid = config->cnodeid; - network->dip = dip; - network->version_stamp = config->version_stamp - 1; - - /* - * initialize network->attr (rsm_controller_attr_t) with both the - * default driver values and the rsm_addr_t of the controller - * Note - it is required the cmmu_init take care of initializing - * other fields of the rsm_controller_attr_t structure. - */ - wrsm_rsm_setup_controller_attr(network); - - if ((err = wrsm_tl_init(network)) != WRSM_SUCCESS) { - remove_network(network); - return (err); - } - - wrsm_memseg_network_init(network); - - - if ((err = wrsm_nc_replaceconfig(rsm_ctlr_id, config, - dip, attached_cnt, attached_wcis)) != WRSM_SUCCESS) { - wrsm_memseg_network_fini(network); - wrsm_tl_fini(network); - remove_network(network); - return (err); - } - - ASSERT(network->nodes[network->cnodeid]); - if ((err = config_new_node(network->nodes[network->cnodeid])) - != WRSM_SUCCESS) { - goto err_cleanup; - } - network->nodes[network->cnodeid]->availability = wrsm_enabled; - - if ((err = wrsm_nc_cleanconfig(rsm_ctlr_id, attached_cnt, - attached_wcis)) != WRSM_SUCCESS) { - goto err_cleanup; - } - - - /* - * make sure the new config allows a loopback route - */ - if (!WRSM_NODE_HAVE_ROUTE(network->nodes[network->cnodeid])) { - DPRINTF(DBG_WARN, (CE_WARN, "no loopback route for " - "controller %d\n", network->rsm_ctlr_id)); - err = EIO; - goto err_cleanup; - } - - if ((err = wrsm_nc_create_errorpage(network, &network->errorpage_tuple, - &network->errorpage_pfn, B_FALSE)) != WRSM_SUCCESS) { - DPRINTF(DBG_WARN, (CE_WARN, "couldn't create error page " - "for controller %d\n", network->rsm_ctlr_id)); - goto err_cleanup; - } - - if ((err = wrsm_nc_installconfig(rsm_ctlr_id)) != WRSM_SUCCESS) { - goto err_cleanup; - } - /* - * notify RSMPI that there is a new network. - * - * RSMPI clients are kernel modules, and are expected to not mess - * up the network data structure. - */ - - if ((err = rsm_register_controller(WRSM_NAME, rsm_ctlr_id, - &network->attr)) != RSM_SUCCESS) { - cmn_err(CE_WARN, "register_controller failed for wrsm%d " - "with error %d\n", rsm_ctlr_id, err); - goto err_cleanup; - } - network->registered = B_TRUE; - - /* - * enable local routing - if necessary delay to allow links to come - * up before enabling routes - */ - mutex_enter(&network->lock); - if (network->availability == wrsm_installed_up) { - /* links are all already up - enable now */ - mutex_exit(&network->lock); - (void) nc_enableconfig(network, - attached_cnt, attached_wcis); - } else { - /* set a timeout to enable network later */ - DPRINTF(DBG_CONFIG, (CE_CONT, "setting timeout to " - "enable network\n")); - network->auto_enable = B_TRUE; - mutex_exit(&network->lock); - network->enable_timeout_id = - timeout(wrsm_nc_config_linksup, (void *)network, - (clock_t)WRSM_ENABLE_TIMEOUT); - } - - ASSERT(network->availability == wrsm_enabled || - network->availability == wrsm_installed || - network->availability == wrsm_installed_up); - - return (WRSM_SUCCESS); - -err_cleanup: - if (wrsm_nc_removeconfig(rsm_ctlr_id) != WRSM_SUCCESS) { - DPRINTF(DBG_WARN, (CE_WARN, "initialconfig: can't remove " - "failed controller %d installation", - network->rsm_ctlr_id)); - if (network->errorpage_tuple) - wrsm_cmmu_free(network, 1, network->errorpage_tuple); - wrsm_memseg_network_fini(network); - wrsm_tl_fini(network); - network->availability = wrsm_disabled; - remove_network(network); - } - return (err); -} - - -/* - * stop using an RSM controller, then remove it - */ -int -wrsm_nc_removeconfig(uint32_t rsm_ctlr_id) -{ - wrsm_controller_t configd; - wrsm_routing_data_t routingd; - wrsm_network_t *network; - int err; -#ifdef DEBUG - int i; -#endif - - TNF_PROBE_0(wrsm_nc_removeconfig, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_removeconfig: rsm_ctlr_id %d\n", - rsm_ctlr_id)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) - return (ENXIO); - /* - * if plugin has controller open, return EBUSY. - * Note, the plugin library (librsmwrsm.so opens the controller - * and keeps it open until completely done. this is how - * the driver knows that the RSMAPI library applications are not - * using the controller. - */ - if (network->is_controller_open) { - DPRINTF(DBG_WARN, - (CE_WARN, "nc_removeconfig: FAILED rsm_ctlr_id %d" - " EBUSY in use plugin\n", rsm_ctlr_id)); - return (EBUSY); - } - - if (network->registered) { - if ((err = rsm_unregister_controller(WRSM_NAME, rsm_ctlr_id)) - != RSM_SUCCESS) { - DPRINTF(DBG_WARN, - (CE_WARN, "rsm_unregister_controller " - "failed with error %d\n", err)); - return (EBUSY); - } - network->registered = B_FALSE; - } - - if (network->enable_timeout_id) { - (void) untimeout(network->enable_timeout_id); - network->enable_timeout_id = 0; - } - - /* - * initialize and install a null configuration - */ - bzero(&configd, sizeof (wrsm_controller_t)); - bzero(&routingd, sizeof (wrsm_routing_data_t)); - configd.controller_id = rsm_ctlr_id; - configd.cnodeid = network->cnodeid; - configd.version_stamp = network->version_stamp + 1; - configd.routing = &routingd; - - network->availability = wrsm_disabled; - if ((err = wrsm_nc_replaceconfig(rsm_ctlr_id, &configd, network->dip, - 0, (wci_ids_t *)NULL)) != WRSM_SUCCESS) { - return (err); - } - - /* - * Tear down communication to all nodes; - * stop using all old wcis, wnodes and links. - */ - (void) wrsm_nc_cleanconfig(rsm_ctlr_id, 0, NULL); - -#ifdef DEBUG - for (i = 0; i < WRSM_MAX_NCSLICES; i++) { - ASSERT(network->wrsm_ncslice_users[i] == 0); - } -#endif - - /* - * tear down loopback error page - */ - if (network->errorpage_tuple) - wrsm_cmmu_free(network, 1, network->errorpage_tuple); - - /* - * teardown segments after tearing down sessions - * (in replaceconfig) but before removing WCIs - * and CMMU entries (in nr_installconfig). - */ - wrsm_memseg_network_fini(network); - - /* - * Make sure cleanup of old wcis/links is complete, - * then remove all data structures associated with - * the configuration. - */ - (void) wrsm_nr_installconfig(network); - mutex_enter(&network->lock); - (void) wrsm_nr_removeconfig(network); - mutex_exit(&network->lock); - - wrsm_tl_fini(network); - network->availability = wrsm_disabled; - remove_network(network); - - return (WRSM_SUCCESS); -} - - -/* - * enable sessions on nodes in an RSM controller - */ -int -wrsm_nc_startconfig(uint32_t rsm_ctlr_id) -{ - wrsm_network_t *network; - int cindex; - - TNF_PROBE_0(wrsm_nc_startconfig, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_startconfig: rsm_ctlr_id %d\n", - rsm_ctlr_id)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) - return (ENXIO); - - for (cindex = 0; cindex < WRSM_MAX_CNODES; cindex++) { - if (network->nodes[cindex]) { - (void) wrsm_sess_enable(network, cindex); - } - } - - return (WRSM_SUCCESS); -} - - -/* - * disable sessions on nodes in an RSM controller - */ -int -wrsm_nc_stopconfig(uint32_t rsm_ctlr_id) -{ - wrsm_network_t *network; - int cindex; - - TNF_PROBE_0(wrsm_nc_stopconfig, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_stopconfig: rsm_ctlr_id %d\n", - rsm_ctlr_id)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) - return (ENXIO); - - for (cindex = 0; cindex < WRSM_MAX_CNODES; cindex++) { - if (network->nodes[cindex]) { - (void) wrsm_sess_disable(network, cindex); - } - } - - return (WRSM_SUCCESS); -} - - -/* - * If auto-enable has been requested, enable all new links and nodes after - * a timeout, or after all links are up, whichever comes first. - * (Auto-enable is requested if nc_initialconfig() is called to install a - * configuration.) - * - * If auto-enable has not been requested, simply set the network - * availability to installed_up so that a higher level entity (the RSM - * proxy) knows when it is a good time to call nc_enableconfig()). - */ -void -wrsm_nc_config_linksup(void *arg) -{ - boolean_t enable = B_FALSE; - wrsm_network_t *network = arg; - - TNF_PROBE_0(wrsm_nc_config_linksup, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_config_linksup: rsm_ctlr_id %d\n", - network->rsm_ctlr_id)); - - if (network->enable_timeout_id) { - (void) untimeout(network->enable_timeout_id); - } - - mutex_enter(&network->lock); - - if (network->auto_enable == B_TRUE) { - /* auto enable of the network has been requested */ - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_config_linksup: " - "auto enable\n")); - network->auto_enable = B_FALSE; - if (network->availability != wrsm_enabled) { - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_config_linksup: " - "enabling\n")); - enable = B_TRUE; - } - } else { - /* don't auto enable - just change network availability */ - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_config_linksup: no auto " - "enable\n")); - if (network->availability != wrsm_enabled) { - DPRINTF(DBG_CONFIG, (CE_CONT, "nc_config_linksup: set " - "state " - "to installed_up\n")); - network->availability = wrsm_installed_up; - } - } - - mutex_exit(&network->lock); - - if (enable) { - /* - * auto-enable was requested - call nc_enableconfig - */ - (void) nc_enableconfig(network, -1, NULL); - /* - * let the controller know we've moved to enabled state - */ - wrsm_cf_is_enabled(network->rsm_ctlr_id); - } -} - - - -/* - * notify the NC that a WCI in the specified controller is now - * attached, so the NC can start using it - */ -int wrsm_nc_newwci(uint32_t rsm_ctlr_id, safari_port_t safid, - lcwci_handle_t lcwci, wrsm_controller_t *config) - -{ - wrsm_network_t *network; - int err; - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) - return (ENXIO); - - if (network->availability != wrsm_enabled) - return (EBUSY); - - if (network->nr == NULL) - return (EINVAL); - - if ((err = wrsm_nr_attachwci(network, safid, lcwci, config, - B_TRUE, B_TRUE)) != - WRSM_SUCCESS) - return (err); - - return (wrsm_nr_enablewci(network, safid, B_TRUE)); -} - - -/* - * notify the NC that a WCI in the specified controller is being - * detached, so the NC stops using it - */ -int -wrsm_nc_removewci(uint32_t rsm_ctlr_id, safari_port_t safid) -{ - wrsm_network_t *network; - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - if (network == NULL) - return (ENXIO); - - if (network->nr == NULL) - return (EINVAL); - - if (network->availability != wrsm_enabled) - return (EBUSY); - - /* force removal even if wci is in use */ - return (wrsm_nr_detachwci(network, safid, B_TRUE)); -} - -/* - * functions for managing lists wrsm_node_t structures - */ - -/* - * find node structure from RSM fmnodeid - */ -wrsm_node_t * -wrsm_fmnodeid_to_node(wrsm_network_t *network, fmnodeid_t fmnodeid) -{ - int index; - wrsm_node_t *node; - - ASSERT(MUTEX_HELD(&network->lock)); - - index = WRSM_CNODE_HASH_FUNC(fmnodeid); - ASSERT(index < WRSM_CNODE_HASH_SIZE); - node = network->node_hash[index]; - while (node) { - if (node->config->fmnodeid == fmnodeid) - return (node); - node = node->hash; - } - - return (NULL); -} - -/* - * get cnodeid from fmnodeid - */ -int -wrsm_fmnodeid_to_cnodeid(wrsm_network_t *network, - fmnodeid_t fmnodeid, cnodeid_t *cnodeidp) -{ - wrsm_node_t *node; - - ASSERT(MUTEX_HELD(&network->lock)); - - node = wrsm_fmnodeid_to_node(network, fmnodeid); - if (node) { - *cnodeidp = node->config->cnodeid; - return (WRSM_SUCCESS); - } else { - return (EBADF); - } -} - - -/* - * create a new node structure; set default values - */ -static int -new_wrsm_node(wrsm_network_t *network, wrsm_net_member_t *member, - wrsm_node_t **nodep) -{ - wrsm_node_t *node, **np; - int index; - cnodeid_t cnodeid; - fmnodeid_t fmnodeid; - - TNF_PROBE_0(wrsm_nc_new_wrsm_node, "wrsm", /* CSTYLED */); - - node = kmem_alloc(sizeof (wrsm_node_t), KM_SLEEP); - bzero(node, sizeof (wrsm_node_t)); - node->network = network; - node->config = member; - node->availability = wrsm_pending; - node->state = wrsm_node_needroute; - node->cesr_vaddr = NULL; - node->lockout_vaddr = NULL; - - cnodeid = member->cnodeid; - fmnodeid = member->fmnodeid; - - mutex_enter(&network->lock); - - if (network->nodes[cnodeid]) { - mutex_exit(&network->lock); - kmem_free(node, sizeof (wrsm_node_t)); - return (EADDRINUSE); - } - - if (wrsm_fmnodeid_to_node(network, fmnodeid) != NULL) { - mutex_exit(&network->lock); - kmem_free(node, sizeof (wrsm_node_t)); - return (EADDRINUSE); - } - - network->wrsm_num_nodes++; /* for each node - remote and local */ - - network->nodes[cnodeid] = node; - /* - * route_umem space was allocated previously by ddi_umem_alloc - * so that the librsmwrsm.c (plugin library) would be able - * to easily mmap in kernel address space. The - * network->node[cnodeid].link_stripesp field is also used - * by the plugin to determine striping - */ - network->nodes[cnodeid]->link_stripesp = (uint32_t *) - ((uint64_t)network->route_umem + sizeof (uint64_t)); - wrsm_memseg_node_init(node); - - /* - * add to node_hash - */ - index = WRSM_CNODE_HASH_FUNC(fmnodeid); - ASSERT(index < WRSM_CNODE_HASH_SIZE); - np = &(network->node_hash[index]); - node->hash = *np; - *np = node; - - mutex_exit(&network->lock); - - *nodep = node; - return (WRSM_SUCCESS); -} - - -/* - * remove node structure from network, free it - */ -static void -remove_wrsm_node(wrsm_node_t *node) -{ - wrsm_network_t *network; - wrsm_node_t **np; - int index; - - TNF_PROBE_0(wrsm_nc_remove_wrsm_node, "wrsm", /* CSTYLED */); - - ASSERT(node != NULL); - ASSERT(node->config != NULL); - ASSERT(node->network != NULL); - ASSERT(node->availability == wrsm_disabled); - - ASSERT(node->routeinfo == NULL); - - network = node->network; - - mutex_enter(&network->lock); - ASSERT(network->nodes[node->config->cnodeid] != NULL); - network->nodes[node->config->cnodeid] = NULL; - - /* - * remove node from hash table - */ - index = WRSM_CNODE_HASH_FUNC(node->config->fmnodeid); - ASSERT(index < WRSM_CNODE_HASH_SIZE); - np = &(network->node_hash[index]); - - while (*np != NULL && *np != node) { - np = &((*np)->hash); - } - - if (*np == NULL) { -#ifdef DEBUG - cmn_err(CE_PANIC, "node %p (cnodeid %d) not in hash table", - (void *) node, node->config->cnodeid); -#endif - mutex_exit(&network->lock); - return; - } - - *np = node->hash; - - mutex_exit(&network->lock); - - wrsm_memseg_node_fini(node); - - kmem_free(node, sizeof (wrsm_node_t)); - /* - * Decrease the number of nodes in the network, - * Since it is decreased we set free_rag_instance to TRUE - * so that the instances can be freed later in installconfig. - */ - - network->free_rag_instance = B_TRUE; - network->wrsm_num_nodes--; -} - - - -/* - * functions for managing lists of wrsm_network_t structures - */ - -wrsm_network_t * -wrsm_nc_cnodeid_to_network(cnodeid_t cnodeid) -{ - wrsm_network_t *network; - - mutex_enter(&wrsm_networks_lock); - for (network = wrsm_networks; network != NULL; - network = network->next) { - if (network->cnodeid == cnodeid) { - mutex_exit(&wrsm_networks_lock); - return (network); - } - } - - mutex_exit(&wrsm_networks_lock); - return (NULL); -} - -wrsm_network_t * -wrsm_nc_ctlr_to_network(uint32_t rsm_ctlr_id) -{ - wrsm_network_t *network; - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - mutex_exit(&wrsm_networks_lock); - return (network); -} - -/* - * find network structure from controller id - */ -static wrsm_network_t * -rsmctlr_to_network(uint32_t rsm_ctlr_id) -{ - wrsm_network_t *network; - - ASSERT(MUTEX_HELD(&wrsm_networks_lock)); - - for (network = wrsm_networks; network != NULL; - network = network->next) { - if (network->rsm_ctlr_id == rsm_ctlr_id) - return (network); - } - return (NULL); -} - -/* - * create a new network structure; initialize it - */ -static int -new_network(uint32_t rsm_ctlr_id, wrsm_network_t **networkp) -{ - wrsm_network_t *network; - - TNF_PROBE_0(wrsm_nc_new_network, "wrsm", /* CSTYLED */); - - network = kmem_alloc(sizeof (wrsm_network_t), KM_SLEEP); - bzero(network, sizeof (wrsm_network_t)); - network->rsm_ctlr_id = rsm_ctlr_id; - network->availability = wrsm_disabled; - network->registered = B_FALSE; - network->errorpage_pfn = 0; - network->errorpage_mappings = 0; - network->num_reconfigs = 0; - /* - * wrsm_num_nodes and free_rag_instance are used to determine if we - * should freeze and or release RAG instances. When there - * are more than 8 nodes on a RSM network we must freeze - * RAG instances per hardware requirement (see PRM). - * We release instances when nodes have been removed from the - * network - that is, when free_rag_instance is set to TRUE - */ - - network->wrsm_num_nodes = 0; - network->free_rag_instance = B_FALSE; - - mutex_init(&network->errorpage_lock, NULL, MUTEX_DRIVER, NULL); - - mutex_enter(&wrsm_networks_lock); - - if (rsmctlr_to_network(rsm_ctlr_id)) { - /* network already exists for this controller */ - mutex_exit(&wrsm_networks_lock); - kmem_free(network, sizeof (wrsm_network_t)); - return (EBUSY); - } - - /* - * allocate kernel space that will also be visible to user - * space by a mmap call - */ - network->route_umem = ddi_umem_alloc(WRSM_PAGESIZE, DDI_UMEM_SLEEP, - &network->route_cookie); - if (network->route_umem == NULL) { - mutex_exit(&wrsm_networks_lock); - kmem_free(network, sizeof (wrsm_network_t)); - return (EAGAIN); - - } - network->route_counterp = (uint32_t *)network->route_umem; - network->reroutingp = (uint32_t *)((uint64_t)network->route_umem + - sizeof (uint32_t)); - network->is_controller_open = B_FALSE; - /* - * add to list of wrsm_networks - */ - network->next = wrsm_networks; - wrsm_networks = network; - - /* Add controller (rsmpi) kstat */ - add_wrsm_ctlr_kstat(network); - - mutex_exit(&wrsm_networks_lock); - - DPRINTF(DBG_CONFIG, (CE_CONT, "added network 0x%p (controller id %d)\n", - (void *) network, network->rsm_ctlr_id)); - - *networkp = network; - return (WRSM_SUCCESS); -} - -/* - * remove network structure from list of wrsm_networks and free - */ -static void -remove_network(wrsm_network_t *network) -{ -#ifdef DEBUG - int i; -#endif - wrsm_network_t **np; - - TNF_PROBE_0(wrsm_nc_remove_network, "wrsm", /* CSTYLED */); - - ASSERT(network != NULL); - ASSERT(network->availability == wrsm_disabled); - ASSERT(network->transport == NULL); - ASSERT(network->nr == NULL); -#ifdef DEBUG - for (i = 0; i < WRSM_MAX_CNODES; i++) { - ASSERT(network->nodes[i] == NULL); - } -#endif - - /* Remove controller (rsmpi) kstat */ - del_wrsm_ctlr_kstat(network); - - mutex_enter(&wrsm_networks_lock); - for (np = &wrsm_networks; *np != NULL; np = &((*np)->next)) { - if (*np == network) { - *np = network->next; - mutex_exit(&wrsm_networks_lock); - - DPRINTF(DBG_CONFIG, (CE_CONT, "found and removed " - "network 0x%p (controller id %d)\n", - (void *) network, network->rsm_ctlr_id)); - ddi_umem_free(network->route_cookie); - mutex_destroy(&network->errorpage_lock); - kmem_free(network, sizeof (wrsm_network_t)); - return; - } - } - mutex_exit(&wrsm_networks_lock); - -#ifdef DEBUG - cmn_err(CE_WARN, "network 0x%p (id %d) not in wrsm_networks", - (void *) network, network->rsm_ctlr_id); -#endif -} - - -int -wrsm_get_peers(rsm_controller_handle_t controller, rsm_addr_t *addr_list, - uint_t count, uint_t *num_addrs) -{ - wrsm_network_t *network = (wrsm_network_t *)controller; - int i, j; - - *num_addrs = 0; - j = 0; - - mutex_enter(&network->lock); - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (network->nodes[i]) { - (*num_addrs)++; - if (j < count) { - addr_list[j] = (rsm_addr_t)i; - j++; - } - } - } - mutex_exit(&network->lock); - - return (RSM_SUCCESS); -} - - - - -/* - * initialization - returns standard errno errors - */ -void -wrsm_nc_init() -{ - TNF_PROBE_0(wrsm_nc_init, "wrsm", /* CSTYLED */); - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nc_init()\n")); - - mutex_init(&wrsm_networks_lock, NULL, MUTEX_DRIVER, NULL); -} - - -/* - * cleanup - */ -int -wrsm_nc_fini() -{ - TNF_PROBE_0(wrsm_nc_fini, "wrsm", /* CSTYLED */); - - if (wrsm_nc_check() == WRSM_SUCCESS) { - wrsm_nc_cleanup(); - return (WRSM_SUCCESS); - } - - return (EBUSY); -} - -int -wrsm_nc_check() -{ - mutex_enter(&wrsm_networks_lock); - - if (wrsm_networks) { - mutex_exit(&wrsm_networks_lock); - return (EBUSY); - } - - mutex_exit(&wrsm_networks_lock); - - return (WRSM_SUCCESS); -} - -void -wrsm_nc_cleanup() -{ - mutex_destroy(&wrsm_networks_lock); -} - -/* Create the controller kstat */ -/* - * add_wrsm_ctlr_kstat - */ -static void -add_wrsm_ctlr_kstat(wrsm_network_t *network) -{ - kstat_t *ctlr_ksp; - wrsm_rsmpi_stat_t *ctlr_named; - - ctlr_ksp = kstat_create(WRSM_KSTAT_WRSM, - network->rsm_ctlr_id, - RSM_KS_NAME, - "net", - KSTAT_TYPE_NAMED, - sizeof (wrsm_rsmpi_stat_t) / sizeof (kstat_named_t), - 0); - - if (ctlr_ksp == NULL) { - cmn_err(CE_WARN, - "rsm ctlr %d: controller kstat_create failed", - network->rsm_ctlr_id); - return; - } - - ctlr_named = (wrsm_rsmpi_stat_t *)(ctlr_ksp->ks_data); - - /* initialize the named kstats (wrsm specific) */ - - kstat_named_init(&ctlr_named->free_cmmu_entries, - WRSMKS_FREE_CMMU_ENTRIES, KSTAT_DATA_UINT32); - - kstat_named_init(&ctlr_named->num_reconfigs, - WRSMKS_NUM_RECONFIGS, KSTAT_DATA_UINT32); - - kstat_named_init(&ctlr_named->num_wcis, - WRSMKS_RSM_NUM_WCIS, KSTAT_DATA_UINT32); - - kstat_named_init(&ctlr_named->avail_wcis, - WRSMKS_RSM_AVAIL_WCIS, KSTAT_DATA_UINT32); - - /* these are defined in rsmpi.h */ - - kstat_named_init(&ctlr_named->ctlr_state, - RSM_KS_CTLR_STATE, KSTAT_DATA_CHAR); - - kstat_named_init(&ctlr_named->addr, - RSM_KS_ADDR, KSTAT_DATA_UINT64); - - kstat_named_init(&ctlr_named->ex_memsegs, - RSM_KS_EX_MEMSEGS, KSTAT_DATA_UINT32); - - kstat_named_init(&ctlr_named->ex_memsegs_pub, - RSM_KS_EX_MEMSEGS_PUB, KSTAT_DATA_UINT32); - - kstat_named_init(&ctlr_named->ex_memsegs_con, - RSM_KS_EX_MEMSEGS_CON, KSTAT_DATA_UINT32); - - kstat_named_init(&ctlr_named->bytes_bound, - RSM_KS_BYTES_BOUND, KSTAT_DATA_UINT64); - - kstat_named_init(&ctlr_named->im_memsegs_con, - RSM_KS_IM_MEMSEGS_CON, KSTAT_DATA_UINT32); - - kstat_named_init(&ctlr_named->sendqs, - RSM_KS_SENDQS, KSTAT_DATA_UINT64); - - kstat_named_init(&ctlr_named->handlers, - RSM_KS_HANDLERS, KSTAT_DATA_UINT64); - - ctlr_ksp->ks_update = ctlr_kstat_update; - ctlr_ksp->ks_private = (void *)network; - kstat_install(ctlr_ksp); - - network->wrsm_rsmpi_stat_ksp = ctlr_ksp; -} - -static void -del_wrsm_ctlr_kstat(wrsm_network_t *network) -{ - kstat_delete(network->wrsm_rsmpi_stat_ksp); -} - -static int -ctlr_kstat_update(kstat_t *ksp, int rw) -{ - wrsm_rsmpi_stat_t *ctlr_ksp; - wrsm_network_t *network; - wrsm_memseg_stat_data_t data; - uint_t num_wcis, avail_wcis; - - ctlr_ksp = (wrsm_rsmpi_stat_t *)ksp->ks_data; - network = (wrsm_network_t *)ksp->ks_private; - - ASSERT(network != NULL); - - if (rw == KSTAT_WRITE) { - return (EACCES); - } - - /* Update the named values */ - ctlr_ksp->num_reconfigs.value.ui32 = network->num_reconfigs; - - if (network->registered) { - (void) strncpy(ctlr_ksp->ctlr_state.value.c, RSM_AE_CTLR_UP, - strlen(RSM_AE_CTLR_UP)); - } else { - (void) strncpy(ctlr_ksp->ctlr_state.value.c, RSM_AE_CTLR_DOWN, - strlen(RSM_AE_CTLR_DOWN)); - } - ctlr_ksp->addr.value.ui64 = network->cnodeid; - - /* access private information form the memseg */ - wrsm_memseg_stat(network, &data); - - ctlr_ksp->ex_memsegs.value.ui32 = data.export_count; - ctlr_ksp->ex_memsegs_pub.value.ui32 = data.export_published; - ctlr_ksp->ex_memsegs_con.value.ui32 = data.export_connected; - ctlr_ksp->bytes_bound.value.ui64 = data.bytes_bound; - ctlr_ksp->im_memsegs_con.value.ui32 = data.import_count; - ctlr_ksp->sendqs.value.ui64 = network->sendqs_num; - ctlr_ksp->handlers.value.ui64 = network->handler_num; - - /* access private information from the cmmu */ - ctlr_ksp->free_cmmu_entries.value.ui32 = wrsm_cmmu_num_free(network); - /* check the number of wcis */ - wrsm_get_wci_num(network, &num_wcis, &avail_wcis); - ctlr_ksp->num_wcis.value.ui32 = num_wcis; - ctlr_ksp->avail_wcis.value.ui32 = avail_wcis; - - return (0); -} - - - - -/* Functions provide for Plugin library librsmwrsm.so support for RSMAPI */ -int -wrsm_nc_open_controller(uint_t rsm_ctlr_id) -{ - wrsm_network_t *network; - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nc_open_controller")); - - network = wrsm_nc_ctlr_to_network(rsm_ctlr_id); - /* if controller isn't part of a configuration, fail */ - if (!network) { - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nc_open_controller no network")); - return (ENXIO); - } - if (!network->registered) { - return (EBUSY); - } - if (!network->is_controller_open) { - /* - * Only needs to be set to TRUE the first time. controller - * can be opened numerous times, however, it is only closed - * once. - */ - network->is_controller_open = B_TRUE; - } - return (WRSM_SUCCESS); -} - -/* - * network->is_controller_open to FALSE so the remove config will - * know that the the controller device is not in use by the plugin. - */ -void -wrsm_nc_close_controller(uint_t rsm_ctlr_id) -{ - wrsm_network_t *network; - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nc_close_controller" - " controller %d", rsm_ctlr_id)); - - network = wrsm_nc_ctlr_to_network(rsm_ctlr_id); - - ASSERT(network); - ASSERT(network->is_controller_open); - network->is_controller_open = B_FALSE; - -} - -/* - * ioctl supplied for plugin library to determine if the export cnode is - * the local cnode - loopback. Returns WRSM_SUCCESS (0) if match - */ -/* ARGSUSED */ -int -wrsm_nc_getlocalnode_ioctl(int minor, int cmd, intptr_t arg, int flag, - cred_t *cred_p, int *rval_p) -{ - wrsm_network_t *network; - rsm_addr_t local_cnode; - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nc_getlocalnode_ioctl")); - network = wrsm_nc_ctlr_to_network(minor); - - if (network == NULL) { - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nc_getlocalnode_ioctl" - " no valid network for controller %d", minor)); - return (ENODEV); - } - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nc_getlocalnode_ioctl local cnode " - " is %d controller %d", network->cnodeid, network->rsm_ctlr_id)); - local_cnode = (rsm_addr_t)network->cnodeid; - if (ddi_copyout(&local_cnode, (void *)arg, sizeof (rsm_addr_t), - flag) != 0) { - *rval_p = EFAULT; - } else { - *rval_p = WRSM_SUCCESS; - } - - return (*rval_p); -} - - -/* - * This function translates from nodename to rsm_addr for that node through - * the specified controller. (This is for SunCluster, if they want it...) - */ -int -wrsm_nodename_to_rsmaddr(uint_t rsm_ctlr_id, char *nodename, rsm_addr_t *addr) -{ - wrsm_network_t *network; - wrsm_node_t *node; - int i; - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - if (network) { - mutex_enter(&network->lock); - } - mutex_exit(&wrsm_networks_lock); - - if (!network) { - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nodename_to_rsmaddr " - "no network")); - return (ENODEV); - } - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (node == NULL) - continue; - - if (strcmp(nodename, node->config->hostname) == 0) { - /* found matching node */ - *addr = (rsm_addr_t)i; - mutex_exit(&network->lock); - return (0); - } - } - - mutex_exit(&network->lock); - return (ENXIO); -} - - -int -wrsm_nc_suspend(uint_t rsm_ctlr_id) -{ - int ret; - wrsm_network_t *network; - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nc_suspend ctlr %d", rsm_ctlr_id)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - if (network) { - mutex_enter(&network->lock); - } - mutex_exit(&wrsm_networks_lock); - - if (!network) { - return (DDI_SUCCESS); - } - - ret = wrsm_nr_suspend(network); - - mutex_exit(&network->lock); - return (ret); -} - - -int -wrsm_nc_resume(uint_t rsm_ctlr_id) -{ - int ret; - wrsm_network_t *network; - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nc_resume ctlr %d", rsm_ctlr_id)); - - mutex_enter(&wrsm_networks_lock); - network = rsmctlr_to_network(rsm_ctlr_id); - if (network) { - mutex_enter(&network->lock); - } - mutex_exit(&wrsm_networks_lock); - - if (!network) { - return (DDI_SUCCESS); - } - - ret = wrsm_nr_resume(network); - - mutex_exit(&network->lock); - return (ret); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_nr.c b/usr/src/uts/sun4u/io/wrsm/wrsm_nr.c deleted file mode 100644 index 5dd57de5da..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_nr.c +++ /dev/null @@ -1,7192 +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" - -/* - * Network routing module of the Wildcat RSM driver. This file manages - * routes to nodes. It calculates which links to use to route transactions - * to each remote node, based on the preferred route list for that node. - * It handles failing routes between links and wcis. This includes setting - * up and tearing down wci striping. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/kmem.h> -#include <sys/disp.h> -#include <sys/cpuvar.h> -#include <sys/tnf_probe.h> -#include <sys/cmn_err.h> -#include <sys/errno.h> -#include <sys/debug.h> -#include <sys/systm.h> -#include <sys/callb.h> -#include <sys/nvpair.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> - - -#include <sys/wci_regs.h> -#include <sys/wci_offsets.h> -#include <sys/wci_common.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_nc_impl.h> -#include <sys/wrsm_lc.h> -#include <sys/wrsm_transport.h> -#include <sys/wrsm_session.h> -#include <sys/wrsm_cmmu.h> -#include <sys/wrsm_intr.h> -#include <sys/wrsm_memseg.h> - -#ifdef DEBUG -#define DBG_CONFIG 0x001 -#define DBG_ROUTE 0x002 -#define DBG_HW 0x004 -#define DBG_EVENT 0x008 -#define DBG_CONFIG_EXTRA 0x010 -#define DBG_ROUTE_EXTRA 0x020 -#define DBG_HW_EXTRA 0x040 -#define DBG_EVENT_EXTRA 0x080 -#define DBG_WARN 0x100 -#define DBG_RT_KSTAT 0x200 -/* - * Shouldn't actually call cmn_err while cpus are paused -- this could - * cause a kmem_alloc to create the string to print, which might require a - * lock, which if currently taken will never be freed because the owning - * cpu is now paused... ask me how I know. In other words, use these - * debug flags at your own risk. - */ -#define DBG_PAUSECPUS 0x1000 -#define DBG_PAUSECPUS_EXTRA 0x2000 -#define DBG_PAUSECPUSWARN 0x4000 - -/* - * 0xff0f - DBG_CONFIG_EXTRA DBG_ROUTE_EXTRA DBG_HW_EXTRA DBG_EVENT_EXTRA - * not turned on - */ -static uint_t wrsm_nr_debug = DBG_WARN; - -#define DPRINTF(a, b) { if (wrsm_nr_debug & a) wrsmdprintf b; } - -#else /* DEBUG */ -#define DPRINTF(a, b) { } -#endif /* DEBUG */ - -static void nr_event_thread(wrsm_network_t *network); -static void nr_wait_for_event_drain(wrsm_network_t *network); -static void nr_wait_for_wcis_rerouted(wrsm_network_t *network); -static void nr_pause_event_thread(wrsm_network_t *network); -static void nr_unpause_event_thread(wrsm_network_t *network); -static void nr_process_event(wrsm_network_t *network, - wrsm_nr_event_t *event); - -static wrsm_ncwci_t *nr_safid_to_wci(wrsm_network_t *network, safari_port_t); -static void nr_wci_routechange(wrsm_ncwci_t *wci, - wrsm_mh_reachable_t *reachable, wrsm_wci_reroute_t reroute); -static void nr_reroute_wcis(void *arg); -static boolean_t wci_in_use(wrsm_ncwci_t *wci); -static void nr_update_wci(wrsm_ncwci_t *wci); -static void nr_add_extended_routes(wrsm_node_t *local_node, - wrsm_controller_t *config); -static void nr_free_extended_routes(wrsm_node_t *local_node); - -static wrsm_nc_strgrp_t *nr_sgid_to_sg(wrsm_network_t *network, - uint32_t sgid); -static int nr_sg_install(wrsm_network_t *network); -static int nr_sg_unstripe(wrsm_nc_strgrp_t *sg); -static int nr_sg_stripe(wrsm_nc_strgrp_t *sg); - -static boolean_t nr_cnode_route(wrsm_node_t *node); -static void ncslice_build_route(wrsm_node_t *node, ncslice_route_t *routep, - wrsm_preferred_route_t *proute, boolean_t force); -static int ncslice_one_wci_route(wrsm_routing_policy_t *policy, - ncslice_route_t *routep, wrsm_preferred_route_t *proute, - cnode_bitmask_t used_switches, int max_stripes, wrsm_ncwci_t *wci, - int wcinum); -static void ncslice_build_wci_route(wrsm_routing_policy_t *policy, - ncslice_route_t *routep, wrsm_preferred_route_t *proute, wrsm_ncwci_t *wci); -static void ncslice_build_sg_route(wrsm_routing_policy_t *policy, - ncslice_route_t *routep, wrsm_preferred_route_t *proute, - wrsm_nc_strgrp_t *sg); -static void ncslice_build_sg_nostripe_route(wrsm_routing_policy_t *policy, - ncslice_route_t *routep, wrsm_preferred_route_t *proute, - wrsm_nc_strgrp_t *sg); -static boolean_t ncslice_routes_match(ncslice_route_t *route1, - ncslice_route_t *route2); -static boolean_t ncslice_switch_to_inids(wrsm_ncwci_t *wci, cnodeid_t cnodeid); -static int ncslice_find_inid(wrsm_ncwci_t *wci, wnodeid_t *dnidlist, - int stripes, cnodeid_t cnodeid); -static void ncslice_add_hw_route(wrsm_node_t *node, ncslice_route_t route); -static void ncslice_remove_hw_route(wrsm_node_t *node, ncslice_route_t route); -static void ncslice_apply_routes(wrsm_network_t *network); - -static void nr_reroute_start(wrsm_network_t *network); -static void nr_reroute_finish(wrsm_network_t *network); -static void nr_noroute(wrsm_node_t *node); -static boolean_t nr_haveroute(wrsm_node_t *node); - -static void pt_noroute(wrsm_node_t *node); -static boolean_t pt_haveroute(wrsm_node_t *node); -static void pt_newptinfo(wrsm_network_t *network, pt_msgtype_t msgtype, - wrsm_node_t *node); -static int pt_sendptlist(wrsm_node_t *node, wrsm_message_t *msg); -static boolean_t pt_ptlist_recv_hdlr(wrsm_network_t *network, - wrsm_message_t *msg); -static void pt_route_update(wrsm_node_t *node, cnode_bitmask_t pt_provided, - int route_counter); -static void stop_ncslice_traffic(wrsm_network_t *network, - boolean_t stop_incoming); -static void restart_ncslice_traffic(wrsm_network_t *network, - boolean_t stop_incoming); -static void nr_rag_freeze(wrsm_ncwci_t *wci, uint_t number_of_nodes); -static void add_wrsm_route_kstat(wrsm_node_t *node); -static void del_wrsm_route_kstat(wrsm_node_t *node); -static int update_wrsm_route_kstat(kstat_t *ksp, int rw); -/* - * Freezes number_to_freeze of RAG instances starting at 0th bit. - * Its is required that the CPUs be inactive before calling this function if - * the number of RAGS to freeze (number_to_freeze) is greater than the number - * of RAGs currently frozen. - * We call this function in wrsm_nr_replaceconfig after freezing CPUs - * in order to freeze additional RAG instances. We call this function from - * wrsm_nr_enableconfig without freezing CPUs in order to unfreeze RAG - * instances. - */ -static void -nr_rag_freeze(wrsm_ncwci_t *wcip, uint_t number_of_nodes) -{ - uint_t number_to_freeze; - wci_ra_freeze_u wci_ra_freeze; - int i; - -#ifdef DEBUG - wci_ra_busy_u wci_ra_busy; -#endif - - DPRINTF(DBG_HW, (CE_CONT, "nr_rag_freeze() ")); - number_to_freeze = WRSM_MAX_RAG_INSTANCE - - min(WRSM_MAX_RAG_INSTANCE, (WRSM_MAX_CNODES/number_of_nodes)); - while (wcip) { - if ((wcip->lcwci == NULL) || (wcip->network == NULL)) { - wcip = wcip->next; - continue; - } -#ifdef DEBUG - wrsm_lc_csr_read(wcip->lcwci, (uint64_t)ADDR_WCI_RA_FREEZE, - &(wci_ra_freeze.val)); - wrsm_lc_csr_read(wcip->lcwci, (uint64_t)ADDR_WCI_RA_BUSY, - &(wci_ra_busy.val)); - - DPRINTF(DBG_HW, (CE_CONT, "nr_rag_freeze: controller %d," - "cnode id %d number of nodes %d, Initial wci_ra_freeze " - "0x%lx initial wci_ra_busy 0x%lx", - wcip->network->rsm_ctlr_id, wcip->network->cnodeid, - number_of_nodes, wci_ra_freeze.bit.vector, - wci_ra_busy.val)); -#endif /* DEBUG */ - - /* - * we don't need to worry about saving Instances frozen due to - * error since such an occurence will cause the domain to - * go dead. - */ - - wci_ra_freeze.val = 0; - DPRINTF(DBG_HW, (CE_CONT, "nr_rag_freeze: number to" - "freeze %d", number_to_freeze)); - /* per PRM, bits are to be set starting from 0th bit up */ - for (i = 0; i < number_to_freeze; i ++) { - wci_ra_freeze.bit.vector |= 1 << i; - } - wrsm_lc_csr_write(wcip->lcwci, (uint64_t)ADDR_WCI_RA_FREEZE, - wci_ra_freeze.val); -#ifdef DEBUG - wrsm_lc_csr_read(wcip->lcwci, (uint64_t)ADDR_WCI_RA_FREEZE, - &(wci_ra_freeze.val)); - DPRINTF(DBG_HW, (CE_CONT, "nr_rag_freeze: final value 0x%lx", - wci_ra_freeze.bit.vector)); -#endif /* DEBUG */ - wcip = wcip->next; - - } - -} - -/* - * Configuration Functions - * - * The configuration functions and wci add/delete function - * (wrsm_nr_replaceconfig(), wrsm_nr_cleanconfig(), wrsm_nr_installconfig(), - * wrsm_nr_enableconfig(), wrsm_nr_initialconfig(), wrsm_nr_removeconfig(), - * wrsm_nr_attachwci(), wrsm_nr_enablecwci() and wrsm_nr_detachwci()) are all - * guaranteed to be single threaded. The config layer causes the NC to - * call these functions. The config later is the only consumer of these and - * it will never call a second function in the NC before the first is - * complete, so none of these functions will be called while another one is - * still running. - */ - - -/* - * verify that the routing configuration meets certain requirements - */ -int -wrsm_nr_verifyconfig(wrsm_network_t *network, wrsm_controller_t *config, - int attached_cnt, wci_ids_t *attached_wcis) -{ - wrsm_wci_data_t *wciconfig; - wrsm_nc_strgrp_t *sg; - wrsm_stripe_group_t *sgconfig; - int i, j, k, wnid; - boolean_t found; - safari_port_t port; - wrsm_routing_policy_t *policy; - wrsm_preferred_route_t *proute; - wrsm_ncwci_t *wci; - boolean_t have_local; - int err; - - ASSERT(network); - ASSERT(config); - - DPRINTF(DBG_CONFIG, (CE_CONT, "ctlr %d wrsm_nr_verifyconfig()\n", - network->rsm_ctlr_id)); - - if (!config->routing) { - DPRINTF(DBG_WARN, (CE_WARN, - "wrsm_nr_verifyconfig: no routing info\n")); - return (EINVAL); - } - - /* - * 2 WCIs are not allowed to be part of the same multi-hop network. - * Check this by verifying that no wnode/cnode on a wci refers to - * the local node. - */ - - for (i = 0; i < config->routing->nwcis; i++) { - wciconfig = config->routing->wcis[i]; - - for (wnid = 0; wnid < WRSM_MAX_WNODES; wnid++) { - if (wciconfig->wnode_reachable[wnid]) { - if (wciconfig->reachable[wnid] == - config->cnodeid) { - /* - * This wnode refers the local node. - * This is only ok if this is the local - * wnode for this wci (for loopback). - */ - if (wnid != wciconfig->local_wnode) { - DPRINTF(DBG_WARN, (CE_WARN, - "wrsm_nr_verifyconfig: " - "wci %d: non-local wnode %d" - " goes to this node (%d)\n", - wciconfig->port, - wnid, config->cnodeid)); - return (EINVAL); - } - } - - /* - * Make sure there is an nmembers structure - * for any cnode in the reachable list. - */ - - for (j = 0; j < config->nmembers; j++) { - if (wciconfig->reachable[wnid] == - config->members[j]->cnodeid) - break; - } - if (j == config->nmembers) { - /* - * no nmember node for wci - * cnodeid - */ - DPRINTF(DBG_WARN, (CE_WARN, - "wrsm_nr_verifyconfig: " - "wci %d wnode %d: cnode %d " - "doesn't exist in this " - "config\n", wciconfig->port, - wnid, wciconfig-> - reachable[wnid])); - return (EINVAL); - } - } - } - } - - /* - * verify that the stripe group configuration is allowed on this - * platform. Also verify that each WCI mentioned in the stripe - * group is in the config. - */ - for (i = 0; i < config->routing->ngroups; i++) { - if ((err = wrsmplat_stripegroup_verify( - config->routing->stripe_groups[i])) != 0) { - DPRINTF(DBG_WARN, (CE_WARN, "wrsm_nr_verifyconfig: " - "stripegroup_verify failed %d for group %d", - err, i)); - return (err); - } - - sgconfig = config->routing->stripe_groups[i]; - for (j = 0; j < sgconfig->nwcis; j++) { - found = B_FALSE; - port = sgconfig->wcis[j]; - for (k = 0; k < config->routing->nwcis; k++) { - if (port == config->routing->wcis[k]->port) { - found = B_TRUE; - } - } - if (!found) { - DPRINTF(DBG_WARN, (CE_WARN, - "wrsm_nr_verifyconfig: " - "in stripegroup %d, wci %d " - "doesn't exist in this " - "config\n", i, port)); - return (EINVAL); - } - } - } - - /* - * any node through which forwarding is allowed must be directly - * connected to it from this node - not checked here; enforced - * in nr_cnode_route(). - */ - - /* - * If the node list is not empty, the local node must be in the list. - */ - if (config->nmembers > 0) { - have_local = B_FALSE; - for (i = 0; i < config->nmembers; i++) { - if (config->members[i]->cnodeid == network->cnodeid) { - have_local = B_TRUE; - break; - } - } - - if (!have_local) { - DPRINTF(DBG_WARN, (CE_WARN, "local node required\n")); - return (EINVAL); - } - } - - /* - * Ensure that each hostname is unique - */ - for (i = 0; i < config->nmembers; i++) { - for (j = 0; j < config->nmembers; j++) { - if (i == j) { - continue; - } - if (strcmp(config->members[i]->hostname, - config->members[j]->hostname) == 0) { - cmn_err(CE_WARN, "hostname %s repeated", - config->members[i]->hostname); - return (EINVAL); - } - } - } - - /* - * Make sure there is preferred route info for each cnode in the - * config. (Both the nmember list and routing policy list are - * ordered by cnodeid, so the index into each for a particular - * cnodeid should be identical.) - */ - - if (config->nmembers != config->routing->npolicy) { - DPRINTF(DBG_WARN, (CE_WARN, "unmatching member and routing " - "policy information\n")); - return (EINVAL); - } - for (i = 0; i < config->nmembers; i++) { - if (config->routing->policy[i]->cnodeid != - config->members[i]->cnodeid) { - DPRINTF(DBG_WARN, (CE_WARN, "no routing policy for " - "node %d\n", config->members[i]->cnodeid)); - return (EINVAL); - } - } - - /* - * make sure each preferred route refers to a valid wci or - * stripe group - */ - for (i = 0; i < config->routing->npolicy; i++) { - policy = config->routing->policy[i]; - for (j = 0; j < policy->nroutes; j++) { - proute = policy->preferred_routes[j]; - if (proute->route_type == route_wci) { - for (k = 0; k < config->routing->nwcis; k++) { - if (config->routing->wcis[k]->port == - proute->route.wci_id) - break; - } - if (k == config->routing->nwcis) { - DPRINTF(DBG_WARN, (CE_WARN, "node %d " - "proute %d uses illegal wci %d\n", - policy->cnodeid, j, - proute->route.wci_id)); - return (EINVAL); - } - } else { - ASSERT(proute->route_type == - route_stripe_group); - for (k = 0; k < config->routing->ngroups; k++) { - if (config->routing-> - stripe_groups[k]->group_id == - proute->route.stripe_group_id) - break; - } - if (k == config->routing->ngroups) { - DPRINTF(DBG_WARN, (CE_WARN, "node %d " - "proute %d uses illegal sg %d\n", - policy->cnodeid, j, - proute->route.stripe_group_id)); - return (EINVAL); - } - } - } - } - - - - /* - * make sure each wci is only in one stripe group. - */ - for (i = 0; i < config->routing->nwcis; i++) { - port = config->routing->wcis[i]->port; - found = B_FALSE; - for (j = 0; j < config->routing->ngroups; j++) { - sgconfig = config->routing->stripe_groups[j]; - for (k = 0; k < sgconfig->nwcis; k++) { - if (sgconfig->wcis[k] == port) { - if (found) { - DPRINTF(DBG_WARN, (CE_WARN, - "wci %d is in more than " - "one stripe group\n", - port)); - return (EINVAL); - } else { - found = B_TRUE; - } - } - } - } - } - - /* - * there must be at least one WCI attached - */ - - if (config->routing->nwcis > 0 && attached_cnt < 1) { - DPRINTF(DBG_WARN, (CE_WARN, "there must be at least one " - "attached wci\n")); - return (ENODEV); - } - - - /* - * checks for conflicts with old config, if there was one - */ - - if (network->nr == NULL) - return (WRSM_SUCCESS); - - /* - * Verify that any stripe groups in both the old and new config - * have matching info (same number of wcis with the same ids) Note: - * sgs in network and sgs in config are both ordered by group id. - */ - sg = network->nr->sgs; - for (i = 0; i < config->routing->ngroups; i++) { - sgconfig = config->routing->stripe_groups[i]; - - while (sg && (sg->config->group_id < sgconfig->group_id)) { - /* sg is not in config; skip it */ - sg = sg->next; - continue; - } - - if (!sg) { - /* rest of sgs in config are new */ - break; - } - - if (sg->config->group_id > sgconfig->group_id) { - /* new sg in config */ - continue; - } - - /* found matching sg */ - ASSERT(sg->config->group_id == sgconfig->group_id); - - if (sg->config->nwcis != sgconfig->nwcis) { - DPRINTF(DBG_WARN, (CE_WARN, - "stripe group %d: old nwcis %d, " - "new nwcis %d\n", sg->config->group_id, - sg->config->nwcis, sgconfig->nwcis)); - return (EINVAL); - } - - for (j = 0; j < sg->config->nwcis; j++) { - if (sg->wcis[j]->config->port != sgconfig->wcis[j]) { - DPRINTF(DBG_WARN, (CE_WARN, "stripe group " - "%d: wci #%d old port is %d, new port " - "is %d\n", sg->config->group_id, j, - sg->wcis[j]->config->port, - sgconfig->wcis[j])); - return (EINVAL); - } - } - } - - - /* - * verify that the passed in LC handles match any already saved away - * LC handles - */ - for (i = 0; i < attached_cnt; i++) { - wci = nr_safid_to_wci(network, attached_wcis[i].port); - if (!wci) - continue; - - if (wci->lcwci != NULL && - wci->lcwci != attached_wcis[i].lcwci) { - /* - * bad LC handle! - */ - cmn_err(CE_WARN, "wci %d - old lc handle " - "(0x%p) doesn't match new handle (0x%p)\n", - wci->config->port, (void *) wci->lcwci, - (void *) attached_wcis[i].lcwci); - return (EINVAL); - } - - } - - /* - * verify that new link config doesn't conflict with old link - * config, and that local wnode hasn't changed. - */ - for (i = 0; i < config->routing->nwcis; i++) { - wciconfig = config->routing->wcis[i]; - wci = nr_safid_to_wci(network, wciconfig->port); - if (!wci) - continue; - - if (wci->lcwci) { - if (!wrsm_lc_verifyconfig(wci->lcwci, wciconfig)) { - DPRINTF(DBG_WARN, (CE_WARN, "nr_verifyconfig: " - "lc_verifyconfig failed")); - return (EINVAL); - } - } - - for (wnid = 0; wnid < WRSM_MAX_WNODES; wnid++) { - if (wci->config->wnode_reachable[wnid] && - wci->config->reachable[wnid] == network->cnodeid && - wci->config->reachable[wnid] != - wciconfig->reachable[wnid]) { - DPRINTF(DBG_WARN, (CE_WARN, "nr_verifyconfig: " - "local wnodeid has changed from %d " - "to %d cnodeid %d", - wci->config->reachable[wnid], - wciconfig->reachable[wnid], - network->cnodeid, wnid)); - return (EINVAL); - } - } - } - - return (WRSM_SUCCESS); -} - - -/* - * set up initial configuration structures for the NR - */ -boolean_t -wrsm_nr_initialconfig(wrsm_network_t *network, - int attached_cnt, wci_ids_t *attached_wcis) -{ - ASSERT(network); - - DPRINTF(DBG_CONFIG, (CE_CONT, "ctlr %d wrsm_nr_initialconfig()\n", - network->rsm_ctlr_id)); - - if (!network->nr) { - network->nr = (wrsm_nr_t *)kmem_alloc(sizeof (wrsm_nr_t), - KM_SLEEP); - bzero(network->nr, sizeof (wrsm_nr_t)); - cv_init(&(network->nr->event_cv), NULL, CV_DEFAULT, NULL); - cv_init(&(network->nr->config_cv), NULL, CV_DEFAULT, NULL); - rw_init(&(network->nr->wcilist_rw), NULL, RW_DEFAULT, NULL); - mutex_init(&(network->nr->lock), NULL, MUTEX_DRIVER, NULL); - (void) wrsm_tl_add_handler(network, - WRSM_MSG_CONFIG_PASSTHROUGH_LIST, WRSM_TL_NO_HANDLER, - pt_ptlist_recv_hdlr); - wrsm_cmmu_init(network, (unsigned)attached_cnt, attached_wcis); - /* - * Per wci cmmu init is not needed - * on an initial config. - */ - network->nr->init_cmmu = B_FALSE; - return (B_TRUE); - - } else { - network->nr->init_cmmu = B_TRUE; - return (B_FALSE); - } - -} - - - -/* - * Allocate data structures for and store routing info for nodes, wcis, - * stripe groups. Mark old wcis and stripe groups as disabled. Call - * lc_replaceconfig() for each old and new wci. - */ -int -wrsm_nr_replaceconfig(wrsm_network_t *network, wrsm_controller_t *config, - int attached_cnt, wci_ids_t *attached_wcis) -{ - int i, j; - cnodeid_t cnodeid; - wrsm_ncwci_t **wcip, *wci, *newwci; - wrsm_wci_data_t *wciconfig; - wrsm_nc_strgrp_t **sgp, *sg, *newsg; - wrsm_stripe_group_t *sgconfig; - wrsm_node_t *node; - - ASSERT(network); - ASSERT(config); - - DPRINTF(DBG_CONFIG, (CE_CONT, "ctlr %d wrsm_nr_replaceconfig()\n", - network->rsm_ctlr_id)); - - ASSERT(network->availability == wrsm_disabled); - - /* start event thread for this network */ - if (!network->nr->event_thread) { - network->nr->stop_event_thr = B_FALSE; - network->nr->event_thread = thread_create(NULL, 0, - nr_event_thread, network, 0, &p0, TS_RUN, maxclsyspri); - } - - /* - * cancel any pending timeout to reconfig wcis - */ - if (network->nr->wcireroute_timeout_id) { - /* - * cancels timeout or waits until it is finished - */ - (void) untimeout(network->nr->wcireroute_timeout_id); - network->nr->wcireroute_timeout_id = 0; - } - - /* - * Cancel any pending timeout to resend passthrough messages - * until the new configuration is installed. - */ - if (network->nr->pt_retry_timeout_id) { - /* - * cancels timeout or waits until it is finished - */ - (void) untimeout(network->nr->pt_retry_timeout_id); - network->nr->pt_retry_timeout_id = 0; - } - - - /* - * pause the event thread while modifying data structures it - * uses - */ - nr_pause_event_thread(network); - -#ifdef DEBUG - /* - * Both the list of config wcis and the list of network wcis - * is ordered by safari port id. - */ - for (i = 1; i < config->routing->nwcis; i++) { - ASSERT(config->routing->wcis[i]->port > - config->routing->wcis[i-1]->port); - } - - wci = network->nr->wcis; - if (wci) - for (; wci->next != NULL; wci = wci->next) { - ASSERT(wci->next->config->port > wci->config->port); - } -#endif - - /* - * Update list of wcis to match config wcis - - * create wci structs for new wcis; disable old wcis; call - * LC for each wci - */ - wcip = &(network->nr->wcis); - wci = *wcip; - for (i = 0; i < config->routing->nwcis; i++) { - wciconfig = config->routing->wcis[i]; - while (wci && (wci->config->port < wciconfig->port)) { - /* - * this wci doesn't exist in the new config - * mark it as disabled - */ - - wci->availability = wrsm_disabled; - WRSMSET_ZERO(wci->nr.cnode_retry); - if (wci->lcwci) { - /* notify LC that LC is not in config */ - wrsm_lc_replaceconfig(wci->lcwci, wci, NULL, - NULL); - } - wcip = &(wci->next); - wci = *wcip; - - } - - - if (wci == NULL || wci->config->port > wciconfig->port) { - /* wci is new */ - newwci = kmem_alloc(sizeof (wrsm_ncwci_t), KM_SLEEP); - bzero(newwci, sizeof (wrsm_ncwci_t)); - newwci->network = network; - newwci->reroute_state = wci_rerouted; - newwci->availability = wrsm_enabled; - newwci->nr.using_inids = B_FALSE; - newwci->nr.reserved_inids = B_FALSE; - - ASSERT(wciconfig->reachable[wciconfig->local_wnode] == - network->cnodeid); - - /* mark all wnodes as unreachable */ - for (j = 0; j < WRSM_MAX_WNODES; j++) { - newwci->nr.mh_reachable.nhops[j] = - WNODE_UNREACHABLE; - } - - /* - * add wci to network's list of wcis - * Take rw lock to prevent controller barrier - * code (nr_check_all_*()) from getting confused. - * (All other accesses of the network->nr_wcis - * list are singled threaded config/event thread - * accesses.) - */ - rw_enter(&network->nr->wcilist_rw, RW_WRITER); - newwci->next = wci; - *wcip = newwci; - wci = *wcip; - rw_exit(&network->nr->wcilist_rw); - } - - /* - * A wci struct now exists in network struct for this wci; - * replace old config info with new info and move to next - * wci in network list - */ - wci->config = wciconfig; - wcip = &(wci->next); - wci = *wcip; - } - - /* - * Any remaining wcis in the network list must no longer - * be part of the configuration. Mark them as disabled. - */ - while (wci) { - /* - * this wci doesn't exist in the new config - * mark it as disabled - */ - - wci->availability = wrsm_disabled; - WRSMSET_ZERO(wci->nr.cnode_retry); - - if (wci->lcwci) { - /* notify LC that LC is not in config */ - wrsm_lc_replaceconfig(wci->lcwci, wci, NULL, NULL); - } - wci = wci->next; - } - - for (i = 0; i < attached_cnt; i++) { - wci = nr_safid_to_wci(network, attached_wcis[i].port); -#ifdef DEBUG - if (!wci) { - DPRINTF(DBG_WARN, (CE_WARN, - "wrsm_nr_replaceconfig() " - "no wci for attached_wci #%d (id %d)\n", i, - attached_wcis[i].port)); - continue; - } - if (attached_wcis[i].lcwci == NULL) { - DPRINTF(DBG_WARN, (CE_WARN, - "wrsm_nr_replaceconfig() " - "no lcwci for attached_wci #%d (id %d)\n", i, - attached_wcis[i].port)); - continue; - } -#endif - ASSERT(wci); - if (wci->lcwci == NULL) { - /* - * new attach - if wrsm_nr_attachwci() fails, the - * LC will not be informed of the new WCI, - * and it won't come up - */ - (void) wrsm_nr_attachwci(network, wci->config->port, - attached_wcis[i].lcwci, config, - network->nr->init_cmmu, B_FALSE); - } else { - /* give LC the replacement configuration */ - wrsm_lc_replaceconfig(wci->lcwci, wci, wci->config, - config); - } - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "wrsm_nr_replaceconfig() " - "wci %d has lcwci (%p)\n", wci->config->port, - (void *)wci->lcwci)); - } - - -#ifdef DEBUG - for (wci = network->nr->wcis; wci != NULL; wci = wci->next) { - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "wrsm_nr_replaceconfig() " - "wci %d: availability %d\n", wci->config->port, - wci->availability)); - } -#endif - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "wrsm_nr_replaceconfig() " - "number of nodes %d", network->wrsm_num_nodes)); - if (network->wrsm_num_nodes > WRSM_RAG_FREEZE_NODE_LIMIT) { - stop_ncslice_traffic(network, B_FALSE); - /* - * Assumption: All WCI's in a controller will have the - * same number of nodes in their multihop group, hence we - * apply the same rag freeze algorithm to the entire list - * of wcis (network->nr->wcis). - */ - nr_rag_freeze(network->nr->wcis, network->wrsm_num_nodes); - restart_ncslice_traffic(network, B_FALSE); - } - - /* - * mark disabled cnodes as no longer needing a route - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - - if ((node != NULL) && (node->availability == wrsm_disabled)) { - node->routeinfo->route_state = ncslice_remove_route; - } - } - - /* - * Free old extended preferred route list if there is one. - */ - nr_free_extended_routes(network->nodes[network->cnodeid]); - - /* - * Update the preferred routes for each cnode in the config. - */ - for (i = 0; i < config->routing->npolicy; i++) { - cnodeid = config->routing->policy[i]->cnodeid; - - node = network->nodes[cnodeid]; - ASSERT(node != NULL); - - if (node->routeinfo == NULL) { - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "adding routinfo " - "for node %d (%d)\n", node->config->cnodeid, - cnodeid)); - node->routeinfo = kmem_alloc( - sizeof (wrsm_node_routeinfo_t), KM_SLEEP); - bzero(node->routeinfo, sizeof (wrsm_node_routeinfo_t)); - - node->routeinfo->policy = kmem_alloc - (sizeof (wrsm_routing_policy_t), KM_SLEEP); - - /* Create the route kstat */ - add_wrsm_route_kstat(node); - } - bcopy(config->routing->policy[i], node->routeinfo->policy, - sizeof (wrsm_routing_policy_t)); - node->routeinfo->current_route.proute = NULL; - node->routeinfo->new_route.proute = NULL; - } - - /* - * For local node, extend the preferred route list to include - * internal loopback routes through all wcis. This guarantees - * there is a loopback route even if a particular wci is removed. - * (It is not permitted to remove the last wci in a controller.) - */ - nr_add_extended_routes(network->nodes[network->cnodeid], config); - - -#ifdef DEBUG - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (node == NULL) - continue; - - if (node->routeinfo == NULL) { - panic("missing routinfo (and policy) info for " - "node %d\n", node->config->cnodeid); - } - } -#endif - - - /* - * Update list of stripe groups to match config stripe groups - - * add sgs, set old sgs to disabled. - * - * Both the list of config stripe groups and the list of network - * stripe groups is ordered by group id. - */ - -#ifdef DEBUG - for (i = 1; i < config->routing->ngroups; i++) { - ASSERT(config->routing->stripe_groups[i]->group_id > - config->routing->stripe_groups[i-1]->group_id); - } - - sg = network->nr->sgs; - if (sg) - for (; sg->next != NULL; sg = sg->next) { - ASSERT(sg->next->config->group_id > - sg->config->group_id); - } -#endif - sgp = &(network->nr->sgs); - sg = *sgp; - for (i = 0; i < config->routing->ngroups; i++) { - sgconfig = config->routing->stripe_groups[i]; - while (sg && (sg->config->group_id < sgconfig->group_id)) { - /* - * this stripe group doesn't exist in the new config - * mark it as disabled - */ - - sg->availability = wrsm_disabled; - sgp = &(sg->next); - sg = *sgp; - } - - - if (sg == NULL || sg->config->group_id > sgconfig->group_id) { - /* sg is new */ - newsg = kmem_alloc(sizeof (wrsm_nc_strgrp_t), KM_SLEEP); - bzero(newsg, sizeof (wrsm_nc_strgrp_t)); - newsg->network = network; - newsg->availability = wrsm_pending; - - for (j = 0; j < sgconfig->nwcis; j++) { - DPRINTF(DBG_CONFIG, (CE_CONT, "sg %d includes " - "wci #%d (id %d)\n", sgconfig->group_id, - j, sgconfig->wcis[j])); - - newsg->wcis[j] = nr_safid_to_wci(network, - sgconfig->wcis[j]); - ASSERT(newsg->wcis[j]); - } - - newsg->config = sgconfig; - - /* - * add sg to network's list of sgs - */ - newsg->next = sg; - *sgp = newsg; - sg = *sgp; - } - - /* - * An sg now exists in network struct for this stripe - * group; if it was there already, it was already checked - * (in wrsm_nr_verifyconfig()) to be sure it matches the one - * in the new config - */ - sgp = &(sg->next); - sg = *sgp; - } - - /* - * Any remaining sgs in the network list must no longer - * be part of the configuration. Mark them as disabled. - */ - while (sg) { - /* - * this sg doesn't exist in the new config - * mark it as disabled - */ - - sg->availability = wrsm_disabled; - WRSMSET_ZERO(sg->cnode_retry); - sg = sg->next; - } - - -#ifdef DEBUG - for (sg = network->nr->sgs; sg != NULL; sg = sg->next) { - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "wrsm_nr_replaceconfig() " - "sg %d: availability %d\n", sg->config->group_id, - sg->availability)); - } -#endif - - /* - * ok to restart event thread - */ - nr_unpause_event_thread(network); - return (WRSM_SUCCESS); - -} -uint32_t -wrsm_nr_getcontroller_id(wrsm_ncwci_t *ncwci) -{ - ASSERT(ncwci); - return (ncwci->network->rsm_ctlr_id); -} - -#define SETLINKBIT(id, bits) ((id) | (1 << (bits))) - -/* - * sets the event name/attribute pair in attr_list for each valid - * striped wci. attibutes are the safari portid and one bitmask for a links - * used on all wcis. returns error from nvlist_xxx calls. - */ -int -nr_get_wcieventdata(nvlist_t *attr_list, wrsm_node_t *node) -{ - ncslice_route_t cur_rte; - char wcistr[5]; - int i, j; - inidwnode_route_t wroute; - int err; - int link; - int wnodeid; - - /* - * linkbitmask is a bitmask of all links for all 4 wci's - * such that bits 0-2 represent link 0, 1, 2 for the first - * wci. bit 3-5 represent links 0, 1, 2 for the second and so on. - */ - uint32_t linkbitmask = 0; - - /* - * Copy the current route info into a local data structure - */ - ASSERT(node); - ASSERT(node->routeinfo); - - cur_rte = node->routeinfo->current_route; - - for (i = 0; i < cur_rte.nwcis; i++) { - ASSERT(i < WRSM_MAX_WCIS_PER_STRIPE); - /* Get the wroute for this stripe */ - wroute = cur_rte.wroutes[i]; - (void) sprintf(wcistr, "wci%d", i); - - if (wroute.wci == NULL) { - /* this piece should never happen */ - err = nvlist_add_int32(attr_list, - wcistr, -1); - if (err != DDI_SUCCESS) { - return (err); - } - continue; - } - err = nvlist_add_uint32(attr_list, - wcistr, (int32_t)wroute.wci->config->port); - if (err != DDI_SUCCESS) { - return (err); - } - - /* - * Depending on the route type, the link and - * node information are found in different - * data structures. - */ - - if (wroute.route_type == nid_route_inid) { - DPRINTF(DBG_CONFIG, (CE_CONT, - "nid_route_inid, stripe=%d", i)); - DPRINTF(DBG_CONFIG, (CE_CONT, - "wroute.id = %d\n", wroute.id)); - - for (j = 0; j < WRSM_MAX_DNIDS; j++) { - - /* - * Go through the inid2dnid table. - * The inid2dnid entry is the wnodeid. - */ - wnodeid = - wroute.wci->nr.inid2dnid[wroute.id]. - wnode_list[j]; - DPRINTF(DBG_CONFIG, - (CE_CONT, "i=%d, wnodeid=%d", j, wnodeid)); - /* - * Since passthrough routes are guaranteed to - * not use link striping we only need to - * loop up the wnode to link mapping once. - */ - link = - wrsm_mh_wnode_to_link(wroute.wci, wnodeid); - if (link != -1) { - linkbitmask = SETLINKBIT(linkbitmask, - (link + (i * WRSM_LINKS_PER_WCI))); - } - } - - } else { /* nid_route_wnode */ - /* There will be one or two links from this wci */ - - /* The wroute.id is the wnodeid. */ - wnodeid = wroute.id; - DPRINTF(DBG_CONFIG, - (CE_CONT, "nid_route_wnode, wnodeid=%d", wnodeid)); - - /* look at links to see which ones lead to wnode */ - for (link = 0; link < WRSM_LINKS_PER_WCI; link++) { - if (wrsm_mh_link_to_wnode(wroute.wci, link, - wnodeid)) { - linkbitmask = SETLINKBIT(linkbitmask, - (link + (i * WRSM_LINKS_PER_WCI))); - } - } - } - } - - /* - * in the event cur_rte.wcis < 4 must set to -1 remaining wci - * name-value pairs - */ - while (i < 4) { - (void) sprintf(wcistr, "wci%d", i); - err = nvlist_add_int32(attr_list, - wcistr, -1); - if (err != DDI_SUCCESS) { - return (err); - } - i++; - } - return (nvlist_add_uint32(attr_list, "links", linkbitmask)); - -} -/* - * system event logger - */ -void -wrsm_nr_logevent(wrsm_network_t *network, wrsm_node_t *node, - wrsm_sys_event_t eventtype, char *reason) -{ - nvlist_t *attr_list; - int err = DDI_SUCCESS; - - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nr_logevent:")); - ASSERT(network); - if ((err = nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, - KM_SLEEP)) == DDI_SUCCESS) { - err = nvlist_add_uint32(attr_list, "controller", - network->rsm_ctlr_id); - switch (eventtype) { - case new_node_route: - DPRINTF(DBG_CONFIG, (CE_CONT, - "wrsm_nr_logevent: new_node_route event")); - ASSERT(node); - ASSERT(node->config); - if (err == DDI_SUCCESS) { - err = nvlist_add_uint32(attr_list, "nodeid", - node->config->fmnodeid); - } - ASSERT(node->routeinfo); - if (err == DDI_SUCCESS) { - err = nvlist_add_int32(attr_list, "stripes", - node->routeinfo->current_route.stripes); - } - if (err == DDI_SUCCESS) { - err = nr_get_wcieventdata(attr_list, node); - } - ASSERT(network->dip); - if (err == DDI_SUCCESS) { - err = ddi_log_sysevent(network->dip, - DDI_VENDOR_SUNW, WRSM_CLASS, - WRSM_SUBCLASS_NEW_NODE, - attr_list, NULL, DDI_SLEEP); - } - break; - case lost_node_route: - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nr_logevent: " - "lost_node_route and reason is %s", reason)); - if (err == DDI_SUCCESS) { - ASSERT(node); - ASSERT(node->config); - err = nvlist_add_uint32(attr_list, "nodeid", - node->config->fmnodeid); - } - if (err == DDI_SUCCESS) { - err = nvlist_add_string(attr_list, "reason", - reason); - } - ASSERT(network->dip); - - if (err == DDI_SUCCESS) { - err = ddi_log_sysevent(network->dip, - DDI_VENDOR_SUNW, WRSM_CLASS, - WRSM_SUBCLASS_LOST_NODE, - attr_list, NULL, DDI_SLEEP); - } - break; - case new_config: - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nr_logevent: " - "new_config")); - ASSERT(network->dip); - if (err == DDI_SUCCESS) { - err = ddi_log_sysevent(network->dip, - DDI_VENDOR_SUNW, WRSM_CLASS, - WRSM_SUBCLASS_NEW_CONFIG, - attr_list, NULL, DDI_SLEEP); - } - break; - } - nvlist_free(attr_list); - } - - if (err != DDI_SUCCESS) { - cmn_err(CE_WARN, "wrsm_nr: error logging system event "); - } -} - -/* - * Remove ncslice routes and routing data structures for disabled cnodes; - * reroute cnodes using invalid wnode routes; takedown disabled links. - * Call lc_cleanconfig() on each old and new wci (takes down old links). - * Cause an MH reroute on specified wcis. - */ -int -wrsm_nr_cleanconfig(wrsm_network_t *network, int reroute_cnt, - wci_ids_t *reroute_wcis) -{ - int i, j; - wrsm_node_t *node; - wrsm_ncwci_t *wci; - wrsm_nc_strgrp_t *sg; - wrsm_nr_event_t *event; - boolean_t reroute; - cnode_bitmask_t lost_route; - wrsm_node_t *local_node; - struct wrsm_node_routeinfo *routeinfo; - - ASSERT(network); - ASSERT(network->availability == wrsm_pending); - - DPRINTF(DBG_CONFIG, (CE_CONT, "ctlr %d wrsm_nr_cleanconfig()\n", - network->rsm_ctlr_id)); - - WRSMSET_ZERO(lost_route); - - /* - * temporarily stop processing of wnode route events - * while queuing up a bunch of them - */ - nr_pause_event_thread(network); - - for (wci = network->nr->wcis; wci != NULL; wci = wci->next) { - /* - * tell the LC to update the link states based on the - * configuration; this will cause the LC to (immediately) - * notify the MH that certain links are down (any that - * are no longer valid in the new config). This should - * cause the MH to (immediately) queue evt_mhdirect events - * for the event thread to process. - */ - if (wci->lcwci) - wrsm_lc_cleanconfig(wci->lcwci); - - /* - * Modify wnodeinfo array of each wci to match new config - * for future route decisions. Remove references to - * disabled cnodes. Request that all cnodes using a no - * longer valid wnode have their routes re-evaluated. - */ - - for (i = 0; i < WRSM_MAX_WNODES; i++) { - reroute = B_FALSE; - if (wci->availability == wrsm_disabled) { - wci->nr.wnodeinfo[i].valid = B_FALSE; - reroute = B_TRUE; - - } else if (wci->config->wnode_reachable[i]) { - /* valid wnode in the new config */ - - if (wci->nr.wnodeinfo[i].valid && - wci->nr.wnodeinfo[i].cnodeid != - wci->config->reachable[i]) { - /* - * wnodeid to cnodeid mapping changed; - * request rerouting for any nodes - * using wnode, then treat as a newly - * valid wnodeid. - */ - wci->nr.wnodeinfo[i].valid = B_FALSE; - reroute = B_TRUE; - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, - "wci %d wnode %d " - "old cnode %d new cnode %d\n", - wci->config->port, i, - wci->nr.wnodeinfo[i].cnodeid, - wci->config->reachable[i])); - - } - - /* set new values for wnode */ - if (!wci->nr.wnodeinfo[i].valid) { - wci->nr.wnodeinfo[i].cnodeid = - wci->config->reachable[i]; - wci->nr.wnodeinfo[i].valid = B_TRUE; - wci->reroute_state = wci_need_reroute; - DPRINTF(DBG_CONFIG, (CE_CONT, - "wci %d add " - "wnode %d cnode %d\n", - wci->config->port, i, - wci->config->reachable[i])); - } - - WRSMSET_ZERO(wci->nr.wnodeinfo[i].interested); - - } else { - /* invalid wnode in this config */ - if (wci->nr.wnodeinfo[i].valid) { - reroute = B_TRUE; - DPRINTF(DBG_CONFIG, (CE_CONT, - "wci %d remove " - "wnode %d cnode %d\n", - wci->config->port, i, - wci->nr.wnodeinfo[i].cnodeid)); - } - wci->nr.wnodeinfo[i].valid = B_FALSE; - } - - if (reroute) { - /* - * old wnode is no longer valid, so - * figure out which nodes were using this - * wnode route (to request a reroute later) - */ - wci->reroute_state = wci_need_reroute; - WRSMSET_OR(wci->nr.cnode_retry, - wci->nr.wnodeinfo[i].users); - - if (wci->nr.inids_enabled) { - for (j = 0; j < WRSM_INID2DNID_ENTRIES; - j++) { - if (WRSM_IN_SET( - wci->nr.inid2dnid[j]. - wnode_bitmask, i)) { - WRSMSET_OR(lost_route, - wci-> - nr.inid2dnid[j]. - users); - } - } - } else { - WRSMSET_OR(lost_route, - wci->nr.wnodeinfo[i].users); - } - } - } - } - - - /* - * Request an ncslice reroute on any cnodes using invalid wnodes. - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if ((node == NULL) || (node->availability == wrsm_disabled)) - continue; - - /* - * if node was using now invalid wnode, request - * reroute - */ - if (WRSM_IN_SET(lost_route, i)) { - ASSERT(network->nodes[i]); - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d cleanconfig invalid wnode, " - "node %d check_route\n", - network->rsm_ctlr_id, i)); - network->nodes[i]->routeinfo->check_route = - B_TRUE; - } - } - - /* - * Request that all nodes using a disabled stripe group have their - * ncslice route re-evaluated. - */ - - for (sg = network->nr->sgs; sg != NULL; sg = sg->next) { - if (sg->availability == wrsm_disabled) { - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (WRSM_IN_SET(sg->users, i)) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d cleanconfig invalid sg, " - "node %d check_route\n", - network->rsm_ctlr_id, i)); - network->nodes[i]-> - routeinfo->check_route = B_TRUE; - } - } - } - } - - /* - * force local node loopback route to be calculated - */ - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d cleanconfig re-eval loopback route " - "node %d check_route\n", - network->rsm_ctlr_id, network->cnodeid)); - network->nodes[network->cnodeid]->routeinfo->check_route = B_TRUE; - - - /* - * restart network event thread - */ - nr_unpause_event_thread(network); - - /* - * wait for routes on disabled nodes to be removed - */ - nr_wait_for_event_drain(network); - - - /* - * temporarily stop processing events - * while modifying node routinfo pointers - */ - - nr_pause_event_thread(network); - - /* - * At this point, there should be no routes for or references to - * disabled cnodes. - * - * Remove routeinfo for disabled cnodes. If local node is being - * removed (only happens when network/controller is being removed), - * also remove its extended preferred route info. - */ - - local_node = network->nodes[network->cnodeid]; - if (local_node->availability == wrsm_disabled) { - nr_free_extended_routes(local_node); - } - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (network->nodes[i] == NULL) - continue; - - node = network->nodes[i]; - if (node->availability == wrsm_disabled) { - ASSERT(node->routeinfo->route_state == - ncslice_no_route); - ASSERT(node->state == wrsm_node_needroute); - - /* Delete the route kstat */ - del_wrsm_route_kstat(node); - - /* - * Set routeinfo to NULL after taking lock -- - * this is to coordinate with passthrough - * messages. All other accesses to routeinfo - * are by the event thread, which is paused. - */ - mutex_enter(&network->nr->lock); - routeinfo = node->routeinfo; - node->routeinfo = NULL; - mutex_exit(&network->nr->lock); - - ASSERT(routeinfo); - kmem_free(routeinfo->policy, - sizeof (wrsm_routing_policy_t)); - kmem_free(routeinfo, - sizeof (wrsm_node_routeinfo_t)); - } - } - - nr_unpause_event_thread(network); - /* - * Cause an MH reroute of specified "reroute" wcis. The - * reroute request will be queued after any wnode down - * events for this wci caused by the lc_cleanconfig() call. - */ - - for (i = 0; i < reroute_cnt; i++) { - wci = nr_safid_to_wci(network, reroute_wcis[i].port); - ASSERT(wci); - - if (wci->lcwci) { - event = kmem_alloc(sizeof (wrsm_nr_event_t), - KM_SLEEP); - event->data.forcereroute.wci = wci; - event->type = wrsm_evt_force_reroute; - wrsm_nr_add_event(network, event, B_TRUE); - } - } - - nr_wait_for_event_drain(network); - - return (WRSM_SUCCESS); -} - - -/* - * Make sure all rerouting around old wcis and stripe groups is complete; - * Call lc_installconfig() on each old and new wci (brings up new links). - * Clean up old wci and stripe group data structures. Make sure ncslice - * reroute caused by removal of routes is complete. Recalculate and - * record which nodes are interested in which wnode/stripe-group/PT routes. - */ -int -wrsm_nr_installconfig(wrsm_network_t *network) -{ - int i, j, k, cindex; - cnodeid_t cnodeid; - wrsm_ncwci_t *wci, **wcip; - wrsm_nr_event_t *event; - wrsm_nc_strgrp_t *sg; - wrsm_node_t *node, *pt_node; - wrsm_routing_policy_t *policy; - wrsm_preferred_route_t *proute; - int err; - - ASSERT(network); - ASSERT(network->availability == wrsm_pending); - - DPRINTF(DBG_CONFIG, (CE_CONT, "ctlr %d wrsm_nr_installconfig()\n", - network->rsm_ctlr_id)); - - /* - * At this point, no old links or wnodes should be in use, and no - * old cnodes should be using routes. - */ - - - /* - * set up bitmasks describing which cnodes are interested in - * various wnode routes and PT routes - */ - - /* - * zero out old passthrough bitmasks - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (node == NULL || node->availability == wrsm_disabled) - continue; - - ASSERT(node->routeinfo); - WRSMSET_ZERO(node->routeinfo->pt_interested); - } - - /* - * now mark which nodes are interested in which routes - */ - for (cindex = 0; cindex < WRSM_MAX_CNODES; cindex++) { - node = network->nodes[cindex]; - if (node == NULL || node->availability == wrsm_disabled) - continue; - - policy = node->routeinfo->policy; - - /* - * for each route, mark in the appropriate passthrough - * node, wci or stripe group that this cnode is a candidate - * user - */ - for (i = 0; i < policy->nroutes; i++) { - proute = policy->preferred_routes[i]; - if (proute->method == routing_passthrough) { - for (j = 0; j < proute->nswitches; j++) { - pt_node = network->nodes[ - proute->switches[j]]; - ASSERT(pt_node); - WRSMSET_ADD( - pt_node->routeinfo->pt_interested, - cindex); - } - } - if (proute->route_type == route_wci) { - wci = nr_safid_to_wci(network, - proute->route.wci_id); - ASSERT(wci); - for (j = 0; j < WRSM_MAX_WNODES; j++) { - if (wci->nr.wnodeinfo[j].valid && - wci->nr.wnodeinfo[j].cnodeid == - cindex) { - WRSMSET_ADD( - wci->nr.wnodeinfo[j]. - interested, cindex); - } - } - } else { - ASSERT(proute->route_type == - route_stripe_group); - sg = nr_sgid_to_sg(network, - proute->route.stripe_group_id); - ASSERT(sg); - for (j = 0; j < sg->config->nwcis; j++) { - wci = sg->wcis[j]; - ASSERT(wci); - for (k = 0; k < WRSM_MAX_WNODES; k++) { - if (wci-> - nr.wnodeinfo[k].valid && - wci-> - nr.wnodeinfo[k].cnodeid == - cindex) { - WRSMSET_ADD( - wci-> - nr.wnodeinfo[k]. - interested, cindex); - } - } - } - } - } - - /* - * current.proute was removed during wrsm_nr_replaceconfig, - * so need to recreate current.proute. - */ - node->routeinfo->check_route = B_TRUE; - } - - /* - * Mark all wcis as needing re-evaluation by all cnodes interested - * in any wnode routes on the wci by setting wci's cnode_retry - * field. (Evaluation takes place once check_route is set for - * cnode). - */ - - for (wci = network->nr->wcis; wci != NULL; wci = wci->next) { - if (wci->availability == wrsm_disabled) - continue; - - WRSMSET_ZERO(wci->nr.cnode_retry); - for (i = 0; i < WRSM_MAX_WNODES; i++) { - if (!wci->nr.wnodeinfo[i].valid) - continue; - - /* - * Add passthrough candidates to list of - * nodes interested in a possible wnode route through - * a particular cnode. - */ - cnodeid = wci->nr.wnodeinfo[i].cnodeid; - WRSMSET_OR(wci->nr.wnodeinfo[i].interested, - network->nodes[cnodeid]->routeinfo->pt_interested); -#ifdef DEBUG - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, - "wrsm_nr_installconfig() " - "wci %d wnode %d interested:\n", - wci->config->port, i)); - if (wrsm_nr_debug & DBG_CONFIG_EXTRA) - DPRINTNODES(wci->nr.wnodeinfo[i]. - interested); -#endif - WRSMSET_OR(wci->nr.cnode_retry, - wci->nr.wnodeinfo[i].interested); - } - -#ifdef DEBUG - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "wrsm_nr_installconfig() " - "wci %d cnode_retry:\n", wci->config->port)); - if (wrsm_nr_debug & DBG_CONFIG_EXTRA) - DPRINTNODES(wci->nr.cnode_retry); -#endif - } - - /* - * Mark all stripe groups as needing a re-evaluation by all cnodes - * that could use stripe groups by setting sg's cnode_retry field. - * (Evaluation takes place once check_route is set for cnode). - */ - - for (sg = network->nr->sgs; sg != NULL; sg = sg->next) { - if (sg->availability == wrsm_disabled) - continue; - - WRSMSET_ZERO(sg->cnode_retry); - for (i = 0; i < sg->config->nwcis; i++) { - WRSMSET_OR(sg->cnode_retry, - sg->wcis[i]->nr.cnode_retry); - } -#ifdef DEBUG - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "wrsm_nr_installconfig() " - "sg %d retry:\n", sg->config->group_id)); - if (wrsm_nr_debug & DBG_CONFIG_EXTRA) - DPRINTNODES(sg->cnode_retry); -#endif - } - - /* - * Force rerouting of any wcis that are marked as needing a - * reroute. This guarantees that invalid wnode routes are no longer - * in use. - */ - for (wci = network->nr->wcis; wci != NULL; wci = wci->next) { - if (wci->reroute_state == wci_need_reroute) { - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->data.forcereroute.wci = wci; - event->type = wrsm_evt_force_reroute; - wrsm_nr_add_event(network, event, B_TRUE); - } - } - - /* - * Wait until all wci reroutes and ncslice re-routes they cause - * are finished. - */ - - nr_wait_for_event_drain(network); - nr_wait_for_wcis_rerouted(network); - - - /* - * At this point, all WCIs are routing only through wnodes valid in - * both configurations. All ncslices are only using routes valid - * in both configurations. All ncslices on wcis that are in old - * stripe groups are set to use only a single wci. All ncslices - * using a single wci have the no_stripe bit set in their nc2nid - * entry. This means the stripe group bits can be changed without - * affecting any ncslices. - */ - - /* may call nr_pause_event_thread() */ - if ((err = nr_sg_install(network)) != WRSM_SUCCESS) { - return (err); - } - - /* - * Tell LC to bringup all links valid to the new configuration on - * each wci. (The LC does not notify the MH of any new up links - * until lc_enableconfig() is called. - */ - - network->nr->waiting_linksup = 0; - for (wci = network->nr->wcis; wci != NULL; wci = wci->next) { - if (wci->lcwci) { - network->nr->waiting_linksup++; - wrsm_lc_installconfig(wci->lcwci); - if (wci->availability == wrsm_disabled) { - wrsm_mh_remove_wci(wci); - } - } - } - - - /* - * Make sure all cnodes with check_route set due to wci reroutes - * have been re-evaluated and ncslices rerouted. - */ - - nr_wait_for_event_drain(network); - - /* - * remove disabled wcis - */ - wcip = &(network->nr->wcis); - wci = *wcip; - while (wci) { - if (wci->availability == wrsm_disabled) { - DPRINTF(DBG_CONFIG, (CE_CONT, "removing wci %d\n", - wci->config->port)); - if (wci->lcwci) { - wrsm_intr_delwci(network, wci->lcwci); - (void) wrsm_cmmu_delwci(network, wci->lcwci); - wci->lcwci = NULL; - } - /* - * remove wci from linked list - * Take rw lock to prevent controller barrier - * code (nr_check_all_*()) from getting confused. - * (All other accesses of the network->nr_wcis - * list are singled threaded config/event thread - * accesses.) - */ - rw_enter(&network->nr->wcilist_rw, RW_WRITER); - *wcip = wci->next; - rw_exit(&network->nr->wcilist_rw); - kmem_free(wci, sizeof (wrsm_ncwci_t)); - wci = *wcip; - } else { - wcip = &(wci->next); - wci = *wcip; - } - } - - return (WRSM_SUCCESS); -} - - -/* - * Allow ncslice routes to use new wnode routes. Force MH reroute on certain - * wcis with new direct wnode routes. Set timeout to ensure MH reroute on - * all wcis with new wnode routes. - */ -int -wrsm_nr_enableconfig(wrsm_network_t *network, int reroute_cnt, - wci_ids_t *reroute_wcis) -{ - int i; - wrsm_node_t *node; - wrsm_ncwci_t *wci; - wrsm_nr_event_t *event; - wrsm_nr_t *nr; - boolean_t ptnotify = B_FALSE; - - ASSERT(network); - ASSERT(network->availability == wrsm_installed || - network->availability == wrsm_installed_up); - - DPRINTF(DBG_CONFIG, (CE_CONT, "ctlr %d wrsm_nr_enableconfig()\n", - network->rsm_ctlr_id)); - - nr = network->nr; - - /* - * allow LC to notify the MH of new links that are up - */ - nr_pause_event_thread(network); - - for (wci = nr->wcis; wci != NULL; wci = wci->next) { - if (wci->lcwci) { - wrsm_lc_enableconfig(wci->lcwci); - } - } - - /* wait for link up notificiations to be processed */ - nr_unpause_event_thread(network); - nr_wait_for_event_drain(network); - - if (reroute_cnt == -1) { - /* reroute all wcis */ - nr_reroute_wcis((void *)network); - - } else { - /* - * Cause an MH reroute on specified wcis, allowing them - * to use any new, up links. Schedule a timeout to force - * MH reroute on remaining wcis in the near future. - */ - - for (i = 0; i < reroute_cnt; i++) { - wci = nr_safid_to_wci(network, reroute_wcis[i].port); - ASSERT(wci); - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->data.forcereroute.wci = wci; - event->type = wrsm_evt_force_reroute; - wrsm_nr_add_event(network, event, B_TRUE); - } - - mutex_enter(&network->nr->lock); - if (network->nr->suspended) { - nr->need_wcireroute_timeout = B_TRUE; - } else { - nr->wcireroute_timeout_id = timeout(nr_reroute_wcis, - (void *)network, (clock_t)WRSM_ENABLE_TIMEOUT); - } - mutex_exit(&network->nr->lock); - } - - - - /* - * Turn on passthrough forwarding to appropriate nodes, - * and send nodes the latest passthrough list from this - * node. - */ - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if ((network->nodes[i] == NULL) || - (i == network->cnodeid)) - continue; - - node = network->nodes[i]; - ASSERT(node->availability == wrsm_enabled); - - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->data.addpt.node = node; - event->type = wrsm_evt_add_passthrough; - wrsm_nr_add_event(network, event, B_TRUE); - ptnotify = B_TRUE; - } - - if (ptnotify) { - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - - WRSMSET_ZERO(event->data.send_ptlist.list); - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if ((network->nodes[i] == NULL) || - (i == network->cnodeid)) - continue; - WRSMSET_ADD(event->data.send_ptlist.list, i); - } - event->type = wrsm_evt_send_ptlist; - wrsm_nr_add_event(network, event, B_TRUE); - } - if (network->free_rag_instance) { - /* - * this can be called here with out the security of - * stopping all network transactions because we know that - * nodes have been removed from the network so that - * instances will be either freed or untouched. - * The only time we must stop traffic is if we want to - * freeze an instance that could potentially be busy. - * The call to nr_rag_freeze must come after the call - * wrsm_lc_replaceconfig and after wci's have been removed - * and or added to the configuation. - */ - nr_rag_freeze(network->nr->wcis, network->wrsm_num_nodes); - network->free_rag_instance = B_FALSE; /* reinit */ - } - return (WRSM_SUCCESS); -} - - - -/* - * kill off event thread and remove NR related data structures for this - * network - */ -void -wrsm_nr_removeconfig(wrsm_network_t *network) -{ - wrsm_nr_t *nr = network->nr; - - DPRINTF(DBG_CONFIG, (CE_CONT, "ctlr %d wrsm_nr_removeconfig()\n", - network->rsm_ctlr_id)); - - wrsm_cmmu_fini(network); - - mutex_enter(&(nr->lock)); - if (nr->event_thread) { - nr->stop_event_thr = B_TRUE; - do { - cv_broadcast(&(nr->event_cv)); - cv_wait(&(nr->config_cv), &(nr->lock)); - } while (nr->event_thread); - } - mutex_exit(&(nr->lock)); - - - cv_destroy(&(network->nr->event_cv)); - cv_destroy(&(network->nr->config_cv)); - rw_destroy(&(network->nr->wcilist_rw)); - mutex_destroy(&(network->nr->lock)); - - kmem_free(network->nr, sizeof (wrsm_nr_t)); - network->nr = NULL; -} - - -/* - * Once LC notifies the NR that all links on all wcis are up, - * notify the NC so it can enable the network (allowing new links - * to be used). - */ -void -wrsm_nr_all_links_up(wrsm_ncwci_t *wci) -{ - wrsm_network_t *network; - - ASSERT(wci); - ASSERT(wci->network); - ASSERT(wci->network->nr); - network = wci->network; - - mutex_enter(&(network->nr->lock)); - if (!wci->linksup) { - wci->linksup = B_TRUE; - network->nr->waiting_linksup--; - } - mutex_exit(&(network->nr->lock)); - - if (network->nr->waiting_linksup == 0) - wrsm_nc_config_linksup(network); -} - - -/* - * Add a route for each wci in the new configuration to the local node's - * list of preferred routes. This guarantees that a loopback route for the - * local node can always be established. - * - * New routes are added by allocating enough space for an array containing - * all the config-supplied routes plus these new routes. - */ -static void -nr_add_extended_routes(wrsm_node_t *local_node, wrsm_controller_t *config) -{ - int policycount; - int nwcis; - int i; - wrsm_preferred_route_t *proute; - - ASSERT(local_node); - ASSERT(local_node->config); - ASSERT(local_node->routeinfo); - ASSERT(local_node->routeinfo->policy); - ASSERT(config); - ASSERT(config->routing); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "add_extended_routes node %d", - local_node->config->cnodeid)); - - policycount = local_node->routeinfo->policy->nroutes; - nwcis = config->routing->nwcis; - local_node->routeinfo->orig_nroutes = policycount; - local_node->routeinfo->orig_routes = - local_node->routeinfo->policy->preferred_routes; - local_node->routeinfo->policy->nroutes = policycount + nwcis; - local_node->routeinfo->policy->preferred_routes = - kmem_alloc(sizeof (wrsm_preferred_route_t *) * - local_node->routeinfo->policy->nroutes, KM_SLEEP); - local_node->routeinfo->extended_routes = - kmem_alloc(sizeof (wrsm_preferred_route_t) * nwcis, KM_SLEEP); - bcopy(local_node->routeinfo->orig_routes, - local_node->routeinfo->policy->preferred_routes, - sizeof (wrsm_preferred_route_t *) * policycount); - for (i = 0; i < nwcis; i++) { - proute = &(local_node->routeinfo->extended_routes[i]); - proute->striping_level = 1; - proute->method = routing_multihop; - proute->route_type = route_wci; - proute->route.wci_id = config->routing->wcis[i]->port; - local_node->routeinfo->policy->preferred_routes[policycount] = - proute; - policycount++; - } -} - - -/* - * Remove extended routes from the local node's prefereed route list, and - * point back to the original preferred route list provided by the - * configuration. - */ -static void -nr_free_extended_routes(wrsm_node_t *local_node) -{ - ASSERT(local_node); - - if (local_node->routeinfo && local_node->routeinfo->orig_routes) { - kmem_free(local_node->routeinfo->extended_routes, - sizeof (wrsm_preferred_route_t) * - (local_node->routeinfo->policy->nroutes - - local_node->routeinfo->orig_nroutes)); - kmem_free(local_node->routeinfo->policy->preferred_routes, - local_node->routeinfo->policy->nroutes * - sizeof (wrsm_preferred_route_t *)); - local_node->routeinfo->policy->preferred_routes = - local_node->routeinfo->orig_routes; - local_node->routeinfo->policy->nroutes = - local_node->routeinfo->orig_nroutes; - local_node->routeinfo->orig_nroutes = 0; - local_node->routeinfo->policy->preferred_routes = - local_node->routeinfo->orig_routes; - local_node->routeinfo->orig_routes = NULL; - } -} - - -/* - * Turn off striping on wcis in disabled stripe groups, then remove the - * stripe groups. - * - * turn on striping on new stripe groups - */ -static int -nr_sg_install(wrsm_network_t *network) -{ - int i; - wrsm_nc_strgrp_t *sg, **sgp; - int err; - - ASSERT(network); - ASSERT(network->nr); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "nr_sg_install()\n")); - - /* - * first, turn off striping on all wcis in disabled stripe - * groups - */ - sgp = &(network->nr->sgs); - sg = *sgp; - while (sg) { - if (sg->availability == wrsm_disabled) { - DPRINTF(DBG_CONFIG, (CE_CONT, "removing sg %d\n", - sg->config->group_id)); - if (sg->attached_wcis == sg->config->nwcis) { - if ((err = nr_sg_unstripe(sg)) - != WRSM_SUCCESS) { - return (err); - } - } - - for (i = 0; i < sg->config->nwcis; i++) { - sg->wcis[i]->nr.sg = NULL; - } - - /* remove sg from linked list */ - *sgp = sg->next; - kmem_free(sg, sizeof (wrsm_nc_strgrp_t)); - sg = *sgp; - } else { - /* this stripe group is ok; skip it */ - sgp = &(sg->next); - sg = *sgp; - } - } - - /* - * now turn on striping on wcis in new stripe groups - */ - for (sg = network->nr->sgs; sg; sg = sg->next) { - if (sg->availability == wrsm_pending) { - for (i = 0; i < sg->config->nwcis; i++) { - sg->wcis[i]->nr.sg = sg; - if (sg->wcis[i]->lcwci) - sg->attached_wcis++; - } - - /* - * if all wcis in this stripe group - * are attached, stripe them - */ - if (sg->attached_wcis == sg->config->nwcis) - if ((err = nr_sg_stripe(sg)) != WRSM_SUCCESS) { - return (err); - } - - - sg->availability = wrsm_enabled; - } - } - - return (WRSM_SUCCESS); -} - - -/* - * Turn off striping across wcis in the stripe group. - * Note: all wcis must be attached. - */ -static int -nr_sg_unstripe(wrsm_nc_strgrp_t *sg) -{ - int i; - lcwci_handle_t lcwci; - wci_config_u wci_config; -#ifdef DEBUG - int j; - uint64_t offset; - wci_nc2nid_array_u wci_nc2nid; -#endif - - ASSERT(sg); - ASSERT(sg->config); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "nr_sg_unstripe() sg %d\n", - sg->config->group_id)); - - nr_pause_event_thread(sg->network); - - sg->striping_on = B_FALSE; - - for (i = 0; i < sg->config->nwcis; i++) { - lcwci = sg->wcis[i]->lcwci; - ASSERT(lcwci); -#ifdef DEBUG - /* - * verify that all used nc2nid entries are set to no stripe - */ - offset = (uint64_t)ADDR_WCI_NC2NID_ARRAY; - for (j = 0; j < WRSM_MAX_CNODES; j++) { - wrsm_lc_csr_read(lcwci, offset, &(wci_nc2nid.val)); - if (wci_nc2nid.bit.launch_remote) - ASSERT(wci_nc2nid.bit.no_stripe); - offset += STRIDE_WCI_NC2NID_ARRAY; - } - -#endif - /* modify register to not do wci striping */ - wrsm_lc_csr_read(lcwci, (uint64_t)ADDR_WCI_CONFIG, - &(wci_config.val)); - wci_config.bit.stripe_bits = WCI_STRIPE_NONE; - wrsm_lc_csr_write(lcwci, (uint64_t)ADDR_WCI_CONFIG, - wci_config.val); - } - nr_unpause_event_thread(sg->network); - - return (WRSM_SUCCESS); -} - - -/* - * Turn on striping across all wcis in the stripe group. - * Note: all wcis must be attached. - */ -static int -nr_sg_stripe(wrsm_nc_strgrp_t *sg) -{ - int i; - int nwcis; - lcwci_handle_t lcwci; - int stripe[4]; - wci_config_u wci_config; -#ifdef DEBUG - int j; - uint64_t offset; - wci_nc2nid_array_u wci_nc2nid; -#endif - ASSERT(sg); - ASSERT(sg->config); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "nr_sg_stripe() sg %d\n", - sg->config->group_id)); - - nwcis = sg->config->nwcis; - ASSERT(nwcis == 1 || nwcis == 2 || nwcis == 4); - if (nwcis == 1) - stripe[0] = WCI_STRIPE_NONE; - if (nwcis == 2) { - stripe[0] = WCI_STRIPE_2WAY_EVEN; - stripe[1] = WCI_STRIPE_2WAY_ODD; - } else if (nwcis == 4) { - stripe[0] = WCI_STRIPE_4WAY_0; - stripe[1] = WCI_STRIPE_4WAY_1; - stripe[2] = WCI_STRIPE_4WAY_2; - stripe[3] = WCI_STRIPE_4WAY_3; - } - - nr_pause_event_thread(sg->network); - - for (i = 0; i < nwcis; i++) { - lcwci = sg->wcis[i]->lcwci; - ASSERT(lcwci); -#ifdef DEBUG - /* - * verify that all used nc2nid entries are - * set to no stripe - */ - offset = (uint64_t)ADDR_WCI_NC2NID_ARRAY; - for (j = 0; j < WRSM_MAX_CNODES; j++) { - wrsm_lc_csr_read(lcwci, offset, &(wci_nc2nid.val)); - if (wci_nc2nid.bit.launch_remote) - ASSERT(wci_nc2nid.bit.no_stripe); - offset += STRIDE_WCI_NC2NID_ARRAY; - } - -#endif - /* modify register to do wci striping */ - wrsm_lc_csr_read(lcwci, (uint64_t)ADDR_WCI_CONFIG, - &(wci_config.val)); - wci_config.bit.stripe_bits = stripe[i]; - wrsm_lc_csr_write(lcwci, (uint64_t)ADDR_WCI_CONFIG, - wci_config.val); - } - - sg->striping_on = B_TRUE; - nr_unpause_event_thread(sg->network); - - return (WRSM_SUCCESS); -} - - - -/* - * Timeout function: causes all WCIs with changed routes to perform - * an mh reroute. - */ -static void -nr_reroute_wcis(void *arg) -{ - wrsm_network_t *network = (wrsm_network_t *)arg; - wrsm_ncwci_t *wci; - wrsm_nr_event_t *event; - - ASSERT(network); - ASSERT(network->nr); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "nr_reroute_wcis()\n")); - - for (wci = network->nr->wcis; wci != NULL; wci = wci->next) { - if (wci->reroute_state == wci_need_reroute) { - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->data.forcereroute.wci = wci; - event->type = wrsm_evt_force_reroute; - wrsm_nr_add_event(network, event, B_TRUE); - } - } -} - - - -/* - * prepare to use new wci - call lc_replaceconfig(), other WCI - * initialization functions - */ -int -wrsm_nr_attachwci(wrsm_network_t *network, safari_port_t saf_id, - lcwci_handle_t lcwci, wrsm_controller_t *config, boolean_t init_cmmu, - boolean_t pause_evt_thread) -{ - wrsm_ncwci_t *wci; - int err; - int i; -#ifdef DEBUG - wci_nc2nid_array_u wci_nc2nid; - uint64_t offset; -#endif - ASSERT(network); - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nr_attachwci() wci %d\n", - saf_id)); - - wci = nr_safid_to_wci(network, saf_id); - if (wci == NULL) - return (EINVAL); - ASSERT(wci->availability == wrsm_enabled); - ASSERT(wci->reroute_state == wci_rerouted); - -#ifdef DEBUG - /* - * verify that all nc2nid entries are turned off - */ - offset = (uint64_t)ADDR_WCI_NC2NID_ARRAY; - for (i = 0; i < WRSM_MAX_CNODES; i++) { - wrsm_lc_csr_read(lcwci, offset, &(wci_nc2nid.val)); - ASSERT(wci_nc2nid.bit.launch_remote == 0); - offset += STRIDE_WCI_NC2NID_ARRAY; - } -#endif /* DEBUG */ - - for (i = 0; i < WRSM_MAX_WNODES; i++) { - if (wci->nr.wnodeinfo[i].cnodeid == network->cnodeid) { - wci->nr.wnodeinfo[i].valid = B_TRUE; - } - } - - if (pause_evt_thread) - nr_pause_event_thread(network); - - wrsm_mh_new_wci(wci); - - wrsm_lc_replaceconfig(lcwci, wci, wci->config, config); - - if (init_cmmu) { - /* - * Cmmu Manager has not yet been notified of this wci - */ - if ((err = wrsm_cmmu_newwci(network, lcwci)) != WRSM_SUCCESS) { - wrsm_lc_replaceconfig(lcwci, wci, NULL, config); - return (err); - } - } - - if ((err = wrsm_intr_newwci(network, lcwci)) != WRSM_SUCCESS) { - if (init_cmmu) - (void) wrsm_cmmu_delwci(network, lcwci); - wrsm_lc_replaceconfig(lcwci, wci, NULL, config); - return (err); - } - - /* - * wci is now initialized and ready for cluster traffic - */ - rw_enter(&network->nr->wcilist_rw, RW_WRITER); - wci->lcwci = lcwci; - rw_exit(&network->nr->wcilist_rw); - - - if (pause_evt_thread) - nr_unpause_event_thread(network); - - return (WRSM_SUCCESS); -} - - -/* - * start using newly attached wci - call lc_installconfig() and - * lc_enableconfig() to bring up links. (For wcis already attached when a - * new config is installed, this function is not called, and the equivalent - * work is done in wrsm_nr_installconfig() and wrsm_nr_enableconfig().) - */ -int -wrsm_nr_enablewci(wrsm_network_t *network, safari_port_t saf_id, - boolean_t dr_attach) -{ - wrsm_ncwci_t *wci; - wrsm_nc_strgrp_t *sg; - boolean_t stripe; - int err; - - ASSERT(network); - - DPRINTF(DBG_CONFIG, (CE_CONT, "wrsm_nr_enablewci() wci %d\n", - saf_id)); - ASSERT(network->availability == wrsm_enabled); - - wci = nr_safid_to_wci(network, saf_id); - ASSERT(wci != NULL); - if (wci->lcwci == NULL) - return (ENODEV); - - if (wci->nr.sg) { - sg = wci->nr.sg; - mutex_enter(&network->nr->lock); - sg->attached_wcis++; - /* - * If a newly attached wci completes a stripe group, - * turn on striping. (For a new config, do this - * during wrsm_nr_installconfig().) - */ - if (dr_attach && (sg->attached_wcis == sg->config->nwcis)) { - stripe = B_TRUE; - } - mutex_exit(&network->nr->lock); - if (stripe) - if ((err = nr_sg_stripe(sg)) != WRSM_SUCCESS) { - return (err); - } - } - - wrsm_lc_installconfig(wci->lcwci); - wrsm_lc_enableconfig(wci->lcwci); - - return (WRSM_SUCCESS); -} - - -/* - * stop using wci in preparation for it being detached - */ -int -wrsm_nr_detachwci(wrsm_network_t *network, safari_port_t saf_id, - boolean_t force) -{ - wrsm_ncwci_t *wci, *chkwci; - lcwci_handle_t lcwci; - boolean_t unstripe = B_FALSE; - wrsm_nc_strgrp_t *sg; - int err; - int wcicount = 0; -#ifdef DEBUG - int i; - wci_nc2nid_array_u wci_nc2nid; - uint64_t offset; -#endif - - ASSERT(network); - - DPRINTF(DBG_CONFIG, (CE_CONT, "nr_detachwci() wci %d\n", - saf_id)); - ASSERT(network->availability == wrsm_enabled); - - wci = nr_safid_to_wci(network, saf_id); - if (!wci) - return (ENOENT); - - lcwci = wci->lcwci; - - if (!lcwci) - return (ENODEV); - - nr_pause_event_thread(network); - - if (!force && wci_in_use(wci)) { - nr_unpause_event_thread(wci->network); - return (EBUSY); - } - - /* - * Can't remove wci if it is the last one in the controller, - * even if force is requested. - */ - - for (chkwci = network->nr->wcis; chkwci != NULL; - chkwci = chkwci->next) { - if (chkwci->lcwci) - wcicount++; - } - if (wcicount == 1) { - nr_unpause_event_thread(wci->network); - return (EBUSY); - } - - wrsm_lc_replaceconfig(wci->lcwci, wci, NULL, NULL); - /* - * tell the LC to update the link states based on the new - * NULL configuration; this will cause the LC to (immediately) - * notify the MH that all links are down (any that - * are no longer valid in the new config). This should - * cause the MH to (immediately) queue evt_mhdirect events - * for the event thread to process. - */ - wrsm_lc_cleanconfig(wci->lcwci); - - nr_unpause_event_thread(wci->network); - /* - * wait for link down events to cause necessary ncslice rerouting - */ - nr_wait_for_wcis_rerouted(network); - nr_wait_for_event_drain(network); - - /* - * wait for links to really come down - */ - wrsm_lc_installconfig(wci->lcwci); - - /* - * turn off striping in the stripe group involving this wci - */ - if (wci->nr.sg) { - sg = wci->nr.sg; - mutex_enter(&network->nr->lock); - if (sg->attached_wcis == sg->config->nwcis) { - unstripe = B_TRUE; - } - sg->attached_wcis--; - mutex_exit(&network->nr->lock); - if (unstripe) { - if ((err = nr_sg_unstripe(sg)) != WRSM_SUCCESS) { - return (err); - } - } - } - - wrsm_mh_remove_wci(wci); - - /* - * wait for loopback route to be removed - */ - nr_wait_for_event_drain(network); - -#ifdef DEBUG - /* - * verify that all nc2nid entries are turned off - */ - offset = (uint64_t)ADDR_WCI_NC2NID_ARRAY; - for (i = 0; i < WRSM_MAX_CNODES; i++) { - wrsm_lc_csr_read(lcwci, offset, &(wci_nc2nid.val)); - ASSERT(wci_nc2nid.bit.launch_remote == 0); - offset += STRIDE_WCI_NC2NID_ARRAY; - } -#endif /* DEBUG */ - - wrsm_intr_delwci(network, lcwci); - (void) wrsm_cmmu_delwci(network, lcwci); - - rw_enter(&network->nr->wcilist_rw, RW_WRITER); - wci->lcwci = NULL; - rw_exit(&network->nr->wcilist_rw); - return (WRSM_SUCCESS); -} - - -/* - * determine whether this wci is being used by any ncslice routes - */ -static boolean_t -wci_in_use(wrsm_ncwci_t *wci) -{ - cnode_bitmask_t users, nullset; - boolean_t inuse; - int i; - - ASSERT(wci); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "wci_in_use() wci %d\n", - wci->config->port)); - - WRSMSET_ZERO(users); - WRSMSET_ZERO(nullset); - - for (i = 0; i < WRSM_MAX_WNODES; i++) { - if (wci->nr.wnodeinfo[i].valid) { - WRSMSET_OR(users, wci->nr.wnodeinfo[i].users); -#ifdef DEBUG - if (wrsm_nr_debug & DBG_ROUTE_EXTRA) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "wnode %d route users:\n", i)); - DPRINTNODES(wci->nr.wnodeinfo[i].users); - } -#endif - } - } - - - - if (WRSMSET_ISEQUAL(users, nullset)) - inuse = B_FALSE; - else - inuse = B_TRUE; - - return (inuse); -} - -/* - * MH calls when there has been a change in link status on this WCI - * (causing a change in wnode route status) - */ -void -wrsm_nr_mhdirect(wrsm_ncwci_t *wci, wrsm_mh_reachable_t *reachable) -{ - wrsm_nr_event_t *event; - - ASSERT(wci); - ASSERT(wci->config); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "wrsm_nr_mhdirect() wci %d\n", - wci->config->port)); - - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->type = wrsm_evt_mhdirect; - event->data.mhevent.wci = wci; - bcopy(reachable, &(event->data.mhevent.mh_reachable), - sizeof (wrsm_mh_reachable_t)); - wrsm_nr_add_event(wci->network, event, B_TRUE); -} - - -/* - * MH calls when it has performed an MH subnet coordinated reroute of the - * wnode routes on this WCI - */ -void -wrsm_nr_mhreroute(wrsm_ncwci_t *wci, wrsm_mh_reachable_t *reachable) -{ - wrsm_nr_event_t *event; - - ASSERT(wci); - ASSERT(wci->config); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "wrsm_nr_mhreroute() wci %d\n", - wci->config->port)); - - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->type = wrsm_evt_mhreroute; - event->data.mhevent.wci = wci; - bcopy(reachable, &(event->data.mhevent.mh_reachable), - sizeof (wrsm_mh_reachable_t)); - wrsm_nr_add_event(wci->network, event, B_TRUE); -} - - -/* - * This is a daemon that processes events for this network. There are - * currently 2 generators of events: a change in configuration ( - * initiated by an ioctl), and a change in route state (initiated by - * the MH after receiving notification of a link up/down or after a - * network wide MH reroute). - */ -static void -nr_event_thread(wrsm_network_t *network) -{ - int i; - callb_cpr_t cprinfo; - wrsm_nr_event_t *event; - wrsm_node_t *node; - int wcis_in_reroute; - wrsm_ncwci_t *wci; - wrsm_nr_t *nr; - boolean_t recalc = B_FALSE; - - ASSERT(network); - ASSERT(network->nr); - nr = network->nr; - - DPRINTF(DBG_EVENT_EXTRA, (CE_CONT, "nr_event_thread(): " - "rsm ctlr id %d\n", network->rsm_ctlr_id)); - - CALLB_CPR_INIT(&cprinfo, &(nr->lock), callb_generic_cpr, - "wrsm_nr_event_thread"); - - /* LINTED: constant in conditional context */ - while (1) { - - /* - * The event thread consumes all events on the event queue. - * Once the event queue is empty, it looks at each cnode to - * see if it needs to be rerouted. After selecting any new - * routes, it then applies them enmasse, thereby avoiding - * too many interruptions. - */ - - mutex_enter(&(nr->lock)); - while (!nr->events) { - if (nr->stop_event_thr) { - DPRINTF(DBG_EVENT, (CE_NOTE, - "nr_event_thread 0x%p network ctlr %d: " - "stopping\n", (void *)curthread, - network->rsm_ctlr_id)); - ASSERT(nr->events == NULL); - nr->event_thread = NULL; - /* awaken config thread */ - ASSERT(nr->pausing == B_FALSE); - nr->wait_pause = 0; - cv_broadcast(&(nr->config_cv)); - /* - * CALLB_CPR_EXIT() calles mutex_exit() on lock - * passed in above. Therefore, do not call - * mutex_exit() explicitly here. - */ - CALLB_CPR_EXIT(&cprinfo); - thread_exit(); - } - DPRINTF(DBG_EVENT_EXTRA, (CE_NOTE, - "nr_event_thread network ctlr %d: sleeping " - "on event_cv\n", network->rsm_ctlr_id)); - CALLB_CPR_SAFE_BEGIN(&cprinfo); - cv_wait(&nr->event_cv, &(nr->lock)); - CALLB_CPR_SAFE_END(&cprinfo, &(nr->lock)); - DPRINTF(DBG_EVENT_EXTRA, (CE_NOTE, - "nr_event_thread network ctlr %d: awakened\n", - network->rsm_ctlr_id)); - /* - * Check if we're supposed to stop running. - * This shouldn't be called unless the network is - * being removed (all activity on this event queue - * should have stopped at this point). - */ - if (nr->stop_event_thr) { - DPRINTF(DBG_EVENT, (CE_NOTE, - "nr_event_thread 0x%p network ctlr %d: " - "stopping\n", (void *)curthread, - network->rsm_ctlr_id)); - ASSERT(nr->events == NULL); - nr->event_thread = NULL; - /* awaken config thread */ - nr->wait_pause = 0; - cv_broadcast(&(nr->config_cv)); - /* - * CALLB_CPR_EXIT() calles mutex_exit() on lock - * passed in above. Therefore, do not call - * mutex_exit() explicitly here. - */ - CALLB_CPR_EXIT(&cprinfo); - thread_exit(); - } - } - mutex_exit(&(nr->lock)); - - nr->event_thr_loopcnt++; - - /* - * process all events - */ - mutex_enter(&(nr->lock)); - while ((event = nr->events) != NULL) { - nr->events = event->next; - if (nr->last_event == event) - nr->last_event = NULL; - mutex_exit(&(nr->lock)); - nr_process_event(network, event); - kmem_free(event, sizeof (wrsm_nr_event_t)); - mutex_enter(&(nr->lock)); - } - mutex_exit(&(nr->lock)); - - /* - * recalculate any cnode's ncslice-routes affected - * by events - */ -recalc: - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (node == NULL || node->routeinfo == NULL) - continue; - - if (node->routeinfo->check_route) { - /* - * Calculate route for this node. If - * selected route affects other nodes, go - * back and restart route evaluation for - * previously processed nodes. - */ - recalc = nr_cnode_route(node); - if (recalc) - goto recalc; - } - } - - /* - * apply calculated routes - */ - ncslice_apply_routes(network); - - /* - * call wrsm_mh_reroute() for any WCIs that are being - * rerouted (must happen after ncslices have been - * routed on any direct connect nodes) - */ - - wcis_in_reroute = 0; - for (wci = network->nr->wcis; wci != NULL; wci = wci->next) { - if (wci->reroute_state == wci_in_reroute) { - wcis_in_reroute++; - } - if ((network->availability == wrsm_enabled && - wci->reroute_state == wci_need_reroute) || - wci->reroute_state == wci_force_reroute) { - if (wrsm_mh_reroute(wci)) - wcis_in_reroute++; - } - } - - /* - * See if thread is waiting to be awakened. - */ - - mutex_enter(&(nr->lock)); - if (nr->wait_eventdrain) { - nr->wait_eventdrain = B_FALSE; - cv_broadcast(&nr->config_cv); - } - - if (nr->wait_wcis_rerouting && wcis_in_reroute == 0) { - nr->wait_wcis_rerouting = B_FALSE; - cv_broadcast(&(nr->config_cv)); - - } - - if (nr->wait_pause > 0) { - DPRINTF(DBG_EVENT_EXTRA, (CE_NOTE, - "nr_event_thread network ctlr %d: pausing " - "on config_cv\n", network->rsm_ctlr_id)); - nr->wait_pause--; - ASSERT(nr->pausing == B_FALSE); - nr->pausing = B_TRUE; - cv_broadcast(&nr->config_cv); - do { - cv_wait(&(nr->config_cv), &(nr->lock)); - } while (nr->pausing == B_TRUE); - DPRINTF(DBG_EVENT_EXTRA, (CE_NOTE, - "nr_event_thread network ctlr %d: unpausing\n", - network->rsm_ctlr_id)); - } - mutex_exit(&(nr->lock)); - } -} - - -/* - * function to queue an event structure to the network events queue - */ -void -wrsm_nr_add_event(wrsm_network_t *network, wrsm_nr_event_t *event, - boolean_t release_lock) -{ - wrsm_nr_t *nr; - - ASSERT(network); - ASSERT(network->nr); - nr = network->nr; - - event->next = NULL; - - mutex_enter(&(nr->lock)); - if (nr->last_event == NULL) { - nr->events = event; - } else { - nr->last_event->next = event; - } - nr->last_event = event; - cv_signal(&(nr->event_cv)); - - if (release_lock) - mutex_exit(&(nr->lock)); -} - - -/* - * calling thread sleeps until the event thread consumes all events - * currently on the queue, re-calculates and applies routes, and - * initiates wci reroutes based on (at least) these events - */ -static void -nr_wait_for_event_drain(wrsm_network_t *network) -{ - wrsm_nr_t *nr; - wrsm_nr_event_t *event; - - ASSERT(network); - ASSERT(network->nr); - nr = network->nr; - - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->type = wrsm_evt_wakeup; - wrsm_nr_add_event(network, event, B_FALSE); - nr->wait_eventdrain = B_TRUE; - do { - DPRINTF(DBG_CONFIG_EXTRA, (CE_NOTE, "waiting for " - "event queue to drain\n")); - cv_wait(&(nr->config_cv), &(nr->lock)); - } while (nr->wait_eventdrain == B_TRUE); - mutex_exit(&nr->lock); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_NOTE, "events have been drained\n")); -} - - -/* - * calling thread sleeps until the event thread determines that no - * wcis are in the middle of an MH reroute. - */ -static void -nr_wait_for_wcis_rerouted(wrsm_network_t *network) -{ - wrsm_nr_t *nr; - wrsm_nr_event_t *event; - - ASSERT(network); - ASSERT(network->nr); - nr = network->nr; - - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->type = wrsm_evt_wakeup; - wrsm_nr_add_event(network, event, B_FALSE); - nr->wait_wcis_rerouting = B_TRUE; - do { - DPRINTF(DBG_CONFIG_EXTRA, (CE_NOTE, "waiting for " - "wci reroutes to finish\n")); - cv_wait(&(nr->config_cv), &(nr->lock)); - } while (nr->wait_wcis_rerouting == B_TRUE); - mutex_exit(&(nr->lock)); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_NOTE, "no wcis are rerouting\n")); -} - - -/* - * cause the event thread to pause after it finishes consuming - * and applying the current set of events on its queue - */ -static void -nr_pause_event_thread(wrsm_network_t *network) -{ - wrsm_nr_t *nr; - wrsm_nr_event_t *event; - uint_t pause; - - ASSERT(network); - ASSERT(network->nr); - nr = network->nr; - - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->type = wrsm_evt_wakeup; - wrsm_nr_add_event(network, event, B_FALSE); - pause = nr->wait_pause; - nr->wait_pause++; - do { - DPRINTF(DBG_CONFIG_EXTRA, (CE_NOTE, "waiting for " - "evt thr to pause with wait_pause %d\n", pause)); - cv_wait(&(nr->config_cv), &(nr->lock)); - } while ((nr->wait_pause != pause) && (nr->wait_pause != 0)); - ASSERT(nr->pausing == B_TRUE); - mutex_exit(&nr->lock); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_NOTE, "evt thr paused\n")); -} - - -/* - * cause the paused event thread to continue consuming events - */ -static void -nr_unpause_event_thread(wrsm_network_t *network) -{ - ASSERT(network); - ASSERT(network->nr); - - mutex_enter(&(network->nr->lock)); - ASSERT(network->nr->pausing == B_TRUE); - network->nr->pausing = B_FALSE; - cv_broadcast(&(network->nr->config_cv)); - mutex_exit(&(network->nr->lock)); -} - - - -/* - * process the event - * return the event type in case some sort of signalling is needed - */ -static void -nr_process_event(wrsm_network_t *network, wrsm_nr_event_t *event) -{ - wrsm_ncwci_t *wci; - wrsm_mh_reachable_t *reachable; - - ASSERT(network); - ASSERT(event); - - DPRINTF(DBG_EVENT, (CE_CONT, "ctlr %d: nr_process_event() " - "type %s\n", network->rsm_ctlr_id, WRSM_EVTSTRING(event->type))); - - switch (event->type) { - - case wrsm_evt_mhdirect: - /* - * store away new wci wnode route info - */ - wci = event->data.mhevent.wci; - reachable = &(event->data.mhevent.mh_reachable); -#ifdef DEBUG - if (!wci) { - DPRINTF(DBG_WARN, (CE_WARN, - "bad event mhdirect: null wci \n")); - break; - } -#endif - if (wci->network->availability == wrsm_enabled) { - /* - * Only check routes for direct connect nodes; the - * rest will be re-evaluated after wrsm_mh_reroute() is - * performed. wrsm_mh_reroute() is initiated during - * this cycle of the event thread based on the - * wci->reroute_state being set to need_reroute. - */ - - nr_wci_routechange(wci, reachable, - wci_reroute_direct); - - } else if (wci->availability == wrsm_disabled) { - /* - * don't change any routes, just record which cnodes - * are affected by changes, and tear down invalid - * routes - */ - nr_wci_routechange(wci, reachable, - wci_reroute_disabled); - - } else { - /* - * The network is pending, installed or - * installed-up; a complete wrsm_mh_reroute() will not - * happen automatically (not until network is moved - * to enabled state), and may be delayed for - * some time: force nodes using lost wnode routes - * to reroute using the currently available wnode - * routes. - */ - - nr_wci_routechange(wci, reachable, wci_reroute_pending); - } - - /* - * need to call wrsm_mh_reroute() called for this wci - */ - wci->reroute_state = wci_need_reroute; - - break; - - - case wrsm_evt_mhreroute: - /* - * re-evaluate ncslices routes for any cnode using a wnode - * whose route has changed. - */ - wci = event->data.mhevent.wci; - reachable = &(event->data.mhevent.mh_reachable); -#ifdef DEBUG - if (!wci) { - DPRINTF(DBG_WARN, (CE_WARN, - "bad event mhdirect: null wci \n")); - break; - } -#endif - if (wci->availability == wrsm_disabled) { - /* - * don't change any routes, just record which cnodes - * are affected by changes, and tear down invalid - * routes - */ - nr_wci_routechange(wci, reachable, - wci_reroute_disabled); - } else { - /* - * re-evaluate all cnodes affected by wnode - * routes changes - */ - nr_wci_routechange(wci, reachable, wci_reroute_all); - } - break; - - - case wrsm_evt_force_reroute: - - /* - * call wrsm_mh_reroute() called for this wci called to cause - * controlled mh_rerouting in a pending/installed/installed-up - * configuration - */ - - wci = event->data.forcereroute.wci; - nr_wci_routechange(wci, NULL, wci_reroute_force); - wci->reroute_state = wci_force_reroute; - break; - - case wrsm_evt_add_passthrough: - /* - * turn on passthrough capability for this node if - * there is a route to it. - */ - (void) pt_haveroute(event->data.addpt.node); - break; - - case wrsm_evt_send_ptlist: { - /* - * Send PTLIST message with current list of nodes - * passthrough is provided for to all specified nodes. - */ - int i; - wrsm_node_t *node; - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (WRSM_IN_SET(event->data.send_ptlist.list, i)) { - node = network->nodes[i]; - if (node && (i != network->cnodeid) && - WRSM_NODE_HAVE_ROUTE(node)) { - pt_newptinfo(network, pt_route_counter, - node); - } - } - } - break; - } - - case wrsm_evt_recv_ptlist: { - /* - * received a PTLIST message from some node: process it - */ - wrsm_node_t *node; - - node = network->nodes[event->data.recv_ptlist.cnodeid]; - if (!node) { - /* ignore requests for non-existant nodes */ - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ctlr %d: " - "evt_recv_ptlist for non-existent node %d\n", - event->data.recv_ptlist.cnodeid)); - break; - } - - pt_route_update(node, - event->data.recv_ptlist.pt_provided, - event->data.recv_ptlist.pt_route_counter); - break; - } - - case wrsm_evt_wakeup: - /* - * an event to get the event thread to run - */ - break; - - case wrsm_evt_sessup: - /* - * initiate a session teardown on a node - */ - wrsm_sess_establish_immediate(network, - event->data.sess.cnodeid); - break; - - case wrsm_evt_sessdown: - /* - * initiate a session teardown on a node - */ - wrsm_sess_teardown_immediate(network, - event->data.sess.cnodeid); - break; - default: - DPRINTF(DBG_WARN, (CE_WARN, - "rsm_ctlr_id %d: unknown event %d", - network->rsm_ctlr_id, event->type)); - break; - } -} - - - - -/* - * Any cnodes using ncslice routes which involve invalid wnode routes on - * this wci must be rerouted. In some cases, cnode routes should be - * re-evaluated to take advantage of new routes. (This depends on the - * state of the network->availability.) Cnodes the need to do a route - * re-evaluation have the check_route field set to true, which causes - * nr_cnode_route() to be called for this cnode from the event thread. - * (The event thread does this after processing all events in the queue.) - * - * Also, the set of routes each cnode should consider when performing - * a route evaluation is controlled by the cnode_retry fields: the - * route evaluation only considers wcis, stripe groups and PT nodes - * which include this wci in their retry field. (This prevents - * continuously re-evaluating routes that haven't changed since they - * were rejected during the last route evaluation.) - */ - -static void -nr_wci_routechange(wrsm_ncwci_t *wci, wrsm_mh_reachable_t *reachable, - wrsm_wci_reroute_t reroute) -{ - int i, wnid; - cnode_bitmask_t lost_route; - cnodeid_t cnodeid; - wrsm_network_t *network; - wrsm_node_t *node; - wrsm_mh_reachable_t old_reachable; -#ifdef DEBUG - boolean_t changed; -#endif - - ASSERT(wci); - ASSERT(wci->config); - network = wci->network; - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "nr_wci_routechange(), wci %d, " - "%s\n", wci->config->port, WCI_RTSTRING(reroute))); - - if (reachable) { - bcopy(&(wci->nr.mh_reachable), &old_reachable, - sizeof (wrsm_mh_reachable_t)); - bcopy(reachable, &(wci->nr.mh_reachable), - sizeof (wrsm_mh_reachable_t)); - } - - WRSMSET_ZERO(lost_route); - - for (wnid = 0; wnid < WRSM_MAX_WNODES; wnid++) { - - if (!wci->nr.wnodeinfo[wnid].valid) - continue; - -#ifdef DEBUG - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "nr_wci_routechange(), " - "wnode %d, valid %d, nhops %d stripes %d " - "changed %d cnode %d\n", wnid, - wci->nr.wnodeinfo[wnid].valid, - wci->nr.mh_reachable.nhops[wnid], - wci->nr.mh_reachable.stripes[wnid], - wci->nr.mh_reachable.changed[wnid], - wci->nr.wnodeinfo[wnid].cnodeid)); - - changed = wci->nr.mh_reachable.changed[wnid]; -#endif - - /* - * If old route change hasn't yet been applied to all - * routes, re-evaluate it. - */ - if (old_reachable.changed[wnid]) - wci->nr.mh_reachable.changed[wnid] = B_TRUE; - - if (!wci->nr.mh_reachable.changed[wnid] && - reroute != wci_reroute_force) - continue; - - - /* - * wnode route has changed - * - * For the reroute_direct case, we only allow the direct - * connect route to be established if it was not available. - * - * The reroute_direct case never tears down a route, and - * only sets up a route for the node accessed by the new - * direct route (if needed). So leave route marked as - * changed so it is evaluated again after wrsm_mh_reroute() - * has completed multihop rerouting and reports back. - * - * The reroute_pending is really reroute_direct while - * config is not yet enabled. It only only causes route - * evaluations if a route is lost. This wnode route must - * still be re-evaluated for new routes, so leave it marked - * as changed. - */ - if ((reroute != wci_reroute_direct) && - (reroute != wci_reroute_pending) && - (reroute != wci_reroute_force)) { - wci->nr.mh_reachable.changed[wnid] = B_FALSE; - } - - if (wci->nr.mh_reachable.nhops[wnid] > WNODE_UNREACHABLE) { - /* - * a route to this wnode is available - */ -#ifdef DEBUG - if (changed) { - DPRINTF(DBG_ROUTE, (CE_CONT, - "ctlr %d: nr route change wci %d wnode %d " - "(nhops %d)\n", - wci->network->rsm_ctlr_id, - wci->config->port, wnid, - wci->nr.mh_reachable.nhops[wnid])); - } -#endif - - cnodeid = wci->nr.wnodeinfo[wnid].cnodeid; - node = network->nodes[cnodeid]; - - ASSERT(node); - ASSERT(node->routeinfo); - - /* - * cnodes currently using this wnode route in their - * ncslice_route are ok - * - * update the wci and stripe group retry lists that - * include this wnode route: the next time cnodes - * that could use this wnode route perform a route - * re-evaluation, they should reconsider this route - */ - - WRSMSET_OR(wci->nr.cnode_retry, - wci->nr.wnodeinfo[wnid].interested); - - if (wci->nr.sg) - WRSMSET_OR(wci->nr.sg->cnode_retry, - wci->nr.wnodeinfo[wnid].interested); - - if (reroute == wci_reroute_all) { - - /* - * cause route re-evaluation on all cnodes - * that could use this wnode - * (nr_cnode_route() is called for each - * cnode). - */ - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (WRSM_IN_SET( - wci->nr.wnodeinfo[wnid].interested, - i)) { - ASSERT(network->nodes[i]); - network->nodes[i]-> - routeinfo->check_route = - B_TRUE; - DPRINTF(DBG_ROUTE_EXTRA, - (CE_CONT, - "re-eval cnode %d on " - "avail route wci %d " - "wnode %d\n", i, - wci->config->port, wnid)); - } - } - - - } else if (reroute == wci_reroute_direct || - reroute == wci_reroute_force) { - - /* - * If this is a direct route and there is - * currently no ncslice route for this - * node, cause a route re-evaluation for - * this node. - * - * the rest of the re-evaluations will take - * place after the next wrsm_evt_mhreroute - * event. - */ - - if (wci->nr.mh_reachable.nhops[wnid] == 1) { - if (!WRSM_NODE_HAVE_ROUTE(node)) { - node->routeinfo->check_route = - B_TRUE; - DPRINTF(DBG_ROUTE_EXTRA, - (CE_CONT, - "re-eval cnode %d on " - "avail route wci %d " - "wnode %d\n", cnodeid, - wci->config->port, wnid)); - } - } - } - continue; - } else { - - /* - * there is no longer a route to this wnode - * - * cnode ncslice routes using this wnode route are - * no longer valid - */ - -#ifdef DEBUG - if (changed) { - DPRINTF(DBG_ROUTE, (CE_CONT, - "ctlr %d: nr lost route wci %d " - "wnode %d\n", - wci->network->rsm_ctlr_id, - wci->config->port, wnid)); - } - - if (wrsm_nr_debug & DBG_ROUTE_EXTRA) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "route users:\n")); - DPRINTNODES(wci->nr.wnodeinfo[wnid].users); - } -#endif - - WRSMSET_OR(wci->nr.cnode_retry, - wci->nr.wnodeinfo[wnid].users); - - - if (wci->nr.inids_enabled) { - for (i = 0; i < WRSM_INID2DNID_ENTRIES; i++) { - if (WRSM_IN_SET( - wci->nr.inid2dnid[i].wnode_bitmask, - wnid)) { - WRSMSET_OR(lost_route, - wci->nr.inid2dnid[i].users); - } - } - } else { - WRSMSET_OR(lost_route, - wci->nr.wnodeinfo[wnid].users); - } - } - } - - if (reroute == wci_reroute_all || reroute == wci_reroute_pending) { - /* - * if a complete reroute was requested or if configuration - * is in pending state, re-evaluate ncslice routes for all - * cnodes using invalid wnodes - */ - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (WRSM_IN_SET(lost_route, i)) { - ASSERT(network->nodes[i]); - ASSERT(network->nodes[i]->routeinfo); - network->nodes[i]->routeinfo->check_route = - B_TRUE; - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "re-eval cnode %d on " - "lost route wci %d\n", i, - wci->config->port, wnid)); - } - } - - } else if (reroute == wci_reroute_disabled) { - /* - * if configuration is currently disabled, teardown routes - * using invalid wnodes (except for the loopback route, - * which is always re-evaluated). - */ - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (WRSM_IN_SET(lost_route, i)) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "nr_wci_routechange(), wci %d cnode %d " - "lost route\n", wci->config->port, - i)); - - ASSERT(network->nodes[i]); - if (i == network->cnodeid) { - /* - * loopback route must always be - * valid. Recalculate. - */ - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d routechange disabled " - "reval loopback " - "node %d check_route\n", - network->rsm_ctlr_id, i)); - network->nodes[i]->routeinfo-> - check_route = B_TRUE; - } else { - if (network->nodes[i]->routeinfo-> - route_state != - ncslice_remove_route) { - network->nodes[i]->routeinfo-> - route_state = - ncslice_use_errloopback; - } - } - } - } - } -} - - - -/* - * Find the best ncslice route to this node. - * Return whether selected route affects other nodes. - */ -static boolean_t -nr_cnode_route(wrsm_node_t *node) -{ - int i; - ncslice_route_t tryroute, *currentp; - boolean_t try_all = B_FALSE; - wrsm_routing_policy_t *policy; - wrsm_preferred_route_t *proute; - cnodeid_t cnodeid; - wrsm_network_t *network; - wrsm_ncwci_t *wci; - wrsm_nc_strgrp_t *sg; - ncslice_route_t *routep; - inid_t id; - boolean_t recalc_prev_nodes = B_FALSE; - - ASSERT(node); - ASSERT(node->config); - ASSERT(node->network); - ASSERT(node->routeinfo); - cnodeid = node->config->cnodeid; - network = node->network; - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ctlr %d: nr_cnode_route(), " - "node %d\n", network->rsm_ctlr_id, - node->config->cnodeid)); - - - if (node->availability == wrsm_pending) { - /* - * Can't set up a route for this node yet. Leave - * check_route set, so that when it is enabled, the next - * time the nr event thread runs it will attempt to set up - * a route. - */ - return (recalc_prev_nodes); - } - - node->routeinfo->check_route = B_FALSE; - - if ((node->routeinfo->route_state == ncslice_remove_route) || - (node->routeinfo->route_state == ncslice_no_route)) { - /* - * this node is being removed, so don't calculate - * a new route for it - */ - return (recalc_prev_nodes); - } - - policy = node->routeinfo->policy; - ASSERT(policy); - currentp = &(node->routeinfo->current_route); - - bzero(&(node->routeinfo->new_route), sizeof (ncslice_route_t)); - bzero(&tryroute, sizeof (ncslice_route_t)); - - - /* - * Evaluate the preferred routes to see what is available. Always - * consider the current route. If current route has changed, - * re-evaluate all possible ncslice routes; otherwise, only - * re-evaluate ncslice routes where some change has been made to - * the wnode or inid routes since last checked. - */ - - - /* - * has the current route changed? - */ - if (!currentp->proute) { - try_all = B_TRUE; - } else if (currentp->proute->method == routing_passthrough) { - /* - * Always re-evaluate passthrough routes, as we don't have - * good information about how each preferred route is - * affected by changes in passthrough routing availability. - */ - try_all = B_TRUE; - - } else if (currentp->proute->route_type == route_wci) { - wci = nr_safid_to_wci(network, currentp->proute->route.wci_id); - if (WRSM_IN_SET(wci->nr.cnode_retry, cnodeid)) - try_all = B_TRUE; - } else { - ASSERT(currentp->proute->route_type == route_stripe_group); - sg = nr_sgid_to_sg(network, - currentp->proute->route.stripe_group_id); - if (WRSM_IN_SET(sg->cnode_retry, cnodeid)) - try_all = B_TRUE; - } - - - /* - * Compare all routes of interest; for each new route, choose - * between it and the current winning route; winning route is - * copied into routeinfo->new_route. - */ - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ctlr %d: node %d has %d routes\n", - network->rsm_ctlr_id, cnodeid, policy->nroutes)); - for (i = 0; i < policy->nroutes; i++) { - proute = policy->preferred_routes[i]; - ncslice_build_route(node, &tryroute, proute, (try_all | - (node->routeinfo->current_route.proute == proute))); - if (tryroute.stripes) { - /* found a viable route */ - if (node->routeinfo->policy->striping_important) { - /* - * choose best route based on number - * of stripes - */ - if (tryroute.stripes > - node->routeinfo->new_route.stripes) { - bcopy(&tryroute, - &node->routeinfo->new_route, - sizeof (ncslice_route_t)); - } - } else { - /* - * Order of routes in the preferred routes - * is most important, so use this route, - * and don't consider any routes after this - * one. - */ - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "use preferred\n")); - bcopy(&tryroute, &node->routeinfo->new_route, - sizeof (ncslice_route_t)); - break; - } - } - } - - - /* - * Selected route is now saved in node's routeinfo->new_route. - * - * if no route found, see if we can look at all wcis, stripe groups, - * passthrough routes; otherwise, remove current route. - */ - - if (ncslice_routes_match(currentp, &(node->routeinfo->new_route))) { - node->routeinfo->route_state = ncslice_use_current; - /* - * If proute nulled to mark update, get value from new_route. - */ - if (!currentp->proute) - currentp->proute = node->routeinfo->new_route.proute; - } else if (node->routeinfo->new_route.stripes == 0) { - node->routeinfo->route_state = ncslice_use_errloopback; - /* - * The local node should never end up without a route, - * as we're guaranteed to have at least one wci for - * the loopback route. - */ - ASSERT(cnodeid != network->cnodeid); - } else { - /* - * apply new route - */ - node->routeinfo->route_state = ncslice_use_new_route; - routep = &node->routeinfo->new_route; - for (i = 0; i < routep->nwcis; i++) { - if (routep->wroutes[i].route_type == nid_route_inid) { - wci = routep->wroutes[i].wci; - if (!wci->nr.using_inids) { - /* - * In order to use this route, we - * need to set up the wci to use - * inids for all routes, and force - * all users of this wci to use - * inids. If any nodes with a - * lower cnodeid are affected, - * return a flag to cause routes - * for these nodes to be - * re-evaluated. - */ - recalc_prev_nodes = - ncslice_switch_to_inids(wci, - cnodeid); - } else { - /* - * only update wci's inid2dnid - * table if this inid entry has - * changed. - */ - id = routep->wroutes[i].id; - if (wci->nr.inid2dnid[id].changed == - B_TRUE) - wci->nr.need_hw_update = B_TRUE; - } - } - } - } - - return (recalc_prev_nodes); -} - - -/* - * Commit to using inids on this wci. - * Return whether switching to inids affects other nodes. - */ -static boolean_t -ncslice_switch_to_inids(wrsm_ncwci_t *wci, cnodeid_t cnodeid) -{ - int i; - cnode_bitmask_t retrynodes; - wrsm_inid2dnid_entry_t *ientry; - wrsm_network_t *network; - boolean_t recalc_prev_nodes = B_FALSE; - - ASSERT(wci); - ASSERT(wci->config); - network = wci->network; - - DPRINTF(DBG_ROUTE, (CE_CONT, "switch_to_inids(), wci %d\n", - wci->config->port)); - - WRSMSET_ZERO(retrynodes); - wci->nr.need_hw_update = B_TRUE; - wci->nr.using_inids = B_TRUE; - - for (i = 0; i < WRSM_INID2DNID_ENTRIES; i++) { - ientry = &(wci->nr.inid2dnid[i]); - /* - * no one should be using inids at this point, as we - * haven't yet switched to using inids! - */ - /* LINTED: E_NOP_IF_STMT */ - if (!WRSMSET_ISNULL(ientry->users)) { - DPRINTF(DBG_ROUTE, - (CE_NOTE, "ientry->users not " - "empty (wci %d, inid2dnid entry %d)\n", - wci->config->port, i)); - DPRINTNODES(ientry->users); - } - if (!WRSMSET_ISNULL(ientry->reserved)) { - WRSMSET_OR(wci->nr.cnode_retry, ientry->reserved); - WRSMSET_OR(retrynodes, ientry->reserved); - if (wci->nr.sg) - WRSMSET_OR(wci->nr.sg->cnode_retry, - ientry->reserved); - } - } - - /* - * If any cnodes using or about to use this wci already had their - * routes calculated, cause their routes to be recalculated. - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (WRSM_IN_SET(retrynodes, i)) { - ASSERT(network); - ASSERT(network->nodes[i]); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d switch_to_inids " - "node %d check_route\n", - network->rsm_ctlr_id, i)); - network->nodes[i]->routeinfo->check_route = B_TRUE; - if (i < cnodeid) { - recalc_prev_nodes = B_TRUE; - } - } - } - - return (recalc_prev_nodes); -} - - -/* - * compare node's current ncslice route and a new ncslice route to see if - * they match - */ -static boolean_t -ncslice_routes_match(ncslice_route_t *route1, ncslice_route_t *route2) -{ - int i; - - ASSERT(route1); - ASSERT(route2); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ncslice_routes_match()\n")); - - if (route1->nwcis != route2->nwcis) - return (B_FALSE); - - for (i = 0; i < route1->nwcis; i++) { - if (route1->wroutes[i].wci != route2->wroutes[i].wci) - return (B_FALSE); - if (route1->wroutes[i].route_type != - route2->wroutes[i].route_type) - return (B_FALSE); - if (route1->wroutes[i].id != route2->wroutes[i].id) - return (B_FALSE); - } - - if (route1->stripes != route2->stripes) - return (B_FALSE); - - return (B_TRUE); -} - - - - - -/* - * only build an ncslice route using this proute if it has changed or if - * force is set to true; otherwise, set it to 0 (indicating there is no - * route using this proute). - */ -static void ncslice_build_route(wrsm_node_t *node, ncslice_route_t *routep, - wrsm_preferred_route_t *proute, boolean_t force) -{ - int changed = B_FALSE; - wrsm_ncwci_t *wci = NULL; - wrsm_nc_strgrp_t *sg = NULL; - cnodeid_t cnodeid; - wrsm_network_t *network; - - ASSERT(node); - ASSERT(node->config); - ASSERT(proute); - cnodeid = node->config->cnodeid; - network = node->network; - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ncslice_build_route() - node %d\n", - node->config->cnodeid)); - - bzero(routep, sizeof (ncslice_route_t)); - - - /* - * Check to see this node should retry evaluating available routes - * on the wci or stripe group for this ncslice route. (This occurs - * if one or more inid2dnid or wnode routes have changed; the wci's - * cnode_retry value includes the nodes that should retry). Remove - * this node from the wci or stripe group's retry list. Note: if - * a wci or stripe group is used in more than one preferred - * route in multi-hop mode, only the first preferred route in the - * list of preferred routes is considered. - */ - - if (proute->route_type == route_wci) { - wci = nr_safid_to_wci(network, proute->route.wci_id); - ASSERT(wci); - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "route_type wci id %d\n", - wci->config->port)); - if (wci->availability == wrsm_disabled) { - changed = B_TRUE; - } else if (proute->method == routing_passthrough || - WRSM_IN_SET(wci->nr.cnode_retry, cnodeid)) { - changed = B_TRUE; - WRSMSET_DEL(wci->nr.cnode_retry, cnodeid); - } - - } else { - sg = nr_sgid_to_sg(network, proute->route.stripe_group_id); - ASSERT(sg); - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "route_type sg id %d\n", - sg->config->group_id)); - if (sg->availability == wrsm_disabled) { - changed = B_TRUE; - } else if (proute->method == routing_passthrough || - WRSM_IN_SET(sg->cnode_retry, cnodeid)) { - changed = B_TRUE; - WRSMSET_DEL(sg->cnode_retry, cnodeid); - } - } - - /* - * If this is a passthrough route, always re-evaluate this route. - * (It is difficult to keep track of which ncslice routes should be - * retried when PT access has changed, so don't bother.) - */ - - if (proute->method == routing_passthrough) - changed = B_TRUE; - - - if (changed || force) { - if (wci) { - ncslice_build_wci_route(node->routeinfo->policy, - routep, proute, wci); -#ifdef DEBUG - if (routep->stripes) { - DPRINTF(DBG_ROUTE, (CE_CONT, "ctlr %d: node %d " - "route on wci %d has %d stripes\n", - network->rsm_ctlr_id, cnodeid, - wci->config->port, routep->stripes)); - } -#endif - } else if (sg) { - ncslice_build_sg_route(node->routeinfo->policy, - routep, proute, sg); -#ifdef DEBUG - if (routep->stripes) { - DPRINTF(DBG_ROUTE, (CE_CONT, "ctlr %d: node %d " - "route on stripe group %d has %d stripes\n", - network->rsm_ctlr_id, cnodeid, - sg->config->group_id, - routep->stripes)); - if ((routep->nwcis == 1) && - (sg->config->nwcis != 1)) - DPRINTF(DBG_ROUTE, (CE_CONT, "route " - "uses wci %d no-stripe from stripe " - "group\n", routep-> - wroutes[0].wci->config->port)); - } -#endif - } -#ifdef DEBUG - if (routep->stripes) { - if ((proute->method == routing_passthrough) && - (wrsm_nr_debug & DBG_ROUTE)) { - DPRINTF(DBG_ROUTE, (CE_CONT, - "route uses passthrough nodes:\n")); - DPRINTNODES(routep->switches); - } - } -#endif - } - -} - - - -/* - * find a route through a particular wci using the preferred route info - */ -static int -ncslice_one_wci_route(wrsm_routing_policy_t *policy, ncslice_route_t *routep, - wrsm_preferred_route_t *proute, cnode_bitmask_t used_switches, - int max_stripes, wrsm_ncwci_t *wci, int wcinum) -{ - wrsm_network_t *network; - wnodeid_t dnidlist[WRSM_MAX_DNIDS]; - cnodeid_t pt_nodeid, dest_cnodeid, inid_nodeid; - int i, j, wnid, dnids, inid; - int best_inid, most_stripes; - int stripes; - - ASSERT(wci); - ASSERT(wci->config); - ASSERT(policy); - ASSERT(proute); - network = wci->network; - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ncslice_one_wci_route()\n")); - - if (wci->availability != wrsm_enabled) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "wci %d not enabled\n", - wci->config->port)); - return (0); - } - - stripes = 0; - dest_cnodeid = policy->cnodeid; - - if (proute->method == routing_multihop) { - - /* just choose one wnode */ - for (wnid = 0; wnid < WRSM_MAX_WNODES; wnid++) { - /* - * There could be more than one wnode that routes - * to this cnode. (This is not actually allowed in - * the configuration currently.) Always use the - * first wnode found. - */ - - if (wci->nr.wnodeinfo[wnid].valid && - wci->config->reachable[wnid] == dest_cnodeid && - wci->nr.mh_reachable.nhops[wnid] > - WNODE_UNREACHABLE) { - stripes = wci->nr.mh_reachable.stripes[wnid]; - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "ncslice_one_wci_route() - wnode %d on " - "wci %d stripes %d\n", wnid, - wci->config->port, - wci->nr.mh_reachable.stripes[wnid])); - break; - } - } - - if (wnid == WRSM_MAX_WNODES) { - /* - * no usable wnode on this wci route to the desired - * cnode - */ - return (0); - } - ASSERT(stripes != 0); - - - /* - * only use inid if we have to - */ - if (!wci->nr.using_inids) { - /* use wnode */ - routep->wroutes[wcinum].wci = wci; - routep->wroutes[wcinum].route_type = nid_route_wnode; - routep->wroutes[wcinum].id = (wnodeid_t)wnid; - WRSMSET_ADD(wci->nr.wnodeinfo[wnid].reserved, - dest_cnodeid); - return (stripes); - - - } - - /* - * Using inids: reserve an inid entry with all dnids set - * to this wnode. - */ - - for (i = 0; i < WRSM_MAX_DNIDS; i++) { - dnidlist[i] = (wnodeid_t)wnid; - } - inid = ncslice_find_inid(wci, dnidlist, 1, dest_cnodeid); - if (inid > -1) { - /* use inid */ - routep->wroutes[wcinum].wci = wci; - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "wci %d using_inids " - "%c, inid #%d\n", wci->config->port, - wci->nr.using_inids ? 'y' : 'n', inid)); - routep->wroutes[wcinum].route_type = nid_route_inid; - routep->wroutes[wcinum].id = (wnodeid_t)inid; - return (stripes); - } else { - /* no inid2dnid entry available */ - return (0); - } - - } else { - ASSERT(proute->method == routing_passthrough); - - /* - * Find routes to max_stripes switches, searching in switch - * list order (preferred order). Use only switches that - * haven't been used by other wcis in this route (if this - * wci is part of a stripe group). - * - * Routemap striping is not allowed in combination with - * passthrough striping, so only use wnode entries with - * stripes == 1. - */ - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "find passthrough routes\n")); - - dnids = 0; - for (i = 0; i < proute->nswitches; i++) { - pt_nodeid = proute->switches[i]; - if (!WRSM_IN_SET( - network->nodes[pt_nodeid]->routeinfo->pt_provided, - dest_cnodeid)) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "passthrough not provided through " - "node %d to node %d\n", - pt_nodeid, dest_cnodeid)); - /* skip this switch - no passthrough to cnode */ - continue; - } - - if (WRSM_IN_SET(used_switches, pt_nodeid)) { - /* skip this switch - used already */ - continue; - } - - for (wnid = 0; wnid < WRSM_MAX_WNODES; wnid++) { - if (wci->nr.wnodeinfo[wnid].valid && - (wci->config->reachable[wnid] == - pt_nodeid) && - (wci->nr.mh_reachable.nhops[wnid] == 1) && - (wci->nr.mh_reachable.stripes[wnid] == 1)) { - dnidlist[dnids] = (wnodeid_t)wnid; - dnids++; - if (dnids == max_stripes) { - /* found enough switches */ - DPRINTF(DBG_ROUTE_EXTRA, - (CE_CONT, - "found max_stripes (%d) " - "switches\n", dnids)); - break; - } - } - } - } - - if (dnids == 0) { - /* no route */ - return (0); - } - - /* - * found a route - */ - - /* - * If just one switch through this wci, can use a - * wnode rather than inid2dnid entry. - */ - if (dnids == 1 && !wci->nr.using_inids) { - /* use wnode */ - routep->wroutes[wcinum].wci = wci; - routep->wroutes[wcinum].route_type = nid_route_wnode; - routep->wroutes[wcinum].id = (wnodeid_t)dnidlist[0]; - WRSMSET_ADD(wci->nr.wnodeinfo[wnid].reserved, - dest_cnodeid); - /* always just one stripe per switch */ - return (1); - } - - /* - * using inids - */ - - /* - * fix up dnid array - */ - /* LINTED: logical expression always true */ - ASSERT(WRSM_MAX_DNIDS == 4); - if (dnids == 1) { - dnidlist[1] = dnidlist[0]; - dnidlist[2] = dnidlist[0]; - dnidlist[3] = dnidlist[0]; - } else if (dnids == 2) { - dnidlist[2] = dnidlist[0]; - dnidlist[3] = dnidlist[1]; - } else if (dnids == 3) { - dnidlist[3] = dnidlist[2]; - } - - /* - * Reserve a new inid entry for this dnid array, or find an - * existing matching entry if there is one. - */ - - inid = ncslice_find_inid(wci, dnidlist, dnids, dest_cnodeid); - if (inid > -1) { - /* use inid */ - stripes = dnids; - routep->wroutes[wcinum].wci = wci; - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, "wci %d using " - "inid %d, inid #%d\n", wci->config->port, - wci->nr.using_inids, inid)); - routep->wroutes[wcinum].route_type = nid_route_inid; - routep->wroutes[wcinum].id = (wnodeid_t)inid; - return (stripes); - } - - - /* - * no inid entry available for the route we created - see - * if one of the existing inid entries can be used instead - */ - - most_stripes = 0; - best_inid = -1; - for (inid = 0; inid < WRSM_INID2DNID_ENTRIES; inid++) { - ASSERT(wci->nr.inid2dnid[inid].stripes != 0); - - /* - * make sure each wnode (dnid) in the nr.inid2dnid - * entry goes to usable switch - */ - dnids = 0; - for (i = 0; i < WRSM_MAX_DNIDS; i++) { - wnid = wci->nr.inid2dnid[inid].wnode_list[i]; - inid_nodeid = wci->config->reachable[wnid]; - - for (j = 0; j < proute->nswitches; j++) { - pt_nodeid = proute->switches[j]; - if (inid_nodeid == pt_nodeid) { - dnids++; - break; - } - } - } - - if (dnids == WRSM_MAX_DNIDS) { - /* found a usable entry - all dnids ok */ - if ((wci->nr.inid2dnid[inid].stripes > - most_stripes) && - (wci->nr.inid2dnid[inid].stripes <= - max_stripes)) { - /* remember the best usable entry */ - best_inid = inid; - most_stripes = - wci->nr.inid2dnid[inid].stripes; - } - } - } - - if (best_inid != -1) { - /* found an inid entry */ - stripes = most_stripes; - routep->wroutes[wcinum].wci = wci; - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, "wci %d using " - "inid %d, inid #%d\n", wci->config->port, - wci->nr.using_inids, best_inid)); - routep->wroutes[wcinum].route_type = nid_route_inid; - routep->wroutes[wcinum].id = (wnodeid_t)best_inid; - WRSMSET_ADD(wci->nr.inid2dnid[best_inid].reserved, - dest_cnodeid); - return (stripes); - } - - /* no inid2dnid entry available */ - return (0); - } -} - - -/* - * build an nclice route using a single wci - */ -static void -ncslice_build_wci_route(wrsm_routing_policy_t *policy, ncslice_route_t *routep, - wrsm_preferred_route_t *proute, wrsm_ncwci_t *wci) -{ - wnodeid_t id; - - ASSERT(routep); - ASSERT(proute); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ncslice_build_wci_route()\n")); - - WRSMSET_ZERO(routep->switches); - - routep->stripes = ncslice_one_wci_route(policy, routep, proute, - routep->switches, proute->striping_level, wci, 0); - - if (routep->stripes > 0) { - ASSERT(wci); - /* - * found a route - */ - routep->proute = proute; - routep->nwcis = 1; - routep->sg = NULL; - routep->nostripe = B_TRUE; - - id = routep->wroutes[0].id; - if (routep->wroutes[0].route_type == nid_route_inid) { - WRSMSET_COPY(wci->nr.inid2dnid[id].cnode_routes, - routep->switches); - } else { - WRSMSET_ADD(routep->switches, - wci->nr.wnodeinfo[id].cnodeid); - } - - } -} - - -/* - * build an nclice route using each wci in stripe group - */ -static void -ncslice_build_sg_route(wrsm_routing_policy_t *policy, ncslice_route_t *routep, - wrsm_preferred_route_t *proute, wrsm_nc_strgrp_t *sg) -{ - int i; - int max_stripes, stripes, totalstripes; - wnodeid_t id; - wrsm_ncwci_t *wci; - - ASSERT(sg); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ncslice_build_sg_route()\n")); - - if (sg->availability != wrsm_enabled || !sg->striping_on) { - /* - * striping is not enabled -- try just using one - * wci from the stripe group - */ - ncslice_build_sg_nostripe_route(policy, routep, proute, sg); - return; - } - - ASSERT(routep); - ASSERT(sg->config); - - routep->stripes = 0; - routep->proute = proute; - routep->nostripe = B_FALSE; - routep->sg = sg; - routep->nwcis = sg->config->nwcis; - - /* - * try to get an equal number of stripes per wci - */ - ASSERT(sg->config->nwcis > 0); - max_stripes = proute->striping_level / sg->config->nwcis; - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "max_stripes per wci = %d\n", - max_stripes)); - if (max_stripes == 0) { - /* - * Too many wcis, can't get a stripe per wci. - * Try using a single wci. - */ - ncslice_build_sg_nostripe_route(policy, routep, - proute, sg); - return; - } - - - - /* - * find a route on each wci in the stripe group - */ - - WRSMSET_ZERO(routep->switches); - totalstripes = 0; -retry: - for (i = 0; i < sg->config->nwcis; i++) { - - wci = sg->wcis[i]; - stripes = ncslice_one_wci_route(policy, routep, proute, - routep->switches, max_stripes, wci, i); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "found %d stripes on wci #%d " - "(id %d)\n", stripes, i, wci->config->port)); - - if ((!policy->wcis_balanced && stripes > 0) || - (policy->wcis_balanced && stripes == max_stripes)) { - /* found a route on this wci */ - totalstripes += stripes; - id = routep->wroutes[i].id; - if (routep->wroutes[i].route_type == nid_route_inid) { - WRSMSET_OR(routep->switches, - wci->nr.inid2dnid[id].cnode_routes); - } else { - WRSMSET_ADD(routep->switches, - wci->nr.wnodeinfo[id].cnodeid); - } - - } else { - ASSERT(stripes == 0 || policy->wcis_balanced); - - /* - * can't use current set of routes - remove routes on - * previous wcis - */ - - WRSMSET_ZERO(routep->switches); - totalstripes = 0; - - if (stripes == 0) { - /* - * There is no route on this wci. Try - * using a single wci from the stripe - * group. - */ - ncslice_build_sg_nostripe_route(policy, - routep, proute, sg); - return; - - } else { - /* - * It is required that the number of - * stripes per wci be balanced. Retry - * finding routes on all wcis with only as - * many routes as can be found on this wci. - * Start over with the first wci. - */ - ASSERT(policy->wcis_balanced); - max_stripes = stripes; - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "retry with " - "max_stripes per wci = %d\n", max_stripes)); - goto retry; - } - } - } - - - /* - * If balanced stripes aren't required, see if we can get - * additional stripes on any wcis. - */ - - if (!policy->wcis_balanced && totalstripes < proute->striping_level) { - - for (i = 0; i < sg->config->nwcis; i++) { - max_stripes = proute->striping_level - totalstripes; - if (max_stripes == 0) { - /* found enough stripes */ - break; - } - - wci = sg->wcis[i]; - - /* remove old route */ - id = routep->wroutes[i].id; - if (routep->wroutes[i].route_type == nid_route_inid) { - totalstripes -= - wci->nr.inid2dnid[id].stripes; - max_stripes += - wci->nr.inid2dnid[id].stripes; - WRSMSET_DIFF(routep->switches, - wci->nr.inid2dnid[id].cnode_routes); - } else { - ASSERT(routep->wroutes[i].route_type == - nid_route_wnode); - totalstripes -= - wci->nr.mh_reachable.stripes[id]; - max_stripes += wci->nr.mh_reachable.stripes[id]; - WRSMSET_DEL(routep->switches, - wci->nr.wnodeinfo[id].cnodeid); - } - - /* build a new route with more stripes */ - stripes = ncslice_one_wci_route(policy, routep, - proute, routep->switches, max_stripes, wci, i); - - /* found a route on this wci */ - totalstripes += stripes; - id = routep->wroutes[i].id; - if (routep->wroutes[i].route_type == nid_route_inid) { - WRSMSET_OR(routep->switches, - wci->nr.inid2dnid[id].cnode_routes); - } else { - WRSMSET_ADD(routep->switches, - wci->nr.wnodeinfo[id].cnodeid); - } - } - } - - routep->stripes = totalstripes; -} - - - -/* - * build an nclice route using just one wci from a stripe group - */ -static void -ncslice_build_sg_nostripe_route(wrsm_routing_policy_t *policy, - ncslice_route_t *routep, wrsm_preferred_route_t *proute, - wrsm_nc_strgrp_t *sg) -{ - int i; - wnodeid_t id; - - ASSERT(routep); - ASSERT(sg); - ASSERT(sg->config); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "ncslice_build_sg_nostripe_route()\n")); - - /* - * wci striping is not required: try using a single - * wci from this stripe group - */ - routep->nostripe = B_TRUE; - routep->sg = NULL; - routep->nwcis = 1; - WRSMSET_ZERO(routep->switches); - - /* - * store the single route in routep entry 0 - */ - for (i = 0; i < sg->config->nwcis; i++) { - routep->stripes = ncslice_one_wci_route(policy, routep, proute, - routep->switches, proute->striping_level, sg->wcis[i], 0); - if (routep->stripes > 0) { - /* found a single wci route */ - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "ncslice_build_sg_nostripe_route() - found route " - "on wci %d\n", sg->wcis[i]->config->port)); - - id = routep->wroutes[0].id; - if (routep->wroutes[0].route_type == nid_route_inid) { - WRSMSET_COPY( - sg->wcis[i]->nr.inid2dnid[id].cnode_routes, - routep->switches); - } else { - WRSMSET_ADD(routep->switches, - sg->wcis[i]->nr.wnodeinfo[id].cnodeid); - } - - return; - } - } -} - - - -/* - * Find a matching inid entry, otherwise find an unused entry and copy - * dnid info into it. - */ -static int -ncslice_find_inid(wrsm_ncwci_t *wci, wnodeid_t *dnidlist, int stripes, - cnodeid_t cnodeid) -{ - int i, j, free_inid, unused_inid; - wnode_bitmask_t wnode_bitmask; - wrsm_inid2dnid_entry_t *ientry; - boolean_t switching_to_inids = B_FALSE; - - ASSERT(wci); - ASSERT(wci->config); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "ncslice_find_inid() wci %d cnode %d " - "stripes %d\n", wci->config->port, cnodeid, stripes)); - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "dnids (cnodes) %d (%d) %d (%d) %d (%d) %d (%d)\n", - dnidlist[0], wci->nr.wnodeinfo[dnidlist[0]].cnodeid, - dnidlist[1], wci->nr.wnodeinfo[dnidlist[1]].cnodeid, - dnidlist[2], wci->nr.wnodeinfo[dnidlist[2]].cnodeid, - dnidlist[3], wci->nr.wnodeinfo[dnidlist[3]].cnodeid)); - - free_inid = 0; - if (!wci->nr.using_inids && !wci->nr.reserved_inids) { - /* - * Need to set up inid2dnid entries for any valid nc2nid - * entries already using or planning to use a wnode route - * on this WCI prior to looking for free inid entries. - */ - switching_to_inids = B_TRUE; - - for (i = 0; i < WRSM_MAX_WNODES; i++) { - if (!WRSMSET_ISNULL(wci->nr.wnodeinfo[i].users) || - !WRSMSET_ISNULL(wci->nr.wnodeinfo[i].reserved)) { - /* - * This wnode is in use (or about to be). - * Use next inid entry to represent this - * wnode. There will always be at least as - * many inid2dnid entries as wnodes. - */ - ientry = &(wci->nr.inid2dnid[free_inid]); - - ASSERT(free_inid < WRSM_INID2DNID_ENTRIES); - ASSERT(WRSMSET_ISNULL(ientry->wnode_bitmask)); - ASSERT(WRSMSET_ISNULL(ientry->cnode_routes)); - ASSERT(WRSMSET_ISNULL(ientry->reserved)); - - /* LINTED: E_NOP_IF_STMT */ - if (!WRSMSET_ISNULL(ientry->users)) { - DPRINTF(DBG_ROUTE, - (CE_NOTE, - "ientry->users not " - "empty (wci %d, " - "inid2dnid entry %d)\n", - wci->config->port, - free_inid)); - DPRINTNODES(ientry->users); - } - - WRSMSET_ADD(ientry->wnode_bitmask, i); - /* all dnids in entry use this wnode */ - for (j = 0; j < WRSM_MAX_DNIDS; j++) { - ientry->wnode_list[j] = i; - } - ientry->stripes = 1; - WRSMSET_ADD(ientry->cnode_routes, - wci->nr.wnodeinfo[i].cnodeid); - WRSMSET_OR(ientry->reserved, - wci->nr.wnodeinfo[i].users); - WRSMSET_OR(ientry->reserved, - wci->nr.wnodeinfo[i].reserved); - ientry->changed = B_TRUE; - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "reserved inid " - "%d for wnode %d stripes %d\n", free_inid, - i, ientry->stripes)); - free_inid++; - } - } - wci->nr.reserved_inids = B_TRUE; - } - - - WRSMSET_ZERO(wnode_bitmask); - for (i = 0; i < WRSM_MAX_DNIDS; i++) { - WRSMSET_ADD(wnode_bitmask, dnidlist[i]); - } - - free_inid = -1; - unused_inid = -1; - for (i = 0; i < WRSM_INID2DNID_ENTRIES; i++) { - if (wci->nr.inid2dnid[i].stripes == 0) { - /* inid not set up; remember */ - free_inid = i; - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "inid %d free", - free_inid)); - ASSERT(WRSMSET_ISNULL(wci->nr.inid2dnid[i].users)); - ASSERT(WRSMSET_ISNULL(wci->nr.inid2dnid[i].reserved)); - continue; - } - - /* - * inid's wnode_list doesn't need to match exactly, just - * need the same number of stripes, and same set of - * wnodes - */ - if ((wci->nr.inid2dnid[i].stripes == stripes) && - WRSMSET_ISEQUAL(wci->nr.inid2dnid[i].wnode_bitmask, - wnode_bitmask)) { - /* found a matching entry */ - DPRINTF(DBG_ROUTE_EXTRA, - (CE_CONT, "inid %d matching entry", - i)); - WRSMSET_ADD(wci->nr.inid2dnid[i].reserved, cnodeid); - return (i); - } - - if (WRSMSET_ISNULL(wci->nr.inid2dnid[i].users) && - WRSMSET_ISNULL(wci->nr.inid2dnid[i].reserved)) - /* no one is using this entry; remember */ - unused_inid = i; - } - - /* prefer a free inid over an unused inid */ - if (free_inid != -1) { - unused_inid = free_inid; - } - - if (unused_inid != -1) { - /* copy information into this inid entry */ - ientry = &(wci->nr.inid2dnid[unused_inid]); - ientry->stripes = stripes; - WRSMSET_COPY(wnode_bitmask, ientry->wnode_bitmask); - WRSMSET_ZERO(ientry->cnode_routes); - for (i = 0; i < WRSM_MAX_DNIDS; i++) { - ientry->wnode_list[i] = dnidlist[i]; - ASSERT(wci->config->wnode_reachable[dnidlist[i]]); - WRSMSET_ADD(ientry->cnode_routes, - wci->nr.wnodeinfo[dnidlist[i]].cnodeid); - } -#ifdef DEBUG - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "inid %d stripes %d cnode_routes", - unused_inid, ientry->stripes)); - if (wrsm_nr_debug & DBG_ROUTE) - DPRINTNODES(ientry->cnode_routes); -#endif - - WRSMSET_ADD(ientry->reserved, cnodeid); - ientry->changed = B_TRUE; - } else { - DPRINTF(DBG_ROUTE, (CE_CONT, "no free inid entry\n")); - if (switching_to_inids) { - for (i = 0; i < WRSM_INID2DNID_ENTRIES; i++) { - ientry = &(wci->nr.inid2dnid[i]); - if (ientry->changed) { - WRSMSET_ZERO(ientry->wnode_bitmask); - WRSMSET_ZERO(ientry->cnode_routes); - WRSMSET_ZERO(ientry->reserved); - ientry->changed = B_FALSE; - } - } - } - } - - return (unused_inid); -} - - -/* - * Map a wci number, as it appears in the - * node->routeinfo->current_route list of wcis to the stripe number - * that it will use. - */ -static int -wci_to_stripe(int i) -{ - ASSERT(i < WRSM_MAX_STRIPEWCIS); - switch (i) { - case 0: return (0); - case 1: return (2); - case 2: return (1); - case 3: return (3); - } - return (0); -} - -/* - * Calculate the striping for barriers. The link_stripes field is a bit - * mask of the offsets to read to collect the CESRs of all wcis and links - * providing access to this node. - * - * Called from event thread. - */ -static void -nr_cnode_stripes(wrsm_node_t *node) -{ - ncslice_route_t *currentp; - int i; - int wci_stripe; - wnodeid_t id; - ushort_t link_stripes = 0; - wrsm_ncwci_t *wci; - - ASSERT(node); - ASSERT(node->routeinfo); - - currentp = &(node->routeinfo->current_route); - - - /* - * WCI striping is controlled by bits 7 and 8. This means - * that striping occurs at a granularity of 128 bytes. - * The striping pattern is as follows: - * - * 4-way 2-way 1-way - * bit 8:7 WCI WCI WCI - * 0 A A A - * 1 B A A - * 2 C B A - * 3 D B A - * - * currentp->nwci can be used to turn on the appropriate WCI - * stripes: - * 1: bit 0; 2: bits 0,1; 4: bits 0-3 - * - * - * - * for inid2dnid striping, there are always 4 dnids. The - * NR programs the dnids in one of the following patterns: - * 1 way: AAAA, 2 way: ABAB, 3 way: ABCC, 4 way: ABCD - * - * The address bits used for striping are bits 9 and 10. - * The striping occurs at a gramularity of 512 bytes. - * - * The bits are used in reverse from expected order - * (see page 5-224 in the PRM, revsion 1.0, Jun 30, 1999). - * This means the striping pattern is not quite as expected: - * - * INID 4 way 3 way 2 way 1 way - * bit 10:9 entry INID INID INID INID - * 0 0 A A A A - * 1 2 C C A A - * 2 1 B B B A - * 3 3 D C B A - * - * The inid2dnid.stripe field can be used to turn on the appropriate - * stripes: - * 1: bit 0; 2: bits 0,2; 3: bits 0-2; 4: bits 0-3 - * - * - * - * For route map striping, there are alway 2 links. The - * possible patterns are: - * 1 way: AA, 2 way: AB - * - * Address bit 9 is used for route map striping. - * The striping occurs at a gramularity of 512 bytes. - * The striping pattern is as follows: - * - * rtmap 2 way 1 way - * bit 9 entry rtmap rtmap - * 0 0 A A - * 1 1 B A - * - * The wnodeinfo.stripes field can be used to turn on the appropriate - * stripes: - * 1: bit 0, 2: bits 0,1 - */ - - for (i = 0; i < currentp->nwcis; i++) { - wci = currentp->wroutes[i].wci; - id = currentp->wroutes[i].id; - wci_stripe = wci_to_stripe(i); - - if (currentp->wroutes[i].route_type == nid_route_wnode) { - - switch (wci->nr.mh_reachable.stripes[id]) { - /* fall through in each case */ - case 2: - link_stripes |= 1 << (BBIT_LINK_STRIDE + - wci_stripe); - /* LINTED: E_CASE_FALLTHRU */ - case 1: - link_stripes |= 1 << wci_stripe; - } - - } else { - ASSERT(currentp->wroutes[i].route_type == - nid_route_inid); - switch (wci->nr.inid2dnid[id].stripes) { - /* fall through in each case */ - case 4: - link_stripes |= 1 << ((3 * BBIT_LINK_STRIDE) - + wci_stripe); - /* LINTED: E_CASE_FALLTHRU */ - case 3: - link_stripes |= 1 << ((1 * BBIT_LINK_STRIDE) - + wci_stripe); - /* LINTED: E_CASE_FALLTHRU */ - case 2: - link_stripes |= 1 << ((2 * BBIT_LINK_STRIDE) - + wci_stripe); - /* LINTED: E_CASE_FALLTHRU */ - case 1: - link_stripes |= 1 << wci_stripe; - } - } - } - - *node->link_stripesp = link_stripes; -} - - -/* - * Check whether any ncslice routes are changing, and if changes require - * traffic to be stopped on the Safari bus. Stop activity on routes that - * are being removed. - * - * Note: the current algorithm removes an old route before adding a new - * route, which means that any time a route changes, traffic must be - * stopped. It might be possible to change the algorithm to change the - * route in one step in the case where the same wci is handling both the - * old and new routes. If this were true, traffic would only need to be - * stopped if the wci handling the route changed (including going from - * striped to non-striped or vice versa). - */ -static boolean_t -find_changing_routes(wrsm_network_t *network, - ncslice_route_t *errloopback_route, boolean_t *stop_trafficp) -{ - boolean_t route_changes = B_FALSE; - boolean_t stop_traffic = B_FALSE; - wrsm_node_t *node; - int i; -#ifdef DEBUG - int x; - ncslice_route_t *routep; -#endif - - ASSERT(network); - - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (node == NULL || node->routeinfo == NULL) - continue; - -#ifdef DEBUG - routep = &node->routeinfo->current_route; - - for (x = 0; x < routep->nwcis; x++) { - if (routep->wroutes[x].route_type == - nid_route_inid) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d: node %d " - "current route wci %d uses " - "inid %d\n", - network->rsm_ctlr_id, - node->config->cnodeid, - routep->wroutes[x].wci-> - config->port, - routep->wroutes[x].id)); - } - } -#endif - - if (node->routeinfo->route_state == ncslice_use_new_route) { -#ifdef DEBUG - routep = &node->routeinfo->new_route; - - for (x = 0; x < routep->nwcis; x++) { - if (routep->wroutes[x].route_type == - nid_route_inid) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d: node %d " - "new route wci %d uses inid %d\n", - network->rsm_ctlr_id, - node->config->cnodeid, - routep->wroutes[x].wci-> - config->port, - routep->wroutes[x].id)); - } else { - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d: node %d new route " - "wci %d no inids\n", - network->rsm_ctlr_id, - node->config->cnodeid, - routep->wroutes[x].wci-> - config->port)); - } - - } -#endif - if (stop_traffic) { - /* - * already set any necessary booleans - */ - continue; - } - - ASSERT(node->routeinfo->new_route.stripes != 0); - - route_changes = B_TRUE; - - if (node->routeinfo->current_route.stripes != 0) { - stop_traffic = B_TRUE; - } - - } else if (node->routeinfo->route_state == - ncslice_use_errloopback) { - DPRINTF(DBG_ROUTE, (CE_CONT, "ctlr %d: node %d will " - "use err loopback route\n", network->rsm_ctlr_id, - node->config->cnodeid)); -#ifdef DEBUG - routep = &node->routeinfo->new_route; - - for (x = 0; x < routep->nwcis; x++) { - if (routep->wroutes[x].route_type == - nid_route_inid) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d: node %d " - "err route wci %d uses inid %d\n", - network->rsm_ctlr_id, - node->config->cnodeid, - routep->wroutes[x].wci-> - config->port, - routep->wroutes[x].id)); - } else { - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d: node %d err route " - "wci %d no inids\n", - network->rsm_ctlr_id, - node->config->cnodeid, - routep->wroutes[x].wci-> - config->port)); - } - - } -#endif - - /* - * Might get here if the error loopback route has - * changed, as well as because of newly losing a route. - */ - - ASSERT(node->routeinfo->current_route.stripes != 0); - ASSERT(errloopback_route); - - /* - * Check whether already using the current - * err loopback route - */ - if (ncslice_routes_match( - &(node->routeinfo->current_route), - errloopback_route)) { - node->routeinfo->route_state = - ncslice_use_current; - continue; - } else { - bcopy(errloopback_route, - &node->routeinfo->new_route, - sizeof (ncslice_route_t)); - } - - if (WRSM_NODE_HAVE_ROUTE(node)) { - /* previous route was a real one */ - nr_noroute(node); - } - - if (stop_traffic) { - continue; - } - - - if (node->routeinfo->route_state != - ncslice_use_current) { - route_changes = B_TRUE; - - ASSERT(node->routeinfo->new_route.stripes != 0); - if (node->routeinfo->current_route.stripes - != 0) { - stop_traffic = B_TRUE; - } - } - - } else if (node->routeinfo->route_state == - ncslice_remove_route) { - DPRINTF(DBG_ROUTE, (CE_CONT, "apply_routes: removing " - "route for node %d", - node->config->cnodeid)); - if (WRSM_NODE_HAVE_ROUTE(node)) { - nr_noroute(node); - } - - /* - * Route will be completely removed if there is - * one. (There may be no route already, or a real - * route or an error route). It is ok to remove - * this route because the only time this happens is - * when a node is being removed from a config, and - * nodes can only be removed from a config after - * the controller unregisters itself (guaranteeing - * that there will be no client accesses to this - * node). There is no need to pause cpus or wcis - * because they've already stopped using this - * route, but we do want to drain wcis of - * transactions, because although we've turned off - * passthrough, we may need to wait for previous - * in-progress transactions to the ncslice. - */ - if (node->routeinfo->current_route.stripes != 0) { - /* there is currently a route to remove */ - DPRINTF(DBG_ROUTE, (CE_CONT, "ctlr %d: " - "node %d removing route\n", - network->rsm_ctlr_id, - node->config->cnodeid)); - route_changes = B_TRUE; - stop_traffic = B_TRUE; - } else { - node->routeinfo->route_state = - ncslice_no_route; - } - } - } - - *stop_trafficp = stop_traffic; - - return (route_changes); -} - - -/* - * Stop all traffic that could be generating new transactions accessing - * ncslice addresses, so that we can safely move ncslice ownership from - * one wci to another. This function is also used by DDI_SUSPEND, to - * stop all incoming traffic. - */ -static void stop_ncslice_traffic(wrsm_network_t *network, - boolean_t stop_incoming) -{ - wci_ca_config_u wci_ca_config; - wci_ca_busy_u wci_ca_busy; - wci_ra_busy_u wci_ra_busy; - wrsm_ncwci_t *wci; - - ASSERT(network); - - /* - * Stop local cpus from generating nc2nid traffic. - * (pause_cpus does a kpreempt_disable) - * The cpu_pause thread on each cpu does a membar sync - * when it starts running, flushing the cpu load/store cache. - */ - if (!stop_incoming) { - mutex_enter(&cpu_lock); - pause_cpus(NULL); - } - - /* - * If wcis are generating passthrough traffic or if all incoming - * traffic should be prevented, stop remote - * nodes from generating new traffic by turning on the - * cluster_disable flag in all wcis. (All wcis have the - * same passthrough configuration.) Note: the list of - * lcwcis can't change in the middle, as all cpus are - * stopped. - * - * Note: we don't actually know which wcis are being used - * by remote nodes for passthrough, so there's no way to - * only perform this disabling on some of the wcis. - */ - - if (network->passthrough_routes || stop_incoming) { - ASSERT(network->nr); - for (wci = network->nr->wcis; wci; wci = wci->next) { - if (!wci->lcwci) - continue; - wrsm_lc_csr_read(wci->lcwci, - (uint64_t)ADDR_WCI_CA_CONFIG, - &(wci_ca_config.val)); - wci_ca_config.bit.cluster_disable = 1; - wrsm_lc_csr_write(wci->lcwci, - (uint64_t)ADDR_WCI_CA_CONFIG, - wci_ca_config.val); - } - - /* - * Make sure already arrived passthrough/incoming requests - * have been issued onto the bus. - * - * Look at CAG busy bits; when no CAGs are busy all - * requests have completed. - */ - for (wci = network->nr->wcis; wci; wci = wci->next) { - if (!wci->lcwci) - continue; - do { - wrsm_lc_csr_read(wci->lcwci, - (uint64_t)ADDR_WCI_CA_BUSY, - &(wci_ca_busy.val)); - } while (wci_ca_busy.bit.vector); - } - } - - /* - * Make sure Request Agents on the wcis having ncslices - * removed are finished servicing requests to moving - * ncslices. Given that all cpus have membar-synced and - * all CAGS are not busy, RAGS should be pretty much idle - * already (some might still be handling a data phase). - * - * For coding simplicity, check all wcis instead of just - * those losing ncslices. - * - * The hardware team advised that we do this. - */ - - for (wci = network->nr->wcis; wci; wci = wci->next) { - if (!wci->lcwci) - continue; - do { - wrsm_lc_csr_read(wci->lcwci, - (uint64_t)ADDR_WCI_RA_BUSY, - &(wci_ra_busy.val)); - } while (wci_ra_busy.bit.vector); - } -} - - -static void -restart_ncslice_traffic(wrsm_network_t *network, boolean_t stop_incoming) -{ - wci_ca_config_u wci_ca_config; - wrsm_ncwci_t *wci; - - ASSERT(network); - - /* - * Allow remote nodes to generate passthrough/incoming nc2nid traffic. - * Note: list of lcwcis can't change in the middle, as all cpus - * are stopped. - */ - - if (network->passthrough_routes || stop_incoming) { - ASSERT(network->nr); - for (wci = network->nr->wcis; wci; wci = wci->next) { - if (!wci->lcwci) - continue; - wrsm_lc_csr_read(wci->lcwci, - (uint64_t)ADDR_WCI_CA_CONFIG, - &(wci_ca_config.val)); - wci_ca_config.bit.cluster_disable = 0; - wrsm_lc_csr_write(wci->lcwci, - (uint64_t)ADDR_WCI_CA_CONFIG, - wci_ca_config.val); - } - } - - /* - * restart local cpus stopped in stop_ncslice_traffic - * (does a kpreempt_enable) - */ - if (!stop_incoming) { - start_cpus(); - mutex_exit(&cpu_lock); - } -} - - - -/* - * Modify the hardware to reflect the newly calculated inid2dnids for - * each wci, and the new nc2nid settings described by the ncslice route - * for each node - */ -static void -ncslice_apply_routes(wrsm_network_t *network) -{ - int i; - wrsm_node_t *node, *local_node; - wrsm_ncwci_t *wci; - cnode_bitmask_t newroute; - boolean_t route_changes = B_FALSE; - boolean_t inid_changes = B_FALSE; - boolean_t stop_traffic = B_FALSE; - boolean_t ptnotify = B_FALSE; - ncslice_route_t *errloopback_route = NULL; - - ASSERT(network); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ncslice_apply_routes()\n")); - - /* - * If there is no routeinfo for the local node, than it is too - * early to set up routes. Do nothing. - */ - local_node = network->nodes[network->cnodeid]; - if (!local_node || !local_node->routeinfo) { - return; - } - - /* - * The local node is required to have a loopback route, which is - * used for any ncslice which has lost its route. The local - * loopback route is set up before any other routes, so it is - * guaranteed to be available by the time it is needed. The only - * time it is allowed to go away is when the configuration is being - * removed (in which case the controller unregisters, and dangling - * accesses to remote nodes are guaranteed to not be a problem). - */ - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "apply_routes: local route " - "state is %s; current stripes %d", - ROUTEINFO_MSGSTRING(local_node->routeinfo->route_state), - local_node->routeinfo->new_route.stripes)); - if (local_node->routeinfo->route_state == ncslice_use_new_route) { - errloopback_route = &local_node->routeinfo->new_route; - } else if (local_node->routeinfo->route_state == ncslice_use_current) { - errloopback_route = &local_node->routeinfo->current_route; - } else if (local_node->routeinfo->route_state == ncslice_no_route) { - /* - * If local node is no_route, then must be removing config, - * and must have already removed routes for all other nodes. - */ -#ifdef DEBUG - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (node && node->routeinfo) - ASSERT(node->routeinfo->route_state == - ncslice_no_route); - } -#endif - return; -#ifdef DEBUG - } else { - /* - * route_state should never be use_errloopback, as this - * _is_ the errloopback route! - */ - ASSERT(local_node->routeinfo->route_state == - ncslice_remove_route); - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (node && node->routeinfo) - ASSERT((node->routeinfo->route_state == - ncslice_remove_route) || - (node->routeinfo->route_state == - ncslice_no_route)); - } -#endif - } - - /* - * check whether any inid2dnids are changing - */ - for (wci = network->nr->wcis; wci; wci = wci->next) { - if (wci->nr.need_hw_update) { - inid_changes = B_TRUE; - } - - for (i = 0; i < WRSM_MAX_WNODES; i++) { - WRSMSET_ZERO(wci->nr.wnodeinfo[i].reserved); - } - for (i = 0; i < WRSM_INID2DNID_ENTRIES; i++) { - WRSMSET_ZERO(wci->nr.inid2dnid[i].reserved); - wci->nr.reserved_inids = B_FALSE; - } - } - - /* - * Look for changing nc2nid routes. Check whether there were - * existing routes for any of the new routes; replacing an existing - * route requires stopping traffic. - */ - route_changes = find_changing_routes(network, errloopback_route, - &stop_traffic); - - if (!inid_changes && !route_changes) - return; - - WRSMSET_ZERO(newroute); - - nr_reroute_start(network); - - /* - * Enter platform ncslice update critical section. - */ - wrsmplat_ncslice_enter(); - - if (stop_traffic) - stop_ncslice_traffic(network, B_FALSE); - - /* - * apply changes to inid2dnid registers if necessary - */ - for (wci = network->nr->wcis; wci; wci = wci->next) { - if (wci->nr.need_hw_update) - nr_update_wci(wci); - } - - /* - * apply changes to nc2nid registers if necessary - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (node == NULL || node->routeinfo == NULL) { - continue; - } - - if (node->routeinfo->route_state == - ncslice_remove_route) { - ncslice_remove_hw_route(node, - node->routeinfo->current_route); - node->routeinfo->current_route.stripes = 0; - *node->link_stripesp = 0; - } else if ((node->routeinfo->route_state == - ncslice_use_new_route) || - (node->routeinfo->route_state == - ncslice_use_errloopback)) { - - ASSERT(errloopback_route); - - - if (node->routeinfo->current_route.stripes > 0) { - ncslice_remove_hw_route(node, - node->routeinfo->current_route); - } - - if ((node->routeinfo->route_state == - ncslice_use_new_route) && (node->state == - wrsm_node_needroute)) { - /* newly able to communicate with this node */ - WRSMSET_ADD(newroute, i); - } - - ncslice_add_hw_route(node, - node->routeinfo->new_route); - } - } - - /* - * Notify platform module of any changes in ncslice ownership. - * (ncslice_responder array is updated by ncslice_add_hw_route() - * and ncslice_remove_hw_route()). - */ - wrsmplat_ncslice_setup(network->nr->ncslice_responder); - - - if (stop_traffic) - restart_ncslice_traffic(network, B_FALSE); - - /* - * Exit platform ncslice update critical section. - */ - wrsmplat_ncslice_exit(); - - /* - * for nodes that have newly acquired routes, do any necessary - * setup and notification - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - - node = network->nodes[i]; - if (!node || !node->routeinfo) - continue; - if (node->routeinfo->route_state == - ncslice_remove_route) { - wrsm_nr_logevent(network, node, lost_node_route, - "unconfigured"); - node->routeinfo->route_state = ncslice_no_route; - } else if (node->routeinfo->route_state == - ncslice_use_errloopback) { - wrsm_nr_logevent(network, node, lost_node_route, - "no-route"); - } else if (node->routeinfo->route_state == - ncslice_use_new_route) { - wrsm_nr_logevent(network, node, new_node_route, NULL); - } - if ((node->routeinfo->route_state == ncslice_use_new_route) || - (node->routeinfo->route_state == - ncslice_use_errloopback)) { - - /* lock the struct */ - mutex_enter(&network->nr->lock); - - bcopy(&node->routeinfo->new_route, - &node->routeinfo->current_route, - sizeof (ncslice_route_t)); - - /* unlock the struct */ - mutex_exit(&network->nr->lock); - - nr_cnode_stripes(node); - node->routeinfo->route_state = ncslice_use_current; - - if (WRSM_IN_SET(newroute, i)) - if (nr_haveroute(node) == B_TRUE) - ptnotify = B_TRUE; - } - } - - nr_reroute_finish(network); - - /* - * notify other nodes if passthrough access has changed - */ - if (ptnotify) - pt_newptinfo(network, pt_route_counter, NULL); -} - - -/* - * Update the wci inid2dnid registers and enable_inid flag in the - * wci_config registers to match what the data structure says they should - * be. - */ -static void -nr_update_wci(wrsm_ncwci_t *wci) -{ - int i, j; - wci_inid2dnid_array_u wci_inid; - wci_config_u wci_config; - lcwci_handle_t lcwci; - uint64_t offset; - - ASSERT(wci); - lcwci = wci->lcwci; - - DPRINTF(DBG_PAUSECPUS_EXTRA, (CE_CONT, "nr_update_wci()\n")); - - if (wci->nr.using_inids) { - /* update dnids in inid table */ - wci_inid.val = 0; - - /* - * There are 64 entries in the hardware, organized - * as inid2dnid[dnid][inid]. Each entry is spaced - * at a distance of STRIDE_WCI_INID2DNID_ARRAY bytes - * apart, and is 8 bytes (uint64_t) large. - */ - for (i = 0; i < WRSM_INID2DNID_ENTRIES; i++) { - if (!wci->nr.inid2dnid[i].changed) { - /* skip over this inid's dnids */ - continue; - } - - for (j = 0; j < WRSM_MAX_DNIDS; j++) { - wci_inid.bit.dnid = - wci->nr.inid2dnid[i].wnode_list[j]; - offset = ((uint64_t)ADDR_WCI_INID2DNID_ARRAY) + - (STRIDE_WCI_INID2DNID_ARRAY * - WRSM_INID2DNID_ENTRIES * j) + - (STRIDE_WCI_INID2DNID_ARRAY * i); - wrsm_lc_csr_write(lcwci, offset, wci_inid.val); - } - wci->nr.inid2dnid[i].changed = 0; - } - - /* modify register to use inid table */ - wrsm_lc_csr_read(lcwci, (uint64_t)ADDR_WCI_CONFIG, - &(wci_config.val)); - wci_config.bit.enable_inid = 1; - wrsm_lc_csr_write(lcwci, (uint64_t)ADDR_WCI_CONFIG, - wci_config.val); - - wci->nr.inids_enabled = B_TRUE; - - } else { - /* modify register to not use inid table */ - wrsm_lc_csr_read(lcwci, (uint64_t)ADDR_WCI_CONFIG, - &(wci_config.val)); - wci_config.bit.enable_inid = 0; - wrsm_lc_csr_write(lcwci, (uint64_t)ADDR_WCI_CONFIG, - wci_config.val); - wci->nr.inids_enabled = B_FALSE; - } - - wci->nr.need_hw_update = B_FALSE; -} - - -/* - * stop using the nc2nid entries on wcis specified by this route - */ -static void -ncslice_remove_hw_route(wrsm_node_t *node, ncslice_route_t route) -{ - int i, j; - wci_nc2nid_array_u wci_nc2nid; - uint64_t offset; - wrsm_ncwci_t *wci; - wnodeid_t id; /* inid is the same */ - wrsm_network_t *network; - ncslice_t ncslice; - - ASSERT(node); - network = node->network; - - DPRINTF(DBG_PAUSECPUS, (CE_CONT, "ctlr %d: ncslice_remove_hw_route() - " - "node %d\n", node->network->rsm_ctlr_id, node->config->cnodeid)); - - /* setting launch remote to 0 means all other fields are ignored */ - wci_nc2nid.bit.launch_remote = 0; - wci_nc2nid.val = 0; /* just to be sure */ - - /* - * turn off launch_remote bit for each ncslice on each wci in route - */ - for (i = 0; i < WRSM_NODE_NCSLICES; i++) { - if ((ncslice = node->config->exported_ncslices.id[i]) == 0) - continue; - - /* - * record that there is no wci/stripe group owner - info - * for updating AXQ's or SSM WCIs - */ - network->nr->ncslice_responder[ncslice].owner_type = - WRSM_NCOWNER_NONE; - - offset = (uint64_t)(ADDR_WCI_NC2NID_ARRAY + - (ncslice * STRIDE_WCI_NC2NID_ARRAY)); - for (j = 0; j < route.nwcis; j++) { - wrsm_lc_csr_write(route.wroutes[j].wci->lcwci, offset, - wci_nc2nid.val); -#ifdef DEBUG - wrsm_lc_csr_read(route.wroutes[j].wci->lcwci, offset, - &(wci_nc2nid.val)); - ASSERT(wci_nc2nid.bit.launch_remote == 0); - wci_nc2nid.val = 0; -#endif - } - } - - /* - * Also need to do this for ncslices forwarded to this cnode. - */ - for (i = 0; i < WRSM_MAX_NCSLICES; i++) { - if (!WRSM_IN_SET(node->routeinfo->policy->forwarding_ncslices, - i)) - continue; - - /* - * record that there is no wci/stripe group owner - info - * for updating AXQ's or SSM WCIs - */ - network->nr->ncslice_responder[i].owner_type = - WRSM_NCOWNER_NONE; - - offset = (uint64_t)(ADDR_WCI_NC2NID_ARRAY + - (i * STRIDE_WCI_NC2NID_ARRAY)); - for (j = 0; j < route.nwcis; j++) { - wrsm_lc_csr_write(route.wroutes[j].wci->lcwci, offset, - wci_nc2nid.val); -#ifdef DEBUG - wrsm_lc_csr_read(route.wroutes[j].wci->lcwci, offset, - &(wci_nc2nid.val)); - ASSERT(wci_nc2nid.bit.launch_remote == 0); - wci_nc2nid.val = 0; -#endif - } - } - - - /* - * record that this cnode is no longer using these routes - */ - for (i = 0; i < route.nwcis; i++) { - wci = route.wroutes[i].wci; - id = route.wroutes[i].id; - ASSERT(id < WRSM_MAX_WNODES); /* same max for inids */ -#ifdef DEBUG - if (wci == NULL) { - DPRINTF(DBG_PAUSECPUSWARN, (CE_WARN, "wci #%d doesn't " - "exist!\n", i)); - continue; - } else if (wci->config == NULL) { - DPRINTF(DBG_PAUSECPUSWARN, (CE_WARN, "wci #%d config " - "doesn't exist!\n", i)); - continue; - } -#endif - if (route.wroutes[i].route_type == nid_route_wnode) { - DPRINTF(DBG_PAUSECPUS, (CE_CONT, "rmv_hw_route on " - "wci %d wnode %d\n", wci->config->port, id)); - WRSMSET_DEL(wci->nr.wnodeinfo[id].users, - node->config->cnodeid); - } else { - DPRINTF(DBG_PAUSECPUS, (CE_CONT, "rmv_hw_route on " - "wci %d inid %d\n", wci->config->port, id)); - WRSMSET_DEL(wci->nr.inid2dnid[id].users, - node->config->cnodeid); - } - } - - if (route.sg) { - DPRINTF(DBG_PAUSECPUS, (CE_CONT, "rmv_hw_route for stripe " - "group %d\n", route.sg->config->group_id)); - WRSMSET_DEL(route.sg->users, node->config->cnodeid); - } -} - - -/* - * start using the nc2nid entries for ncslices belonging to this node - * on wcis specified by this route - */ -static void -ncslice_add_hw_route(wrsm_node_t *node, ncslice_route_t route) -{ - int i, j; - wci_nc2nid_array_u wci_nc2nid; - uint64_t offset; - wrsm_ncwci_t *wci; - wrsm_ncowner_t ncslice_owner_type; - wrsm_ncowner_id_t ncslice_owner; - wrsm_network_t *network; - ncslice_t ncslice; - - ASSERT(node); - ASSERT(node->config); - ASSERT(node->network); - network = node->network; - - DPRINTF(DBG_PAUSECPUS, (CE_CONT, "ctlr %d: ncslice_add_hw_route() - " - "cnode %d\n", node->network->rsm_ctlr_id, - node->config->cnodeid)); - - wci_nc2nid.val = 0; - wci_nc2nid.bit.launch_remote = 1; - wci_nc2nid.bit.encode_cluster_origin_tag = 1; - if (route.nostripe) { - wci_nc2nid.bit.no_stripe = 1; - ncslice_owner_type = WRSM_NCOWNER_WCI; - ncslice_owner.wci_id = route.wroutes[0].wci->config->port; - } else { - wci_nc2nid.bit.no_stripe = 0; - ncslice_owner_type = WRSM_NCOWNER_STRIPEGROUP; - ncslice_owner.stripe_group = route.sg->config; - } - - /* - * set the inid/wnode for each ncslice on each wci in route - */ - for (i = 0; i < WRSM_NODE_NCSLICES; i++) { - if ((ncslice = node->config->exported_ncslices.id[i]) == 0) - continue; - - /* - * record new wci/stripe group owner - info for updating - * AXQ's or SSM WCIs - */ - network->nr->ncslice_responder[ncslice].owner_type = - ncslice_owner_type; - network->nr->ncslice_responder[ncslice].owner = ncslice_owner; - - offset = (uint64_t)(ADDR_WCI_NC2NID_ARRAY + - (ncslice * STRIDE_WCI_NC2NID_ARRAY)); - - for (j = 0; j < route.nwcis; j++) { - wci_nc2nid.bit.dest_node_id = route.wroutes[j].id; - wrsm_lc_csr_write(route.wroutes[j].wci->lcwci, offset, - wci_nc2nid.val); - } - } - - /* - * Also need to do this for ncslices forwarded to this cnode. - */ - for (i = 0; i < WRSM_MAX_NCSLICES; i++) { - if (!WRSM_IN_SET(node->routeinfo->policy->forwarding_ncslices, - i)) - continue; - - /* - * record new wci/stripe group owner - info for updating - * AXQ's or SSM WCIs - */ - network->nr->ncslice_responder[i].owner_type = - ncslice_owner_type; - network->nr->ncslice_responder[i].owner = ncslice_owner; - - offset = (uint64_t)(ADDR_WCI_NC2NID_ARRAY + - (i * STRIDE_WCI_NC2NID_ARRAY)); - - for (j = 0; j < route.nwcis; j++) { - wci_nc2nid.bit.dest_node_id = route.wroutes[j].id; - wrsm_lc_csr_write(route.wroutes[j].wci->lcwci, offset, - wci_nc2nid.val); - } - } - - /* - * record that this cnode is now using these routes - */ - for (i = 0; i < route.nwcis; i++) { - wci = route.wroutes[i].wci; - if (route.wroutes[i].route_type == nid_route_wnode) { - DPRINTF(DBG_PAUSECPUS, (CE_CONT, "add_hw_route on " - "wci %d wnode %d\n", wci->config->port, - route.wroutes[i].id)); - WRSMSET_ADD( - wci->nr.wnodeinfo[route.wroutes[i].id].users, - node->config->cnodeid); - } else { - DPRINTF(DBG_PAUSECPUS, (CE_CONT, "add_hw_route on " - "wci %d inid %d\n", wci->config->port, - route.wroutes[i].id)); - WRSMSET_ADD( - wci->nr.inid2dnid[route.wroutes[i].id].users, - node->config->cnodeid); - } - } - if (route.sg) { - DPRINTF(DBG_PAUSECPUS, (CE_CONT, "add_hw_route for stripe " - "group %d\n", route.sg->config->group_id)); - WRSMSET_ADD(route.sg->users, node->config->cnodeid); - } -} - - - -/* - * A route to this node was established (previously there was no - * route). Notify transport layer and passthrough clients. - * - * return whether passthrough notification is needed - */ -static boolean_t -nr_haveroute(wrsm_node_t *node) -{ - ASSERT(node); - ASSERT(node->network); - ASSERT(node->config); - - DPRINTF(DBG_ROUTE, (CE_CONT, "ctlr %d: nr_haveroute() node %d\n", - node->network->rsm_ctlr_id, node->config->cnodeid)); - - ASSERT(node->state == wrsm_node_needroute); - - node->state = wrsm_node_haveroute; - wrsm_tl_reachable(node->network, node->config->cnodeid); - return (pt_haveroute(node)); -} - - -/* - * The route to this node was lost: - * tear down all communication to node; notify passthrough - * clients - */ -static void -nr_noroute(wrsm_node_t *node) -{ - ASSERT(node); - ASSERT(node->network); - ASSERT(node->config); - - DPRINTF(DBG_ROUTE, (CE_CONT, "ctlr %d: nr_noroute() node %d\n", - node->network->rsm_ctlr_id, node->config->cnodeid)); - - ASSERT(WRSM_NODE_HAVE_ROUTE(node)); - - wrsm_tl_unreachable(node->network, node->config->cnodeid); - - /* - * notify passthrough clients - * etc.etc. - */ - pt_noroute(node); - - /* - * record new state - */ - node->state = wrsm_node_needroute; -} - - -/* - * about to change routes in the hardware - */ -static void -nr_reroute_start(wrsm_network_t *network) -{ - ASSERT(network); - ASSERT(network->reroutingp); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "nr_reroute_start()\n")); - - /* - * update local routechange counter - */ - mutex_enter(&network->lock); - (*network->reroutingp)++; - mutex_exit(&network->lock); - - /* - * notify remote nodes using passthrough through this node of - * changing routes - */ - if (network->passthrough_routes) { - pt_newptinfo(network, pt_reroute_start, NULL); - } -} - - -/* - * finished changing routes in the hardware - */ -static void -nr_reroute_finish(wrsm_network_t *network) -{ - ASSERT(network); - ASSERT(network->route_counterp); - ASSERT(network->reroutingp); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "nr_reroute_finish()\n")); - mutex_enter(&network->lock); - (*network->route_counterp)++; - (*network->reroutingp)--; - mutex_exit(&network->lock); - - /* - * notify remote nodes using passthrough through this node of - * changing routes - */ - if (network->passthrough_routes) { - pt_newptinfo(network, pt_reroute_finish, NULL); - } -} - -/* - * This routine is called from wrsm_lc_check_lockout() when it notices - * that wci_ra_esr.acc_write_lockout is set. This means that the - * remote node that exports 'ncslice' has its write-lockout bit set - * corresponding to our cnodeid. We have to clear it by doing a read - * from page 1 of that slice (for all stripes) and make sure that all - * currently open barriers fail since this indicates that an - * undetected write error could have occured. - */ -/* ARGSUSED */ -void -wrsm_nr_clear_lockout(wrsm_ncwci_t *wci, ncslice_t ncslice) -{ - int i, j; - wrsm_network_t *network = wci->network; - wrsm_node_t *node; - volatile caddr_t lockout_vaddr; - wrsm_raw_message_t raw_buf; - uint64_t *buf = (uint64_t *)&raw_buf; - uint64_t stripes; - - ASSERT(wci); - ASSERT(wci->network); - network = wci->network; - - kpreempt_disable(); - nr_reroute_start(network); - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (!node) - continue; - /* - * Search the list of ncslices exported by the cnode, - * to see if the cnode exports the failed ncslice. - */ - for (j = 0; j < WRSM_NODE_NCSLICES; j++) { - if (ncslice == node->config->exported_ncslices.id[j]) - break; - } - - /* If this cnode doesn't export the ncslice, continue */ - if (j == WRSM_NODE_NCSLICES) - continue; - - /* If haven't yet established a route to node, don't bother */ - if (node->state != wrsm_node_haveroute) { - continue; - } - lockout_vaddr = node->lockout_vaddr; - - DPRINTF(DBG_WARN, (CE_CONT, - "nr_clear_lockout: clearing node %d vaddr %p stripes=%d", - i, (void *)lockout_vaddr, *node->link_stripesp)); - for (stripes = *node->link_stripesp; - stripes != 0; - stripes = stripes >> 1) { - if (stripes & 1) { - /* Do block read from remote page 1 */ - wrsm_blkread(lockout_vaddr, buf, 1); - } - /* Advance pointers to next stripe */ - lockout_vaddr += WCI_CLUSTER_STRIPE_STRIDE; - } - } - nr_reroute_finish(network); - kpreempt_enable(); -} - -/* - * Passthrough related route teardown - remove passthrough forwarding - * to this node, and notify other nodes of this loss of capability. - */ -static void -pt_noroute(wrsm_node_t *node) -{ - int i; - wrsm_network_t *network; - - ASSERT(node); - ASSERT(node->config); - ASSERT(node->routeinfo); - ASSERT(node->routeinfo->policy); - ASSERT(node->network); - network = node->network; - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "pt_noroute() node %d\n", - node->config->cnodeid)); - - if (!node->routeinfo->policy->forwarding_allowed) - return; - - /* - * stop waiting for this node to finish rerouting - */ - mutex_enter(&network->nr->lock); - if (node->routeinfo->pt_rerouting) { - node->routeinfo->pt_rerouting = B_FALSE; - mutex_exit(&network->nr->lock); - mutex_enter(&network->lock); - (*network->route_counterp)++; - (*network->reroutingp)--; - mutex_exit(&network->lock); - } else { - mutex_exit(&network->nr->lock); - } - - /* - * Reroute cnodes that might be using this node as a switch. - * (At some point, we might want to keep better track of which - * nodes really _are_ using a passthrough route through this node, - * to avoid unnecessary route re-evaluations.) - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (WRSM_IN_SET(node->routeinfo->pt_provided, i)) { - if (!network->nodes[i] || (i == network->cnodeid)) { - continue; - } - - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d pt_noroute " - "node %d check_route\n", - network->rsm_ctlr_id, i)); - network->nodes[i]->routeinfo->check_route = B_TRUE; - } - } - - /* - * The remote node can't be offering passthrough to anyone if - * there's no route! Zero out pt_provided list, and decrement - * pt_route_counter to be sure the next time we communicate with - * the remote node, we get an updated passthrough list. - */ - node->routeinfo->pt_route_counter--; - WRSMSET_ZERO(node->routeinfo->pt_provided); - - mutex_enter(&network->nr->lock); - if (!WRSM_IN_SET(network->nr->pt_provided, node->config->cnodeid)) { - /* - * Don't provide passthrough to this node, so skip rest - * of this function. - */ - mutex_exit(&network->nr->lock); - return; - } - - /* - * Update pt_provided list, and immediately notify other nodes of - * loss of passthrough access to this node. - */ - - WRSMSET_DEL(network->nr->pt_provided, node->config->cnodeid); - network->nr->pt_route_counter++; - mutex_exit(&network->nr->lock); - - pt_newptinfo(network, pt_route_counter, NULL); - - - /* - * remove passthrough capability to this node - */ - for (i = 0; i < WRSM_MAX_NCSLICES; i++) { - if (WRSM_IN_SET(node->routeinfo->policy->forwarding_ncslices, - i)) { - /* - * Note: no lock is needed because passthrough - * operations are single threaded (handled by nr - * event thread, and only passthrough ncslices are - * managed by nr event thread. - */ - network->wrsm_ncslice_users[i]--; - if (network->wrsm_ncslice_users[i] == 0) { - wrsm_ncsliceconfig_set(network, i, - ncslice_invalid); - } - network->passthrough_routes--; - } - } - - /* - * It shouldn't be necessary to wait for CAG busy bits to clear on - * all wcis to guarantee that they are no longer using this - * passthrough route. Turning off passthrough in the wci should - * just cause CAGs to timeout or return errors. - */ -} - - -/* - * Passthrough related route setup after a node becomes newly accessible: - * turn on passthrough forwarding to this node if it is allowed, and notify - * other nodes of this capability. - * - * Return whether passthrough notification is needed. - */ -static boolean_t -pt_haveroute(wrsm_node_t *node) -{ - int i; - wrsm_network_t *network; - - ASSERT(node); - ASSERT(node->config); - network = node->network; - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "pt_haveroute() node %d\n", - node->config->cnodeid)); - - if (!WRSM_NODE_HAVE_ROUTE(node)) - return (B_FALSE); - - ASSERT(node->routeinfo); - ASSERT(node->routeinfo->policy); - - if (!node->routeinfo->policy->forwarding_allowed) { - ASSERT(network); - if (node->config->cnodeid != network->cnodeid) { - /* - * let the remote node know about passthrough - * routes the local node currently supplies - */ - pt_newptinfo(network, pt_route_counter, node); - } - return (B_FALSE); - } - - DPRINTF(DBG_ROUTE, (CE_CONT, "ctlr %d: node %d passthrough allowed\n", - network->rsm_ctlr_id, node->config->cnodeid)); - - /* - * add passthrough capability for this node - */ - for (i = 0; i < WRSM_MAX_NCSLICES; i++) { - if (WRSM_IN_SET(node->routeinfo->policy->forwarding_ncslices, - i)) { - /* - * Note: no lock is needed because passthrough - * operations are single threaded (handled by nr - * event thread, and only passthrough ncslices are - * managed by nr event thread. - */ - if (network->wrsm_ncslice_users[i] == 0) { - wrsm_ncsliceconfig_set(network, i, - ncslice_passthrough); -#ifdef DEBUG - } else { - ASSERT(wrsm_ncsliceconfig_get(network, i) == - ncslice_passthrough); -#endif - } - network->wrsm_ncslice_users[i]++; - network->passthrough_routes++; - } - } - - - /* - * update pt_provided list - */ - mutex_enter(&network->nr->lock); - WRSMSET_ADD(network->nr->pt_provided, node->config->cnodeid); - network->nr->pt_route_counter++; - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "pt_provided now = %d\n", - network->nr->pt_route_counter)); - mutex_exit(&network->nr->lock); - - /* - * request notification of new passthrough routes - */ - return (B_TRUE); -} - - -/* - * Timeout to send pt_counter to any node that hasn't yet received - * it. - */ -static void -pt_resend_timeout(void *arg) -{ - wrsm_network_t *network; - wrsm_nr_t *nr; - wrsm_nr_event_t *event; - - ASSERT(arg); - network = (wrsm_network_t *)arg; - ASSERT(network->nr); - nr = network->nr; - - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - - mutex_enter(&nr->lock); - if (network->availability != wrsm_enabled) { - mutex_exit(&nr->lock); - kmem_free(event, sizeof (wrsm_nr_event_t)); - return; - } - WRSMSET_COPY(nr->pt_retrylist, event->data.send_ptlist.list); - WRSMSET_ZERO(nr->pt_retrylist); - nr->pt_retry_timeout_id = 0; - mutex_exit(&nr->lock); - - event->type = wrsm_evt_send_ptlist; - wrsm_nr_add_event(network, event, B_TRUE); -} - - -/* - * pt_sendptlist to this node failed; schedule a retry - */ -static void -pt_retry(wrsm_node_t *node) -{ - wrsm_network_t *network; - wrsm_nr_t *nr; - - ASSERT(node); - ASSERT(node->network); - ASSERT(node->network->nr); - network = node->network; - nr = node->network->nr; - - mutex_enter(&nr->lock); - - if ((node->network->availability != wrsm_enabled) && - (node->network->availability != wrsm_installed)) { - mutex_exit(&nr->lock); - return; - } - - WRSMSET_ADD(nr->pt_retrylist, node->config->cnodeid); - if (nr->pt_retry_timeout_id == 0) { - /* set up timeout */ - if (network->nr->suspended) { - nr->need_pt_retry_timeout = B_TRUE; - } else { - nr->pt_retry_timeout_id = timeout(pt_resend_timeout, - (void *)network, (clock_t)WRSM_PTRETRY_TIMEOUT); - } - } - - mutex_exit(&nr->lock); -} - - - -/* - * Send current set of nodes this node provides passthrough access to - * to each other remote node (or to one specified node) - */ -static void -pt_newptinfo(wrsm_network_t *network, pt_msgtype_t msgtype, - wrsm_node_t *to_node) -{ - int i; - wrsm_raw_message_t msgbuf; - wrsm_message_t *msg = (wrsm_message_t *)&msgbuf; - wrsm_ptlist_msg_t args; - wrsm_node_t *node; - - ASSERT(network); - ASSERT(network->nr); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "pt_newptinfo() %s\n", - PT_MSGSTRING(msgtype))); - - /* - * send message to all remote nodes (or the specified node) - * notifying them of available PT route - */ - bzero(&args, sizeof (wrsm_ptlist_msg_t)); - - /* - * set up message - */ - msg->header.message_type = WRSM_MSG_CONFIG_PASSTHROUGH_LIST; - - /* - * take lock to guarantee local pt_provided and pt_route_counter - * match when pt_ptlist_recv_hdlr copies info out - */ - mutex_enter(&network->nr->lock); - WRSMSET_COPY(network->nr->pt_provided, args.pt_provided); - args.pt_route_counter = network->nr->pt_route_counter; - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "ctlr %d: sending pt msg with pt_route_counter = %d\n", - network->rsm_ctlr_id, network->nr->pt_route_counter)); - mutex_exit(&network->nr->lock); - args.pt_msgtype = msgtype; - bcopy(&args, &(msg->body), sizeof (args)); - - if (to_node) { - ASSERT(WRSM_NODE_HAVE_ROUTE(to_node)); - if (pt_sendptlist(to_node, msg) == B_FALSE) { - /* - * queue up an event to retry sending this message - */ - pt_retry(to_node); - } - } else for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = network->nodes[i]; - if (!node || (i == network->cnodeid) || - !WRSM_NODE_HAVE_ROUTE(node)) { - continue; - } - - if (pt_sendptlist(node, msg) == B_FALSE) { - /* - * queue up an event retry sending this message - */ - pt_retry(node); - } - } -} - - -/* - * send PTLIST message to specified node; receive and handle reply - * message - */ -static int -pt_sendptlist(wrsm_node_t *node, wrsm_message_t *msg) -{ - wrsm_raw_message_t recvmsgbuf; - wrsm_message_t *recvmsg = (wrsm_message_t *)&recvmsgbuf; - wrsm_network_t *network; - wrsm_ptlist_msg_t recvargs; - wrsm_nr_event_t *event; - - ASSERT(node); - ASSERT(node->config); - ASSERT(node->network); - network = node->network; - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ctlr %d: pt_sendptlist() " - "node %d\n", network->rsm_ctlr_id, node->config->cnodeid)); - - ASSERT(WRSM_NODE_HAVE_ROUTE(node)); - -#ifdef DEBUG - if (wrsm_nr_debug & DBG_ROUTE_EXTRA) - wrsm_tl_dump_message("pt_sendptlist sends ", msg); -#endif - - if (wrsm_tl_rpc(network, node->config->cnodeid, msg, - recvmsg) != WRSM_SUCCESS) { - /* - * This node is not responding (message not delivered or - * response not received). (Transport Layer tears down the - * session if there is a message delivery failure). - * - * stop waiting for this node to finish rerouting - */ - mutex_enter(&network->nr->lock); - if (node->routeinfo->pt_rerouting) { - node->routeinfo->pt_rerouting = B_FALSE; - mutex_exit(&network->nr->lock); - mutex_enter(&network->lock); - (*network->route_counterp)++; - (*network->reroutingp)--; - mutex_exit(&network->lock); - } else { - mutex_exit(&network->nr->lock); - } - return (B_FALSE); - } - -#ifdef DEBUG - if (wrsm_nr_debug & DBG_ROUTE_EXTRA) - wrsm_tl_dump_message("pt_sendptlist response: ", recvmsg); -#endif - ASSERT(recvmsg->header.message_type == - WRSM_MSG_CONFIG_PASSTHROUGH_LIST_RESPONSE); - - bcopy(&(recvmsg->body), &recvargs, sizeof (recvargs)); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ctlr %d: pt_sendptlist() " - "node %d response message %s route_counter %d\n", - network->rsm_ctlr_id, node->config->cnodeid, - PT_MSGSTRING(recvargs.pt_msgtype), - recvargs.pt_route_counter)); - /* - * queue up passthrough event to event handler - * to record new passthrough info from this node. - */ - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->type = wrsm_evt_recv_ptlist; - event->data.recv_ptlist.cnodeid = node->config->cnodeid; - WRSMSET_COPY(recvargs.pt_provided, - event->data.recv_ptlist.pt_provided); - event->data.recv_ptlist.pt_route_counter = - recvargs.pt_route_counter; - wrsm_nr_add_event(network, event, B_TRUE); - - return (B_TRUE); -} - - - -/* - * Handler for the PTLIST message: save new passthrough information - * from sending node, and reply with passthrough information from this - * node (what nodes this node provides passthrough access to). - * - * The transport layer won't call a handler to deliver a message from - * a node unless the transport layer knows that node exists. The transport - * layer is notified when a node is removed by NC, before it removes the - * node pointer in network->nodes. So it's safe to use that pointer in - * the handler. - */ -static boolean_t -pt_ptlist_recv_hdlr(wrsm_network_t *network, wrsm_message_t *msg) -{ - wrsm_ptlist_msg_t args; - cnodeid_t cnodeid = msg->header.source_cnode; - wrsm_node_t *node; - wrsm_ptlist_msg_t respargs; - wrsm_raw_message_t msgbuf; - wrsm_message_t *respmsg = (wrsm_message_t *)&msgbuf; - wrsm_nr_event_t *event; - - ASSERT(network); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ctlr %d: pt_recv_hdlr()\n", - network->rsm_ctlr_id)); - -#ifdef DEBUG - if (wrsm_nr_debug & DBG_ROUTE_EXTRA) - wrsm_tl_dump_message("pt_ptlist_recv_hdlr: ", msg); -#endif - - node = network->nodes[cnodeid]; - - bcopy(&(msg->body), &args, sizeof (args)); - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ctlr %d: pt_recv_hdlr() " - "node %d message %s route_counter %d\n", - network->rsm_ctlr_id, cnodeid, - PT_MSGSTRING(args.pt_msgtype), - args.pt_route_counter)); - - /* - * handle passthrough reroute start message - */ - if (args.pt_msgtype == pt_reroute_start) { - mutex_enter(&network->nr->lock); - if (!node->routeinfo) { - mutex_exit(&network->nr->lock); - } else if (!node->routeinfo->pt_rerouting) { - node->routeinfo->pt_rerouting = B_TRUE; - mutex_exit(&network->nr->lock); - mutex_enter(&network->lock); - (*network->reroutingp)++; - mutex_exit(&network->lock); - } else { - mutex_exit(&network->nr->lock); - } - } - - - /* - * handle passthrough reroute finish message - */ - if (args.pt_msgtype == pt_reroute_finish) { - mutex_enter(&network->nr->lock); - if (!node->routeinfo) { - mutex_exit(&network->nr->lock); - } else if (node->routeinfo->pt_rerouting) { - node->routeinfo->pt_rerouting = B_FALSE; - mutex_exit(&network->nr->lock); - mutex_enter(&network->lock); - (*network->route_counterp)++; - (*network->reroutingp)--; - mutex_exit(&network->lock); - } else { - mutex_exit(&network->nr->lock); - } - } - - /* - * queue up passthrough event to event handler with latest - * passthrough info from this node - */ - - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->type = wrsm_evt_recv_ptlist; - event->data.recv_ptlist.cnodeid = cnodeid; - WRSMSET_COPY(args.pt_provided, event->data.recv_ptlist.pt_provided); - event->data.recv_ptlist.pt_route_counter = args.pt_route_counter; - wrsm_nr_add_event(network, event, B_TRUE); - - /* - * Always send a response message regardless of the pt_msgtype. - */ - respmsg->header.message_type = - WRSM_MSG_CONFIG_PASSTHROUGH_LIST_RESPONSE; - - /* - * take lock to guarantee local pt_provided and pt_route_counter - * match - */ - bzero(&respargs, sizeof (wrsm_ptlist_msg_t)); - mutex_enter(&network->nr->lock); - WRSMSET_COPY(network->nr->pt_provided, respargs.pt_provided); - respargs.pt_route_counter = network->nr->pt_route_counter; - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "ctlr %d: sending pt msg with pt_route_counter = %d\n", - network->rsm_ctlr_id, network->nr->pt_route_counter)); - mutex_exit(&network->nr->lock); - bcopy(&respargs, &(respmsg->body), sizeof (respargs)); - -#ifdef DEBUG - if (wrsm_nr_debug & DBG_ROUTE_EXTRA) - wrsm_tl_dump_message("pt_recv_hdlr responds with", respmsg); -#endif - if (wrsm_tl_rsp(network, msg, respmsg) != WRSM_SUCCESS) { - /* - * This node is not responding. (Transport Layer tears - * down the session if there is a message delivery - * failure). - * - * stop waiting for this node to finish rerouting - */ - mutex_enter(&network->nr->lock); - if (!node->routeinfo) { - mutex_exit(&network->nr->lock); - } else if (node->routeinfo->pt_rerouting) { - node->routeinfo->pt_rerouting = B_FALSE; - mutex_exit(&network->nr->lock); - mutex_enter(&network->lock); - (*network->route_counterp)++; - (*network->reroutingp)--; - mutex_exit(&network->lock); - } else { - mutex_exit(&network->nr->lock); - } - /* other side will resend, so don't call pt_retry() here. */ - } else { - mutex_enter(&network->nr->lock); - WRSMSET_DEL(network->nr->pt_retrylist, cnodeid); - mutex_exit(&network->nr->lock); - } - - return (B_TRUE); -} - - -/* - * Update the passthrough routing info for the specified node, and - * cause affected cnodes to re-evaluate their current routes. - */ -static void -pt_route_update(wrsm_node_t *node, cnode_bitmask_t pt_provided, - int route_counter) -{ - int i; - wrsm_network_t *network = node->network; - - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ctlr %d: pt_route_update() " - "from node %d\n", network->rsm_ctlr_id, node->config->cnodeid)); - - if (!node->routeinfo || node->availability == wrsm_disabled) { - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, "ctlr %d: pt_route_update - " - "no routinfo or disabled node %d\n", - network->rsm_ctlr_id, node->config->cnodeid)); - /* this node is going away; ignore update message */ - return; - } - - - if (node->routeinfo->pt_route_counter == route_counter) { - /* - * list of passthrough nodes hasn't changed - */ - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "pt_route_counter unchanged\n")); -#ifdef DEBUG - if (!WRSMSET_ISEQUAL(node->routeinfo->pt_provided, - pt_provided)) - DPRINTF(DBG_WARN, (CE_WARN, - "pt_provided bitmasks don't match\n")); -#endif - - return; - } - - /* - * Received new list of nodes this node provides passthrough - * access to. - */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - /* - * only re-evaluate routes for nodes interested in using - * this node as a switch - */ - if (!WRSM_IN_SET(node->routeinfo->pt_interested, i)) - continue; - - if (WRSM_IN_SET(node->routeinfo->pt_provided, i) != - WRSM_IN_SET(pt_provided, i)) { - /* - * Passthrough access to this node has changed; - * cause route re-evalauation. - */ - if (!network->nodes[i]) - continue; - - DPRINTF(DBG_ROUTE_EXTRA, (CE_NOTE, - "ctlr %d pt_route_update " - "node %d check_route\n", - network->rsm_ctlr_id, i)); - network->nodes[i]->routeinfo->check_route = B_TRUE; -#ifdef DEBUG - if (WRSM_IN_SET(pt_provided, i)) { - DPRINTF(DBG_ROUTE, (CE_CONT, "ctlr %d: " - "gained access " - "through node %d to node %d\n", - network->rsm_ctlr_id, - node->config->cnodeid, i)); - } else { - DPRINTF(DBG_ROUTE, (CE_CONT, "ctlr %d: " - "lost access through node %d to node %d\n", - network->rsm_ctlr_id, - node->config->cnodeid, i)); - } -#endif - } - } - - WRSMSET_COPY(pt_provided, node->routeinfo->pt_provided); - node->routeinfo->pt_route_counter = route_counter; -#ifdef DEBUG - DPRINTF(DBG_ROUTE_EXTRA, (CE_CONT, - "ctlr %d: node %d pt_provided - \n", - network->rsm_ctlr_id, node->config->cnodeid)); - - if (wrsm_nr_debug & DBG_ROUTE_EXTRA) - DPRINTNODES(node->routeinfo->pt_provided); -#endif - -} - - - -/* - * translate from safari port id to wci structure - */ -static wrsm_ncwci_t * -nr_safid_to_wci(wrsm_network_t *network, safari_port_t id) -{ - wrsm_ncwci_t *wci; - - ASSERT(network); - ASSERT(network->nr); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "nr_safid_to_wci()\n")); - - for (wci = network->nr->wcis; wci != NULL; wci = wci->next) { - ASSERT(wci->config); - if (wci->config->port == id) - return (wci); - } - - DPRINTF(DBG_WARN, (CE_WARN, - "safid_to_wci - no wci with id %d!\n", id)); - return (NULL); -} - - -/* - * translate from stripe group id to stripe group structure - */ -static wrsm_nc_strgrp_t * -nr_sgid_to_sg(wrsm_network_t *network, uint32_t sgid) -{ - wrsm_nc_strgrp_t *sg; - - ASSERT(network); - ASSERT(network->nr); - - DPRINTF(DBG_CONFIG_EXTRA, (CE_CONT, "nr_sgid_to_sg()\n")); - - for (sg = network->nr->sgs; sg != NULL; sg = sg->next) { - ASSERT(sg); - ASSERT(sg->config); - if (sg->config->group_id == sgid) - return (sg); - } - - DPRINTF(DBG_WARN, (CE_WARN, - "sgid_to_sg - no sg with id %d!\n", sgid)); - return (NULL); -} - - -/* - * add_wrsm_route_kstat - */ -static void -add_wrsm_route_kstat(wrsm_node_t *node) -{ - kstat_t *rte_ksp; - wrsm_route_kstat_t *rte_named; - int i, j; - char tmp_str[30]; - - ASSERT(node); - ASSERT(node->network); - ASSERT(node->config); - - rte_ksp = kstat_create(WRSM_KSTAT_WRSM_ROUTE, - node->network->rsm_ctlr_id, - node->config->hostname, - "net", - KSTAT_TYPE_NAMED, - sizeof (wrsm_route_kstat_t) / sizeof (kstat_named_t), - 0); - - if (rte_ksp == NULL) { - cmn_err(CE_WARN, - "rsm ctlr %d to host %s: routes kstat_create failed", - node->network->rsm_ctlr_id, node->config->hostname); - node->routeinfo->wrsm_route_ksp = NULL; - return; - } - - rte_named = (wrsm_route_kstat_t *)(rte_ksp->ks_data); - - /* initialize the named kstats */ - kstat_named_init(&rte_named->version, - WRSMKS_CONFIG_VERSION_NAMED, KSTAT_DATA_UINT64); - - kstat_named_init(&rte_named->type, - WRSMKS_ROUTE_TYPE_NAMED, KSTAT_DATA_UINT32); - - kstat_named_init(&rte_named->num_wcis, - WRSMKS_NUM_WCIS, KSTAT_DATA_UINT32); - - kstat_named_init(&rte_named->num_stripes, - WRSMKS_NUM_STRIPES, KSTAT_DATA_UINT32); - - kstat_named_init(&rte_named->num_changes, - WRSMKS_NUMCHANGES, KSTAT_DATA_UINT32); - - kstat_named_init(&rte_named->cnodeid, - WRSMKS_CNODEID, KSTAT_DATA_UINT32); - - kstat_named_init(&rte_named->fmnodeid, - WRSMKS_FMNODEID, KSTAT_DATA_UINT32); - - for (i = 0; i < WRSM_MAX_WCIS_PER_STRIPE; i++) { - (void) sprintf(tmp_str, WRSMKS_ROUTE_PORTID, i); - - kstat_named_init(&rte_named->portid[i], - tmp_str, KSTAT_DATA_UINT32); - - (void) sprintf(tmp_str, WRSMKS_ROUTE_INSTANCE, i); - - kstat_named_init(&rte_named->instance[i], - tmp_str, KSTAT_DATA_UINT32); - - (void) sprintf(tmp_str, WRSMKS_ROUTE_NUMHOPS, i); - kstat_named_init(&rte_named->numhops[i], - tmp_str, KSTAT_DATA_UINT32); - - (void) sprintf(tmp_str, WRSMKS_ROUTE_NUMLINKS, i); - kstat_named_init(&rte_named->numlinks[i], - tmp_str, KSTAT_DATA_UINT32); - - for (j = 0; j < WRSM_MAX_DNIDS; j++) { - (void) sprintf(tmp_str, WRSMKS_ROUTE_LINKID, i, j); - kstat_named_init(&rte_named->linkid[i][j], - tmp_str, KSTAT_DATA_UINT32); - - (void) sprintf(tmp_str, WRSMKS_ROUTE_NODEID, i, j); - kstat_named_init(&rte_named->nodeid[i][j], - tmp_str, KSTAT_DATA_UINT32); - - (void) sprintf(tmp_str, WRSMKS_ROUTE_GNID, i, j); - kstat_named_init(&rte_named->gnid[i][j], - tmp_str, KSTAT_DATA_UINT32); - } - } - - /* save the kstat pointer in the routeinfo struct */ - node->routeinfo->wrsm_route_ksp = rte_ksp; - - rte_ksp->ks_update = update_wrsm_route_kstat; - rte_ksp->ks_private = (void *)node; - kstat_install(rte_ksp); -} - -static void -del_wrsm_route_kstat(wrsm_node_t *node) -{ - ASSERT(node); - ASSERT(node->routeinfo); - /* - * The kstat framework guarantees that any outstanding - * calls to the update function will be completed before - * the kstat can be deleted. - */ - if (node->routeinfo->wrsm_route_ksp) { - kstat_delete(node->routeinfo->wrsm_route_ksp); - } -} - -/* - * update the route kstat - */ -static int -update_wrsm_route_kstat(kstat_t *ksp, int rw) -{ - wrsm_route_kstat_t *rte_named; - wrsm_node_t *node; -#ifdef DEBUG - char *fm_node_name; -#endif - ncslice_route_t cur_rte; - inidwnode_route_t wroute; - int wnodeid; - int link; - int i, j; - - DPRINTF(DBG_RT_KSTAT, (CE_CONT, "in update_wrsm_route_kstat")); - - /* This is a read=only kstat */ - if (rw == KSTAT_WRITE) { - /* Writing is not allowed - log the error */ - DPRINTF(DBG_RT_KSTAT, (CE_CONT, "route_kstat is read-only")); - return (EACCES); - } - - ASSERT(ksp); - - /* Get the kstat structure */ - rte_named = (wrsm_route_kstat_t *)ksp->ks_data; - - /* Get node structure from private part of kstat */ - node = (wrsm_node_t *)ksp->ks_private; - - /* always initialize to 0 then count number of links for each wci */ - rte_named->num_stripes.value.ui32 = 0; - - /* - * Initialize the following values to 0, so that there will not be - * bogus values when there is no route - */ - rte_named->num_wcis.value.ui32 = 0; - for (i = 0; i < WRSM_MAX_WCIS_PER_STRIPE; i++) { - rte_named->portid[i].value.ui32 = 0; - rte_named->instance[i].value.ui32 = 0; - rte_named->numhops[i].value.ui32 = 0; - rte_named->numlinks[i].value.ui32 = 0; - for (j = 0; j < WRSM_MAX_DNIDS; j++) { - rte_named->linkid[i][j].value.ui32 = 0; - rte_named->nodeid[i][j].value.ui32 = 0; - rte_named->gnid[i][j].value.ui32 = 0; - } - } - - if (node == NULL) { - DPRINTF(DBG_RT_KSTAT, (CE_CONT, "kstat: node is NULL")); - return (0); - } - -#ifdef DEBUG - /* Get the FM node name */ - fm_node_name = node->config->hostname; -#endif - DPRINTF(DBG_RT_KSTAT, (CE_CONT, "node name = %s", fm_node_name)); - DPRINTF(DBG_RT_KSTAT, (CE_CONT, "cnodeid = %d", - node->config->cnodeid)); - - if (node->availability != wrsm_enabled) { - DPRINTF(DBG_WARN, - (CE_CONT, "kstat: node availability not enabled")); - return (0); - } - - if (node->state != wrsm_node_haveroute) { - DPRINTF(DBG_WARN, (CE_CONT, "kstat: no route for node")); - return (0); - } - - if (node->routeinfo->route_state != ncslice_use_current) { - DPRINTF(DBG_WARN, - (CE_CONT, "kstat: cannot access current route")); - return (0); - } - - /* Lock the network router info */ - mutex_enter(&node->network->nr->lock); - - /* Copy the current route info into a local data structure */ - bcopy(&node->routeinfo->current_route, - &cur_rte, sizeof (ncslice_route_t)); - - rte_named->version.value.ui64 = node->network->version_stamp; - rte_named->num_changes.value.ui32 = - (uint32_t)node->routeinfo->num_rte_changes; - - /* Unlock the network router info */ - mutex_exit(&node->network->nr->lock); - - DPRINTF(DBG_RT_KSTAT, (CE_CONT, "after mutex_exit")); - - if (cur_rte.proute == NULL) { - DPRINTF(DBG_WARN, (CE_CONT, "proute is null")); - /* do something to indicate this state */ - return (0); - } - - rte_named->type.value.ui32 = - (uint32_t)cur_rte.proute->method; - rte_named->num_wcis.value.ui32 = - (uint32_t)cur_rte.nwcis; - rte_named->cnodeid.value.ui32 = - (uint32_t)node->config->cnodeid; - rte_named->fmnodeid.value.ui32 = - (uint32_t)node->config->fmnodeid; - - DPRINTF(DBG_RT_KSTAT, - (CE_CONT, "kstat: getting per wci/stripe info")); - - /* Get the per stripe information */ - for (i = 0; i < cur_rte.nwcis; i++) { - - /* Get the wroute for this stripe */ - wroute = cur_rte.wroutes[i]; - - if (wroute.wci == NULL) { - DPRINTF(DBG_WARN, - (CE_CONT, "kstat: NULL wroute.wci encountered")); - rte_named->portid[i].value.ui32 = 0; - rte_named->instance[i].value.ui32 = 0; - rte_named->numhops[i].value.ui32 = 0; - rte_named->numlinks[i].value.ui32 = 0; - continue; - } - - rte_named->portid[i].value.ui32 = - (uint32_t)wroute.wci->config->port; - - rte_named->instance[i].value.ui32 = - (uint32_t)wrsm_lc_get_instance(wroute.wci->lcwci); - - rte_named->numhops[i].value.ui32 = - wroute.wci->nr.mh_reachable.nhops[wroute.id]; - - /* If nhops==0, set numlinks=0, and forget about links */ - /* This must be the loopback route */ - if (rte_named->numhops[i].value.ui32 == 0) { - rte_named->numlinks[i].value.ui32 = 0; - continue; - } - - rte_named->numlinks[i].value.ui32 = - wroute.wci->nr.mh_reachable.stripes[wroute.id]; - - /* - * Depending on the route type, the link and node - * information are found in different data structures. - */ - - if (wroute.route_type == nid_route_inid) { - - DPRINTF(DBG_RT_KSTAT, (CE_CONT, - "nid_route_inid, stripe=%d", i)); - DPRINTF(DBG_RT_KSTAT, (CE_CONT, - "wroute.id = %d\n", wroute.id)); - - for (j = 0; j < WRSM_MAX_DNIDS; j++) { - - /* - * Go through the inid2dnid table. - * The inid2dnid entry is the wnodeid. - */ - wnodeid = - wroute.wci->nr.inid2dnid[wroute.id].wnode_list[j]; - - DPRINTF(DBG_RT_KSTAT, (CE_CONT, "i=%d, wnodeid=%d", - j, wnodeid)); - /* - * Use wnodeid to look up the link. - */ - link = wrsm_mh_wnode_to_link(wroute.wci, wnodeid); - - rte_named->linkid[i][j].value.ui32 = link; - - /* - * Use the wnodeid to look up the node id. - */ - if (wroute.wci->nr.wnodeinfo[wnodeid].valid) { - rte_named->nodeid[i][j].value.ui32 = - wroute.wci->nr.wnodeinfo[wnodeid].cnodeid; - rte_named->num_stripes.value.ui32++; - DPRINTF(DBG_RT_KSTAT, (CE_CONT, "kstat: " - "current stripe total for passthrough %d", - rte_named->num_stripes.value.ui32)); - } else { - rte_named->nodeid[i][j].value.ui32 = - (uint32_t)-1; - } - - rte_named->gnid[i][j].value.ui32 = - wroute.wci->config->links[link].remote_gnid; - - } - - } else { /* nid_route_wnode */ - /* There will be one or two links from this wci */ - - /* The wroute.id is the wnodeid. */ - wnodeid = wroute.id; - DPRINTF(DBG_RT_KSTAT, - (CE_CONT, "nid_route_wnode, wnodeid=%d", wnodeid)); - - /* look at links to see which ones lead to wnode */ - j = 0; - for (link = 0; link < WRSM_LINKS_PER_WCI; link++) { - - if (wrsm_mh_link_to_wnode(wroute.wci, link, - wnodeid)) { - - rte_named->linkid[i][j].value.ui32 = - link; - rte_named->num_stripes.value.ui32++; - DPRINTF(DBG_RT_KSTAT, (CE_CONT, "kstat: " - "current stripe total for multihop %d", - rte_named->num_stripes.value.ui32)); - - /* Use the wnodeid to look up the node id. */ - rte_named->nodeid[i][j].value.ui32 = - wroute.wci->nr.wnodeinfo[wnodeid].cnodeid; - - rte_named->gnid[i][j].value.ui32 = - wroute.wci->config->links[link]. - remote_gnid; - j++; - } - } - } - } - return (0); -} - -void -wrsm_get_wci_num(wrsm_network_t *network, uint_t *num_wcis, uint_t *avail_wcis) -{ - wrsm_ncwci_t *wci; - *num_wcis = *avail_wcis = 0; - - ASSERT(network); - ASSERT(network->nr); - - mutex_enter(&network->nr->lock); - wci = network->nr->wcis; - - /* loop over the wcis and determine which one are available */ - while (wci != NULL) { - (*num_wcis)++; - if (wci->lcwci != NULL) (*avail_wcis)++; - wci = wci->next; - } - mutex_exit(&network->nr->lock); - -} - - -/* - * Pause threads and cancel timeouts in NR. - * Disable all incoming traffic. - */ -int -wrsm_nr_suspend(wrsm_network_t *network) -{ - timeout_id_t cancel_reroute = 0; - timeout_id_t cancel_pt_retry = 0; - - if (!network->nr) { - return (DDI_SUCCESS); - } - - if (network->nr->suspended) { - return (DDI_FAILURE); - } - - /* - * Pause event thread first. This guarantees that it - * doesn't re-enable the wcis. - */ - nr_pause_event_thread(network); - - mutex_enter(&network->nr->lock); - - if (network->nr->suspended) { - mutex_exit(&network->nr->lock); - nr_unpause_event_thread(network); - return (DDI_FAILURE); - - } - - stop_ncslice_traffic(network, B_TRUE); - network->nr->suspended = B_TRUE; - - /* - * cancel any pending timeout to reconfig wcis - */ - if (network->nr->wcireroute_timeout_id) { - cancel_reroute = network->nr->wcireroute_timeout_id; - network->nr->wcireroute_timeout_id = 0; - network->nr->need_wcireroute_timeout = B_TRUE; - } - - /* - * Cancel any pending timeout to resend passthrough messages - */ - if (network->nr->pt_retry_timeout_id) { - /* - * cancels timeout or waits until it is finished - */ - cancel_pt_retry = network->nr->pt_retry_timeout_id; - network->nr->pt_retry_timeout_id = 0; - network->nr->need_pt_retry_timeout = B_TRUE; - } - - mutex_exit(&network->nr->lock); - - if (cancel_reroute) { - (void) untimeout(cancel_reroute); - } - - if (cancel_pt_retry) { - (void) untimeout(cancel_pt_retry); - } - - return (DDI_SUCCESS); -} - -/* - * Restart threads and timeouts in NR. - * Re-enable incoming traffic. - */ -int -wrsm_nr_resume(wrsm_network_t *network) -{ - if (!network->nr) { - return (DDI_SUCCESS); - } - - mutex_enter(&network->nr->lock); - - if (!network->nr->suspended) { - mutex_exit(&network->nr->lock); - return (DDI_FAILURE); - } - - restart_ncslice_traffic(network, B_TRUE); - network->nr->suspended = B_FALSE; - - if (network->nr->need_wcireroute_timeout) { - /* - * restart cancelled timeout to force an MH reroute on wcis - */ - network->nr->wcireroute_timeout_id = timeout(nr_reroute_wcis, - (void *)network, (clock_t)WRSM_ENABLE_TIMEOUT); - network->nr->need_wcireroute_timeout = B_FALSE; - } - - if (network->nr->need_pt_retry_timeout) { - /* - * restart cancelled timeout to retry passthrough message - */ - network->nr->pt_retry_timeout_id = timeout(pt_resend_timeout, - (void *)network, (clock_t)WRSM_PTRETRY_TIMEOUT); - network->nr->need_pt_retry_timeout = B_FALSE; - } - - mutex_exit(&network->nr->lock); - - /* - * unpause event thread, and verify that it is running again - */ - nr_unpause_event_thread(network); - nr_wait_for_event_drain(network); - - return (DDI_SUCCESS); -} - - -int -wrsm_nr_session_up(ncwci_handle_t ncwci, wnodeid_t wnid) -{ - wrsm_sessionid_t session_id; - wrsm_ncwci_t *wci = (wrsm_ncwci_t *)ncwci; - - session_id = wrsm_sess_get(wci->network, - wci->nr.wnodeinfo[wnid].cnodeid); - return (session_id != SESS_ID_INVALID); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_offsets.in b/usr/src/uts/sun4u/io/wrsm/wrsm_offsets.in deleted file mode 100644 index 503bd7ff94..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_offsets.in +++ /dev/null @@ -1,58 +0,0 @@ -\ -\ Copyright 2005 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, 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 -\ -\ ident "%Z%%M% %I% %E% SMI" -\ -\ Based on sun4u/ml/offsets.in. -\ -\ Definitions needed by IDN send-mondo support. -\ -\ Offset definitions for wrsm_trap_handler() (assembly code) -\ - -#include <sys/types.h> -#include <sys/sunddi.h> -#include <sys/wrsm_intr.h> -#include <sys/wrsm_intr_impl.h> -#include <sys/wrsm_memseg_impl.h> - -wrsm_intr_recvq WRSM_RECVQ_SIZE - packet_ring - packet_ring_info - high_water_mark - low_water_mark - sram_paddr - cmmu_index - drainer - drainer_next - exportseg - high_water_count - -wrsm_intr_drainer_t WRSM_DRAINER_SIZE - drainer_inum - drainer_psl - -__rsm_memseg_export_handle WRSM_EXPORTSEG_SIZE - pfn_list - diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_rsmpi.c b/usr/src/uts/sun4u/io/wrsm/wrsm_rsmpi.c deleted file mode 100644 index 0fc52c27db..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_rsmpi.c +++ /dev/null @@ -1,232 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file provides RSMPI initialization/release functions - * that are called by the RSMPI rsmops module. - */ - -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/mutex.h> -#include <sys/param.h> -#include <sys/modctl.h> -#include <sys/open.h> -#include <sys/stat.h> - -#include <sys/cmn_err.h> - -/* Driver specific headers */ -#include <sys/wrsm_rsmpi.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_barrier.h> -#include <sys/wrsm_intr.h> -#include <sys/wrsm_transport.h> - - -#ifdef DEBUG -#define WRSM_RSM_DEBUG 0x0001 -static uint32_t wrsm_rsm_debug = 0; -#define DPRINTF(a, b) { if (wrsm_rsm_debug & a) wrsmdprintf b; } -#else -#define DPRINTF(a, b) { } -#endif - -/* For pagesizes, nth bit being set means pagesizes of 2^n are supported */ -#define WRSM_ATTR_PAGESIZE_8K 0x8 -#define WRSM_ATTR_PAGESIZE_4M 0x1000 -#define WRSM_ATTR_PAGESIZES (WRSM_ATTR_PAGESIZE_8K) - -static int wrsmrsm_getv(rsm_controller_handle_t cp, - rsmpi_scat_gath_t *sg_io); -static int wrsmrsm_putv(rsm_controller_handle_t cp, - rsmpi_scat_gath_t *sg_io); - -static rsm_ops_t wrsm_rsm_ops = { - RSM_VERSION, /* version 2.0 */ - wrsmrsm_seg_create, /* seg create - export side */ - wrsmrsm_seg_destroy, /* seg destroy - export side */ - wrsmrsm_bind, /* rsm bind - export side */ - wrsmrsm_unbind, /* rsm unbind - export side */ - wrsmrsm_rebind, /* rsm rebind - export side */ - wrsmrsm_publish, /* rsm publish - export side */ - wrsmrsm_unpublish, /* rsm unpublish - export side */ - wrsmrsm_republish, /* rsm republish - export side */ - wrsmrsm_connect, /* rsm connect - import side */ - wrsmrsm_disconnect, /* rsm disconnect - import side */ - wrsmrsm_get8, /* get8 - import side read */ - wrsmrsm_get16, /* get16 - import side read */ - wrsmrsm_get32, /* get32 - import side read */ - wrsmrsm_get64, /* get64 - import side read */ - wrsmrsm_get, /* get - import side read */ - wrsmrsm_put8, /* put8 - import write */ - wrsmrsm_put16, /* put16 - import write */ - wrsmrsm_put32, /* put32 - import write */ - wrsmrsm_put64, /* put64 - import write */ - wrsmrsm_put, /* put - import write */ - wrsmrsm_map, /* map - import side */ - wrsmrsm_unmap, /* unmap - import side */ - wrsm_open_barrier_region, /* open barrier region - import */ - wrsm_open_barrier_regions, /* open barrier regionS - import */ - wrsm_open_barrier_node, /* open barrier node - import */ - wrsm_open_barrier_ctrl, /* open barrier ctrl - import */ - wrsm_open_barrier_region_thr, /* open barrier region thread - import */ - wrsm_open_barrier_regions_thr, /* open barrier regionS thread import */ - wrsm_open_barrier_node_thr, /* open barrier node thread - import */ - wrsm_open_barrier_ctrl_thr, /* open barrier ctrl thread - import */ - wrsm_close_barrier, /* close barrier - import */ - wrsm_reopen_barrier, /* reopen barrier - import */ - wrsm_order_barrier, /* order barrier - import */ - wrsm_thread_init, /* thread init - import */ - wrsm_thread_fini, /* thread fini - import */ - wrsm_get_barrier_mode, /* get barrier mode - import */ - wrsm_set_barrier_mode, /* set barrier mode - import */ - wrsm_sendq_create, /* sendq create - sending side intr */ - wrsm_sendq_config, /* sendq config - sending side intr */ - wrsm_sendq_destroy, /* sendq destroy - sending side intr */ - wrsm_send, /* send - sending side intr */ - wrsmrsm_register_handler, /* register handler - rcv side intr */ - wrsmrsm_unregister_handler, /* unregister handler - rcv side intr */ - wrsmrsm_getv, /* getv */ - wrsmrsm_putv, /* putv */ - wrsm_get_peers, /* get node hardware addresses */ - NULL /* rsm extension */ -}; - -static rsm_controller_attr_t attr = { - "Wildcat", /* attr_name */ - 0, /* set at run time for each controller */ - 0x40, /* attr_direct_access_sizes */ - 0x4F, /* attr_atomic_sizes */ - 0x2F, /* attr_error_sizes */ - RSM_ERR_ZEROES, /* attr_error_behavior */ - B_TRUE, /* attr_mmu_protections */ - WRSM_ATTR_PAGESIZES, /* attr_page_sizes */ - 0, /* set at run time for each controller */ - 0, /* set at run time for each controller */ - 0x200000, /* attr_max_export_segments - 2 Meg */ - 0x2000000000, /* attr_max_import_map_size -128 GB */ - 0x36800000000, /* attr_tot_import_map_size - 3.7 TB */ - 0x1B400000, /* attr_max_import_segments - 457 M */ - B_FALSE, /* attr_io_space_exportable */ - B_FALSE, /* attr_imported_space_ioable */ - B_TRUE, /* attr_intr_sender_ident */ - WRSM_TL_MSG_SIZE - sizeof (uint64_t), /* attr_intr_data_size_max */ - 8, /* attr_intr_data_align */ - B_FALSE, /* attr_intr_piggyback */ - B_FALSE /* attr_resource_callbacks */ -}; - - -/* - * returns the rsm_controller_handle_t and the wrsm_rsm_ops in controller - */ -/* ARGSUSED */ -int -wrsmrsm_get_controller_handler(const char *name, uint_t number, - rsm_controller_object_t *controller, uint_t version) -{ - DPRINTF(WRSM_RSM_DEBUG, (CE_CONT, "in wrsm_get_controller_handler" - " controller number %d, driver name %s", number, name)); - - if (version != wrsm_rsm_ops.rsm_version) { - DPRINTF(WRSM_RSM_DEBUG, (CE_CONT, "wrsm_get_controller_handler:" - " bad version %d != %d", version, - wrsm_rsm_ops.rsm_version)); - return (RSMERR_UNSUPPORTED_VERSION); - } - if (controller == NULL) { - DPRINTF(WRSM_RSM_DEBUG, (CE_CONT, "wrsm_get_controller_handler:" - " controller is null")); - return (RSMERR_BAD_CTLR_HNDL); - } - controller->handle = - (rsm_controller_handle_t)wrsm_nc_ctlr_to_network((uint32_t)number); - if (controller->handle != NULL) { - DPRINTF(WRSM_RSM_DEBUG, (CE_CONT, "wrsm_get_controller_handler:" - " found controller, setting ops")); - controller->ops = &wrsm_rsm_ops; - return (RSM_SUCCESS); - } else { - DPRINTF(WRSM_RSM_DEBUG, (CE_CONT, "wrsm_get_controller_handler:" - " no controler number %d, driver name %s", number, name)); - return (RSMERR_CTLR_NOT_PRESENT); - } -} -/* - * This functions doesn't currently do anything really important - yet - * a controller must exist before this call. - */ -/* ARGSUSED */ -int -wrsmrsm_release_controller_handler(const char *name, uint_t number, - rsm_controller_object_t *controller) -{ - - DPRINTF(WRSM_RSM_DEBUG, (CE_CONT, - "in wrsm_release_controller_handler")); - /* we should not be trying to release a nonexistant controller */ - if (controller->handle == NULL) { - return (RSMERR_BAD_CTLR_HNDL); - } - - ASSERT(strcmp(name, "wrsm") == 0); - controller->ops = NULL; - controller->handle = NULL; - return (RSM_SUCCESS); -} - -/* - * record the addr (cnodeid for this controller) in the - */ -void -wrsm_rsm_setup_controller_attr(wrsm_network_t *network) -{ - /* set fixed attribute values */ - network->attr = attr; - /* set config specific values */ - DPRINTF(WRSM_RSM_DEBUG, (CE_CONT, - "in wrsm_rsm_setup_controller_addr - cnodeid is %ld", - (rsm_addr_t)network->cnodeid)); - network->attr.attr_controller_addr = (rsm_addr_t)network->cnodeid; -} - -/* ARGSUSED */ -static int -wrsmrsm_getv(rsm_controller_handle_t cp, rsmpi_scat_gath_t *sg_io) -{ - return (RSMERR_UNSUPPORTED_OPERATION); -} - -/* ARGSUSED */ -static int -wrsmrsm_putv(rsm_controller_handle_t cp, rsmpi_scat_gath_t *sg_io) -{ - return (RSMERR_UNSUPPORTED_OPERATION); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_session.c b/usr/src/uts/sun4u/io/wrsm/wrsm_session.c deleted file mode 100644 index 3ebe180ace..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_session.c +++ /dev/null @@ -1,946 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Session management module of the Wildcat RSM driver. This module sets - * up sessions with remote drivers. If communication is lost, it notifies - * interested registered modules so they can invalidate any existing - * communication paths. - */ - -#include <sys/types.h> - -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/errno.h> -#include <sys/debug.h> -#include <sys/membar.h> - -#include <sys/wrsm_session.h> -#include <sys/wrsm_config.h> -#include <sys/wrsm_transport.h> -#include <sys/wrsm_cmmu.h> -#include <sys/wrsm_nc.h> -#include <sys/wrsm_sess_impl.h> -#include <sys/wrsm_intr.h> -#include <sys/wrsm_memseg.h> - -/* - * The following macros define a DPRINTF macro which can be used to enable - * or disable various levels of logging for this module. - */ -#ifdef DEBUG - -#define SESSDBG 0x1 -#define SESSWARN 0x2 -#define SESSERR 0x4 -#define SESSTRACE 0x8 -static uint_t wrsm_sess_debug = SESSERR; - -#define DPRINTF(a, b) { if (wrsm_sess_debug & a) wrsmdprintf b; } - -static const char *sess_state_txt[] = { - "SESS_STATE_UNREACH", - "SESS_STATE_DOWN", - "SESS_STATE_ESTAB", - "SESS_STATE_UP"}; - -#else /* DEBUG */ - -#define DPRINTF(a, b) - -#endif /* DEBUG */ - -#define DTRC(s) DPRINTF(SESSTRACE, (CE_CONT, s)) -#define ERR(s) DPRINTF(SESSERR, (CE_WARN, s)) -#define WARN(s) DPRINTF(SESSWARN, (CE_WARN, s)) -#define NOTE(s) DPRINTF(SESSDBG, (CE_NOTE, s)) - - -/* - * Local function prototypes - */ -static void node_init(wrsm_session_t *, cnodeid_t); -static void node_fini(wrsm_node_session_t *); -static void node_new_state(wrsm_network_t *, cnodeid_t, - sess_state, wrsm_sessionid_t); -static void msg_init(wrsm_network_t *); -static void msg_fini(wrsm_network_t *); -static boolean_t msg_session_start(wrsm_network_t *, wrsm_message_t *); -static boolean_t msg_session_start_rsp(wrsm_network_t *, wrsm_message_t *); -static boolean_t msg_session_end(wrsm_network_t *, wrsm_message_t *); - -/* - * Local functions - */ - - -/* Distributes callbacks to all clients */ -static int -callback_clients(wrsm_network_t *net, cnodeid_t cnode, wrsm_sess_state state) -{ - uint_t i; - wrsm_session_t *sess = net->session; - int dereferences_needed = 0; - - DPRINTF(SESSTRACE, (CE_CONT, "callback clients ctlr %d\n", - net->rsm_ctlr_id)); - - for (i = 0; i < MAX_CLIENTS; i++) { - wrsm_sess_func_t fn = sess->cb[i]; - if (fn) { - if (!(*fn)(net, cnode, state)) { - dereferences_needed++; - } - } - } - - return (dereferences_needed); -} - - -/* - * Node related functions - */ - -/* Initializes node structure */ -static void -node_init(wrsm_session_t *sess, cnodeid_t cnodeid) -{ - wrsm_node_session_t *node = &sess->node[cnodeid]; - node->cnodeid = cnodeid; - mutex_init(&node->mutex, NULL, MUTEX_DRIVER, NULL); - cv_init(&node->cv_session_up, NULL, CV_DRIVER, NULL); - cv_init(&node->cv_state_changing, NULL, CV_DRIVER, NULL); - cv_init(&node->cv_await_dereferences, NULL, CV_DRIVER, NULL); - node->enabled = B_TRUE; - node->state = SESS_STATE_UNREACH; - node->session_id = SESS_ID_INVALID; - node->last_session_id = 0; - node->barrier_mem = NULL; -} - -/* Cleans up node structure */ -static void -node_fini(wrsm_node_session_t *node) -{ - mutex_destroy(&node->mutex); - cv_destroy(&node->cv_session_up); - cv_destroy(&node->cv_state_changing); - cv_destroy(&node->cv_await_dereferences); -} - -/* - * Changes state of node, performing callback if required. - * NOTE: Releases the node->mutex lock during callbacks. - */ -static void -node_new_state(wrsm_network_t *net, cnodeid_t cnodeid, - sess_state new_state, wrsm_sessionid_t new_session_id) -{ - wrsm_session_t *sess = net->session; - wrsm_node_session_t *node = &sess->node[cnodeid]; - sess_state old_state; - int err; - - DPRINTF(SESSTRACE, (CE_CONT, - "node_new_state(ctrl=%u, cnode=%u, state=%s, sess_id=%u)", - net->rsm_ctlr_id, cnodeid, sess_state_txt[new_state], - new_session_id)); - ASSERT(mutex_owned(&node->mutex)); - while (node->state_changing) { - cv_wait(&node->cv_state_changing, &node->mutex); - } - old_state = node->state; - node->state = new_state; - node->session_id = new_session_id; - node->state_changing = B_TRUE; - if (node->state == SESS_STATE_UP) { - cv_broadcast(&node->cv_session_up); - } - mutex_exit(&node->mutex); - - if (old_state == SESS_STATE_UP && new_state != SESS_STATE_UP) { - node->dereferences_needed = callback_clients(net, cnodeid, - SESSION_DOWN); - DPRINTF(SESSDBG, (CE_CONT, "callback clients ctlr %d " - "node %d dereferences_needed %d\n", - net->rsm_ctlr_id, cnodeid, node->dereferences_needed)); - wrsm_clustermember_delete(net, cnodeid); - /* Unmap remote barrier page */ - ddi_unmap_regs(wrsm_ncslice_dip, - node->remote_tuple.ncslice, - &node->barrier_page, - (off_t)node->remote_tuple.offset, - MMU_PAGESIZE); - node->barrier_page = NULL; - } else if (old_state != SESS_STATE_UP && new_state == SESS_STATE_UP) { - /* Map remote barrier page */ - if (node->remote_tuple.ncslice != - net->nodes[cnodeid]->config->exported_ncslices.id[0]) { - /* - * Node is claiming it exports an ncslice it doesn't! - * Something must be wrong with connection. - */ - DPRINTF(SESSWARN, (CE_WARN, "sess node_new_state: " - "bad ncslice %d from node %d\n", - node->remote_tuple.ncslice, cnodeid)); - node->state = old_state; - } else { - err = ddi_map_regs(wrsm_ncslice_dip, - node->remote_tuple.ncslice, - &node->barrier_page, - (off_t)node->remote_tuple.offset, - MMU_PAGESIZE); - if (err) { - node->state = old_state; - } else { - wrsm_clustermember_add(net, cnodeid); - (void) callback_clients(net, cnodeid, - SESSION_UP); - } - } - } - - /* Re-enter the node->mutex lock */ - mutex_enter(&node->mutex); - node->state_changing = B_FALSE; - cv_signal(&node->cv_state_changing); -} - -/* - * Message related functions - */ - -/* Regiseters message handling functions */ -static void -msg_init(wrsm_network_t *net) -{ - (void) wrsm_tl_add_handler(net, WRSM_MSG_SESSION_START, - WRSM_TL_NO_HANDLER, msg_session_start); - (void) wrsm_tl_add_handler(net, WRSM_MSG_SESSION_START_RESPONSE, - WRSM_TL_NO_HANDLER, msg_session_start_rsp); - (void) wrsm_tl_add_handler(net, WRSM_MSG_SESSION_END, - WRSM_TL_NO_HANDLER, msg_session_end); -} - -/* Removes message handling functions */ -static void -msg_fini(wrsm_network_t *net) -{ - (void) wrsm_tl_add_handler(net, WRSM_MSG_SESSION_START, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - (void) wrsm_tl_add_handler(net, WRSM_MSG_SESSION_END, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); - (void) wrsm_tl_add_handler(net, WRSM_MSG_SESSION_START_RESPONSE, - WRSM_TL_NO_HANDLER, WRSM_TL_NO_HANDLER); -} - -/* Handles session start message */ -static boolean_t -msg_session_start(wrsm_network_t *net, wrsm_message_t *message) -{ - msg_session_start_t *msg = (msg_session_start_t *)message; - wrsm_node_session_t *node; - wrsm_raw_message_t raw_response; - msg_session_start_rsp_t *response = (msg_session_start_rsp_t *) - &raw_response; - DTRC("msg_session_start"); - - ASSERT(net); - ASSERT(msg); - ASSERT(response); - - node = &net->session->node[msg->header.source_cnode]; - response->header.message_type = WRSM_MSG_SESSION_START_RESPONSE; - response->session_id = msg->session_id; - response->barrier_ncslice = node->barrier_tuple->ncslice; - response->barrier_offset = (off_t)node->barrier_tuple->offset; - response->result = SESS_SUCCESS; /* Assume success */ - mutex_enter(&node->mutex); - - switch (node->state) { - case SESS_STATE_UNREACH: - response->result = (node->enabled) ? ENXIO : EPERM; - break; - - case SESS_STATE_DOWN: - if (node->enabled) { - node->remote_tuple.ncslice = msg->barrier_ncslice; - node->remote_tuple.offset = msg->barrier_offset; - node_new_state(net, node->cnodeid, - SESS_STATE_UP, msg->session_id); - } else { - response->result = EPERM; - } - break; - - case SESS_STATE_ESTAB: - if (msg->header.source_cnode > net->cnodeid) { - /* If we have lower cnodeid, ignore them */ - response->result = EBUSY; - } else { - /* If they have lower cnodeid, then they win */ - node->remote_tuple.ncslice = msg->barrier_ncslice; - node->remote_tuple.offset = msg->barrier_offset; - node_new_state(net, node->cnodeid, - SESS_STATE_UP, msg->session_id); - } - break; - - case SESS_STATE_UP: - /* New session request. Go down then back up */ - node_new_state(net, node->cnodeid, - SESS_STATE_DOWN, SESS_ID_INVALID); - node->remote_tuple.ncslice = msg->barrier_ncslice; - node->remote_tuple.offset = msg->barrier_offset; - node_new_state(net, node->cnodeid, - SESS_STATE_UP, msg->session_id); - break; - } - - /* Only send response if this is not loopback */ - if (net->cnodeid != msg->header.source_cnode) { - (void) wrsm_tl_dg(net, msg->header.source_cnode, - (wrsm_message_t *)response); - } - mutex_exit(&node->mutex); - return (B_TRUE); -} - -static boolean_t -msg_session_start_rsp(wrsm_network_t *net, wrsm_message_t *message) -{ - msg_session_start_rsp_t *msg = (msg_session_start_rsp_t *)message; - wrsm_node_session_t *node; - cnodeid_t source; - DTRC("msg_session_start_rsp"); - - ASSERT(net); - ASSERT(msg); - - source = msg->header.source_cnode; - node = &net->session->node[source]; - mutex_enter(&node->mutex); - - if (node->state == SESS_STATE_ESTAB && - node->session_id == msg->session_id) { - if (msg->result) { - DPRINTF(SESSERR, (CE_WARN, - "sess_start_rsp from cnode %u to ctlr %u:" - "bad result = %d", - source, net->rsm_ctlr_id, msg->result)); - node_new_state(net, source, SESS_STATE_DOWN, - SESS_ID_INVALID); - } else { - node->remote_tuple.ncslice = msg->barrier_ncslice; - node->remote_tuple.offset = - (caddr_t)msg->barrier_offset; - node_new_state(net, source, SESS_STATE_UP, - node->session_id); - } - /* LINTED: E_NOP_ELSE_STMT */ - } else { - DPRINTF(SESSERR, (CE_WARN, - "unexpected sess_start_rsp from cnode %u to ctlr %u: " - "result %d, wrong state %s", - source, net->rsm_ctlr_id, msg->result, - sess_state_txt[node->state])); - } - mutex_exit(&node->mutex); - return (B_TRUE); -} - -static boolean_t -msg_session_end(wrsm_network_t *net, wrsm_message_t *message) -{ - msg_session_end_t *msg = (msg_session_end_t *)message; - wrsm_node_session_t *node; - DTRC("msg_session_end"); - - ASSERT(net); - ASSERT(msg); - - node = &net->session->node[msg->header.source_cnode]; - mutex_enter(&node->mutex); - - switch (node->state) { - case SESS_STATE_ESTAB: - case SESS_STATE_UP: - node_new_state(net, node->cnodeid, SESS_STATE_DOWN, - SESS_ID_INVALID); - break; - } - - mutex_exit(&node->mutex); - return (B_TRUE); -} - -/* - * Interface Functions - */ - -/* Init function. */ -void -wrsm_sess_init(wrsm_network_t *net) -{ - uint_t i; - wrsm_session_t *sess; - DTRC("wrsm_sess_init"); - - /* Add session structure to the net structure. */ - ASSERT(net); - sess = kmem_zalloc(sizeof (wrsm_session_t), KM_SLEEP); - ASSERT(sess); - - /* Initialize client callback structure to all NULL */ - for (i = 0; i < MAX_CLIENTS; i++) { - sess->cb[i] = NULL; - } - - /* Initialize cnode-specific structures */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node_init(sess, i); - } - - /* Tell transport about our message handlers */ - msg_init(net); - - /* Publish! */ - net->session = sess; -} - -/* Fini function. */ -void -wrsm_sess_fini(wrsm_network_t *net) -{ - uint_t i; - wrsm_node_session_t *node; - - DTRC("wrsm_sess_fini"); - - /* Remove our transport message handlers */ - msg_fini(net); - - /* Clean-up per node session structures */ - for (i = 0; i < WRSM_MAX_CNODES; i++) { - node = &net->session->node[i]; - ASSERT((node->state == SESS_STATE_DOWN) || - (node->state == SESS_STATE_UNREACH)); - ASSERT(node->dereferences_needed == 0); - node_fini(node); - } - - kmem_free(net->session, sizeof (wrsm_session_t)); - net->session = NULL; - -} - -/* Informs session that a new cnode is reachable */ -void -wrsm_sess_reachable(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_node_session_t *node; - unsigned num_tuples; - caddr_t aligned_vaddr; - wrsm_cmmu_t cmmu; - int err; - - ASSERT(net); - ASSERT(net->session); - node = &net->session->node[cnodeid]; - ASSERT(node->state == SESS_STATE_UNREACH); - - DPRINTF(SESSTRACE, (CE_CONT, "wrsm_sess_reachable: cnodeid = %u", - cnodeid)); - mutex_enter(&node->mutex); - - /* First, allocate a cmmu entry */ - err = wrsm_cmmu_alloc(net, CMMU_PAGE_SIZE_SMALL, 1, - &node->barrier_tuple, &num_tuples, 0); - if (err != WRSM_SUCCESS) { - mutex_exit(&node->mutex); - return; - } - /* - * Fix up the ncslice in the tuple to use the ncslice the - * remote node imports. - */ - ASSERT(net->exported_ncslices.id[0] == node->barrier_tuple->ncslice); - node->barrier_tuple->ncslice = - net->nodes[cnodeid]->config->imported_ncslices.id[0]; - - /* Allocate enough memory to create an aligned page */ - node->barrier_mem = wrsm_alloc((MMU_PAGESIZE * 2), VM_SLEEP); - bzero(node->barrier_mem, (MMU_PAGESIZE * 2)); - - /* Find page-aligned address */ - aligned_vaddr = (caddr_t) - ((uint64_t)((caddr_t)node->barrier_mem + MMU_PAGEOFFSET) & - (uint64_t)MMU_PAGEMASK); - - /* Write CMMU entry */ - cmmu.entry_0.val = 0; - cmmu.entry_0.bit.count_enable = B_FALSE; - cmmu.entry_0.bit.large_page = B_FALSE; - cmmu.entry_0.bit.user_err = B_FALSE; - cmmu.entry_0.bit.writable = B_TRUE; - cmmu.entry_0.bit.from_all = B_FALSE; - cmmu.entry_0.bit.valid = B_TRUE; - cmmu.entry_0.bit.type = CMMU_TYPE_CACHEABLE; - cmmu.entry_0.bit.from_node = cnodeid; - - cmmu.entry_1.val = 0; - cmmu.entry_1.addr.lpa_page = hat_getpfnum(kas.a_hat, aligned_vaddr); - - /* Update the CMMU */ - wrsm_cmmu_update(net, &cmmu, node->barrier_tuple->index, - CMMU_UPDATE_ALL); - - node_new_state(net, cnodeid, SESS_STATE_DOWN, SESS_ID_INVALID); - mutex_exit(&node->mutex); - - /* Start the process of establishing a new session */ - wrsm_sess_establish(net, cnodeid); -} - -/* Informs session that a cnode is no longer reachable */ -void -wrsm_sess_unreachable(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_cmmu_t cmmu; - wrsm_node_session_t *node; - - ASSERT(net); - ASSERT(net->session); - node = &net->session->node[cnodeid]; - ASSERT(node->state != SESS_STATE_UNREACH); - - DPRINTF(SESSTRACE, (CE_CONT, "wrsm_sess_unreachable: cnodeid = %u", - cnodeid)); - - mutex_enter(&node->mutex); - node_new_state(net, cnodeid, SESS_STATE_UNREACH, SESS_ID_INVALID); - - /* Set CMMU to invalid */ - cmmu.entry_0.val = 0; - cmmu.entry_1.val = 0; - wrsm_cmmu_update(net, &cmmu, node->barrier_tuple->index, - CMMU_UPDATE_ALL); - wrsm_cmmu_free(net, 1, node->barrier_tuple); - - /* Free barrier page memory */ - wrsm_free(node->barrier_mem, MMU_PAGESIZE * 2); - node->barrier_mem = NULL; - - mutex_exit(&node->mutex); -} - -/* - * Functions for client use. - */ - -/* Establishes a session with a remote cnode, if enabled. */ -wrsm_sessionid_t -wrsm_sess_establish(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_sessionid_t session_id = SESS_ID_INVALID; - - wrsm_node_session_t *node; - - DPRINTF(SESSTRACE, (CE_CONT, "wrsm_sess_establish: cnodeid = %u", - cnodeid)); - - ASSERT(net); - node = &net->session->node[cnodeid]; - if (!node->enabled) { - return (SESS_ID_INVALID); - } - - mutex_enter(&node->mutex); - - /* If the session is currently down or being established... */ - if (node->state == SESS_STATE_DOWN || - node->state == SESS_STATE_ESTAB) { - clock_t timeout; - - /* Queue an event to the event thread, if necessary */ - if (!node->event_queued) { - wrsm_nr_event_t *event; - - node->event_queued = B_TRUE; - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->type = wrsm_evt_sessup; - event->data.sess.cnodeid = cnodeid; - wrsm_nr_add_event(net, event, B_TRUE); - } - /* Wait for session to be established, or timeout */ - timeout = ddi_get_lbolt() + drv_usectohz(SESS_TIMEOUT); - (void) cv_timedwait(&node->cv_session_up, &node->mutex, - timeout); - } - - /* If the session came up, return the session id */ - if (node->state == SESS_STATE_UP) { - session_id = node->session_id; - } - mutex_exit(&node->mutex); - return (session_id); -} - -/* Establishes a session with a remote cnode, if enabled. */ -void -wrsm_sess_establish_immediate(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_node_session_t *node; - wrsm_raw_message_t raw_msg; - msg_session_start_t *msg = (msg_session_start_t *)&raw_msg; - clock_t timeout; - wrsm_sessionid_t session_id; - - DPRINTF(SESSTRACE, (CE_CONT, "wrsm_sess_establish_immediate: " - "cnodeid = %u", cnodeid)); - - ASSERT(net); - ASSERT(msg); - - node = &net->session->node[cnodeid]; - mutex_enter(&node->mutex); - - /* Deal with disabled nodes */ - if (!node->enabled) { - node->event_queued = B_FALSE; - mutex_exit(&node->mutex); - return; - } - - if (node->state == SESS_STATE_DOWN) { - /* Get a new session id and set state to establishing */ - node->last_session_id++; - if (node->last_session_id == SESS_ID_INVALID) { - node->last_session_id++; - } - session_id = node->last_session_id; - node_new_state(net, cnodeid, SESS_STATE_ESTAB, - session_id); - - /* Create and send session start message */ - msg->session_id = node->session_id; - msg->barrier_ncslice = node->barrier_tuple->ncslice; - msg->barrier_offset = node->barrier_tuple->offset; - msg->header.message_type = WRSM_MSG_SESSION_START; - (void) wrsm_tl_dg(net, cnodeid, (wrsm_message_t *)msg); - - /* Wait for msg_session_start_rsp */ - timeout = ddi_get_lbolt() + drv_usectohz(SESS_TIMEOUT); - (void) cv_timedwait_sig(&node->cv_session_up, &node->mutex, - timeout); - /* Don't care why cv was signaled, just check state... */ - if (node->state != SESS_STATE_UP) { - node_new_state(net, cnodeid, - SESS_STATE_DOWN, SESS_ID_INVALID); - } - } - node->event_queued = B_FALSE; - mutex_exit(&node->mutex); -} - -void -wrsm_sess_teardown_immediate(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_node_session_t *node; - wrsm_raw_message_t raw_msg; - msg_session_end_t *msg = (msg_session_end_t *)&raw_msg; - - ASSERT(net); - ASSERT(net->session); - - DPRINTF(SESSTRACE, (CE_CONT, "wrsm_sess_teardown_immediate: " - "ctlr %d cnodeid = %u", net->rsm_ctlr_id, cnodeid)); - - node = &net->session->node[cnodeid]; - - mutex_enter(&node->mutex); - switch (node->state) { - case SESS_STATE_UNREACH: - case SESS_STATE_DOWN: - break; - - case SESS_STATE_ESTAB: - case SESS_STATE_UP: - msg->header.message_type = WRSM_MSG_SESSION_END; - msg->session_id = node->session_id; - (void) wrsm_tl_dg(net, cnodeid, (wrsm_message_t *)msg); - node_new_state(net, cnodeid, SESS_STATE_DOWN, SESS_ID_INVALID); - } - mutex_exit(&node->mutex); -} - - -/* Asynchronously tears down a session to a cnode. */ -void -wrsm_sess_teardown(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_nr_event_t *event; - - DTRC("wrsm_sess_teardown"); - - event = kmem_alloc(sizeof (wrsm_nr_event_t), KM_SLEEP); - event->type = wrsm_evt_sessdown; - event->data.sess.cnodeid = cnodeid; - wrsm_nr_add_event(net, event, B_TRUE); -} - - -/* Returns the current session. */ -wrsm_sessionid_t -wrsm_sess_get(wrsm_network_t *net, cnodeid_t cnodeid) -{ - DPRINTF(SESSTRACE, (CE_CONT, "wrsm_sess_get: cnodeid = %u", cnodeid)); - - ASSERT(net); - ASSERT(net->session); - - /* - * We don't need node->mutex here, because reading one int - * is atomic. Also, since the session_is is set to INVALID - * any time the session is not in the UP state, we don't need - * to check which state we're in now. - */ - return (net->session->node[cnodeid].session_id); -} - -/* Allows user to register for callbacks. */ -void -wrsm_sess_register(wrsm_network_t *net, wrsm_sess_func_t fn) -{ - uint_t i; - DTRC("wrsm_sess_register"); - - ASSERT(net); - ASSERT(net->session); - for (i = 0; i < MAX_CLIENTS; i++) { - if (net->session->cb[i] == NULL) { - net->session->cb[i] = fn; - break; - } - } - ASSERT(i < MAX_CLIENTS); -} - -/* Removes a user callback registration. */ -void -wrsm_sess_unregister(wrsm_network_t *net, wrsm_sess_func_t fn) -{ - uint_t i; - DTRC("wrsm_sess_unregister"); - - ASSERT(net); - ASSERT(net->session); - for (i = 0; i < MAX_CLIENTS; i++) { - if (net->session->cb[i] == fn) { - net->session->cb[i] = NULL; - return; - } - } - ASSERT(0); -} - -/* - * Functions for use by some session control software entitiy. - */ - -/* Enables communication with a cnode. */ -void -wrsm_sess_enable(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_node_session_t *node = &(net->session->node[cnodeid]); - clock_t timeout; - - DPRINTF(SESSTRACE, (CE_CONT, "wrsm_sess_enable: cnodeid = %u", - cnodeid)); - - ASSERT(net); - - mutex_enter(&node->mutex); - if ((node->enabled == B_FALSE) && node->dereferences_needed) { - /* - * A sess disable is in progress. Wait for it to complete - * or fail before enabling. - */ - timeout = ddi_get_lbolt() + drv_usectohz(SESS_TIMEOUT); - (void) cv_timedwait(&node->cv_await_dereferences, &node->mutex, - timeout); - } - node->enabled = B_TRUE; - mutex_exit(&node->mutex); - wrsm_sess_establish(net, cnodeid); -} - - -/* Disables communication with a cnode. May cause a teardown. */ -int -wrsm_sess_disable(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_raw_message_t raw_msg; - msg_session_start_t *msg = (msg_session_start_t *)&raw_msg; - wrsm_node_session_t *node = &(net->session->node[cnodeid]); - clock_t timeout; - - DPRINTF(SESSTRACE, (CE_CONT, "wrsm_sess_disable: cnodeid = %u", - cnodeid)); - - ASSERT(net); - - mutex_enter(&node->mutex); - node->enabled = B_FALSE; - if (node->state == SESS_STATE_ESTAB || node->state == SESS_STATE_UP) { - msg->header.message_type = WRSM_MSG_SESSION_END; - msg->session_id = node->session_id; - (void) wrsm_tl_dg(net, cnodeid, (wrsm_message_t *)msg); - node_new_state(net, cnodeid, SESS_STATE_DOWN, SESS_ID_INVALID); - } - if (node->dereferences_needed) { - timeout = ddi_get_lbolt() + drv_usectohz(SESS_TIMEOUT); - if (cv_timedwait(&node->cv_await_dereferences, &node->mutex, - timeout) == -1) { - /* timed out waiting for dereferences - fail */ - mutex_exit(&node->mutex); - return (EBUSY); - } - } - mutex_exit(&node->mutex); - return (WRSM_SUCCESS); -} - - -/* Returns a cnode bitmask indicating which cnodes have valid sessions */ -void -wrsm_sess_get_cnodes(wrsm_network_t *net, cnode_bitmask_t *cnodes) -{ - uint_t i; - DTRC("wrsm_sess_get_cnodes"); - - ASSERT(net); - - WRSMSET_ZERO(*cnodes); - for (i = 0; i < WRSM_MAX_CNODES; i++) { - if (net->session->node[i].state == SESS_STATE_UP) { - WRSMSET_ADD(*cnodes, i); - } - } -} - -/* - * Clients call this when all references to node with invalid session - * are truly freed - */ -void -wrsm_sess_unreferenced(wrsm_network_t *net, cnodeid_t cnode) -{ - wrsm_session_t *sess = net->session; - wrsm_node_session_t *node = &sess->node[cnode]; - - DPRINTF(SESSTRACE, (CE_CONT, "wrsm_sess_unreferenced ctlr %d node %d\n", - net->rsm_ctlr_id, cnode)); - - mutex_enter(&node->mutex); - - if (node->dereferences_needed) { - node->dereferences_needed--; - DPRINTF(SESSDBG, (CE_CONT, - "wrsm_sess_unreferenced dereferences needed now %d\n", - node->dereferences_needed)); - if (node->dereferences_needed == 0) { - cv_broadcast(&node->cv_await_dereferences); - } - } - - mutex_exit(&node->mutex); -} - -int -wrsm_sess_touch_node(wrsm_network_t *net, cnodeid_t cnodeid, uint32_t stripes) -{ - int str; - caddr_t vaddr; - wrsm_raw_message_t raw_buf; - uint64_t *buf = (uint64_t *)&raw_buf; - wrsm_node_session_t *node = &net->session->node[cnodeid]; - const uint64_t pattern = 0x0123456789abcdef; /* Arbitrary, non-zero */ - - DPRINTF(SESSTRACE, (CE_CONT, - "wrsm_sess_touch_node(cnode=%d,stripes=0x%X)", - cnodeid, stripes)); - - membar_sync(); - mutex_enter(&node->mutex); - - if (node->state != SESS_STATE_UP) { - WARN("wrsm_sess_touch_node: session not up"); - mutex_exit(&node->mutex); - return (RSMERR_CONN_ABORTED); - } - if (node->barrier_page == NULL) { - WARN("wrsm_sess_touch_node: NULL barrier_page pointer"); - mutex_exit(&node->mutex); - return (RSMERR_CONN_ABORTED); - } - buf[0] = pattern; /* Seed first part of buffer with pattern */ - buf[4] = ~pattern; /* Seed second half of buffer */ - - /* If multiple stripes, get all the writes going in parallel... */ - vaddr = node->barrier_page; - for (str = stripes; str; str = str >> 1) { - if (str & 1) { - wrsm_blkwrite(buf, vaddr, 1); - } - vaddr += WCI_CLUSTER_STRIPE_STRIDE; - } - membar_sync(); - - /* Now read back. If we get an error, data will be 0. */ - vaddr = node->barrier_page; - for (str = stripes; str; str = str >> 1) { - if (str & 1) { - wrsm_blkread(vaddr, buf, 1); - if (buf[0] != pattern || - buf[4] != ~pattern) { - WARN("wrsm_sess_touch_node: pattern mismatch"); - mutex_exit(&node->mutex); - return (RSMERR_BARRIER_FAILURE); - } - } - vaddr += WCI_CLUSTER_STRIPE_STRIDE; - } - - mutex_exit(&node->mutex); - return (RSM_SUCCESS); -} diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_tl.c b/usr/src/uts/sun4u/io/wrsm/wrsm_tl.c deleted file mode 100644 index 974482eabc..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_tl.c +++ /dev/null @@ -1,1330 +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 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Transport Layer of the Wildcat RSM driver. This module provides an rpc - * and datagram service by sending/receiving interrupts to/from remote - * drivers. - */ - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/kmem.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <vm/hat.h> -#include <sys/promif.h> -#include <sys/disp.h> -#include <sys/callb.h> -#include <sys/taskq.h> - -#include <sys/wci_common.h> -#include <sys/wrsm_transport.h> -#include <sys/wrsm_cmmu.h> -#include <sys/wrsm_intr.h> -#include <sys/wrsm_session.h> -#include <sys/wrsm_memseg.h> -#include <sys/wrsm_memseg_impl.h> -/* - * Manifest Constants and Macros - */ - -#ifdef DEBUG - -#define TLDBG 0x1 -#define TLWARN 0x2 -#define TLERR 0x4 -#define TLTRACE 0x8 -#define TLDUMP 0x10 -static uint_t tl_debug = TLERR; - -#define DPRINTF(a, b) { if (tl_debug & a) wrsmdprintf b; } - -#else /* DEBUG */ - -#define DPRINTF(a, b) { } - -#endif /* DEBUG */ - -#define WARN(s) DPRINTF(TLWARN, (CE_WARN, s)) -#define NOTE(s) DPRINTF(TLDBG, (CE_NOTE, s)) - -#define WRSM_TL_PACKETRING_SIZE 118 /* Fill up 1 page */ -/* - * Set RPC message highwater mark to 44%, lowwater to 20% of packetring - * size. 44% allows reply messages and other messages that don't go through - * the flow control to have some space. - */ -#define WRSM_TL_RPC_HIGHWATER_PERCENT (88) -#define WRSM_TL_RPC_LOWWATER_PERCENT (20) -#define WRSM_TL_RPC_HIGHWATER (((((WRSM_TL_PACKETRING_SIZE) / 2) * \ - (WRSM_TL_RPC_HIGHWATER_PERCENT)) / 100) + 1) -#define WRSM_TL_RPC_LOWWATER (((WRSM_TL_PACKETRING_SIZE) * \ - (WRSM_TL_RPC_LOWWATER_PERCENT)) / 100) -int wrsm_tl_rpc_highwater = WRSM_TL_RPC_HIGHWATER; -int wrsm_tl_rpc_lowwater = WRSM_TL_RPC_LOWWATER; - -#define WRSM_TL_DEVLOAD_ATTRS (PROT_READ | PROT_WRITE | HAT_NEVERSWAP | \ - HAT_STRICTORDER) - -/* - * Message IDs go from 1 through 0x7fffffff. ID 0 is reserved as a null id. - * The MSB of the message ID is reserved as an RPC response flag. If this - * bit is set, the message is a response to the message whose ID is stored - * in the lower 31 bits. - */ -#define MESSAGE_ID_INVALID 0 -#define MESSAGE_ID_FIRST 1 -#define MESSAGE_ID_MAX 0x7fffffff -#define MESSAGE_ID_RPCRESP 0x80000000 - -#define MAKERESPID(msgid) ((msgid) | MESSAGE_ID_RPCRESP) -#define MAKEORIGID(respid) ((respid) & MESSAGE_ID_MAX) -#define ISRESPONSEID(msgid) (((msgid) & MESSAGE_ID_RPCRESP) != 0) -#define ISDATAGRAMID(msgid) (!ISRESPONSEID(msgid)) - -#define MASK_ALIGN (~0x3f) -#define IS_ALIGNED(ptr) (((uint64_t)(ptr) & 0x3f) == 0) - -/* - * RPC timeout: - * The nr_event_thread that awakens to process response events may actually - * be delayed by up to 1.5 seconds if the processor it is scheduled to run on - * is in the middle of running wrsm_lc_clear_cmmu() for another controller. - * This function calls wrsm_lc_cmmu_update() 2,097,152 times, resulting in the - * observed delay. Therefore, we set the RPC timeout to 5 seconds to be safe. - */ -static uint_t wrsm_tl_rpc_timeout = (5*1000*1000); /* 5 secs */ - -/* - * This tunable controls the number of worker threads available per taskq. - * There is one taskq for each of the 7 categories of messages, so multiply - * this value by 7 to get the total number of worker threads created. - */ -static uint_t wrsm_tl_tqthreads = 1; - -/* #define msgcpy(dest, src) bcopy((dest), (src), sizeof (wrsm_message_t)) */ -void -msgcpy(wrsm_message_t *dest, wrsm_message_t *src) -{ - unsigned i; - - dest->header.reserved1 = src->header.reserved1; - dest->header.version = src->header.version; - dest->header.session_id = src->header.session_id; - dest->header.source_cnode = src->header.source_cnode; - dest->header.message_type = src->header.message_type; - dest->header.message_id = src->header.message_id; - dest->header.reserved2 = src->header.reserved2; - for (i = 0; i < WRSM_MESSAGE_BODY_SIZE; i++) { - dest->body[i] = src->body[i]; - } -} - -/* - * Local Typedefs - */ - -/* - * The following is an element in a linked list of RPC's waiting for a - * response. The message_id is used to match response with original - * message, and *response is where the user wants the response placed. - */ -typedef struct pending_rpc { - wrsm_messageid_t message_id; - struct pending_rpc *next; - struct pending_rpc *prev; - kcondvar_t cv; - kmutex_t mutex; - boolean_t resp_recvd; - wrsm_message_t *response; -} pending_rpc_t; - -/* - * The wrsm_transport holds the state of a given instance of - * the transport. - */ -typedef struct tl_cnode { - wrsm_intr_recvq_t *recvq; - wrsm_cmmu_tuple_t tuple; - caddr_t addr; - uint_t offset; - boolean_t reachable; -} tl_cnode_t; - -typedef struct tl_event { - wrsm_network_t *net; - wrsm_message_t msg; - wrsm_message_rxhandler_t handler; - struct tl_event *next; -} tl_event_t; - -struct wrsm_transport { - kmutex_t mutex; - wrsm_message_txhandler_t tx_handlers[WRSM_MSG_TYPES_MAX]; - wrsm_message_rxhandler_t rx_handlers[WRSM_MSG_TYPES_MAX]; - pending_rpc_t *rpc_list; - kcondvar_t rpc_cv; - uint_t rpc_count; - wrsm_messageid_t last_message_id; - tl_cnode_t cnode[WRSM_MAX_CNODES]; - - /* event thread handling */ - kmutex_t event_mutex; - kcondvar_t event_cv; - kthread_t *event_thread; - tl_event_t *events; - boolean_t stop_events; - kcondvar_t event_exit_cv; - - /* taskqs for WRSM_MSG_SEGMENT_* messages */ - kmutex_t taskq_mutex; - boolean_t stop_taskqs; - taskq_t *connect_taskq; - taskq_t *smallputmap_taskq; - taskq_t *barriermap_taskq; - taskq_t *segmap_taskq; - taskq_t *disconnect_taskq; - taskq_t *unpublish_taskq; - taskq_t *access_taskq; -}; - -/* - * Event Handling - */ - -/* Processes events for the event thread. */ -static void -tl_process_events(wrsm_transport_t *tl) -{ - tl_event_t *event; - - ASSERT(mutex_owned(&tl->event_mutex)); - - while (tl->events) { - event = tl->events; - tl->events = event->next; - mutex_exit(&tl->event_mutex); - - (void) (*event->handler)(event->net, &event->msg); - - kmem_free(event, sizeof (tl_event_t)); - - mutex_enter(&tl->event_mutex); - } - -} - -/* - * Event thread. Handles TL message processing so we don't have to - * process in the interrupt thread - */ -static void -tl_event_thread(void *arg) -{ - wrsm_transport_t *tl = (wrsm_transport_t *)arg; - callb_cpr_t cprinfo; - - CALLB_CPR_INIT(&cprinfo, &tl->event_mutex, - callb_generic_cpr, "tl_event_thread"); - - mutex_enter(&tl->event_mutex); - - while (!tl->stop_events) { - tl_process_events(tl); - - CALLB_CPR_SAFE_BEGIN(&cprinfo); - cv_wait(&tl->event_cv, &tl->event_mutex); - CALLB_CPR_SAFE_END(&cprinfo, &tl->event_mutex); - } - - tl_process_events(tl); - cv_broadcast(&tl->event_exit_cv); - - /* - * CALLB_CPR_EXIT() calls mutex_exit() on the - * lock passed into CALLB_CPR_INIT() above, therefore - * we don't want to call mutex_exit() here. See - * common/sys/callb.h and common/sys/cpr.h. - */ - CALLB_CPR_EXIT(&cprinfo); - - thread_exit(); -} - -/* Adds an event to the event queue and wakes up the event thread */ -static void -tl_add_event(wrsm_transport_t *tl, tl_event_t *event) -{ - tl_event_t *evt; - - mutex_enter(&tl->event_mutex); - - if (tl->stop_events) { - mutex_exit(&tl->event_mutex); - return; - } - - evt = tl->events; - if (evt) { - while (evt->next) - evt = evt->next; - evt->next = event; - } else { - tl->events = event; - } - - cv_broadcast(&tl->event_cv); - mutex_exit(&tl->event_mutex); -} - - -/* - * Utility functions - */ - -/* Implements a ping service */ -static boolean_t -ping_message_rxhandler(wrsm_network_t *net, wrsm_message_t *msg) -{ - wrsm_raw_message_t raw_resp; - wrsm_message_t *resp = (wrsm_message_t *)&raw_resp; - - ASSERT(msg->header.message_type == WRSM_MSG_PING); - DPRINTF(TLDBG, (CE_NOTE, "Cnode %d is being pinged by %d", - net->cnodeid, - msg->header.source_cnode)); - resp->header.message_type = WRSM_MSG_PING_RESPONSE; - (void) wrsm_tl_rsp(net, msg, resp); - - return (B_TRUE); -} - -#ifdef DEBUG -/* Debug function to print pending RPC list info */ -static void -list_print(wrsm_transport_t *tl) -{ - pending_rpc_t *p; - - ASSERT(mutex_owned(&tl->mutex)); - - for (p = tl->rpc_list; p; p = p->next) { - DPRINTF(TLWARN, (CE_NOTE, "addr=%p, id=0x%08X, next=%p, " - "prev=%p", (void *)p, p->message_id, (void *)p->next, - (void *)p->prev)); - } -} -#endif /* DEBUG */ - -/* Adds a pending_rpc entry to the linked list */ -static int -add_to_list(wrsm_transport_t *tl, pending_rpc_t *entry) -{ - int retval; - - mutex_enter(&tl->mutex); - - /* Check to see if pending rpc is above highwater mark */ - while (tl->rpc_count >= wrsm_tl_rpc_highwater) { - retval = cv_wait_sig(&tl->rpc_cv, &tl->mutex); - /* retval of 0 indicates a signal was received */ - if (retval <= 0 && tl->rpc_count >= wrsm_tl_rpc_highwater) { - mutex_exit(&tl->mutex); - return (EAGAIN); - } - } - /* We got in! */ - tl->rpc_count++; - - /* Point to who used to be first */ - entry->next = tl->rpc_list; - /* If someone else used to be first on list... */ - if (entry->next) { - /* Make them point back at me */ - entry->next->prev = entry; - } - /* Change list to point to me */ - tl->rpc_list = entry; - mutex_exit(&tl->mutex); - return (0); -} - -/* Removes a pending_rpc entry to the linked list */ -static void -remove_from_list(wrsm_transport_t *tl, pending_rpc_t *entry) -{ - mutex_enter(&tl->mutex); - /* - * If there's a previous node, make them point to our next - * node. If not, we were first, so update head pointer. - */ - if (entry->prev) { - (entry->prev)->next = entry->next; - } else { - tl->rpc_list = entry->next; - } - /* - * If there's a next node, have them point - * back to whomever we pointed back to. - */ - if (entry->next) { - (entry->next)->prev = entry->prev; - } - /* If rpc count is falling below lowwater, wake up waiting threads */ - if (tl->rpc_count == wrsm_tl_rpc_lowwater) { - cv_broadcast(&tl->rpc_cv); - } - tl->rpc_count--; - mutex_exit(&tl->mutex); -} - -/* Constructs and initializes a wrsm_transport structure */ -static wrsm_transport_t * -alloc_state(void) -{ - int i; - wrsm_transport_t *tl = - kmem_zalloc(sizeof (wrsm_transport_t), KM_SLEEP); - - ASSERT(tl); - mutex_init(&tl->mutex, NULL, MUTEX_DRIVER, NULL); - mutex_init(&tl->event_mutex, NULL, MUTEX_DRIVER, NULL); - mutex_init(&tl->taskq_mutex, NULL, MUTEX_DRIVER, NULL); - cv_init(&tl->event_cv, NULL, CV_DRIVER, NULL); - cv_init(&tl->event_exit_cv, NULL, CV_DRIVER, NULL); - cv_init(&tl->rpc_cv, NULL, CV_DRIVER, NULL); - for (i = 0; i < WRSM_MSG_TYPES_MAX; i++) { - tl->tx_handlers[i] = NULL; - tl->rx_handlers[i] = NULL; - } - tl->last_message_id = 0; - tl->rpc_list = NULL; - tl->rpc_count = 0; - - return (tl); -} - -/* Cleans-up and destroys a wrsm_transport structure */ -static void -free_state(wrsm_transport_t *tl) -{ - while (tl->rpc_list) { - remove_from_list(tl, tl->rpc_list); - } - mutex_destroy(&tl->mutex); - mutex_destroy(&tl->event_mutex); - mutex_destroy(&tl->taskq_mutex); - cv_destroy(&tl->event_cv); - cv_destroy(&tl->event_exit_cv); - cv_destroy(&tl->rpc_cv); - kmem_free(tl, sizeof (wrsm_transport_t)); -} - -/* Handles incoming messages */ -/* ARGSUSED */ -static rsm_intr_hand_ret_t -intr_handler( - rsm_controller_object_t *controller, - rsm_intr_q_op_t operation, - rsm_addr_t sender, - void *data, - size_t size, - rsm_intr_hand_arg_t arg) -{ - wrsm_network_t *net = (wrsm_network_t *)arg; - wrsm_message_t *msg = (wrsm_message_t *)data; - wrsm_transport_t *tl = net->transport; - wrsm_message_rxhandler_t handler; - tl_event_t *event; - boolean_t handler_retval = B_TRUE; - cnodeid_t from_cnode = (cnodeid_t)sender; - - NOTE("wrsm_tl::intr_handler"); -#ifdef DEBUG - if (TLDUMP & tl_debug) { - WRSM_TL_DUMP_MESSAGE("tl intr_handler:", msg); - } -#endif /* DEBUG */ - - if (msg->header.version != WRSM_TL_VERSION) { - cmn_err(CE_WARN, "Remote driver version mismatch: " - "local version %u, remote version %u", - WRSM_TL_VERSION, msg->header.version); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } - /* - * Verify that the msg->source_cnode matches where the - * interrupt came from. - */ - if (msg->header.source_cnode != from_cnode) { - DPRINTF(TLERR, (CE_WARN, - "msg->header.source_cnode %d != from_cnode %d", - msg->header.source_cnode, from_cnode)); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } - - if (tl->cnode[from_cnode].addr == NULL) { - DPRINTF(TLERR, (CE_WARN, - "sender %d is not reachable; dropping message", - from_cnode)); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } - - if (tl->rx_handlers[msg->header.message_type]) { - /* - * All messages with an identifier in the _SESSION_ or _RECVQ_ - * range could possibly either block, or take locks from other - * threads that could block. Therefore, handle them on the - * event thread. - */ - if (ISDATAGRAMID(msg->header.message_id) && - ((msg->header.message_type >= - WRSM_MSG_SESSION_START && - msg->header.message_type <= - WRSM_MSG_SESSION_END) || - (msg->header.message_type >= - WRSM_MSG_INTR_RECVQ_CREATE && - msg->header.message_type <= - WRSM_MSG_INTR_RECVQ_DESTROY))) { - event = kmem_alloc(sizeof (tl_event_t), - KM_NOSLEEP); - event->net = net; - event->handler = - tl->rx_handlers[msg->header.message_type]; - msgcpy(&event->msg, msg); - event->next = (tl_event_t *)NULL; - - tl_add_event(tl, event); - - } else { - handler = tl->rx_handlers[msg->header.message_type]; - handler_retval = (*handler)(net, msg); - } - } - - if (ISRESPONSEID(msg->header.message_id) && handler_retval) { - /* - * This is an RPC response and handler was successful - */ - wrsm_messageid_t orig_id = MAKEORIGID(msg->header.message_id); - pending_rpc_t *p; - mutex_enter(&tl->mutex); - /* Walk the linked list, looking for matching message id */ - for (p = tl->rpc_list; p; p = p->next) { - if (p->message_id == orig_id) { - mutex_enter(&p->mutex); - - /* Clear message id, so we don't reenter. */ - p->message_id = MESSAGE_ID_INVALID; - - /* Copy response to holding area */ - msgcpy(p->response, msg); - - /* Set flag indicating response was received */ - p->resp_recvd = B_TRUE; - - /* Wake up the waiting thread */ - cv_signal(&p->cv); - - mutex_exit(&p->mutex); - - break; - } - } - if (!p) { - DPRINTF(TLERR, (CE_WARN, "intr_handler: " - "rpc resp but no one waiting: 0x%08X 0x%08X", - msg->header.message_id, orig_id)); -#ifdef DEBUG - list_print(tl); - WRSM_TL_DUMP_MESSAGE("intr_handler:", msg); -#endif - } - mutex_exit(&tl->mutex); - /* LINTED: E_NOP_IF_STMT */ - } else if (ISDATAGRAMID(msg->header.message_id) && (handler == NULL)) { - /* - * This is a datagram and we don't have a handler - */ - DPRINTF(TLERR, (CE_WARN, "intr_handler: " - "no handler for message_type %u", - msg->header.message_type)); - } - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); -} - -/* Formats and sends a message, used by dg, rpc and resp */ -static int -send_message(wrsm_network_t *net, - cnodeid_t destination, - wrsm_message_t *msg, - wrsm_messageid_t msg_id) -{ - wrsm_message_txhandler_t h; - wrsm_transport_t *tl; - caddr_t node_addr; - caddr_t rem_addr; - int retry; - const int max_retries = 8; /* At most, retry on each wci/link */ - int retval; - boolean_t handler_rc; - - ASSERT(net); - ASSERT(net->transport); - tl = net->transport; - - /* Validate the message. */ - ASSERT(msg); - - mutex_enter(&tl->mutex); - /* Validate that we know how to get to destination */ - node_addr = tl->cnode[destination].addr; - if (node_addr == NULL) { - DPRINTF(TLERR, (CE_WARN, "send_message: unknown dest %d", - destination)); - mutex_exit(&tl->mutex); - return (EPIPE); - } - if (tl->cnode[destination].reachable == B_FALSE) { - DPRINTF(TLERR, (CE_WARN, "send_message: dest %d unreachable", - destination)); - mutex_exit(&tl->mutex); - return (EPIPE); - } - mutex_exit(&tl->mutex); - msg->header.reserved1 = 0; - msg->header.reserved2 = 0; - msg->header.message_id = msg_id; - msg->header.version = WRSM_TL_VERSION; - msg->header.session_id = 0; - msg->header.source_cnode = net->cnodeid; - - /* Call send function handler before sending message. */ - h = tl->tx_handlers[msg->header.message_type]; - if (h) { - handler_rc = (*h)(net, destination, msg); - if (handler_rc == B_FALSE) { - DPRINTF(TLERR, (CE_WARN, "send_message: tx_handler " - "failed rc=%d handler=%p", handler_rc, (void *)h)); - return (EAGAIN); - } - } - - for (retry = 0; retry < max_retries; retry++) { - - /* Calculate remote address, taking into account striping */ - rem_addr = node_addr + tl->cnode[destination].offset; - - /* - * Advance the offset by the link stripe stride, so we tend to - * distribute interrupts across link and WCI stripes, but make - * sure not to exceed the page size! - * - * Note that this should be atomic, but the worst thing that - * can happen is we send two interrupts in a row on the same - * link which is probably less of a performance impact than - * grabbing a mutex for every single interrupt. - */ - tl->cnode[destination].offset = - (tl->cnode[destination].offset + - WCI_CLUSTER_STRIPE_STRIDE) & WCI_CLUSTER_STRIPE_MASK; - - /* Send the message */ -#ifdef DEBUG - if (TLDUMP & tl_debug) { - WRSM_TL_DUMP_MESSAGE("wrsm_intr_send:", msg); - } -#endif /* DEBUG */ - retval = wrsm_intr_send(net, rem_addr, destination, msg, 0, - WRSM_INTR_WAIT_DEFAULT, 0); - - /* Stop retrying on success */ - if (retval == 0) { - break; - } - } - return (retval); -} - -/* Atomically allocates a unique message id */ -static wrsm_messageid_t -allocate_message_id(wrsm_transport_t *tl) -{ - wrsm_messageid_t msg_id; - - mutex_enter(&tl->mutex); - tl->last_message_id++; - if (tl->last_message_id > MESSAGE_ID_MAX) { - tl->last_message_id = MESSAGE_ID_FIRST; - } - msg_id = tl->last_message_id; - mutex_exit(&tl->mutex); - - return (msg_id); -} - -/* - * Transport API functions - */ -int -wrsm_tl_init(wrsm_network_t *net) -{ - int retval; - wrsm_transport_t *tl; - ASSERT(net); - - /* First, initialize interrupt component */ - retval = wrsm_intr_init(net); - if (retval) { - return (retval); - } - wrsm_intr_print(net); - - /* Allocate structure to store transport state */ - tl = alloc_state(); - ASSERT(tl); - - /* Spin up the event thread for this transport */ - tl->stop_events = B_FALSE; - tl->events = (tl_event_t *)NULL; - tl->event_thread = thread_create(NULL, 0, tl_event_thread, - (void *)tl, 0, &p0, TS_RUN, maxclsyspri); - - /* - * Allocate all the taskq's for MSG_SEGMENT handlers. You need to - * allocate one for each message type we handle in this way in order - * to guarantee that one message type blocking doesn't interfere with - * any other message types. - * - * The gloabl variable wrsm_tl_tqthreads controls the number of - * threads servicing -each- taskq. - */ - tl->stop_taskqs = B_FALSE; - tl->connect_taskq = taskq_create("wrsm_connect_taskq", - wrsm_tl_tqthreads, maxclsyspri, 1, 8, - TASKQ_PREPOPULATE); - tl->smallputmap_taskq = taskq_create("wrsm_smallputmap_taskq", - wrsm_tl_tqthreads, maxclsyspri, 1, 8, - TASKQ_PREPOPULATE); - tl->barriermap_taskq = taskq_create("wrsm_barriermap_taskq", - wrsm_tl_tqthreads, maxclsyspri, 1, 8, - TASKQ_PREPOPULATE); - tl->segmap_taskq = taskq_create("wrsm_segmap_taskq", - wrsm_tl_tqthreads, maxclsyspri, 1, 8, - TASKQ_PREPOPULATE); - tl->disconnect_taskq = taskq_create("wrsm_disconnect_taskq", - wrsm_tl_tqthreads, maxclsyspri, 1, 8, - TASKQ_PREPOPULATE); - tl->unpublish_taskq = taskq_create("wrsm_unpublish_taskq", - wrsm_tl_tqthreads, maxclsyspri, 1, 8, - TASKQ_PREPOPULATE); - tl->access_taskq = taskq_create("wrsm_access_taskq", - wrsm_tl_tqthreads, maxclsyspri, 1, 8, - TASKQ_PREPOPULATE); - - /* Hook structure into network */ - net->transport = tl; - - /* Register with the interrupt component for driver messages */ - (void) wrsm_register_handler(net, NULL, WRSM_TL_INTR_TYPE, - intr_handler, (rsm_intr_hand_arg_t)net, NULL, 0); - - /* Register ping message handler with ourselves */ - (void) wrsm_tl_add_handler(net, WRSM_MSG_PING, - WRSM_TL_NO_HANDLER, ping_message_rxhandler); - - wrsm_sess_init(net); - wrsm_intr_rsminit(net); - - return (0); -} - -void -wrsm_tl_fini(wrsm_network_t *net) -{ - wrsm_transport_t *tl = (wrsm_transport_t *)net->transport; - - /* First, validate pointers */ - ASSERT(net); - ASSERT(net->transport); - - wrsm_intr_rsmfini(net); - - /* Unregister from interrupt component */ - (void) wrsm_unregister_handler(net, WRSM_TL_INTR_TYPE, - intr_handler, (rsm_intr_hand_arg_t)net); - - /* stop the taskq's and wait for them to drain */ - mutex_enter(&tl->taskq_mutex); - tl->stop_taskqs = B_TRUE; - - taskq_destroy(tl->connect_taskq); - taskq_destroy(tl->smallputmap_taskq); - taskq_destroy(tl->barriermap_taskq); - taskq_destroy(tl->segmap_taskq); - taskq_destroy(tl->disconnect_taskq); - taskq_destroy(tl->unpublish_taskq); - taskq_destroy(tl->access_taskq); - mutex_exit(&tl->taskq_mutex); - - /* Stop and exit the event thread */ - mutex_enter(&tl->event_mutex); - tl->stop_events = B_TRUE; - cv_broadcast(&tl->event_cv); - cv_wait(&tl->event_exit_cv, &tl->event_mutex); - mutex_exit(&tl->event_mutex); - - wrsm_sess_fini(net); - free_state(net->transport); - net->transport = NULL; - - /* Last, fini interrupt component */ - wrsm_intr_fini(net); -} - -int -wrsm_tl_newcnode(wrsm_network_t *net, cnodeid_t cnodeid) -{ - int retval = RSM_SUCCESS; - wrsm_transport_t *tl; - - DPRINTF(TLDBG, (CE_NOTE, "wrsm_tl_newcnode: %d", cnodeid)); - ASSERT(net); - tl = net->transport; - ASSERT(tl); - - mutex_enter(&tl->mutex); - - retval = wrsm_cmmu_comm_alloc(net, - (uint_t)net->nodes[net->cnodeid]->config->comm_ncslice, - (wrsm_cmmu_offset_t)net->nodes[cnodeid]->config->local_offset, - &(tl->cnode[cnodeid].tuple)); - if (retval) { - mutex_exit(&tl->mutex); - return (retval); - } - - DPRINTF(TLDBG, (CE_NOTE, "wrsm_tl_newcnode: cnode %d got cmmu %d", - cnodeid, tl->cnode[cnodeid].tuple.index)); - - retval = wrsm_intr_create_recvq(net, - WRSM_TL_INTR_TYPE, - WRSM_TL_PACKETRING_SIZE, - tl->cnode[cnodeid].tuple.index, - &(tl->cnode[cnodeid].recvq), - cnodeid, - NULL, - WRSM_CREATE_RECVQ_NOFLAGS); - if (retval) { - wrsm_cmmu_comm_free(net, &tl->cnode[cnodeid].tuple); - mutex_exit(&tl->mutex); - return (retval); - } - - mutex_exit(&tl->mutex); - - return (RSM_SUCCESS); -} - -int -wrsm_tl_removecnode(wrsm_network_t *net, cnodeid_t cnodeid) -{ - int rc = RSM_SUCCESS; - wrsm_transport_t *tl; - - DPRINTF(TLDBG, (CE_NOTE, "wrsm_tl_removecnode: %d", cnodeid)); - ASSERT(net); - tl = net->transport; - ASSERT(tl); - - mutex_enter(&tl->mutex); - - if (tl->cnode[cnodeid].reachable) { - wrsm_tl_unreachable(net, cnodeid); - } - - if (tl->cnode[cnodeid].recvq == NULL) { - DPRINTF(TLDBG, (CE_CONT, "wrsm_tl_removecnode: %d " - "no recvq - tl_newcnode never called\n", cnodeid)); - mutex_exit(&tl->mutex); - return (ENOENT); - } - - /* Unmap remote address if it had been mapped */ - if (tl->cnode[cnodeid].addr) { - ddi_unmap_regs(wrsm_ncslice_dip, - (uint_t)net->nodes[cnodeid]->config->comm_ncslice, - &(tl->cnode[cnodeid].addr), - (off_t)net->nodes[cnodeid]->config->comm_offset, - PAGESIZE); - tl->cnode[cnodeid].addr = NULL; - } - - wrsm_intr_destroy_recvq(net, tl->cnode[cnodeid].recvq); - tl->cnode[cnodeid].recvq = NULL; - - wrsm_cmmu_comm_free(net, &(tl->cnode[cnodeid].tuple)); - - mutex_exit(&tl->mutex); - - return (rc); -} - -void -wrsm_tl_reachable(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_transport_t *tl; - int retval; - - DPRINTF(TLDBG, (CE_NOTE, "wrsm_tl_reachable: %d", cnodeid)); - ASSERT(net); - tl = net->transport; - ASSERT(tl); - - mutex_enter(&tl->mutex); - if (tl->cnode[cnodeid].addr == NULL) { - /* We've never been able to reach this node before... */ - retval = ddi_map_regs(wrsm_ncslice_dip, - (uint_t)net->nodes[cnodeid]->config->comm_ncslice, - &(tl->cnode[cnodeid].addr), - (off_t)net->nodes[cnodeid]->config->comm_offset, - PAGESIZE); - - if (retval != DDI_SUCCESS) { - cmn_err(CE_WARN, "ddi_map_regs returned error: %d", - retval); - } - } - tl->cnode[cnodeid].reachable = B_TRUE; - mutex_exit(&tl->mutex); - -#ifdef DEBUG - if (tl_debug & TLDBG) { - uint64_t kpf; /* Kernel Page Frame */ - uint64_t pa; /* Physical address */ - uint_t ncslice; - - kpf = hat_getpfnum(kas.a_hat, tl->cnode[cnodeid].addr); - pa = (kpf << 13); - ncslice = (uint_t)((pa >> 34) & 0xff); - - DPRINTF(TLDBG, (CE_WARN, - "ncslice %u off 0x%p mapped to va=0x%p, pa=0x%p, nc=%u", - (uint_t)net->nodes[cnodeid]->config->comm_ncslice, - (void *)net->nodes[cnodeid]->config->comm_offset, - (void *)tl->cnode[cnodeid].addr, - (void *)pa, - ncslice)); - } -#endif /* DEBUG */ - wrsm_sess_reachable(net, cnodeid); -} - -void -wrsm_tl_unreachable(wrsm_network_t *net, cnodeid_t cnodeid) -{ - wrsm_transport_t *tl; - - DPRINTF(TLDBG, (CE_NOTE, "wrsm_tl_unreachable: %d", cnodeid)); - ASSERT(net); - tl = net->transport; - ASSERT(tl); - - tl->cnode[cnodeid].reachable = B_FALSE; - if (tl->cnode[cnodeid].addr == NULL) { - /* Node was never reachable */ - return; - } - wrsm_sess_unreachable(net, cnodeid); -} - -int -wrsm_tl_add_handler(wrsm_network_t *net, - wrsm_message_type_t msg_type, - wrsm_message_txhandler_t send_fn, - wrsm_message_rxhandler_t rcv_fn) -{ - int rc = RSM_SUCCESS; - wrsm_transport_t *tl = net->transport; - - mutex_enter(&tl->mutex); - - if (rcv_fn && tl->rx_handlers[msg_type]) { - DPRINTF(TLERR, (CE_WARN, "wrsm_tl_add_handler: " - "receive handler already exists for msg type %u", - msg_type)); - rc = EEXIST; - } - - if (send_fn && tl->tx_handlers[msg_type]) { - DPRINTF(TLERR, (CE_WARN, "wrsm_tl_add_handler: " - "send handler already exists for msg type %u", - msg_type)); - rc = EEXIST; - } - - if (!rc) { - tl->rx_handlers[msg_type] = rcv_fn; - tl->tx_handlers[msg_type] = send_fn; - } - mutex_exit(&tl->mutex); - - return (rc); -} - -int -wrsm_tl_dg(wrsm_network_t *net, - cnodeid_t destination, - wrsm_message_t *msg) -{ - int rc; - ASSERT(net); - ASSERT(net->transport); - - rc = send_message(net, destination, msg, - allocate_message_id(net->transport)); - return (rc); -} - -int -wrsm_tl_rpc(wrsm_network_t *net, - cnodeid_t destination, - wrsm_message_t *msg, - wrsm_message_t *resp) -{ - int rc = RSM_SUCCESS; - clock_t timeout_ticks; - wrsm_messageid_t message_id; - pending_rpc_t me; - wrsm_transport_t *tl = net->transport; - - /* Allocate ourselves a message id now, before it's too late */ - message_id = allocate_message_id(tl); - - /* Create and initialize a pending rpc item in linked list */ - /* Don't need to use mutex, cause we're still not listed */ - - me.message_id = message_id; - me.next = NULL; - me.prev = NULL; - me.response = resp; - me.resp_recvd = B_FALSE; - cv_init(&me.cv, NULL, CV_DRIVER, NULL); - mutex_init(&me.mutex, NULL, MUTEX_DRIVER, NULL); - - /* Add me to the front of the waiting rpc list */ - if (add_to_list(tl, &me) != 0) { - /* Failed to add to list, return error */ - mutex_destroy(&me.mutex); - wrsm_sess_teardown(net, destination); - return (EAGAIN); - } - - /* Grab our mutex -- response could come before we get to wait */ - mutex_enter(&me.mutex); - - /* Send the message */ - rc = send_message(net, destination, msg, message_id); - - if (rc == RSM_SUCCESS) { - /* Wait for rpc response */ - timeout_ticks = ddi_get_lbolt() + - drv_usectohz(wrsm_tl_rpc_timeout); - /* - * If cv_timedwait returns -1, condition was "not necessarily" - * signaled. To see if response was actually received, we - * really need to check resp_recvd flag. - */ - (void) cv_timedwait(&me.cv, &me.mutex, timeout_ticks); - if (!me.resp_recvd) { - DPRINTF(TLWARN, (CE_WARN, "rpc: timed out waiting for " - "response, msg id = 0x%08X", me.message_id)); - rc = ETIME; - } - /* LINTED: E_NOP_ELSE_STMT */ - } else { - DPRINTF(TLWARN, (CE_WARN, "send_message failed: %d", rc)); - } - - me.message_id = MESSAGE_ID_INVALID; - - if (rc != RSM_SUCCESS) { - wrsm_sess_teardown(net, destination); - } - - mutex_exit(&me.mutex); - -#ifdef DEBUG - /* - * can't take tl->mutex while holding me.mutex, so do debug stuff here - */ - if (!me.resp_recvd) { - mutex_enter(&tl->mutex); - list_print(tl); - mutex_exit(&tl->mutex); - } -#endif - remove_from_list(tl, &me); - mutex_destroy(&me.mutex); - - return (rc); -} - -int -wrsm_tl_rsp(wrsm_network_t *net, - wrsm_message_t *orig, - wrsm_message_t *resp) -{ - wrsm_messageid_t resp_id = MAKERESPID(orig->header.message_id); - int rc = send_message(net, orig->header.source_cnode, - resp, resp_id); - return (rc); -} - -boolean_t -wrsm_tl_txhandler_sessionid(wrsm_network_t *net, cnodeid_t cnodeid, - wrsm_message_t *msg) -{ - if (ISRESPONSEID(msg->header.message_id)) { - /* - * If this message is a response, don't try to establish - * a new session, just get the current session id or - * SESS_ID_INVALID if the session has ended. - */ - msg->header.session_id = wrsm_sess_get(net, cnodeid); - } else { - /* - * If this message is not a response, try to establish - * a new session if one doesn't already exist. - */ - msg->header.session_id = wrsm_sess_establish(net, cnodeid); - } - return (msg->header.session_id != SESS_ID_INVALID); -} - -boolean_t -wrsm_tl_rxhandler_sessionid(wrsm_network_t *net, wrsm_message_t *msg) -{ - wrsm_sessionid_t session_id; - - session_id = wrsm_sess_get(net, msg->header.source_cnode); - - return ((session_id != SESS_ID_INVALID) && - (msg->header.session_id == session_id)); -} - -/* - * Generic memseg message handler for the following message types: - * CONNECT SMALLPUTMAP BARRIERMAP SEGMAP DISCONNECT UNPUBLISH ACCESS - * - * Note: This must reside in wrsm_tl.c because it needs to know about - * the innards of the wrsm_transport structure. - */ -boolean_t -wrsm_memseg_msg_hdlr(wrsm_network_t *network, wrsm_message_t *msg) -{ - wrsm_node_t *node = network->nodes[msg->header.source_cnode]; - wrsm_transport_t *tl = network->transport; - wrsm_memseg_evt_args_t *args; - - if (node == NULL) { - /* non-existent node */ - return (B_FALSE); - } - - /* Verify that this is a message type we support */ - ASSERT(msg->header.message_type >= WRSM_MSG_SEGMENT_CONNECT); - ASSERT(msg->header.message_type <= WRSM_MSG_SEGMENT_ACCESS); - - if (wrsm_tl_rxhandler_sessionid(network, msg) == B_FALSE) { - /* session must not be valid */ - return (B_FALSE); - } - - /* - * Allocate the args structure, to be passed to the event handlers. - * NEEDS TO BE DEALLOCATED IN THE HANDLERS! - */ - args = kmem_alloc(sizeof (wrsm_memseg_evt_args_t), KM_SLEEP); - args->network = network; - msgcpy(&args->msg, msg); - - /* grab the taskq's lock so they don't disappear out from under us */ - mutex_enter(&tl->taskq_mutex); - - if (tl->stop_taskqs) { - mutex_exit(&tl->taskq_mutex); - return (B_FALSE); - } - - switch (msg->header.message_type) { - - /* export segment events */ - case WRSM_MSG_SEGMENT_CONNECT: - taskq_dispatch(tl->connect_taskq, - wrsm_connect_msg_evt, - (void *)args, TQ_SLEEP); - break; - case WRSM_MSG_SEGMENT_SMALLPUTMAP: - taskq_dispatch(tl->smallputmap_taskq, - wrsm_smallputmap_msg_evt, - (void *)args, TQ_SLEEP); - break; - case WRSM_MSG_SEGMENT_BARRIERMAP: - taskq_dispatch(tl->barriermap_taskq, - wrsm_barriermap_msg_evt, - (void *)args, TQ_SLEEP); - break; - case WRSM_MSG_SEGMENT_SEGMAP: - taskq_dispatch(tl->segmap_taskq, - wrsm_segmap_msg_evt, - (void *)args, TQ_SLEEP); - break; - case WRSM_MSG_SEGMENT_DISCONNECT: - taskq_dispatch(tl->disconnect_taskq, - wrsm_disconnect_msg_evt, - (void *)args, TQ_SLEEP); - break; - - /* import segment events */ - case WRSM_MSG_SEGMENT_UNPUBLISH: - taskq_dispatch(tl->unpublish_taskq, - wrsm_unpublish_msg_evt, - (void *)args, TQ_SLEEP); - break; - case WRSM_MSG_SEGMENT_ACCESS: - taskq_dispatch(tl->access_taskq, - wrsm_access_msg_evt, - (void *)args, TQ_SLEEP); - break; - } - - mutex_exit(&tl->taskq_mutex); - - return (B_TRUE); -} - - -#ifdef DEBUG -static char * -messagetype2string(wrsm_message_type_t type) -{ - switch (type) { - case WRSM_MSG_ACK: - return ("ACK"); - case WRSM_MSG_NACK: - return ("NACK"); - case WRSM_MSG_PING: - return ("PING"); - case WRSM_MSG_PING_RESPONSE: - return ("PING_RESPONSE"); - case WRSM_MSG_CONFIG_COOKIE: - return ("CONFIG_COOKIE"); - case WRSM_MSG_CONFIG_PASSTHROUGH_LIST: - return ("CONFIG_PASSTHROUGH_LIST"); - case WRSM_MSG_CONFIG_PASSTHROUGH_LIST_RESPONSE: - return ("CONFIG_PASSTHROUGH_LIST_RESPONSE"); - case WRSM_MSG_CONFIG_CNODE_ACCESS: - return ("CONFIG_CNODE_ACCESS"); - case WRSM_MSG_SESSION_START: - return ("SESSION_START"); - case WRSM_MSG_SESSION_START_RESPONSE: - return ("SESSION_START_RESPONSE"); - case WRSM_MSG_SESSION_END: - return ("SESSION_END"); - case WRSM_MSG_SEGMENT_CONNECT: - return ("SEGMENT_CONNECT"); - case WRSM_MSG_SEGMENT_CONNECT_RESPONSE: - return ("SEGMENT_CONNECT_RESPONSE"); - case WRSM_MSG_SEGMENT_SMALLPUTMAP: - return ("SEGMENT_SMALLPUTMAP"); - case WRSM_MSG_SEGMENT_SMALLPUTMAP_RESPONSE: - return ("SEGMENT_SMALLPUTMAP_RESPONSE"); - case WRSM_MSG_SEGMENT_BARRIERMAP: - return ("SEGMENT_BARRIERMAP"); - case WRSM_MSG_SEGMENT_BARRIERMAP_RESPONSE: - return ("SEGMENT_BARRIERMAP_RESPONSE"); - case WRSM_MSG_SEGMENT_SEGMAP: - return ("SEGMENT_SEGMAP"); - case WRSM_MSG_SEGMENT_SEGMAP_RESPONSE: - return ("SEGMENT_SEGMAP_RESPONSE"); - case WRSM_MSG_SEGMENT_DISCONNECT: - return ("SEGMENT_DISCONNECT"); - case WRSM_MSG_SEGMENT_UNPUBLISH: - return ("SEGMENT_UNPUBLISH"); - case WRSM_MSG_SEGMENT_UNPUBLISH_RESPONSE: - return ("SEGMENT_UNPUBLISH_RESPONSE"); - case WRSM_MSG_SEGMENT_ACCESS: - return ("SEGMENT_ACCESS"); - case WRSM_MSG_SEGMENT_ACCESS_RESPONSE: - return ("SEGMENT_ACCESS_RESPONSE"); - case WRSM_MSG_INTR_RECVQ_CREATE: - return ("INTR_RECVQ_CREATE"); - case WRSM_MSG_INTR_RECVQ_CREATE_RESPONSE: - return ("INTR_RECVQ_CREATE_RESPONSE"); - case WRSM_MSG_INTR_RECVQ_DESTROY: - return ("INTR_RECVQ_DESTROY"); - default: - return ("Unknown"); - } -} - -void -wrsm_tl_dump_message(char *txt, wrsm_message_t *msg) -{ - unsigned i; - - cmn_err(CE_CONT, "%s", txt); - cmn_err(CE_CONT, "---- Message ----\n"); - cmn_err(CE_CONT, "Reserved1: 0x%08X\n", msg->header.reserved1); - cmn_err(CE_CONT, "Message Id: 0x%08X\n", msg->header.message_id); - cmn_err(CE_CONT, "Version: %u\n", msg->header.version); - cmn_err(CE_CONT, "Session: %u\n", msg->header.session_id); - cmn_err(CE_CONT, "Source cnode: %u\n", msg->header.source_cnode); - cmn_err(CE_CONT, "Message type: %s (%u)\n", - messagetype2string(msg->header.message_type), - msg->header.message_type); - cmn_err(CE_CONT, "Reserved2: 0x%08X\n", msg->header.reserved2); - cmn_err(CE_CONT, "Body:\n"); - for (i = 0; i < WRSM_MESSAGE_BODY_SIZE; i += 8) { - cmn_err(CE_CONT, " " - "%02X %02X %02X %02X %02X %02X %02X %02X\n", - msg->body[i+0], - msg->body[i+1], - msg->body[i+2], - msg->body[i+3], - msg->body[i+4], - msg->body[i+5], - msg->body[i+6], - msg->body[i+7]); - } - - cmn_err(CE_CONT, "-----------------\n"); -} -#endif /* DEBUG */ diff --git a/usr/src/uts/sun4u/io/wrsm/wrsm_trap.s b/usr/src/uts/sun4u/io/wrsm/wrsm_trap.s deleted file mode 100644 index a83113b99c..0000000000 --- a/usr/src/uts/sun4u/io/wrsm/wrsm_trap.s +++ /dev/null @@ -1,790 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * TL1 trap handler for DMV interrupts generated by WCIs - * Note: You must build sun4u/genassym before assembling this file. - * - * This handler places incoming interrupts onto the appropriate receive - * queue for waiting handlers based on the interrupt mondo. It also - * directly handles "small put interrupts"; it writes <64 chunks of data - * passed by the interrupt into the memory segment, again based on the - * interrupt mondo. - */ - -#if !defined(lint) -#include <sys/asm_linkage.h> -#include <sys/asi.h> -#include <sys/machasi.h> -#include <sys/privregs.h> -#include <sys/machthread.h> -#include <sys/fsr.h> -#include <sys/machparam.h> -#include <sys/wrsm_config.h> -#include <sys/wrsm_intr.h> -#include <sys/wrsm_intr_impl.h> -#include <wrsm_offsets.h> -#endif /* lint */ - -/* - * The definitions of the interrupt recieve and send registers - * (IRDR_x and IDDR_x) are different for Cheetah than for spitfire - * so the values in intreg.h won't work. - */ -#define IRDR_0 0x40 -#define IRDR_1 0x48 -#define IRDR_2 0x50 -#define IRDR_3 0x58 -#define IRDR_4 0x60 -#define IRDR_5 0x68 -#define IRDR_6 0x80 -#define IRDR_7 0x88 - -#define CMMU_MONDO_SHIFT 32 -#define CMMU_MONDO_MASK 0xffff -#define RING_EMPTY 1 -#define RING_FULL 2 - -#define PFN_INVALID -1 - -#if defined(lint) - -/* ARGSUSED */ -void -wrsm_tl_handler(unsigned long dmv_arg, unsigned long irdr_0) -{} - -#endif /* lint */ - -#if !defined(lint) - - .seg ".data" - - .global wrsm_null_intr_count - .align 8 -wrsm_null_intr_count: - .word 0, 0 - -#ifdef DEBUG - .global wrsm_dropped_intr - .align 8 -wrsm_dropped_intr: - .word 0, 0 - - .global wrsm_trap_softint_count - .align 8 -wrsm_trap_softint_count: - .word 0, 0 - - .global wrsm_trap_ring_info - .align 8 -wrsm_trap_ring_info: - .word 0, 0 - - .global wrsm_trap_arg1 - .align 8 -wrsm_trap_arg1: - .word 0, 0xbadd - - .global wrsm_trap_arg2 - .align 8 -wrsm_trap_arg2: - .word 0, 0xcafe - - .global wrsm_trap_highwater - .align 8 -wrsm_trap_highwater: - .word 0, 0 -#endif /* DEBUG */ - -#ifdef WRSM_STORE_TRAP_DATA - .global wrsm_trap_data - .align 8 -wrsm_trap_data: - .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -#endif /* WRSM_STORE_TRAP_DATA */ - - ! - ! %g1 The argument passed to dmv_add_intr() - ! %g2 Word 0 of the incoming mondo vector(IRDR_0) - ! The argument in %g1 is the pointer to the base - ! of the recvq_table - ! - .seg ".text" - ENTRY(wrsm_tl1_handler) - -#ifdef DEBUG - set wrsm_trap_arg1, %g3 - stx %g1, [%g3] - set wrsm_trap_arg2, %g3 - stx %g2, [%g3] -#endif - - /* - * The 16-bit index into the recvq_table is in bits 47 through - * 32 of IRDR_0 - */ - srlx %g2, CMMU_MONDO_SHIFT, %g3 - set CMMU_MONDO_MASK, %g5 - andcc %g3, %g5, %g3 ! %g3 now holds the 16-bit index - - bne 0f - nop - - ! If the mondo is 0, bump a counter and resume without - ! triggering a softint - set wrsm_null_intr_count, %g4 - ldx [%g4], %g5 - inc %g5 - stx %g5, [%g4] - set dmv_finish_intr, %g5 - jmp %g5 - sub %g0, 1, %g1 ! no softint -0: - - mov %g3, %g4 - srlx %g3, WRSM_INTR_TABLE_SHIFT, %g3 - and %g3, WRSM_INTR_TABLE_MASK, %g3 - - srlx %g4, WRSM_INTR_INDEX_SHIFT, %g4 - and %g4, WRSM_INTR_INDEX_MASK, %g4 - ! %g3 has the table number and %g4 has the table index - - sllx %g3, 3, %g3 ! g3 = g3 * sizeof(void *) - add %g3, %g1, %g3 ! g3 = &recvq_tables[table] - ldx [%g3], %g5 ! g5 = recvq_tables[table] - - sllx %g4, 3, %g4 ! g4 = g4 * sizeof(void *) - add %g4, %g5, %g4 - ldx [%g4], %g6 - - ! %g6 has the pointer to the correct recvq struct - ! We no longer need %g3, %g4, or %g5 - - - - /* - * If the recvq exportseg field is set, this must be a small put - * interrupt; parse and handle message here. Otherwise it is - * a standard packet to be put onto a recvq. - */ - ldx [%g6 + EXPORTSEG], %g3 ! get exportseg pointer - cmp %g0, %g3 ! is it NULL? - be,a,pn %xcc, 1f ! yes; handle normal packet - add %g6, PACKET_RING_INFO, %g3 ! execute on branch only - - /* - * %g3 has exportseg pointer - */ - - ldx [%g3 + PFN_LIST], %g4 ! get pfn_list pointer - cmp %g0, %g4 ! is it NULL? - be,a,pn %xcc, 5f ! yes; toss this packet - sub %g0, 1, %g1 ! dmv_finish_intr: no softint - - - /* - * no longer need %g1, %g3 or %g6 - * still don't need need %g5 - * - * %g4 has pfn_list pointer - * - * %g2 has word 0 of the incoming mondo vector (IRDR_0), which - * contains the first 8 bytes of small put message. - * - * Parse message and find the length to write, and offset into - * message putdata field holding first byte. Both of these values - * are in IRDR_0 (bytes 0-7). - */ - - srlx %g2, 24, %g1 ! byte 4 holds # bytes to write - and %g1, 0xff, %g1 ! just want byte 4 - - srlx %g2, 16, %g2 ! byte 5 holds putdata offset - and %g2, 0xff, %g2 ! just want byte 5 - - - /* - * If no bytes to write, finished small put interrupt handling. - * Skip to cleanup. - */ - cmp %g0, %g1 ! any bytes to write? - be,a,pn %xcc, 5f ! none, branch to cleanup - sub %g0, 1, %g1 ! dmv_finish_intr: no softint - - - /* - * %g1 holds the number of bytes left to write - * %g2 holds the message putdata offset to write - * %g4 has pfn_list pointer - * - * still don't need %g3, %g5 or %g6 - * - * Calculate the physical address to start at. The segment offset - * is translated into the page backing the segment offset. The - * exact physical address is this page plus the offset into this - * page. - */ - - mov IRDR_1, %g3 - ldxa [%g3]ASI_INTR_RECEIVE, %g3 ! bytes 8-15 - srlx %g3, MMU_PAGESHIFT, %g7 ! calculate pfn_list index - sllx %g7, 3, %g7 ! calculate pfn_list offset - add %g4, %g7, %g4 ! add to pfn_list start address - ldx [%g4], %g5 ! get the pfn - cmp %g5, PFN_INVALID ! is pfn invalid? - be,a,pn %xcc, 5f ! yes; toss this packet - sub %g0, 1, %g1 ! dmv_finish_intr: no softint - - sllx %g5, MMU_PAGESHIFT, %g5 ! turn into a physical address - - /* calculate offset into the page */ - sllx %g3, (64 - MMU_PAGESHIFT), %g3 ! clean out upper bits - srlx %g3, (64 - MMU_PAGESHIFT), %g3 ! shift back to get page offset - add %g5, %g3, %g5 ! add; now have start address - - -6: - /* - * While (len > 0) {} - * - * Loop through the data in putdata, writing it to physical memory - * using the largest possible sized atomic write in each case: 8, - * 4, 2 or 1 byte chunks. The alignment of the write location and - * number of bytes to write determines the largest usable write to - * use. - * - * The data in the putdata buffer is guaranteed be aligned so that - * each Mondo register falls onto an aligned 8 bytes in the - * segment. - * - * %g1 holds the number of bytes left to write - * %g2 holds the message putdata offset to write - * %g4 holds the address of the current pfn_list entry - * %g5 holds the physical address to write to - * still don't need %g3 or %g6 - */ - - /* - * The maximum amount of bytes that can be transfered via a DMV is - * is 48 bytes. The data payload can span two Dcache lines. Invalidate - * two D$ lines starting at %g5. We do not have to mask %g5 as the - * lower 5 bits of the physical address are ignored. - */ - sethi %hi(dcache_line_mask), %g6 - ld [%g6 + %lo(dcache_line_mask)], %g6 - - and %g5, %g6, %g3 - - sethi %hi(dcache_linesize), %g6 - ld [%g6 + %lo(dcache_linesize)], %g6 - - stxa %g0, [%g3]ASI_DC_INVAL - membar #Sync - stxa %g0, [%g3 + %g6]ASI_DC_INVAL - membar #Sync - - /* - * Read in appropriate message data based on the offset into the - * message putdata field. Offset 0 of the putdata starts at byte - * 16 in the message buffer, or IRDR_2. - */ - subcc %g2, 8, %g0 - blu,a,pt %xcc, calc_valid_bytes - mov IRDR_2, %g3 - - subcc %g2, 16, %g0 - blu,a,pt %xcc, calc_valid_bytes - mov IRDR_3, %g3 - - subcc %g2, 24, %g0 - blu,a,pt %xcc, calc_valid_bytes - mov IRDR_4, %g3 - - subcc %g2, 32, %g0 - blu,a,pt %xcc, calc_valid_bytes - mov IRDR_5, %g3 - - subcc %g2, 40, %g0 - blu,a,pt %xcc, calc_valid_bytes - mov IRDR_6, %g3 - - /* - * must be the last register (bytes 40 - 47 of putdata) - */ - - mov IRDR_7, %g3 - -calc_valid_bytes: - - - /* - * %g3 now IRDR_X register that needs to be read - * - * Read the IRDR_X register into %g3 - * Calculate the number of valid bytes in register. - * First, subtract off bytes at the start of the register - * that shouldn't be written (this only happens for IRDR_2). - */ - ldxa [%g3]ASI_INTR_RECEIVE, %g3 - and %g2, 7, %g6 ! byte offset into this register - set 8, %g7 ! calc number of valid bytes: - sub %g7, %g6, %g6 ! (8 - byte offset) - - /* - * %g3 holds the data to write, with the valid bytes in the - * least significant bytes of the register - * - * %g6 holds the number valid bytes - * - * The number of bytes from this register to be written must be no - * more than the lesser of # valid bytes (%g6) and bytes left (%g1). - */ - - cmp %g6, %g1 - bleu,a,pn %xcc, calc_offset_bytes ! %g6 holds correct value - nop - - /* - * Adjust for the number of bytes in %g1. Shift register to the - * right to get the valid bytes in the lower part of the register. - */ - sub %g6, %g1, %g7 ! get rid of how many bytes? - sllx %g7, 3, %g7 ! calculate number of bits to shift - srlx %g3, %g7, %g3 ! shift data - mov %g1, %g6 - - -calc_offset_bytes: - /* - * %g3 holds the data to write, with the valid bytes in the - * least significant bytes of the register - * - * %g6 holds the number of valid bytes - * - * The maximum number of bytes to write is the lesser of the - * number of valid bytes (%g6) and the number of bytes that - * can be written atomicly at this offset. - */ - - - and %g5, 1, %g7 ! offset is 1 byte aligned - cmp %g7, 1 - be,a,pn %xcc, calc_least_bytes ! can only write 1 byte - nop - - and %g5, 0x2, %g7 ! offset is 2 byte aligned - cmp %g7, 0x2 - be,a,pn %xcc, calc_least_bytes ! can only write 2 bytes - nop - - and %g5, 0x4, %g7 ! offset 4 byte aligned - cmp %g7, 0x4 - be,a,pn %xcc, calc_least_bytes ! can only write 4 bytes - nop - - set 8, %g7 ! offset is 8 byte aligned - -calc_least_bytes: - - /* - * %g6 holds the number of valid bytes - * %g7 holds the max atomic write bytes - * - * save the lesser of %g6 and %g7 in %g7 - */ - cmp %g7, %g6 - bleu,a,pn %xcc, calc_write_bytes ! %g7 holds correct value - nop - - mov %g6, %g7 - -calc_write_bytes: - - /* - * %g3 holds the data to write, with the valid bytes in the - * least significant bytes of the register - * - * %g6 holds the number of valid bytes - * - * %g7 holds max number of bytes to write - */ - - cmp %g7, 1 ! can only write 1 byte - be,a %xcc, write_one - sub %g6, 1, %g6 ! calculate # of excess bytes - - cmp %g7, 3 - bleu,a,pn %xcc, write_two ! can only write 2 bytes - sub %g6, 2, %g6 ! calculate # of excess bytes - - cmp %g7, 7 - bleu,a,pn %xcc, write_four ! can only write 4 bytes - sub %g6, 4, %g6 ! calculate # of excess bytes - - ba,a write_eight ! can write all 8 bytes - nop - - -write_one: /* write 1 byte */ - - /* - * %g6 hold number of excess bytes (shift right to get rid of them) - */ - sllx %g6, 3, %g6 ! how many bits is that? - srlx %g3, %g6, %g3 - - rdpr %pstate, %g6 - andn %g6, PSTATE_IE | PSTATE_AM, %g7 - wrpr %g7, 0, %pstate - stba %g3, [%g5]ASI_MEM ! store 1 byte - wrpr %g0, %g6, %pstate ! restore earlier pstate register value - sub %g1, 1, %g1 ! decrement bytes left to write - add %g2, 1, %g2 ! increment putdata offset - add %g5, 1, %g5 ! increment address to write to - ba check_complete - nop - - -write_two: /* write 2 bytes */ - - /* - * %g6 hold number of excess bytes (shift right to get rid of them) - */ - sllx %g6, 3, %g6 ! how many bits is that? - srlx %g3, %g6, %g3 - - rdpr %pstate, %g6 - andn %g6, PSTATE_IE | PSTATE_AM, %g7 - wrpr %g7, 0, %pstate - stha %g3, [%g5]ASI_MEM ! store 2 bytes - wrpr %g0, %g6, %pstate ! restore earlier pstate register value - sub %g1, 2, %g1 ! decrement bytes left to write - add %g2, 2, %g2 ! increment putdata offset - add %g5, 2, %g5 ! increment address to write to - ba check_complete - nop - - -write_four: /* write 4 bytes */ - - /* - * %g6 hold number of excess bytes (shift right to get rid of them) - */ - sllx %g6, 3, %g6 ! how many bits is that? - srlx %g3, %g6, %g3 - - rdpr %pstate, %g6 - andn %g6, PSTATE_IE | PSTATE_AM, %g7 - wrpr %g7, 0, %pstate - sta %g3, [%g5]ASI_MEM ! store 4 bytes - wrpr %g0, %g6, %pstate ! restore earlier pstate register value - sub %g1, 4, %g1 ! decrement bytes left to write - add %g2, 4, %g2 ! increment putdata offset - add %g5, 4, %g5 ! increment address to write to - ba check_complete - nop - - -write_eight: /* write 8 bytes */ - - rdpr %pstate, %g6 - andn %g6, PSTATE_IE | PSTATE_AM, %g7 - wrpr %g7, 0, %pstate - stxa %g3, [%g5]ASI_MEM ! store 8 bytes - wrpr %g0, %g6, %pstate ! restore earlier pstate register value - sub %g1, 8, %g1 ! decrement bytes left to write - add %g2, 8, %g2 ! increment putdata offset - add %g5, 8, %g5 ! increment address to write to - ba check_complete - nop - - -check_complete: - /* - * If no bytes left to write, finished small put interrupt handling. - * Skip to cleanup. - */ - cmp %g0, %g1 ! any bytes left? - be,a,pn %xcc, smallput_done ! none left, branch to cleanup - nop - - /* - * Determine whether there are any bytes left on the current page. - * If not, get the next page from the pfn_list, and loop. - */ - sllx %g5, (64 - MMU_PAGESHIFT), %g7 ! clean out upper bits - bnz %xcc, 6b ! more bytes left on this page, loop - nop - - - add %g4, 8, %g4 ! move to next entry in pfn_list - ldx [%g4], %g5 ! get the pfn - cmp %g5, PFN_INVALID ! is pfn invalid? - be,a,pn %xcc, smallput_done ! yes; toss rest of packet - nop - - sllx %g5, MMU_PAGESHIFT, %g5 ! turn it into a physical address - ba 6b ! loop - nop - -smallput_done: - membar #Sync ! flush write cache - ba 5f ! branch to cleanup - sub %g0, 1, %g1 ! dmv_finish_intr: no softint - - - /* - * Handle recvq messages - */ -1: - ldx [%g3], %g4 ! get packet_ring_info - set 1, %g5 ! turn on lock bit - sllx %g5, 48, %g5 - or %g4, %g5, %g5 - casxa [%g3]ASI_N, %g4, %g5 - cmp %g4, %g5 - bne,pn %xcc, 1b - nop - ! %g5 has the current packet info - ! The bits of packet info have the following structure - ! 48-63 lock - ! 32-47 head - ! 16-31 tail - ! 0 -15 size - sllx %g5, 16, %g4 - srlx %g4, 48, %g4 ! %g4 has the head pointer - - ldx [%g6 + PACKET_RING], %g3 - mulx %g4, WRSM_INTR_PACKET_SIZE, %g7 - add %g3, %g7, %g3 - - ! %g2 still has IRDR_0 - ! %g3 is a pointer to the next available packet ring - ! %g4 still has packet_ring_head which we will need later - ! %g5 has the packet_info data - ! %g6 has pointer to the recvq struct - ! - ! Now store the payload data into the packet - stx %g2, [%g3] - mov IRDR_1, %g7 - ldxa [%g7]ASI_INTR_RECEIVE, %g7 - stx %g7, [%g3 + 8] - mov IRDR_2, %g7 - ldxa [%g7]ASI_INTR_RECEIVE, %g7 - stx %g7, [%g3 + 16] - mov IRDR_3, %g7 - ldxa [%g7]ASI_INTR_RECEIVE, %g7 - stx %g7, [%g3 + 24] - mov IRDR_4, %g7 - ldxa [%g7]ASI_INTR_RECEIVE, %g7 - stx %g7, [%g3 + 32] - mov IRDR_5, %g7 - ldxa [%g7]ASI_INTR_RECEIVE, %g7 - stx %g7, [%g3 + 40] - mov IRDR_6, %g7 - ldxa [%g7]ASI_INTR_RECEIVE, %g7 - stx %g7, [%g3 + 48] - mov IRDR_7, %g7 - ldxa [%g7]ASI_INTR_RECEIVE, %g7 - stx %g7, [%g3 + 56] - - ! %g2 and %g3 are now available - - sllx %g5, 32, %g3 - srlx %g3, 48, %g3 ! %g3 has the tail pointer - sllx %g5, 48, %g1 - srlx %g1, 48, %g1 ! %g1 has the ring size - - ! g2, g5 and g7 available - - /* - * NOTE: num_items does not include the interrupt serviced - * g4 (head) was not yet incremented - */ - lduw [%g6 + HIGH_WATER_MARK], %g2 ! load the HWM in g2 (uint32) - subcc %g4, %g3, %g5 ! g5 = head - tail (num_items) - bl,a 6f ! if (head < tail) - add %g1, %g5, %g5 ! g5 = size + (head - tail) - -6: - inc %g5 ! account for this interrupt - cmp %g5, %g2 ! num_items ? high_water_mark - bl 8f ! num_items < high_water_mark - nop - - /* num_items >= high_water_mark */ - ldx [%g6 + HIGH_WATER_COUNT], %g2 - inc %g2 - stx %g2, [%g6 + HIGH_WATER_COUNT] - set WRSM_MAX_WCIS, %g2 - -9: brz,pn %g2, 8f ! while (i > 0) { - dec %g2 ! %g2 = i-- : index into wci array - - ldx [%g6 + SRAM_PADDR], %g5 ! beginning of wci sram - sllx %g2, 3, %g7 ! g7 = g2 * sizeof(void *) - add %g5, %g7, %g5 ! address of i-th wci - ldx [%g5], %g5 ! load the address of i-th sram - brz,a %g5, 9b ! if (%g5 == NULL) break ; - nop - - lduw [%g6 + CMMU_INDEX], %g7 ! offset to correct cmmu (uint32) - sllx %g7, 6, %g7 ! %g7 = %g7 * sizeof(CMMU entry) - add %g5, %g7, %g5 ! get the address - set WRSM_CMMU_0_DISABLE, %g7 ! bit 2 and 26 (error + valid) - ! (set handles 32 bits) - stxa %g7, [%g5]ASI_IO ! write to the cmmu. - ba 9b ! } - nop - - -8: - mov %g0, %g7 - cmp %g3, %g4 ! compare head and tail - move %xcc, RING_EMPTY, %g7 - - ! Increment the packet_ring_head - mov %g4, %g2 ! save head in case ring full - inc %g4 - cmp %g4, %g1 ! %g1 = ring size, %g4 = head - movge %icc, %g0, %g4 ! if head >= size then head = 0 - cmp %g3, %g4 ! if head==tail then the ring is full - bne %xcc, 1f - nop - mov %g2, %g4 ! restore original head - -#ifdef DEBUG - set wrsm_dropped_intr, %g2 - ldx [%g2], %g5 - inc %g5 - stx %g5, [%g2] -#endif /* DEBUG */ - mov RING_FULL, %g7 - -1: - ! Rebuild packet_ring_info in %g5 - mov %g1, %g5 ! size - sllx %g3, 16, %g3 - or %g5, %g3, %g5 ! tail - sllx %g4, 32, %g4 - or %g5, %g4, %g5 ! head - stx %g5, [%g6 + PACKET_RING_INFO] ! release lock - -#ifdef DEBUG - set wrsm_trap_ring_info, %g2 - stx %g5, [%g2] -#endif - - ldx [%g6 + DRAINER], %g3 ! g3 = recvq->drainer - - cmp %g7, RING_EMPTY ! if ring is non-empty - bne,pn %xcc, 5f ! exit without a softint - sub %g0, 1, %g1 - - /* - * If recvq->drainer_next != NULL then this recvq is - * already on a service list, so don't queue it again - */ - ldx [%g6 + DRAINER_NEXT], %g4 - brnz,pn %g4, 4f - nop - -2: - ! Insert the recvq into the drainer's pending service - ! list (PSL) - add %g3, DRAINER_PSL, %g2 ! g2 = &drainer->psl - ldx [%g2], %g4 ! g4 = drainer->psl - -3: - mov %g6, %g5 ! g5 = revcq - stx %g4, [%g6 + DRAINER_NEXT] ! recvq->dranr_next=dranr->psl - mov %g4, %g1 ! %g1 has old value of psl - - ! casx does the following as an atomic: - ! if (g4 == *g2) { /* If g4 equals what's at g2... */ - ! swap *g2, g5; - ! } else { /* Else... */ - ! g5 = *g2; /* Place what's currently in g2 into g5 */ - ! } - ! Regardless of the outcome, g5 will contain what was at g2 when - ! the operation began. The only way to see if the store took place - ! is to see if the data at g2 hasn't changed. In other words, the - ! store took place iff g4==g5 after the casx instruction. - casxa [%g2]ASI_N, %g4, %g5 ! drainer->psl = recvq - - cmp %g4, %g5 ! if psl hasn't changed... - be %xcc, 4f ! then break out of loop - nop - mov %g5, %g4 ! else g4 = new drainer->psl - - ba 3b ! loop - nop -4: - ! if drainer->psl was PSL_IDLE before the insert, then we - ! generate a softint, otherwise we don't - cmp %g1, WRSM_INTR_PSL_IDLE - bne,pn %xcc, 5f - sub %g0, 1, %g1 - -#ifdef DEBUG - ! Keep track of the number of softints triggered - set wrsm_trap_softint_count, %g5 - ldx [%g5], %g2 - inc %g2 - stx %g2, [%g5] -#endif - - ! Get the softint inum from the drainer structure - ld [%g3 + DRAINER_INUM], %g1 - -5: - set dmv_finish_intr, %g5 - jmp %g5 - nop - -#ifdef WRSM_STORE_TRAP_DATA -30: - set wrsm_trap_data, %g7 - stx %g3, [%g7+0] - stx %g4, [%g7+8] - stx %g5, [%g7+16] - stx %g6, [%g7+24] - - ! If no secondary interrupt, return -1 - set -1, %g1 - sra %g1, 0, %g1 - ! Return - set dmv_finish_intr, %g5 - jmp %g5 - nop -#endif - - SET_SIZE(wrsm_tl1_handler) - -#endif /* !lint */ diff --git a/usr/src/uts/sun4u/io/wrsmd.c b/usr/src/uts/sun4u/io/wrsmd.c deleted file mode 100644 index 47a3dfa532..0000000000 --- a/usr/src/uts/sun4u/io/wrsmd.c +++ /dev/null @@ -1,7922 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * DLPI driver for RSMPI - * - * Based on scid.c 1.39 98/10/28 - from the SCI group/Sun Cluster code base. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/errno.h> -#include <sys/debug.h> -#include <sys/stropts.h> -#include <sys/stream.h> -#include <sys/strlog.h> -#include <sys/cmn_err.h> -#include <sys/kmem.h> -#include <sys/conf.h> -#include <sys/ksynch.h> -#include <sys/stat.h> -#include <sys/dlpi.h> -#include <sys/modctl.h> -#include <sys/kstat.h> -#include <sys/note.h> -#include <sys/disp.h> -#include <sys/callb.h> - -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/strsun.h> - -#include <sys/rsm/rsm_common.h> -#include <sys/rsm/rsmpi.h> - - -#include <sys/tnf_probe.h> - -#ifdef DEBUG -#define DEBUG_WRSMD 1 -#define DEBUG_PRINTF 1 -#define DEBUG_LOG 1 -#endif - - -#include <sys/wrsmd.h> /* This driver's data structures */ -#define WRSM_NAME "wrsm" - -/* - * Lock hierarchy: - * - * ssp->ss_lock - * wrsmdp->wrsmd_lock - * wrsmddevlock - * - * rd->rd_lock - * rd->rd_xmit_lock - * rd->rd_net_lock - * - * wrsmd->wrsmd_dest_lock - * wrsmd->wrsmd_runq_lock - * - * wrsmdp->wrsmd_ipq_rwlock - * wrsmdp->event_lock; - * wrsmdstruplock - * rd->rd_nlb_lock -- currently never taken while another lock is held - * wrsmdattlock - * wrsmddbglock - */ - - -/* - * Defining DEBUG_WRSMD on the compile line (-DDEBUG_WRSMD) will compile - * debugging code into the driver. Whether any debug output actually gets - * printed depends on the value of wrsmddbg, which determines the class of - * messages that the user is interested in, and wrsmddbgmode, which - * determines how the user wants the messages to be produced. - * - * See the #defines for D1(), D2(), etc. below for which bits in wrsmddbg - * cause which messages to get printed. - * - * There are two ways debug output may be produced. The code to produce - * these various types is also conditionally compiled, using the following - * symbols: - * - * DEBUG_LOG If this is defined, support for an internal circular - * buffer of log entries is compiled in. The buffer may - * be dumped out by using the wrsmddumplog utility. - * This is currently the preferred trace method. - * - * DEBUG_PRINTF If this is defined, support for kernel debug printfs - * is compiled in. In many cases, this is not very - * useful since the sheer volume of tracing information - * overwhelms the console driver. In particular, if a - * problem causes a panic, you will very often not see - * the last few debugging messages produced before the - * panic, which are probably the ones you really wanted - * to see. - * - * The various types of output are controlled by bits in wrsmddbgmode, as - * follows. Multiple types of output may be used at once, if desired. - * - * (wrsmddbgmode & 1) Use debugging log. - * (wrsmddbgmode & 2) Use kernel printfs. - */ - -#ifndef lint - -#ifdef DEBUG_WRSMD - -int wrsmddbg = 0x100; -int wrsmddbgmode = 0x3; -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmddbg)) - -/* Always print -- at least for now */ -#define D0 wrsmddebug - - -/* wrsmd function enter/exit, parameters, return values. */ -#define D1 \ - _NOTE(CONSTCOND) \ - if (wrsmddbg & 0x01) \ - wrsmddebug - -/* Additional function debugging. */ -#define D2 \ - _NOTE(CONSTCOND) \ - if (wrsmddbg & 0x02) \ - wrsmddebug - -/* rsmpi interface routine enter/exit, parameters, return */ -#define D4 \ - _NOTE(CONSTCOND) \ - if (wrsmddbg & 0x08) \ - wrsmddebug - -/* Latency timing output. */ -#define D5 \ - _NOTE(CONSTCOND) \ - if (wrsmddbg & 0x10) \ - wrsmddebug - -/* Excessive debugging output */ -#define D6 \ - _NOTE(CONSTCOND) \ - if (wrsmddbg & 0x20) \ - wrsmddebug - -/* outgoing packet tossed due to queue overflow */ -#define DERR \ - _NOTE(CONSTCOND) \ - if (wrsmddbg & 0x100) \ - wrsmddebug - -/* Dumps of incoming packets */ -#define D3D \ - _NOTE(CONSTCOND) \ - if (wrsmddbg & 0x04) wrsmdump - -#else /* DEBUG_WRSMD */ - -#define D0 if (0) printf -#define D1 if (0) printf -#define D2 if (0) printf -#define D4 if (0) printf -#define D5 if (0) printf -#define D6 if (0) printf -#define DERR if (0) printf -#define D3D(a, b) - -#endif /* DEBUG_WRSMD */ - -#else /* lint */ - -#ifdef DEBUG_WRSMD -int wrsmddbg; -int wrsmddbgmode; -#endif - -#define D0 printf -#define D1 printf -#define D2 printf -#define D4 printf -#define D5 printf -#define D6 printf -#define DERR printf -#define D3D wrsmdump -#endif /* lint */ - - - -/* - * Function prototypes. - */ - -static int wrsmdprobe(dev_info_t *); -static int wrsmdattach(dev_info_t *, ddi_attach_cmd_t); -static int wrsmddetach(dev_info_t *, ddi_detach_cmd_t); -static int wrsmdopen(queue_t *, dev_t *, int, int, cred_t *); -static int wrsmdclose(queue_t *, int, cred_t *); -static int wrsmdwput(queue_t *, mblk_t *); -static int wrsmdwsrv(queue_t *); -static void wrsmddumpqueue(wrsmd_t *, wrsmd_dest_t *); -static int wrsmdcrexfer(wrsmd_t *, wrsmd_dest_t *); -static int wrsmdsconn(wrsmd_t *, wrsmd_dest_t *, int); -static int wrsmdconnxfer(wrsmd_t *, wrsmd_dest_t *); -static int wrsmdsack(wrsmd_t *, wrsmd_dest_t *); -static int wrsmdsaccept(wrsmd_t *wrsmdp, wrsmd_dest_t *rd); -static void wrsmdproto(queue_t *, mblk_t *); -static void wrsmdioctl(queue_t *, mblk_t *); -static int wrsmdioctlimmediate(queue_t *, mblk_t *); -static void wrsmd_dl_ioc_hdr_info(queue_t *, mblk_t *); -static void wrsmdareq(queue_t *, mblk_t *); -static void wrsmddreq(queue_t *, mblk_t *); -static void wrsmddodetach(wrsmdstr_t *); -static void wrsmdbreq(queue_t *, mblk_t *); -static void wrsmdubreq(queue_t *, mblk_t *); -static void wrsmdireq(queue_t *, mblk_t *); -static void wrsmdponreq(queue_t *, mblk_t *); -static void wrsmdpoffreq(queue_t *, mblk_t *); -static void wrsmdpareq(queue_t *, mblk_t *); -static void wrsmdudreq(queue_t *, mblk_t *); -static mblk_t *wrsmdstrip(mblk_t *, dl_rsm_addr_t *, ushort_t *); -static void wrsmdstart(wrsmd_t *, mblk_t *, dl_rsm_addr_t, ushort_t, int); -static wrsmd_dest_t *wrsmdmkdest(wrsmd_t *, rsm_addr_t); -static void wrsmdsetupfqewait(wrsmd_t *, wrsmd_dest_t *); -static void wrsmdxfer(wrsmd_t *, wrsmd_dest_t *); -static void wrsmdfqetmo(void *); -static void wrsmdsconntmo(void *); -static void wrsmdacktmo(void *); -static void wrsmdaccepttmo(void * arg); -static void wrsmdfreedestevt(void *); -static void wrsmdteardown_tmo(void * arg); - -static void wrsmd_event_thread(void *); -static void wrsmd_process_event(wrsmd_t *); -static void wrsmd_add_event(wrsmd_t *, int, void *); - -static void wrsmdmsghdlr_req_connect(wrsmd_dest_t *, wrsmd_msg_t *); -static void wrsmdmsghdlr_con_accept(wrsmd_dest_t *, wrsmd_msg_t *); -static void wrsmdmsghdlr_syncdqe(wrsmd_dest_t *, wrsmd_msg_t *); -static void wrsmdmsghdlr_syncdqe_evt(wrsmd_dest_t *rd); -static void wrsmdmsghdlr_default(wrsmd_dest_t *, wrsmd_msg_t *); - -static int wrsmdisstate(wrsmd_dest_t *, int); -static int wrsmdgetstate(wrsmd_dest_t *); -static void wrsmdsetstate(wrsmd_dest_t *, int); -static void wrsmdsetstate_nosrv(wrsmd_dest_t *, int); -static int wrsmdmovestate(wrsmd_dest_t *, int, int newstate); -static int wrsmdread(wrsmd_dest_t *, int, int, int, ushort_t sap); -static void wrsmdsendup(wrsmd_t *, mblk_t *, dl_rsm_addr_t, dl_rsm_addr_t, - ushort_t); -static void wrsmdpromsendup(wrsmd_t *, mblk_t *, dl_rsm_addr_t, - dl_rsm_addr_t, ushort_t); -static mblk_t *wrsmdaddudind(wrsmd_t *, mblk_t *, dl_rsm_addr_t, - dl_rsm_addr_t, ushort_t); -static mblk_t *wrsmdaddhdr(wrsmd_t *, mblk_t *, dl_rsm_addr_t, dl_rsm_addr_t, - ushort_t); -static int wrsmdinit(wrsmd_t *); -static int wrsmduninit(wrsmd_t *wrsmdp); -static boolean_t wrsmddest_refcnt_0(wrsmd_dest_t *); -static void wrsmdfreedest(wrsmd_t *, rsm_addr_t); - -/* LINTED: E_STATIC_FUNC_CALLD_NOT_DEFINED */ -static void wrsmddebug(const char *, ...); -static void wrsmderror(dev_info_t *, const char *, ...); -static void wrsmdkstatinit(wrsmd_t *); -static void wrsmdkstatremove(wrsmd_t *wrsmdp); -static void wrsmdgetparam(dev_info_t *, wrsmd_t *); -static void wrsmdtakedown(wrsmd_t *, int); -static void wrsmdsetipq(wrsmd_t *); - -static void wrsmdfreebuf(wrsmdbuf_t *); -static void wrsmdputfqe(wrsmd_dest_t *, int); -static void wrsmdsyncfqe(wrsmd_dest_t *); -static void wrsmdputdqe(wrsmd_dest_t *, int, int, uint_t, ushort_t sap); -static void wrsmdsyncdqe(wrsmd_dest_t *); -static int wrsmdavailfqe(wrsmd_dest_t *); -static int wrsmdgetfqe(wrsmd_dest_t *, int *); -static void wrsmdungetfqe(wrsmd_dest_t *, int); -static int wrsmdgetdqe(wrsmd_dest_t *, int *, int *, int *, ushort_t *); -static int wrsmdsendmsg(wrsmd_dest_t *, uint8_t, wrsmd_msg_t *); -/* LINTED: E_STATIC_FUNC_CALLD_NOT_DEFINED */ -static void wrsmdump(uchar_t *, int); - -static rsm_intr_hand_ret_t wrsmd_rsm_intr_handler(rsm_controller_object_t *, - rsm_intr_q_op_t, rsm_addr_t, void *, size_t, rsm_intr_hand_arg_t); - - -#ifdef _DDICT -#define ENOSR 63 /* out of streams resources */ -#endif - - -/* - * The wrsmd driver implements a reference count scheme for destination - * structures. The idea behind the scheme is to prevent the driver from - * deleting a destination structure while it is being used elsewhere, for - * example in a message handling routine. (Failures to protect against - * this occurrence have led to a fair array of baffling bugs over the - * lifetime of the driver.) - * - * The following set of macros implement the reference count scheme, - * translation from RSM address to destination structure, and removal of - * destinations from the run queue. All must be intertwined, since - * otherwise it would be possible to get a destination pointer from an RSM - * address , or from the run queue, but have some other part of the driver - * delete the destination before you could bump its reference count. The - * incorporation of reference count code in FINDDEST/MAKEDEST/GETRUNQ - * solves this race condition. - */ - -/* - * FINDDEST attempts to find the destination with RSM address rsm_addr. If the - * destination exists, rd is set to point to it. If the destination exists, - * isdel is set to indicate whether the destination is currently being deleted - * (nonzero implies a delete is in progress). If the destination exists and - * is not being deleted, its reference count is increased by one. - */ -#define FINDDEST(rd, isdel, wrsmd, rsm_addr) { \ - mutex_enter(&wrsmd->wrsmd_dest_lock); \ - (rd) = (((rsm_addr) >= RSM_MAX_DESTADDR) ? NULL : \ - (wrsmd)->wrsmd_desttbl[(rsm_addr)]); \ - if (rd) \ - if (((isdel) = (rd)->rd_dstate) == 0) { \ - (rd)->rd_refcnt++; \ - D6("FINDDEST ctlr %d addr %ld refcnt++ is %d\n", \ - wrsmd->wrsmd_ctlr_id, rsm_addr, \ - (rd)->rd_refcnt); \ - } \ - mutex_exit(&(wrsmd)->wrsmd_dest_lock); \ - _NOTE(CONSTCOND); \ -} - - -/* - * MAKEDEST attempts to find the destination with RSM address rsm_addr. If the - * destination exists, rd and isdel are set as in the description of FINDDEST, - * above. If the destination does not exist, a new destination structure is - * allocated and installed, rd is set to point to it, and isnew is set to 1. - */ -#define MAKEDEST(rd, isdel, isnew, wrsmd, rsm_addr) { \ - mutex_enter(&(wrsmd)->wrsmd_dest_lock); \ - (rd) = ((wrsmd)->wrsmd_desttbl[(rsm_addr)]); \ - if (!(rd)) { \ - (rd) = wrsmdmkdest((wrsmd), (rsm_addr)); \ - (isnew) = 1; \ - } \ - if (rd) \ - if (((isdel) = (rd)->rd_dstate) == 0) { \ - (rd)->rd_refcnt++; \ - D6("MAKEDEST ctlr %d addr %ld refcnt++ is %d\n", \ - wrsmd->wrsmd_ctlr_id, (uint64_t)rsm_addr, \ - (rd)->rd_refcnt); \ - } \ - mutex_exit(&(wrsmd)->wrsmd_dest_lock); \ - _NOTE(CONSTCOND); \ -} - - -/* - * GETRUNQ attempts to return the destination which is at the head of wrsmd's - * run queue. If the run queue is non-empty, the head of the queue is removed, - * and rd is set to point to it; otherwise, rd is set to NULL. If rd is - * nonzero, isdel is set to 1 if the destination pointed to by rd is being - * deleted, or to 0 otherwise. Finally, if rd is nonzero, and isdel is zero, - * then rd's reference count is increased by one. - */ -#define GETRUNQ(rd, isdel, wrsmd) { \ - mutex_enter(&(wrsmd)->wrsmd_dest_lock); \ - mutex_enter(&(wrsmd)->wrsmd_runq_lock); \ - rd = (wrsmd)->wrsmd_runq; \ - if (rd) { \ - (wrsmd)->wrsmd_runq = rd->rd_next; \ - if (((isdel) = (rd)->rd_dstate) == 0) { \ - (rd)->rd_refcnt++; \ - D6("GETRUNQ ctlr %d addr %ld refcnt++ is %d\n", \ - wrsmd->wrsmd_ctlr_id, \ - (rd)->rd_rsm_addr, \ - (rd)->rd_refcnt); \ - } \ - } \ - mutex_exit(&(wrsmd)->wrsmd_runq_lock); \ - mutex_exit(&(wrsmd)->wrsmd_dest_lock); \ - _NOTE(CONSTCOND); \ -} - - -/* - * REFDEST checks to see if the destination pointed to by rd is currently being - * deleted. If so, isdel is set to a nonzero value; otherwise, it is set to - * zero, and the destination's reference count is incremented. - */ -#define REFDEST(rd, isdel) { \ - mutex_enter(&(rd)->rd_wrsmdp->wrsmd_dest_lock); \ - if (((isdel) = (rd)->rd_dstate) == 0) { \ - (rd)->rd_refcnt++; \ - D6("REFDEST ctlr %d addr %ld refcnt++ is %d\n", \ - wrsmd->wrsmd_ctlr_id, rsm_addr, \ - (rd)->rd_refcnt); \ - } \ - mutex_exit(&(rd)->rd_wrsmdp->wrsmd_dest_lock); \ - _NOTE(CONSTCOND); \ -} - - -/* - * UNREFDEST decrements the reference count of the destination pointed to by - * rd. If the reference count becomes zero, we start the deletion process for - * the destination. - */ -#define UNREFDEST(rd) { \ - mutex_enter(&(rd)->rd_wrsmdp->wrsmd_dest_lock); \ - D6("UNREFDEST ctlr %d addr %ld refcnt-- is %d\n", \ - (rd)->rd_wrsmdp->wrsmd_ctlr_id, (rd)->rd_rsm_addr, \ - (rd)->rd_refcnt - 1); \ - if (--(rd)->rd_refcnt <= 0) { \ - mutex_exit(&(rd)->rd_wrsmdp->wrsmd_dest_lock); \ - if (wrsmddest_refcnt_0(rd)) { rd = NULL; } \ - } else \ - mutex_exit(&(rd)->rd_wrsmdp->wrsmd_dest_lock); \ - _NOTE(CONSTCOND); \ -} - - - -/* Local Static def's */ - -/* - * Lock and variable to allow attach routines to initialize global mutexes - */ - -static kmutex_t wrsmdattlock; /* Protects wrsmddbginit */ - -/* - * Linked list of "wrsmd" structures - one per physical device. - */ -static wrsmd_t *wrsmddev = NULL; /* Head of list */ -static kmutex_t wrsmddevlock; /* Protects list contents */ -static uint_t wrsmdminbuflen = 0; /* Smallest buf length we've seen; updated */ - /* when we add a device to the list */ -_NOTE(MUTEX_PROTECTS_DATA(wrsmddevlock, - wrsmddev wrsmdminbuflen wrsmd::wrsmd_nextp)) - -/* - * Linked list of active (inuse) driver Streams. - */ -static wrsmdstr_t *wrsmdstrup = NULL; /* Head of list */ -static krwlock_t wrsmdstruplock; /* Protects list of streams */ -_NOTE(RWLOCK_PROTECTS_DATA(wrsmdstruplock, wrsmdstrup wrsmdstr::ss_nextp)) - -/* - * Our DL_INFO_ACK template. - */ -static dl_info_ack_t wrsmdinfoack = { - DL_INFO_ACK, /* dl_primitive */ - MEDIUM_MTU, /* dl_max_sdu */ - 0, /* dl_min_sdu */ - WRSMD_DEVICE_ADDRL, /* dl_addr_length */ - DL_ETHER, /* dl_mac_type */ - 0, /* dl_reserved */ - 0, /* dl_current_state */ - -2, /* dl_sap_length - 2 bytes (short), */ - /* second component in DLSAP address */ - DL_CLDLS, /* dl_service_mode */ - 0, /* dl_qos_length */ - 0, /* dl_qos_offset */ - 0, /* dl_range_length */ - 0, /* dl_range_offset */ - DL_STYLE2, /* dl_provider_style */ - sizeof (dl_info_ack_t), /* dl_addr_offset */ - DL_VERSION_2, /* dl_version */ - WRSMD_BCAST_ADDRL, /* dl_brdcst_addr_length */ - sizeof (dl_info_ack_t) + WRSMD_DEVICE_ADDRL, /* dl_brdcst_addr_offset */ - 0 /* dl_growth */ -}; - -/* - * use standard ethernet broadcast address - all 1's - */ -static struct ether_addr wrsmdbcastaddr = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff -}; - -static struct ether_addr wrsmdbadaddr = { - 0xB, 0xAD, 0xB, 0xAD, 0xB, 0xAD -}; - - -_NOTE(READ_ONLY_DATA(wrsmdinfoack)) -_NOTE(READ_ONLY_DATA(wrsmdbcastaddr)) - -static void *wrsmd_state; /* opaque handle for soft state structs */ - - -/* - * **************************************************************** - * * - * B E G I N BASIC MODULE BOILERPLATE * - * * - * **************************************************************** - */ - -/* Standard Streams declarations */ - -static struct module_info wrsmdminfo = { - WRSMDIDNUM, /* mi_idnum */ - WRSMDNAME, /* mi_idname */ - WRSMDMINPSZ, /* mi_minpsz */ - WRSMDMAXPSZ, /* mi_minpsz */ - WRSMDHIWAT, /* mi_hiwat */ - WRSMDLOWAT, /* mi_lowat */ -}; - -static struct qinit wrsmdrinit = { - 0, /* qi_putp */ - 0, /* qi_srvp */ - wrsmdopen, /* qi_qopen */ - wrsmdclose, /* qi_qclose */ - 0, /* qi_qadmin */ - &wrsmdminfo, /* qi_minfo */ - NULL, /* qi_mstat */ -}; - -static struct qinit wrsmdwinit = { - wrsmdwput, /* qi_putp */ - wrsmdwsrv, /* qi_srvp */ - 0, /* qi_qopen */ - 0, /* qi_qclose */ - 0, /* qi_qadmin */ - &wrsmdminfo, /* qi_minfo */ - NULL, /* qi_mstat */ -}; - -static struct streamtab wrsmd_info = { - &wrsmdrinit, /* st_rdinit */ - &wrsmdwinit, /* st_wrinit */ - NULL, /* st_muxrinit */ - NULL, /* st_muxwrinit */ -}; - - -/* Module Loading/Unloading and Autoconfiguration declarations */ - -/* - * cb_ops contains the driver entry points and is roughly equivalent - * to the cdevsw and bdevsw structures in previous releases. - * - * dev_ops contains, in addition to the pointer to cb_ops, the routines - * that support loading and unloading our driver. - * - * Unsupported entry points are set to nodev, except for the poll - * routine , which is set to nochpoll(), a routine that returns ENXIO. - */ - -static struct cb_ops wrsmd_cb_ops = { - nodev, /* cb_open */ - nodev, /* cb_close */ - nodev, /* cb_strategy */ - nodev, /* cb_print */ - nodev, /* cb_dump */ - nodev, /* cb_read */ - nodev, /* cb_write */ - nodev, /* cb_ioctl */ - nodev, /* cb_devmap */ - nodev, /* cb_mmap */ - nodev, /* cb_segmap */ - nochpoll, /* cb_chpoll */ - ddi_prop_op, /* cb_prop_op */ - &wrsmd_info, /* cb_stream */ - D_MP, /* cb_flag */ -}; - -static struct dev_ops wrsmd_ops = { - DEVO_REV, /* devo_rev */ - 0, /* devo_refcnt */ - ddi_no_info, /* devo_getinfo */ - nulldev, /* devo_identify */ - wrsmdprobe, /* devo_probe */ - wrsmdattach, /* devo_attach */ - wrsmddetach, /* devo_detach */ - nodev, /* devo_reset */ - &wrsmd_cb_ops, /* devo_cb_ops */ - (struct bus_ops *)NULL /* devo_bus_ops */ -}; - - -/* - * Module linkage information for the kernel. - */ -static struct modldrv modldrv = { - &mod_driverops, /* Type of module. This one is a driver */ - "RSMPI DLPI %I% %E%", /* Description */ - &wrsmd_ops, /* driver ops */ -}; - -static struct modlinkage modlinkage = { - MODREV_1, &modldrv, NULL -}; - -/* - * Module Loading and Installation Routines. - */ - -/* - * Module Installation - * Install the driver, initialize soft state system, initialize wrsmdattlock - */ - -int -_init(void) -{ - int status; - - _NOTE(COMPETING_THREADS_NOW) - _NOTE(NO_COMPETING_THREADS_NOW) - status = ddi_soft_state_init(&wrsmd_state, sizeof (wrsmd_t), 1); - if (status != 0) { - _NOTE(CONSTCOND) - D1("wrsmd:_init - soft_state_init failed: 0x%x\n", status); - cmn_err(CE_CONT, - "wrsmd:_init - soft_state_init failed: 0x%x\n", status); - return (status); - } - - /* initialize global locks here */ - - mutex_init(&wrsmdattlock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&wrsmddevlock, NULL, MUTEX_DRIVER, NULL); - rw_init(&wrsmdstruplock, NULL, RW_DRIVER, NULL); - - status = mod_install(&modlinkage); - if (status != DDI_SUCCESS) { - mutex_destroy(&wrsmdattlock); - mutex_destroy(&wrsmddevlock); - rw_destroy(&wrsmdstruplock); - } - return (status); -} - -/* - * Module Removal - */ - -int -_fini(void) -{ - int status; - - /* LINTED possibly invalid annotation name */ - _NOTE(COMPETING_THREADS_NOW) - _NOTE(NO_COMPETING_THREADS_NOW) - - if ((status = mod_remove(&modlinkage)) != 0) { - D1("wrsmd_fini - mod_remove failed: 0x%x\n", status); - return (status); - } - - ddi_soft_state_fini(&wrsmd_state); - - mutex_destroy(&wrsmdattlock); - mutex_destroy(&wrsmddevlock); - rw_destroy(&wrsmdstruplock); - - return (status); -} - -/* - * Return Module Info. - */ - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - - - -/* - * Autoconfiguration Routines - */ - - -/* - * Probe to see if device exists. - */ -static int -wrsmdprobe(dev_info_t *dip) -{ - int inst = ddi_get_instance(dip); - - D1("wrsmdprobe: dip 0x%p, inst %d", (void *)dip, inst); - - return (DDI_PROBE_SUCCESS); -} - -/* - * Attach the device, create and fill in the device-specific structure. - */ - -static int -wrsmdattach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - wrsmd_t *wrsmdp; - int instance; - int progress = 0; - - D1("wrsmdattach: dip 0x%p, cmd %d", (void *)dip, cmd); - TNF_PROBE_2(wrsmdattach_start, "RSMPI", "wrsmdattach start", - tnf_long, dip, (tnf_long_t)dip, tnf_long, command, cmd); - - if (cmd != DDI_ATTACH) { - TNF_PROBE_2(wrsmdattach_end, "RSMPI", - "wrsmdattach end; failure 'cmd != DDI_ATTACH'", - tnf_string, failure, "cmd != DDI_ATTACH", - tnf_long, cmd, DDI_FAILURE); - return (DDI_FAILURE); - } - - /* - * Allocate soft data structure - */ - - instance = ddi_get_instance(dip); - - if (ddi_soft_state_zalloc(wrsmd_state, instance) != DDI_SUCCESS) { - D1("wrsmdattach: bad state zalloc, returning DDI_FAILURE"); - TNF_PROBE_2(wrsmdattach_end, "RSMPI", - "wrsmdattach end; failure 'ddi_soft_state_zalloc'", - tnf_string, failure, "ddi_soft_state_zalloc", - tnf_long, rval, DDI_FAILURE); - return (DDI_FAILURE); - } - - wrsmdp = ddi_get_soft_state(wrsmd_state, instance); - if (wrsmdp == NULL) { - TNF_PROBE_2(wrsmdattach_end, "RSMPI", - "wrsmdattach end; failure get_soft_state", - tnf_string, failure, "get_soft_state", - tnf_long, cmd, DDI_FAILURE); - return (DDI_FAILURE); - } - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wrsmdp)) - - /* - * Stuff private info into dip. - */ - rw_init(&wrsmdp->wrsmd_ipq_rwlock, NULL, RW_DRIVER, NULL); - wrsmdp->wrsmd_dip = dip; - ddi_set_driver_private(dip, wrsmdp); - wrsmdp->wrsmd_ctlr_id = instance; - - /* - * Get device parameters from the device tree and save them in our - * per-device structure for later use. - */ - wrsmdgetparam(dip, wrsmdp); - - - /* - * Initialize mutexes for this device. - */ - mutex_init(&wrsmdp->wrsmd_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&wrsmdp->wrsmd_dest_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&wrsmdp->wrsmd_runq_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&wrsmdp->event_lock, NULL, MUTEX_DRIVER, NULL); - cv_init(&wrsmdp->event_cv, NULL, CV_DEFAULT, NULL); - cv_init(&wrsmdp->event_thread_exit_cv, NULL, CV_DEFAULT, NULL); - progress |= WRSMD_ATT_MUTEX; - - /* - * Initialize kernel statistics. - */ - wrsmdkstatinit(wrsmdp); - progress |= WRSMD_ATT_KSTAT; - - /* - * Create the filesystem device node. - */ - if (ddi_create_minor_node(dip, "wrsmd", S_IFCHR, - ddi_get_instance(dip), - DDI_PSEUDO, CLONE_DEV) != DDI_SUCCESS) { - D1("wrsmdattach: bad create_minor_node, returning " - "DDI_FAILURE"); - wrsmdtakedown(wrsmdp, progress); - TNF_PROBE_2(wrsmdattach_end, "RSMPI", - "wrsmdattach end; failure 'ddi_create_minor_node'", - tnf_string, failure, "ddi_create_minor_node", - tnf_long, rval, DDI_FAILURE); - return (DDI_FAILURE); - } - progress |= WRSMD_ATT_MINOR; - - /* - * Link this per-device structure in with the rest. - */ - mutex_enter(&wrsmddevlock); - wrsmdp->wrsmd_nextp = wrsmddev; - - /* - * Update our idea of the smallest buffer size seen so far. We do this - * because many clients do a get_info request before they've attached - * to a particular piece of hardware (ie, PPA). We need to have - * something to give them for the MTU, and giving them a value that's - * bigger than the one used by the device they eventually attach to - * causes problems. - */ - if (wrsmddev == NULL) - wrsmdminbuflen = wrsmdp->wrsmd_param.wrsmd_buffer_size; - else if (wrsmdminbuflen > wrsmdp->wrsmd_param.wrsmd_buffer_size) - wrsmdminbuflen = wrsmdp->wrsmd_param.wrsmd_buffer_size; - - wrsmddev = wrsmdp; - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*wrsmdp)) - mutex_exit(&wrsmddevlock); - progress |= WRSMD_ATT_LINKED; - - /* - * Start up event thread for this wrsmd device. - * This seems like as good a place as any... - */ - wrsmdp->stop_events = B_FALSE; - wrsmdp->events = (wrsmd_event_t *)NULL; - wrsmdp->event_thread = thread_create(NULL, 0, wrsmd_event_thread, - (void *)wrsmdp, 0, &p0, TS_RUN, maxclsyspri - 1); - progress |= WRSMD_ATT_EVT_THREAD; - - ddi_report_dev(dip); - - D1("wrsmdattach: returning DDI_SUCCESS"); - TNF_PROBE_2(wrsmdattach_end, "RSMPI", "wrsmdattach end", - tnf_string, success, "", - tnf_long, rval, DDI_SUCCESS); - return (DDI_SUCCESS); -} - -/* - * Detach - Free resources allocated in attach - */ - -/*ARGSUSED*/ -static int -wrsmddetach(dev_info_t *dip, ddi_detach_cmd_t cmd) -{ - int instance; - wrsmd_t *wrsmdp; - timeout_id_t tmoid, tmoid_orig; - - D1("wrsmddetach: dip 0x%p, cmd %d", (void *)dip, cmd); - TNF_PROBE_2(wrsmddetach_start, "RSMPI", "wrsmddetach start", - tnf_long, dip, (tnf_long_t)dip, tnf_long, command, cmd); - - if (cmd != DDI_DETACH) { - TNF_PROBE_1(wrsmddetach_end, "RSMPI", - "wrsmddetach end; failure 'cmd != DDI_DETACH'", - tnf_long, rval, DDI_FAILURE); - return (DDI_FAILURE); - } - - instance = ddi_get_instance(dip); - wrsmdp = ddi_get_soft_state(wrsmd_state, instance); - if (wrsmdp == NULL) { - TNF_PROBE_2(wrsmddetach_end, "RSMPI", - "wrsmddetach end; failure get_soft_state", - tnf_string, failure, "get_soft_state", - tnf_long, cmd, DDI_FAILURE); - return (DDI_FAILURE); - } - - - mutex_enter(&wrsmdp->wrsmd_lock); - - /* - * The teardown timeout now reschedules itself, so we - * have to go to great lengths to kill it. - */ - tmoid_orig = tmoid = wrsmdp->wrsmd_teardown_tmo_id; - - while (tmoid) { - /* - * A timeout is scheduled to teardown the - * device. Cancel, as we intend to do this now. - */ - mutex_exit(&wrsmdp->wrsmd_lock); - - (void) untimeout(tmoid); - /* - * untimeout guarantees the either the function was - * cancelled, or it has completed. If timeout was - * cancelled before the function ran, the timout id will - * not have changed. - */ - mutex_enter(&wrsmdp->wrsmd_lock); - - if (tmoid == wrsmdp->wrsmd_teardown_tmo_id) - wrsmdp->wrsmd_teardown_tmo_id = 0; - tmoid = wrsmdp->wrsmd_teardown_tmo_id; - } - - /* - * If we can't release all destination and RSMPI resources, we can't - * detach. The user will have to try later to unload the driver. - */ - mutex_exit(&wrsmdp->wrsmd_lock); - if (wrsmduninit(wrsmdp) != 0) { - TNF_PROBE_1(wrsmddetach_end, "RSMPI", - "wrsmddettach end; failure 'wrsmduninit'", - tnf_long, rval, DDI_FAILURE); - if (tmoid_orig) { - /* restart cancelled timeout */ - mutex_enter(&wrsmdp->wrsmd_lock); - wrsmdp->wrsmd_teardown_tmo_id = - timeout(wrsmdteardown_tmo, - (caddr_t)wrsmdp, - wrsmdp->wrsmd_param.wrsmd_teardown_tmo); - mutex_exit(&wrsmdp->wrsmd_lock); - } - return (DDI_FAILURE); - } - - /* - * Release all our resources. At this point, all attachment - * setup must have completed, so must all be torn down. - */ - wrsmdtakedown(wrsmdp, WRSMD_ATT_ALL); - - TNF_PROBE_0(wrsmddetach_end, "RSMPI", "wrsmddettach end"); - return (DDI_SUCCESS); -} - -/* - * Undo tasks done by wrsmdattach(), either because we're detaching or because - * attach() got partly done then failed. progress is a bitmap that tells - * us what has been done so far. - */ -static void -wrsmdtakedown( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - int progress) /* Mask of RSMPI_ATT_xxx values */ -{ - int instance; - dev_info_t *dip; - - D1("wrsmdtakedown: wrsmdp 0x%p (ctlr %d), progress 0x%x", - (void *)wrsmdp, wrsmdp->wrsmd_ctlr_id, progress); - TNF_PROBE_2(wrsmdtakedown_start, "RSMPI", "wrsmdtakedown start", - tnf_long, wrsmdp, (tnf_long_t)wrsmdp, tnf_long, progress, progress); - - ASSERT(wrsmdp); - - if (progress & WRSMD_ATT_EVT_THREAD) { - mutex_enter(&wrsmdp->event_lock); - wrsmdp->stop_events = B_TRUE; - cv_broadcast(&wrsmdp->event_cv); - cv_wait(&wrsmdp->event_thread_exit_cv, &wrsmdp->event_lock); - wrsmdp->event_thread = (kthread_t *)NULL; - mutex_exit(&wrsmdp->event_lock); - - progress &= ~WRSMD_ATT_EVT_THREAD; - } - - if (progress & WRSMD_ATT_LINKED) { - mutex_enter(&wrsmddevlock); - - if (wrsmddev == wrsmdp) - wrsmddev = wrsmdp->wrsmd_nextp; - else { - wrsmd_t *ptr; - - for (ptr = wrsmddev; ptr->wrsmd_nextp; ptr = - ptr->wrsmd_nextp) - if (ptr->wrsmd_nextp == wrsmdp) { - ptr->wrsmd_nextp = wrsmdp->wrsmd_nextp; - break; - } - } - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wrsmdp)) - mutex_exit(&wrsmddevlock); - progress &= ~WRSMD_ATT_LINKED; - } - - dip = wrsmdp->wrsmd_dip; - instance = ddi_get_instance(dip); - - - if (progress & WRSMD_ATT_KSTAT) { - wrsmdkstatremove(wrsmdp); - progress &= ~WRSMD_ATT_KSTAT; - } - - if (progress & WRSMD_ATT_MINOR) { - ddi_remove_minor_node(dip, NULL); - progress &= ~WRSMD_ATT_MINOR; - } - - if (progress & WRSMD_ATT_MUTEX) { - mutex_destroy(&wrsmdp->wrsmd_lock); - mutex_destroy(&wrsmdp->wrsmd_dest_lock); - mutex_destroy(&wrsmdp->wrsmd_runq_lock); - mutex_destroy(&wrsmdp->event_lock); - cv_destroy(&wrsmdp->event_cv); - cv_destroy(&wrsmdp->event_thread_exit_cv); - progress &= ~WRSMD_ATT_MUTEX; - } - - ASSERT(progress == 0); - - ddi_soft_state_free(wrsmd_state, instance); - - D1("wrsmdtakedown: returning DDI_SUCCESS"); - TNF_PROBE_1(wrsmdtakedown_end, "RSMPI", "wrsmdtakedown end", - tnf_long, rval, DDI_SUCCESS); -} - -/* - * Determine the device ipq pointer after a state change. The device ipq - * pointer is basically a performance hack; it is set to one of our attached - * queues if, and only if, (a) that queue is the only one which has bound to - * IP's SAP, i.e., has expressed interest in getting IP packets; and (b) there - * is no stream attached to us which has gone into any sort of promiscuous mode, - * i.e., has expressed interest in getting all packets. The performance win - * comes when ipq is set; if it is, we can just send all incoming IP packets - * to that queue without having to traverse the entire list of queues attached - * to us. - */ -static void -wrsmdsetipq(wrsmd_t *wrsmdp) /* WRSMD device (RSM controller) pointer */ -{ - struct wrsmdstr *ssp; - queue_t *ipq = NULL; - - /* - * Take ipq writer lock to prevent the fastpath from using the - * wrong ipq. Note: must take prior to taking struplock. - */ - rw_enter(&wrsmdp->wrsmd_ipq_rwlock, RW_WRITER); - - rw_enter(&wrsmdstruplock, RW_READER); - - for (ssp = wrsmdstrup; ssp; ssp = ssp->ss_nextp) - if (ssp->ss_wrsmdp == wrsmdp) { - if (ssp->ss_flags & WRSMD_SLALLSAP) { - ipq = NULL; - break; - } else if (ssp->ss_sap == WRSMD_IP_SAP) { - if ((ssp->ss_flags & WRSMD_SLFAST) == 0) { - ipq = NULL; - break; - } else if (ipq == NULL) { - ipq = ssp->ss_rq; - } else { - ipq = NULL; - break; - } - } - } - - wrsmdp->wrsmd_ipq = ipq; - - rw_exit(&wrsmdstruplock); - rw_exit(&wrsmdp->wrsmd_ipq_rwlock); -} - -/* - * Hook a new stream onto the driver. We create a wrsmdstr structure for the - * new stream, and, if this is a clone open, allocate an unused minor device - * number for it. - */ - -/*ARGSUSED*/ -static int -wrsmdopen(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp) -{ - wrsmdstr_t *ssp; - wrsmdstr_t **prevssp; - minor_t minordev; - int rc = 0; - - D1("wrsmdopen: rq 0x%p, *dev 0x%lx, flag %d, sflag %d", - (void *)rq, *devp, flag, sflag); - TNF_PROBE_4(wrsmdopen_start, "RSMPI", "wrsmdopen start", - tnf_long, rq, (tnf_long_t)rq, tnf_long, device, (tnf_long_t)devp, - tnf_long, flags, flag, tnf_long, sflags, sflag); - - ASSERT(sflag != MODOPEN); - - /* - * Serialize all driver open and closes. - */ - rw_enter(&wrsmdstruplock, RW_WRITER); - - /* - * Determine minor device number. - */ - prevssp = &wrsmdstrup; - if (sflag == CLONEOPEN) { - minordev = 0; - for (; ((ssp = *prevssp) != NULL); prevssp = &ssp->ss_nextp) { - if (minordev < ssp->ss_minor) - break; - minordev++; - } - *devp = makedevice(getmajor(*devp), minordev); - } else - minordev = getminor(*devp); - - if (rq->q_ptr == NULL) { - ssp = (wrsmdstr_t *)kmem_zalloc(sizeof (wrsmdstr_t), KM_SLEEP); - - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ssp)) - - ssp->ss_minor = minordev; - ssp->ss_rq = rq; - ssp->ss_state = DL_UNATTACHED; - ssp->ss_sap = 0; - ssp->ss_flags = 0; - ssp->ss_wrsmdp = NULL; - mutex_init(&ssp->ss_lock, NULL, MUTEX_DRIVER, NULL); - - /* - * Link new entry into the list of active entries. - */ - ssp->ss_nextp = *prevssp; - *prevssp = ssp; - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*ssp)) - - rq->q_ptr = WR(rq)->q_ptr = ssp; - } - - rw_exit(&wrsmdstruplock); - qprocson(rq); - D1("wrsmdopen: returning %d", rc); - TNF_PROBE_1(wrsmdopen_end, "RSMPI", "wrsmdopen end", tnf_long, - rval, rc); - - (void) qassociate(rq, -1); - return (rc); -} - -/* - * Unhook a stream from the driver. If it was attached to a specific physical - * device, detach it from the device, then remove it from our list of streams. - */ - -/*ARGSUSED*/ -static int -wrsmdclose(queue_t *rq, int flag, cred_t *credp) -{ - wrsmdstr_t *ssp; - wrsmdstr_t **prevssp; - - D1("wrsmdclose: rq 0x%p, flag %d", (void *)rq, flag); - TNF_PROBE_2(wrsmdclose_start, "RSMPI", "wrsmdclose start", - tnf_long, rq, (tnf_long_t)rq, tnf_long, flags, flag); - - ASSERT(rq); - - /* Disable put/service routines */ - - qprocsoff(rq); - - ASSERT(rq->q_ptr); - - ssp = (wrsmdstr_t *)rq->q_ptr; - - /* Detach Stream from interface */ - - mutex_enter(&ssp->ss_lock); - if (ssp->ss_wrsmdp) - wrsmddodetach(ssp); - mutex_exit(&ssp->ss_lock); - - rw_enter(&wrsmdstruplock, RW_WRITER); - - /* Unlink the per-Stream entry from the active list and free it */ - - for (prevssp = &wrsmdstrup; ((ssp = *prevssp) != NULL); - prevssp = &ssp->ss_nextp) - if (ssp == (wrsmdstr_t *)rq->q_ptr) - break; - ASSERT(ssp); - *prevssp = ssp->ss_nextp; - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ssp)) - - mutex_destroy(&ssp->ss_lock); - kmem_free(ssp, sizeof (wrsmdstr_t)); - - rq->q_ptr = WR(rq)->q_ptr = NULL; - - rw_exit(&wrsmdstruplock); - D1("wrsmdclose: returning 0"); - TNF_PROBE_1(wrsmdclose_end, "RSMPI", "wrsmdclose end", - tnf_long, rval, 0); - - (void) qassociate(rq, -1); - return (0); -} - -/* - * **************************************************************** - * * - * E N D BASIC MODULE BOILERPLATE * - * * - * **************************************************************** - */ - - -/* - * **************************************************************** - * * - * B E G I N STATUS REPORTING STUFF * - * * - * **************************************************************** - */ - -/* - * This routine makes the data in our kernel statistics structure reflect - * the current state of the device; it's called whenever a user requests - * the kstat data. Basically, all we do is copy the stats from the RSMPI - * controller structure, where they're maintained, to the kstat's data - * portion. - */ -static int -wrsmdstat_kstat_update( - kstat_t *ksp, /* Pointer to kstat that will be updated */ - int rw) /* Indicates read or write (we don't support write) */ -{ - wrsmd_t *wrsmdp; - wrsmd_stat_t *wrsmdsp; - - if (rw == KSTAT_WRITE) - return (EACCES); - - wrsmdp = (wrsmd_t *)ksp->ks_private; - wrsmdsp = (wrsmd_stat_t *)ksp->ks_data; - - wrsmdsp->rsm_ipackets.value.ul = (uint_t)wrsmdp->wrsmd_ipackets; - wrsmdsp->rsm_ipackets64.value.ui64 = wrsmdp->wrsmd_ipackets; - wrsmdsp->rsm_ierrors.value.ul = wrsmdp->wrsmd_ierrors; - wrsmdsp->rsm_opackets.value.ul = (uint_t)wrsmdp->wrsmd_opackets; - wrsmdsp->rsm_opackets64.value.ui64 = wrsmdp->wrsmd_opackets; - wrsmdsp->rsm_oerrors.value.ul = wrsmdp->wrsmd_oerrors; - wrsmdsp->rsm_collisions.value.ul = wrsmdp->wrsmd_collisions; - - wrsmdsp->rsm_xfers.value.ul = wrsmdp->wrsmd_xfers; - wrsmdsp->rsm_xfer_pkts.value.ul = wrsmdp->wrsmd_xfer_pkts; - wrsmdsp->rsm_syncdqes.value.ul = wrsmdp->wrsmd_syncdqes; - wrsmdsp->rsm_lbufs.value.ul = wrsmdp->wrsmd_lbufs; - wrsmdsp->rsm_nlbufs.value.ul = wrsmdp->wrsmd_nlbufs; - wrsmdsp->rsm_pullup.value.ul = wrsmdp->wrsmd_pullup; - wrsmdsp->rsm_pullup_fail.value.ul = wrsmdp->wrsmd_pullup_fail; - wrsmdsp->rsm_starts.value.ul = wrsmdp->wrsmd_starts; - wrsmdsp->rsm_start_xfers.value.ul = wrsmdp->wrsmd_start_xfers; - wrsmdsp->rsm_fqetmo_hint.value.ul = wrsmdp->wrsmd_fqetmo_hint; - wrsmdsp->rsm_fqetmo_drops.value.ul = wrsmdp->wrsmd_fqetmo_drops; - wrsmdsp->rsm_maxq_drops.value.ul = wrsmdp->wrsmd_maxq_drops; - wrsmdsp->rsm_errs.value.ul = wrsmdp->wrsmd_errs; - wrsmdsp->rsm_in_bytes.value.ul = (uint_t)wrsmdp->wrsmd_in_bytes; - wrsmdsp->rsm_in_bytes64.value.ui64 = wrsmdp->wrsmd_in_bytes; - wrsmdsp->rsm_out_bytes.value.ul = (uint_t)wrsmdp->wrsmd_out_bytes; - wrsmdsp->rsm_out_bytes64.value.ui64 = wrsmdp->wrsmd_out_bytes; - - return (0); -} - -/* - * This routine initializes the kernel statistics structures for an - * WRSMD device. - */ -static void -wrsmdkstatinit( - wrsmd_t *wrsmdp) /* WRSMD device (RSM controller) pointer */ -{ - struct kstat *ksp; - wrsmd_stat_t *wrsmdsp; - - /* - * We create a kstat for the device, then create a whole bunch of - * named stats inside that first kstat. - */ - if ((ksp = kstat_create("wrsmd", ddi_get_instance(wrsmdp->wrsmd_dip), - NULL, "net", KSTAT_TYPE_NAMED, sizeof (wrsmd_stat_t) / - sizeof (kstat_named_t), 0)) == NULL) { - wrsmderror(wrsmdp->wrsmd_dip, "kstat_create failed"); - return; - } - wrsmdsp = (wrsmd_stat_t *)(ksp->ks_data); - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wrsmdsp)) - - /* - * The first five named stats we create have well-known names, and are - * used by standard SunOS utilities (e.g., netstat). (There is actually - * a sixth well-known stat, called "queue", which we don't support.) - */ - kstat_named_init(&wrsmdsp->rsm_ipackets, "ipackets", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_ierrors, "ierrors", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_opackets, "opackets", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_oerrors, "oerrors", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_collisions, "collisions", - KSTAT_DATA_ULONG); - - /* - * MIB II kstat variables - */ - kstat_named_init(&wrsmdsp->rsm_in_bytes, "rbytes", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_out_bytes, "obytes", KSTAT_DATA_ULONG); - - /* - * PSARC 1997/198 - */ - kstat_named_init(&wrsmdsp->rsm_ipackets64, "ipackets64", - KSTAT_DATA_ULONGLONG); - kstat_named_init(&wrsmdsp->rsm_opackets64, "opackets64", - KSTAT_DATA_ULONGLONG); - kstat_named_init(&wrsmdsp->rsm_in_bytes64, "rbytes64", - KSTAT_DATA_ULONGLONG); - kstat_named_init(&wrsmdsp->rsm_out_bytes64, "obytes64", - KSTAT_DATA_ULONGLONG); - - - /* - * The remainder of the named stats are specific to our driver, and - * are extracted using the kstat utility. - */ - kstat_named_init(&wrsmdsp->rsm_xfers, "xfers", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_xfer_pkts, "xfer_pkts", - KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_syncdqes, "syncdqes", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_lbufs, "lbufs", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_nlbufs, "nlbufs", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_pullup, "pullup", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_pullup_fail, "pullup_fail", - KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_starts, "starts", KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_start_xfers, "start_xfers", - KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_fqetmo_hint, "fqetmo_hint", - KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_fqetmo_drops, "fqetmo_drops", - KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_maxq_drops, "maxq_drops", - KSTAT_DATA_ULONG); - kstat_named_init(&wrsmdsp->rsm_errs, "errs", KSTAT_DATA_ULONG); - - ksp->ks_update = wrsmdstat_kstat_update; - ksp->ks_private = (void *) wrsmdp; - wrsmdp->wrsmd_ksp = ksp; - kstat_install(ksp); - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*wrsmdsp)) -} - -/* - * This routine removes any kstats we might have created. - */ -static void -wrsmdkstatremove( - wrsmd_t *wrsmdp) /* WRSMD device (RSM controller) pointer */ -{ - _NOTE(ASSUMING_PROTECTED(wrsmdp->wrsmd_ksp)) - - if (wrsmdp->wrsmd_ksp) - kstat_delete(wrsmdp->wrsmd_ksp); -} - -static void -print_fqe(volatile wrsmd_fqe_t *fqep) -{ - D0("%02x %04x ", fqep->s.fq_seqnum, fqep->s.fq_bufnum); -} - -static void -print_dqe(volatile wrsmd_dqe_t *dqep) -{ - D0("%02x %04x ", dqep->s.dq_seqnum, dqep->s.dq_bufnum); -} - -/* Dump detailed information about the destination entry */ -static void -dump_dest(rsm_addr_t rsm_addr) -{ - int found; - wrsmd_t *wrsmd_dp; - wrsmd_dest_t *rd, *nrd; - volatile wrsmd_fqe_t *fqep; - volatile wrsmd_dqe_t *dqep; - int isdel; - - found = 0; - mutex_enter(&wrsmddevlock); - for (wrsmd_dp = wrsmddev; wrsmd_dp; wrsmd_dp = wrsmd_dp->wrsmd_nextp) { - FINDDEST(rd, isdel, wrsmd_dp, rsm_addr); - if (rd == NULL) continue; - - found = 1; - D0("\nwrsmd: 0x%p\n", (void *) wrsmd_dp); - D0("rsmaddr %ld\n", - wrsmd_dp->wrsmd_rsm_addr.m.rsm); - D0("wrsmd_runq: "); - for (nrd = wrsmd_dp->wrsmd_runq; nrd; nrd = nrd->rd_next) - D0("(%ld, %d) ", nrd->rd_rsm_addr, - nrd->rd_state); - - D0("sd 0x%p (%ld, %ld): state (%d, 0x%x, %d) ref %d " - "nlb %d nlb_del %d\n", - (void *)rd, rsm_addr, rd->rd_rsm_addr, rd->rd_state, - rd->rd_sstate, rd->rd_dstate, rd->rd_refcnt, - rd->rd_nlb, rd->rd_nlb_del); - - D0(" numlbufs %d nlb_del %d rbuflen %d " - "numrbuf %d, queueh %lx tail %lx\n", - rd->rd_numlbufs, rd->rd_nlb_del, - rd->rd_rbuflen, rd->rd_numrbuf, - (uintptr_t)rd->rd_queue_h, (uintptr_t)rd->rd_queue_t); - - D0(" stopq %d\n", rd->rd_stopq); - - if (isdel) continue; /* No need to UNREFDEST */ - - mutex_enter(&rd->rd_xmit_lock); - - D0(" XMT: queue_len %d (max %d), tmo_int %d tmo_tot %d " - "(max %d) tmo_id %lx\n", - rd->rd_queue_len, - wrsmd_dp->wrsmd_param.wrsmd_max_queued_pkts, - rd->rd_tmo_int, rd->rd_tmo_tot, - wrsmd_dp->wrsmd_param.wrsmd_nobuf_drop_tmo, - (uintptr_t)rd->rd_tmo_id); - - mutex_enter(&rd->rd_net_lock); - - D0(" FQR: cached %d fqr_seq %04x size %d, fqr f/l/n " - "= %lx %lx %lx\n", - rd->rd_cached_fqr_cnt, rd->rd_fqr_seq, rd->rd_num_fqrs, - (uintptr_t)rd->rd_fqr_f, (uintptr_t)rd->rd_fqr_l, - (uintptr_t)rd->rd_fqr_n); - - if ((fqep = rd->rd_fqr_n) != NULL) { - do { - print_fqe(fqep); - if (fqep == rd->rd_fqr_l) - D0("* "); - fqep = (fqep == rd->rd_fqr_l) ? - rd->rd_fqr_f : fqep + 1; - } while (fqep != rd->rd_fqr_n); - } - - D0("\n shadow DQ: dqeq f/l/i/o = %lx %lx %lx %lx\n", - (uintptr_t)rd->rd_shdwdqw_f, - (uintptr_t)rd->rd_shdwdqw_l, - (uintptr_t)rd->rd_shdwdqw_i, - (uintptr_t)rd->rd_shdwdqw_o); - - if ((dqep = rd->rd_shdwdqw_o) != NULL) { - do { - print_dqe(dqep); - if (dqep == rd->rd_shdwdqw_l) - D0("* "); - dqep = (dqep == rd->rd_shdwdqw_l) ? - rd->rd_shdwdqw_f : dqep + 1; - } while (dqep != rd->rd_shdwdqw_o); - } - - D0("\n remote DQ: dqw_seq %04x size %d, " - "dqw f_off = %lx\n", - rd->rd_dqw_seq, rd->rd_num_dqws, rd->rd_dqw_f_off); - - D0("\n\n RCV: rd_rbufoff %08lx, rbuflen %d, numrbuf %d\n", - rd->rd_rbufoff, rd->rd_rbuflen, rd->rd_numrbuf); - - D0(" DQR: dqr_seq = %04x size = %d, dqr f/l/n = " - "%lx %lx %lx\n", - rd->rd_dqr_seq, rd->rd_num_dqrs, - (uintptr_t)rd->rd_dqr_f, (uintptr_t)rd->rd_dqr_l, - (uintptr_t)rd->rd_dqr_n); - - if ((dqep = rd->rd_dqr_n) != NULL) { - do { - print_dqe(dqep); - if (dqep == rd->rd_dqr_l) - D0("* "); - dqep = (dqep == rd->rd_dqr_l) ? - rd->rd_dqr_f : dqep + 1; - } while (dqep != rd->rd_dqr_n); - } - - D0("\n shadow FQE: shdwfqw f/l/i/o = %lx %lx %lx %lx\n", - (uintptr_t)rd->rd_shdwfqw_f, - (uintptr_t)rd->rd_shdwfqw_l, - (uintptr_t)rd->rd_shdwfqw_i, - (uintptr_t)rd->rd_shdwfqw_o); - - if ((fqep = rd->rd_shdwfqw_o) != NULL) { - do { - print_fqe(fqep); - if (fqep == rd->rd_shdwfqw_l) - D0("* "); - fqep = (fqep == rd->rd_shdwfqw_l) ? - rd->rd_shdwfqw_f : fqep + 1; - } while (fqep != rd->rd_shdwfqw_o); - } - - D0("\n remote FQ: fqw_seq %04x size %d, fqw f = %lx\n", - rd->rd_fqw_seq, rd->rd_num_fqws, rd->rd_fqw_f_off); - - mutex_exit(&rd->rd_net_lock); - - mutex_exit(&rd->rd_xmit_lock); - - UNREFDEST(rd); - } - mutex_exit(&wrsmddevlock); - if (found == 0) D0("Sorry - entry for %ld not found\n", - rsm_addr); -} - -/* Dump summary information about all destination entries */ -static void -dump_ioctl(void) -{ - wrsmd_t *wrsmd_np; - wrsmd_dest_t *rd; - int dest; - - D0("..head of wrsmd structure list, wrsmddev: 0x%lx\n", - (uintptr_t)wrsmddev); - - mutex_enter(&wrsmddevlock); - for (wrsmd_np = wrsmddev; wrsmd_np; wrsmd_np = wrsmd_np->wrsmd_nextp) { - D0("\n wrsmd: 0x%lx\n", (uintptr_t)wrsmd_np); - D0(" next wrsmd pointer, wrsmd_nextp: 0x%lx\n", - (uintptr_t)wrsmd_np->wrsmd_nextp); - D0(" dev info pointer, wrsmd_dip: 0x%lx, ipq 0x%lx\n", - (uintptr_t)wrsmd_np->wrsmd_dip, - (uintptr_t)wrsmd_np->wrsmd_ipq); - D0(" rsmaddr %ld\n", - wrsmd_np->wrsmd_rsm_addr.m.rsm); - - mutex_enter(&wrsmd_np->wrsmd_dest_lock); - for (dest = 0; dest < RSM_MAX_DESTADDR; dest++) { - if ((rd = wrsmd_np->wrsmd_desttbl[dest]) == NULL) - continue; - D0(" rd 0x%p (%d, %ld): state (%d, " - "0x%x, %d) ref %d nlb %d nlb_del %d\n", - (void *)rd, dest, rd->rd_rsm_addr, - rd->rd_state, rd->rd_sstate, rd->rd_dstate, - rd->rd_refcnt, rd->rd_nlb, rd->rd_nlb_del); - } - mutex_exit(&wrsmd_np->wrsmd_dest_lock); - } - mutex_exit(&wrsmddevlock); -} - -/* - * Print an error message to the console. - */ -static void -wrsmderror( - dev_info_t *dip, /* Dev info for the device in question */ - const char *fmt, /* Format of output */ - ...) /* Parameters for output */ -{ - char name[16]; - char buf[1024]; - va_list ap; - - if (dip) { - (void) sprintf(name, "%s%d", ddi_get_name(dip), - ddi_get_instance(dip)); - } else { - (void) sprintf(name, "wrsmd"); - } - - va_start(ap, fmt); - (void) vsprintf(buf, fmt, ap); - va_end(ap); - - D1("%s:\t%s", name, buf); - cmn_err(CE_CONT, "%s:\t%s", name, buf); -} - - -#ifdef DEBUG_WRSMD - -#ifdef DEBUG_LOG - -/* - * The following variables support the debug log buffer scheme. - */ - -char wrsmddbgbuf[0x80000]; /* The log buffer */ -int wrsmddbgsize = sizeof (wrsmddbgbuf); /* Size of the log buffer */ -int wrsmddbgnext; /* Next byte to write in buffer (note */ - /* this is an index, not a pointer */ -int wrsmddbginit = 0; /* Nonzero if wrsmddbglock's inited */ -kmutex_t wrsmddbglock; - -_NOTE(MUTEX_PROTECTS_DATA(wrsmdattlock, wrsmddbginit)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmddbginit)) - -_NOTE(MUTEX_PROTECTS_DATA(wrsmddbglock, wrsmddbgbuf wrsmddbgnext)) - -/* - * Add the string str to the end of the debug log, followed by a newline. - */ -static void -wrsmddbglog(char *str) -{ - int length, remlen; - - /* - * If this is the first time we've written to the log, initialize it. - */ - if (!wrsmddbginit) { - mutex_enter(&wrsmdattlock); - if (!wrsmddbginit) { - mutex_init(&wrsmddbglock, NULL, MUTEX_DRIVER, - NULL); - bzero(wrsmddbgbuf, sizeof (wrsmddbgbuf)); - wrsmddbgnext = 0; - wrsmddbginit = 1; - } - mutex_exit(&wrsmdattlock); - } - - mutex_enter(&wrsmddbglock); - - /* - * Note the log is circular; if this string would run over the end, - * we copy the first piece to the end and then the last piece to - * the beginning of the log. - */ - length = strlen(str); - - remlen = sizeof (wrsmddbgbuf) - wrsmddbgnext; - - if (length > remlen) { - if (remlen) - bcopy(str, wrsmddbgbuf + wrsmddbgnext, remlen); - str += remlen; - length -= remlen; - wrsmddbgnext = 0; - } - - bcopy(str, wrsmddbgbuf + wrsmddbgnext, length); - wrsmddbgnext += length; - - if (wrsmddbgnext >= sizeof (wrsmddbgbuf)) - wrsmddbgnext = 0; - wrsmddbgbuf[wrsmddbgnext++] = '\n'; - - mutex_exit(&wrsmddbglock); -} - -#endif - - -/* - * Add a printf-style message to whichever debug logs we're currently using. - */ -static void -wrsmddebug(const char *fmt, ...) -{ - char buf[512]; - va_list ap; - - va_start(ap, fmt); - (void) vsprintf(buf, fmt, ap); - va_end(ap); - -#ifdef DEBUG_LOG - if (wrsmddbgmode & 0x1) - wrsmddbglog(buf); -#endif - -#ifdef DEBUG_PRINTF - if (wrsmddbgmode & 0x2) - cmn_err(CE_CONT, "%s\n", buf); -#endif -} - -/* - * Debugging routine, dumps data in hex. - */ -static void -wrsmdump( - uchar_t *data, /* Start of data */ - int length) /* Bytes to dump */ -{ - int bytesonline; - int offset; - char *lineptr; - char line[80]; - - lineptr = line; - bytesonline = 0; - offset = 0; - - - wrsmddebug("wrsmdump: dump of %d bytes at 0x%p", length, (void *)data); - - while (length) { - if (bytesonline == 0) { - (void) sprintf(line, "%8x: ", offset); - lineptr = line + strlen(line); - } - - (void) sprintf(lineptr, "%2x ", *data++); - length--; - lineptr += 3; - bytesonline++; - - if (bytesonline >= 16) { - *lineptr = '\0'; - wrsmddebug("%s", line); - bytesonline = 0; - offset += 16; - } - - } - - if (bytesonline) { - *lineptr = '\0'; - wrsmddebug("%s", line); - } -} - -#endif - - -/* - * **************************************************************** - * * - * E N D STATUS REPORTING STUFF * - * * - * **************************************************************** - */ - - -/* - * **************************************************************** - * * - * B E G I N BASIC STREAMS OPERATIONS * - * * - * **************************************************************** - */ - -/* - * Process a new message being sent down one of our streams. - */ -static int -wrsmdwput( - queue_t *wq, /* Queue message was written on */ - mblk_t *mp) /* The message itself */ -{ - wrsmdstr_t *ssp = /* Pointer to this stream's structure */ - (wrsmdstr_t *)wq->q_ptr; - wrsmd_t *wrsmdp; /* WRSMD device (RSM controller) pointer */ - - D1("wrsmdwput: wq 0x%p, mp 0x%p, ssp 0x%p", (void *)wq, - (void *)mp, (void *)ssp); - D5("wrsmdwput: time 0x%llx", gethrtime()); - TNF_PROBE_1(wrsmdwput_start, "RSMPI", "wrsmdwput start", - tnf_long, length, msgdsize(mp)); - - switch (DB_TYPE(mp)) { - case M_DATA: - /* - * This message is a raw data item. Most messages - * end up in this case. - */ - - /* - * It is possible that an interrupt thread handling - * incoming packets has taken wrsmdstruplock or - * ipq_rwlock, sent a packet upstream (usually to - * ar), then looped back down to here. Meanwhile, - * a separate thread could be attempting to modify - * the ipq shortcut, which first takes - * ssp->ss_lock, then takes wrsmdstriplock. This - * causes a deadlock. Avoid this by enqueueing the - * message if the ssp->ss_lock can't be taken - * immediately. - */ - if (!mutex_tryenter(&ssp->ss_lock)) { - (void) putq(wq, mp); - break; - } - - wrsmdp = ssp->ss_wrsmdp; - - /* If we're not supposed to get raw data, toss it. */ - - if (((ssp->ss_flags & - (WRSMD_SLRAW | WRSMD_SLFAST)) == 0) || - (ssp->ss_state != DL_IDLE) || (wrsmdp == NULL)) { - merror(wq, mp, EPROTO); - mutex_exit(&ssp->ss_lock); - TNF_PROBE_1(wrsmdwput_end, "RSMPI", - "wrsmdwput end; type M_DATA", - tnf_string, type, "M_DATA"); - break; - } - - /* - * If any msgs already enqueued or the interface will - * loop back up the message (due to wrsmd_promisc), - * then enqueue the msg. (Can't handle promiscuous - * here because it takes wrsmdstruplock, which might - * cause a recursive rw_enter.) Otherwise just xmit it - * directly. - */ - if (wq->q_first || wrsmdp->wrsmd_promisc) { - (void) putq(wq, mp); - } else { - dl_rsm_addr_t addr; - ushort_t sap; - - if (mp = wrsmdstrip(mp, &addr, &sap)) - wrsmdstart(wrsmdp, mp, addr, - sap, 1); - } - - mutex_exit(&ssp->ss_lock); - TNF_PROBE_1(wrsmdwput_end, "RSMPI", - "wrsmdwput end; type M_DATA", - tnf_string, type, "M_DATA"); - break; - - case M_PROTO: - case M_PCPROTO: - /* - * This message is a DLPI control message. In - * almost all cases, we just put this on the queue - * for the service routine to process. Why? - * Basically, because processing of some of the - * M_PROTO/M_PCPROTO requests involves acquiring - * internal locks that are also held across - * upstream putnext calls. For instance, - * wrsmdread() holds wrsmdstruplock and may - * hold wrsmdp->wrsmd_ipq_rwlock when it - * calls putnext(). In some cases, IP's or - * TCP's put routine, which was called from - * putnext() could immediately loop back, do a - * downward putnext() of a M_PROTO message, and end - * up right here. If we were then to try and - * process that message, we could try to obtain - * wrsmdstruplock or wrsmd_ipq_rwlock, which we - * already have, thus leading to a recursive - * mutex_enter panic. - * - * To prevent this, we put the M_PROTO message on - * the service routine's queue. When the service - * routine runs, it will be in a different context - * which can safely acquire the appropriate locks. - */ - - (void) putq(wq, mp); - TNF_PROBE_1(wrsmdwput_end, "RSMPI", - "wrsmdwput end; type M_PROTO", - tnf_string, type, "M_PROTO"); - break; - - case M_IOCTL: - /* - * ARP may do a downward putnext() of an M_IOCTL - * stream in response to an ack sent upstream - * by this module while holding internal locks. - * As described above, we avoid a recursive mutex - * enter by handling it in the service routine. - * We do an immediate nak for unrecognized ioctls. - */ - if (!wrsmdioctlimmediate(wq, mp)) - (void) putq(wq, mp); - - TNF_PROBE_1(wrsmdwput_end, "RSMPI", - "wrsmdwput end; type M_IOCTL", - tnf_string, type, "M_IOCTL"); - break; - - case M_FLUSH: - /* - * This message is asking us to flush our queues, - * probably in preparation for taking down the - * stream. - */ - if (*mp->b_rptr & FLUSHW) { - flushq(wq, FLUSHALL); - *mp->b_rptr &= ~FLUSHW; - } - if (*mp->b_rptr & FLUSHR) - qreply(wq, mp); - else - freemsg(mp); - TNF_PROBE_1(wrsmdwput_end, "RSMPI", - "wrsmdwput end; type M_FLUSH", - tnf_string, type, "M_FLUSH"); - break; - - default: - freemsg(mp); - TNF_PROBE_1(wrsmdwput_end, "RSMPI", - "wrsmdwput end; type unknown", - tnf_string, type, "UNKNOWN"); - break; - } - - D1("wrsmdwput: returning 0"); - TNF_PROBE_1(wrsmdwput_end, "RSMPI", "wrsmdwput end", - tnf_long, rval, 0); - return (0); -} - -/* - * Write service routine. This routine processes any messages put on the queue - * via a putq() in the write put routine. It also handles any destinations put - * on the destination run queue. - */ -static int -wrsmdwsrv(queue_t *wq) /* Queue we should service */ -{ - mblk_t *mp; - wrsmdstr_t *ssp; - wrsmd_t *wrsmdp; - wrsmd_dest_t *rd; - int isdel; - - D1("wrsmdwsrv: wq 0x%p", (void *)wq); - D5("wrsmdwsrv: time 0x%llx", gethrtime()); - - ssp = (wrsmdstr_t *)wq->q_ptr; - wrsmdp = ssp->ss_wrsmdp; - - D1("wrsmdwsrv: ssp 0x%p, wrsmdp 0x%p (cltr %d)", (void *)ssp, - (void *)wrsmdp, wrsmdp ? wrsmdp->wrsmd_ctlr_id : -1); - TNF_PROBE_0(wrsmdwsrv_start, "RSMPI", "wrsmdwsrv start"); - - /* - * Process message queue. - */ - while (mp = getq(wq)) { - switch (DB_TYPE(mp)) { - case M_DATA: - D5("wrsmdwsrv: got data time 0x%llx", - gethrtime()); - if (wrsmdp) { - dl_rsm_addr_t addr; - ushort_t sap; - - if (mp = wrsmdstrip(mp, &addr, &sap)) - wrsmdstart(wrsmdp, mp, - addr, sap, 0); - } else - freemsg(mp); - TNF_PROBE_1(wrsmdwsrv_msg, "RSMPI", - "wrsmdwsrv qcount; type M_DATA", - tnf_string, type, "M_DATA"); - break; - - case M_PROTO: - case M_PCPROTO: - D5("wrsmdwsrv: got proto time 0x%llx", - gethrtime()); - wrsmdproto(wq, mp); - wrsmdp = ssp->ss_wrsmdp; - TNF_PROBE_1(wrsmdwsrv_msg, "RSMPI", - "wrsmdwsrv qcount; type M_PROTO", - tnf_string, type, "M_PROTO"); - break; - - case M_IOCTL: - /* - * This message is an ioctl. - * We do not hold locks around the whole ioctl - * processing, as the holding of locks across a - * qreply() of ack or nak is a violation of the - * SVR4 DDI/DKI - */ - wrsmdioctl(wq, mp); - - TNF_PROBE_1(wrsmdwsrv_msg, "RSMPI", - "wrsmdwsrv msg; type M_IOCTL", - tnf_string, type, "M_IOCTL"); - break; - - - default: /* nothing is working at ths point */ - TNF_PROBE_1(wrsmdwsrv_msg, "RSMPI", - "wrsmdwsrv qcount; type unknown", - tnf_string, type, "UNKNOWN"); - ASSERT(0); - break; - } - } - - /* - * Traverse list of scheduled destinations, looking for work to do - */ - - if (wrsmdp == NULL) { - D1("wrsmdwsrv: wrsmdp NULL, returning 0"); - TNF_PROBE_0(wrsmdwsrv_end, "RSMPI", "wrsmdwsrv end"); - return (0); - } - - /* - * rd's refcnt is incremented by GETRUNQ - */ - GETRUNQ(rd, isdel, wrsmdp); - while (rd) { - int oldstate, delete; - - if (isdel) { - D2("wrsmdwsrv: dest 0x%p being deleted, ignored", - (void *)rd); - GETRUNQ(rd, isdel, wrsmdp); - continue; - } - - mutex_enter(&rd->rd_lock); - delete = 0; - - oldstate = wrsmdgetstate(rd); - D5("wrsmdwsrv: running state %s time 0x%llx", - WRSMD_STATE_STR(oldstate), gethrtime()); - switch (oldstate) { - - case WRSMD_STATE_S_XFER: { - mutex_enter(&rd->rd_xmit_lock); - if (rd->rd_queue_h) - wrsmdxfer(wrsmdp, rd); - else - wrsmdsetstate(rd, WRSMD_STATE_W_READY); - mutex_exit(&rd->rd_xmit_lock); - - break; - } - - case WRSMD_STATE_S_REQ_CONNECT: { - if (wrsmdcrexfer(wrsmdp, rd) != 0 || - wrsmdsconn(wrsmdp, rd, 0) != 0) { - wrsmdsetstate(rd, WRSMD_STATE_DELETING); - delete = 1; - } - break; - } - - case WRSMD_STATE_S_NEWCONN: { - if (wrsmdcrexfer(wrsmdp, rd) != 0 || - wrsmdconnxfer(wrsmdp, rd) != 0 || - wrsmdsaccept(wrsmdp, rd) != 0) { - wrsmdsetstate(rd, WRSMD_STATE_DELETING); - delete = 1; - } - break; - } - - case WRSMD_STATE_S_CONNXFER_ACCEPT: { - if (wrsmdconnxfer(wrsmdp, rd) != 0 || - wrsmdsaccept(wrsmdp, rd) != 0) { - wrsmdsetstate(rd, WRSMD_STATE_DELETING); - delete = 1; - } - break; - } - - case WRSMD_STATE_S_CONNXFER_ACK: { - if (wrsmdconnxfer(wrsmdp, rd) != 0 || - wrsmdsack(wrsmdp, rd) != 0) { - wrsmdsetstate(rd, WRSMD_STATE_DELETING); - delete = 1; - } - break; - } - - /* - * Delete this connection. This causes a message - * to be sent to the remote side when RSM_SENDQ_DESTROY - * is called, so there is no need to send an additional - * message. - */ - case WRSMD_STATE_S_DELETE: { - wrsmdsetstate(rd, WRSMD_STATE_DELETING); - delete = 1; - - break; - } - - /* - * Retry the SCONN. - */ - case WRSMD_STATE_S_SCONN: { - if (wrsmdsconn(wrsmdp, rd, 1) != 0) { - wrsmdsetstate(rd, WRSMD_STATE_DELETING); - delete = 1; - } - break; - } - - default: - D1("wrsmd: bad state %s in wsrv " - " for dest 0x%lx", WRSMD_STATE_STR(oldstate), - (uintptr_t)rd); - cmn_err(CE_PANIC, "wrsmd: bad state %s in wsrv " - " for dest 0x%lx", WRSMD_STATE_STR(oldstate), - (uintptr_t)rd); - break; - } - - mutex_exit(&rd->rd_lock); - - if (delete) - wrsmdfreedest(wrsmdp, rd->rd_rsm_addr); - - UNREFDEST(rd); - - GETRUNQ(rd, isdel, wrsmdp); - } - - D1("wrsmdwsrv: returning 0"); - TNF_PROBE_0(wrsmdwsrv_end, "RSMPI", "wrsmdwsrv end"); - return (0); -} - - -/* - * Discard all messages queued for output to this destination, updating - * error statistics as appropriate. - */ -static void -wrsmddumpqueue(wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - wrsmd_dest_t *rd) /* Destination pointer */ -{ - mblk_t *mp, *nmp; - - ASSERT(MUTEX_HELD(&rd->rd_xmit_lock)); - - D1("wrsmddumpqueue: wrsmdp 0x%p (ctlr %d), rd 0x%p (addr %ld)", - (void *)wrsmdp, - wrsmdp ? wrsmdp->wrsmd_ctlr_id : -1, (void *)rd, rd->rd_rsm_addr); - TNF_PROBE_2(wrsmddumpqueue_start, "RSMPI", - "wrsmddumpqueue start", - tnf_long, wrsmdp, (tnf_long_t)wrsmdp, tnf_long, rd, (tnf_long_t)rd); - - mp = rd->rd_queue_h; - rd->rd_queue_h = NULL; - rd->rd_queue_len = 0; - - while (mp) { - nmp = mp->b_next; - mp->b_next = mp->b_prev = NULL; - freemsg(mp); - wrsmdp->wrsmd_oerrors++; - mp = nmp; - } - D1("wrsmddumpqueue: done"); - TNF_PROBE_0(wrsmddumpqueue_end, "RSMPI", "wrsmddumpqueue end"); -} - -/* - * Execute an ioctl request from the service routine. - */ -static void -wrsmdioctl(queue_t *wq, mblk_t *mp) -{ - - struct iocblk *iocp = (struct iocblk *)mp->b_rptr; - wrsmdstr_t *ssp = (wrsmdstr_t *)wq->q_ptr; - rsm_addr_t dest; - - D1("wrsmdioctl: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - switch (iocp->ioc_cmd) { - case DLIOCRAW: /* raw M_DATA mode */ - D1("wrsmdioctl: DLIOCRAW"); - mutex_enter(&ssp->ss_lock); - ssp->ss_flags |= WRSMD_SLRAW; - mutex_exit(&ssp->ss_lock); - miocack(wq, mp, 0, 0); - break; - - case DL_IOC_HDR_INFO: /* M_DATA "fastpath" info request */ - D1("wrsmdioctl: DL_IOC_HDR_INFO"); - wrsmd_dl_ioc_hdr_info(wq, mp); - break; - - case WRSMD_DUMP_IOCTL: - mutex_enter(&ssp->ss_lock); - dump_ioctl(); - mutex_exit(&ssp->ss_lock); - miocack(wq, mp, 0, 0); - break; - - case WRSMD_DUMP_DEST: - if ((mp->b_cont == NULL) || - ((mp->b_cont->b_wptr - mp->b_cont->b_rptr) != - sizeof (dest))) { - miocnak(wq, mp, 0, EINVAL); - break; - } - - bcopy(mp->b_cont->b_rptr, &dest, sizeof (dest)); - mutex_enter(&ssp->ss_lock); - dump_dest(dest); - mutex_exit(&ssp->ss_lock); - miocack(wq, mp, 0, 0); - break; - - default: - D1("wrsmdioctl: unknown ioctl 0x%x", iocp->ioc_cmd); - miocnak(wq, mp, 0, EINVAL); - break; - } - D1("wrsmdioctl: done"); -} - -/* - * Execute an immediate ioctl request from the put routine. - * Does not take any locks. Returns FALSE if not handled immediately. - */ -static int -wrsmdioctlimmediate(queue_t *wq, mblk_t *mp) -{ - struct iocblk *iocp = (struct iocblk *)mp->b_rptr; - - D1("wrsmdioctlimmediate: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - switch (iocp->ioc_cmd) { - case DLIOCRAW: /* raw M_DATA mode */ - case DL_IOC_HDR_INFO: /* M_DATA "fastpath" info request */ - case WRSMD_DUMP_IOCTL: - case WRSMD_DUMP_DEST: - /* handle from the service routine */ - return (B_FALSE); - - default: - D1("wrsmdioctlimmediate: unknown ioctl 0x%x", iocp->ioc_cmd); - miocnak(wq, mp, 0, EINVAL); - break; - } - D1("wrsmdioctlimmediate: done"); - - return (B_TRUE); -} - -/* - * M_DATA "fastpath" info request. - * Following the M_IOCTL mblk should come a DL_UNITDATA_REQ mblk. We ack with - * an M_IOCACK pointing to the original DL_UNITDATA_REQ mblk, followed by an - * mblk containing the raw medium header corresponding to the destination - * address. Subsequently, we may receive M_DATA msgs which start with this - * header and may send up M_DATA msgs containing the network-layer data. - * This is all selectable on a per-Stream basis. - */ -static void -wrsmd_dl_ioc_hdr_info(queue_t *wq, mblk_t *mp) -{ - mblk_t *nmp; - wrsmdstr_t *ssp; - wrsmddladdr_t *dlap; - dl_unitdata_req_t *dludp; - struct ether_header *headerp; - wrsmd_t *wrsmdp; - uint32_t off, len; - int minsize; - - D1("wrsmd_dl_ioc_hdr_info: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - minsize = sizeof (dl_unitdata_req_t) + WRSMD_DEVICE_ADDRL; - - mutex_enter(&ssp->ss_lock); - - /* - * Sanity check the request. - */ - if ((mp->b_cont == NULL) || - (MBLKL(mp->b_cont) < minsize) || - (((union DL_primitives *)mp->b_cont->b_rptr)->dl_primitive != - DL_UNITDATA_REQ) || - ((wrsmdp = ssp->ss_wrsmdp) == NULL)) { - mutex_exit(&ssp->ss_lock); - miocnak(wq, mp, 0, EINVAL); - D1("wrsmd_dl_ioc_hdr_info: bad req, done"); - return; - } - - /* - * Sanity check the DL_UNITDATA_REQ destination address - * offset and length values. - */ - dludp = (dl_unitdata_req_t *)mp->b_cont->b_rptr; - off = dludp->dl_dest_addr_offset; - len = dludp->dl_dest_addr_length; - if (!MBLKIN(mp->b_cont, off, len) || (len != WRSMD_DEVICE_ADDRL)) { - mutex_exit(&ssp->ss_lock); - miocnak(wq, mp, 0, EINVAL); - D1("wrsmd_dl_ioc_hdr_info: bad addr, done"); - return; - } - - dlap = (wrsmddladdr_t *)(mp->b_cont->b_rptr + off); - - /* - * Allocate a new mblk to hold the medium header. - */ - if ((nmp = allocb(sizeof (struct ether_header), BPRI_MED)) - == NULL) { - mutex_exit(&ssp->ss_lock); - miocnak(wq, mp, 0, ENOMEM); - D1("wrsmd_dl_ioc_hdr_info: ENOMEM, done"); - return; - } - nmp->b_wptr += sizeof (struct ether_header); - - /* - * Fill in the medium header. - */ - headerp = (struct ether_header *)nmp->b_rptr; - - ether_copy(&(dlap->dl_addr), &(headerp->ether_dhost)); - ether_copy(&(wrsmdp->wrsmd_rsm_addr.m.ether.addr), - &(headerp->ether_shost)); - headerp->ether_type = dlap->dl_sap; - - /* - * Link new mblk in after the "request" mblks. - */ - linkb(mp, nmp); - - ssp->ss_flags |= WRSMD_SLFAST; - - wrsmdsetipq(wrsmdp); - - mutex_exit(&ssp->ss_lock); - - miocack(wq, mp, MBLKL(mp->b_cont)+MBLKL(nmp), 0); - - D1("wrsmd_dl_ioc_hdr_info: done"); -} - -/* - * **************************************************************** - * * - * E N D BASIC STREAMS OPERATIONS * - * * - * **************************************************************** - */ - - - -/* - * **************************************************************** - * * - * B E G I N DLPI OPERATIONS * - * * - * **************************************************************** - */ - -/* - * Parse and execute a DLPI request. - */ -static void -wrsmdproto( - queue_t *wq, /* Queue the request came in on */ - mblk_t *mp) /* The request message itself */ -{ - union DL_primitives *dlp; - wrsmdstr_t *ssp; - uint32_t prim; - - D1("wrsmdproto: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - TNF_PROBE_2(wrsmdproto_start, "RSMPI", "wrsmdproto start", - tnf_long, wq, (tnf_long_t)wq, tnf_long, mp, (tnf_long_t)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - dlp = (union DL_primitives *)mp->b_rptr; - /* Make sure we at least have dlp->dl_primitive */ - if ((caddr_t)mp->b_wptr < - (caddr_t)&dlp->dl_primitive + sizeof (dlp->dl_primitive)) { - dlerrorack(wq, mp, 0xffff, DL_BADPRIM, 0); - return; - } - prim = dlp->dl_primitive; - - mutex_enter(&ssp->ss_lock); - - switch (prim) { - case DL_UNITDATA_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_UNITDATA_REQ, ""); - wrsmdudreq(wq, mp); - break; - - case DL_ATTACH_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_ATTACH_REQ, ""); - wrsmdareq(wq, mp); - break; - - case DL_DETACH_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_DETACH_REQ, ""); - wrsmddreq(wq, mp); - break; - - case DL_ENABMULTI_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_ENABMULTI_REQ, ""); - /* Accept enable-multicast-request */ - dlokack(wq, mp, DL_ENABMULTI_REQ); - break; - - case DL_DISABMULTI_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_DISABMULTI_REQ, ""); - /* Accept disable-multicast-request */ - dlokack(wq, mp, DL_DISABMULTI_REQ); - break; - - case DL_BIND_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_BIND_REQ, ""); - wrsmdbreq(wq, mp); - break; - - case DL_UNBIND_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_UNBIND_REQ, ""); - wrsmdubreq(wq, mp); - break; - - case DL_INFO_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_INFO_REQ, ""); - wrsmdireq(wq, mp); - break; - - case DL_PROMISCON_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_PROMISCON_REQ, ""); - wrsmdponreq(wq, mp); - break; - - case DL_PROMISCOFF_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_PRIMISCOFF_REQ, ""); - wrsmdpoffreq(wq, mp); - break; - - case DL_PHYS_ADDR_REQ: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_PHYS_ADDR_REQ, ""); - wrsmdpareq(wq, mp); - break; - - default: - TNF_PROBE_1(wrsmdproto_prim, "RSMPI", - "wrsmdproto prim", - tnf_string, DL_UNSUPPORTED, ""); - dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0); - break; - } - - mutex_exit(&ssp->ss_lock); - - D1("wrsmdproto: done"); - TNF_PROBE_1(wrsmdproto_end, "RSMPI", "wrsmdproto end", - tnf_string, completed, ""); -} - -/* - * START OF GENERIC DLPI INTERFACE ROUTINES - */ - -/* - * DLPI attach request (attach stream to physical device) - * - * The PPA is the RSM controller id, which equals the DLPI device instance - * number. - */ -static void -wrsmdareq(queue_t *wq, mblk_t *mp) -{ - wrsmdstr_t *ssp; - union DL_primitives *dlp; - wrsmd_t *wrsmdp; - uint32_t ppa; - timeout_id_t tmoid; - - D1("wrsmdareq: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - dlp = (union DL_primitives *)mp->b_rptr; - - if (MBLKL(mp) < DL_ATTACH_REQ_SIZE) { - dlerrorack(wq, mp, DL_ATTACH_REQ, DL_BADPRIM, 0); - D1("wrsmdareq: bad size, done"); - return; - } - - if (ssp->ss_state != DL_UNATTACHED) { - dlerrorack(wq, mp, DL_ATTACH_REQ, DL_OUTSTATE, 0); - D1("wrsmdareq: bad state, done"); - return; - } - - ppa = dlp->attach_req.dl_ppa; - - /* - * Valid ppa? - */ - if (ppa == -1 || qassociate(wq, ppa) != 0) { - dlerrorack(wq, mp, dlp->dl_primitive, DL_BADPPA, 0); - D1("wrsmdareq: bad ppa, done"); - return; - } - mutex_enter(&wrsmddevlock); - for (wrsmdp = wrsmddev; wrsmdp; - wrsmdp = wrsmdp->wrsmd_nextp) { - if (ppa == wrsmdp->wrsmd_ctlr_id) { - break; - } - } - mutex_exit(&wrsmddevlock); - /* when qassociate() succeeds, ppa must be present */ - ASSERT(wrsmdp); - - /* - * The teardown timeout now reschedules itself, so we - * have to go to great lengths to kill it. - */ - mutex_enter(&wrsmdp->wrsmd_lock); - tmoid = wrsmdp->wrsmd_teardown_tmo_id; - - while (tmoid) { - /* - * A timeout is scheduled to teardown the device - - * cancel it, as device is once again in use. - */ - mutex_exit(&wrsmdp->wrsmd_lock); - - (void) untimeout(tmoid); - /* - * untimeout guarantees the either the function was - * cancelled, or it has completed. If timeout was - * cancelled before the function ran, the timout id will - * not have changed. - */ - mutex_enter(&wrsmdp->wrsmd_lock); - - if (tmoid == wrsmdp->wrsmd_teardown_tmo_id) - wrsmdp->wrsmd_teardown_tmo_id = 0; - tmoid = wrsmdp->wrsmd_teardown_tmo_id; - } - - /* - * Has WRSMD device (RSM controller) been initialized? Do so if - * necessary. - */ - if ((wrsmdp->wrsmd_flags & WRSMDREGHANDLER) == 0) { - if (wrsmdinit(wrsmdp)) { - mutex_exit(&wrsmdp->wrsmd_lock); - dlerrorack(wq, mp, dlp->dl_primitive, - DL_INITFAILED, 0); - D1("wrsmdareq: init failed, done"); - /* dissociate on failure */ - (void) qassociate(wq, -1); - return; - } - } - if (ssp->ss_flags & WRSMD_SLALLPHYS) - wrsmdp->wrsmd_promisc++; - - wrsmdp->wrsmd_attached_streams++; - mutex_exit(&wrsmdp->wrsmd_lock); - - - /* - * Save pointer to this queue if this destination doesn't already - * have one - */ - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - if (wrsmdp->wrsmd_wq == NULL) - wrsmdp->wrsmd_wq = wq; - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - /* - * Set link to WRSMD device (RSM controller) and update our state. - */ - ssp->ss_wrsmdp = wrsmdp; - ssp->ss_state = DL_UNBOUND; - - dlokack(wq, mp, DL_ATTACH_REQ); - - D1("wrsmdareq: done"); -} - -/* - * DLPI detach request (detach stream from physical device) - */ -static void -wrsmddreq(queue_t *wq, mblk_t *mp) -{ - wrsmdstr_t *ssp; - - D1("wrsmddreq: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - - if (MBLKL(mp) < DL_DETACH_REQ_SIZE) { - dlerrorack(wq, mp, DL_DETACH_REQ, DL_BADPRIM, 0); - D1("wrsmddreq: bad size, done"); - return; - } - - if (ssp->ss_state != DL_UNBOUND) { - dlerrorack(wq, mp, DL_DETACH_REQ, DL_OUTSTATE, 0); - D1("wrsmddreq: bad state, done"); - return; - } - - wrsmddodetach(ssp); - (void) qassociate(wq, -1); - dlokack(wq, mp, DL_DETACH_REQ); - - D1("wrsmddreq: done"); -} - -/* - * Detach a Stream from an interface. - */ -static void -wrsmddodetach(wrsmdstr_t *ssp) -{ - wrsmdstr_t *tslp; - wrsmd_t *wrsmdp; - - D1("wrsmddodetach: ssp 0x%p", (void *)ssp); - - ASSERT(MUTEX_HELD(&ssp->ss_lock)); - ASSERT(ssp->ss_wrsmdp); - - wrsmdp = ssp->ss_wrsmdp; - - mutex_enter(&wrsmdp->wrsmd_lock); - - /* - * Need to protect this assignment with wrsmd_lock mutex in case - * of concurrent execution of detach for different streams, to avoid - * detaching device structure until all streams detached. - */ - ssp->ss_wrsmdp = NULL; - - wrsmdp->wrsmd_attached_streams--; - - if (ssp->ss_flags & WRSMD_SLALLPHYS) - wrsmdp->wrsmd_promisc--; - - /* - * Detach from device structure. - * Uninit the device when no other streams are attached to it. - */ - rw_enter(&wrsmdstruplock, RW_READER); - - for (tslp = wrsmdstrup; tslp; tslp = tslp->ss_nextp) - if (tslp->ss_wrsmdp == wrsmdp) - break; - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - if (tslp) - wrsmdp->wrsmd_wq = WR(tslp->ss_rq); - else - wrsmdp->wrsmd_wq = NULL; - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - /* Make sure teardown only scheduled once. */ - if (wrsmdp->wrsmd_attached_streams == 0) { - /* - * Schedule a teardown. This allows queues to destinations - * through this controller to drain, and keeps the data - * structures around in case a new connection to this - * device is about to occur. - */ - ASSERT(tslp == NULL); - wrsmdp->wrsmd_teardown_tmo_id = timeout(wrsmdteardown_tmo, - (caddr_t)wrsmdp, wrsmdp->wrsmd_param.wrsmd_teardown_tmo); - } - - rw_exit(&wrsmdstruplock); - - mutex_exit(&wrsmdp->wrsmd_lock); - - ssp->ss_state = DL_UNATTACHED; - - wrsmdsetipq(wrsmdp); - - D1("wrsmddodetach: done"); -} - -/* - * DLPI bind request (register interest in a particular address & SAP) - */ -static void -wrsmdbreq(queue_t *wq, mblk_t *mp) -{ - wrsmdstr_t *ssp; - union DL_primitives *dlp; - wrsmd_t *wrsmdp; - wrsmddladdr_t wrsmdaddr; - ushort_t sap; - uint32_t xidtest; - - D1("wrsmdbreq: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - - if (MBLKL(mp) < DL_BIND_REQ_SIZE) { - dlerrorack(wq, mp, DL_BIND_REQ, DL_BADPRIM, 0); - D1("wrsmdbreq: bad size, done"); - return; - } - - if (ssp->ss_state != DL_UNBOUND) { - dlerrorack(wq, mp, DL_BIND_REQ, DL_OUTSTATE, 0); - D1("wrsmdbreq: bad state, done"); - return; - } - - dlp = (union DL_primitives *)mp->b_rptr; - wrsmdp = ssp->ss_wrsmdp; - xidtest = dlp->bind_req.dl_xidtest_flg; - - ASSERT(wrsmdp); - - if (xidtest) { - dlerrorack(wq, mp, DL_BIND_REQ, DL_NOAUTO, 0); - D1("wrsmdbreq: bad xidtest, done"); - return; - } - - if (dlp->bind_req.dl_service_mode != DL_CLDLS) { - dlerrorack(wq, mp, DL_BIND_REQ, DL_UNSUPPORTED, 0); - return; - } - - if (dlp->bind_req.dl_sap > MEDIUMSAP_MAX) { - dlerrorack(wq, mp, dlp->dl_primitive, DL_BADSAP, 0); - D1("wrsmdbreq: bad sap, done"); - return; - } - sap = (ushort_t)dlp->bind_req.dl_sap; - - /* - * Save SAP value for this Stream and change state. - */ - ssp->ss_sap = sap; - ssp->ss_state = DL_IDLE; - - wrsmdaddr.dl_sap = sap; - wrsmdaddr.dl_addr = wrsmdp->wrsmd_rsm_addr.m.ether.addr; - dlbindack(wq, mp, (t_scalar_t)sap, (caddr_t)&wrsmdaddr, - WRSMD_DEVICE_ADDRL, 0, 0); - - wrsmdsetipq(wrsmdp); - - D1("wrsmdbreq: done"); -} - -/* - * DLPI unbind request (cancel interest in a particular local address & SAP) - */ -static void -wrsmdubreq(queue_t *wq, mblk_t *mp) -{ - wrsmdstr_t *ssp; - - D1("wrsmdubreq: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - - if (MBLKL(mp) < DL_UNBIND_REQ_SIZE) { - dlerrorack(wq, mp, DL_UNBIND_REQ, DL_BADPRIM, 0); - D1("wrsmdubreq: bad size, done"); - return; - } - - if (ssp->ss_state != DL_IDLE) { - dlerrorack(wq, mp, DL_UNBIND_REQ, DL_OUTSTATE, 0); - D1("wrsmdubreq: bad state, done"); - return; - } - - ssp->ss_state = DL_UNBOUND; - ssp->ss_sap = 0; - - (void) putnextctl1(RD(wq), M_FLUSH, FLUSHRW); - - dlokack(wq, mp, DL_UNBIND_REQ); - - wrsmdsetipq(ssp->ss_wrsmdp); - - D1("wrsmdubreq: done"); -} - -/* - * DLPI device information request - */ -static void -wrsmdireq(queue_t *wq, mblk_t *mp) -{ - wrsmdstr_t *ssp; - dl_info_ack_t *dlip; - wrsmddladdr_t *dlap; - void *dlbcastap; - size_t size; - - D1("wrsmdireq: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - - if (MBLKL(mp) < DL_INFO_REQ_SIZE) { - dlerrorack(wq, mp, DL_INFO_REQ, DL_BADPRIM, 0); - D1("wrsmdireq: bad size, done"); - return; - } - - /* - * Exchange current msg for a DL_INFO_ACK. - */ - size = sizeof (dl_info_ack_t) + WRSMD_DEVICE_ADDRL + WRSMD_BCAST_ADDRL; - if ((mp = mexchange(wq, mp, size, M_PCPROTO, DL_INFO_ACK)) == NULL) { - D1("wrsmdireq: bad mexchange, done"); - return; - } - - /* - * Fill in the DL_INFO_ACK fields and reply. - */ - dlip = (dl_info_ack_t *)mp->b_rptr; - *dlip = wrsmdinfoack; - dlip->dl_current_state = ssp->ss_state; - - /* - * fill in the local DLSAP address, if connected to a controller - */ - dlap = (wrsmddladdr_t *)(mp->b_rptr + dlip->dl_addr_offset); - if (ssp->ss_wrsmdp) { - ether_copy(&(ssp->ss_wrsmdp->wrsmd_rsm_addr.m.ether.addr), - &(dlap->dl_addr)); - dlip->dl_max_sdu = - ssp->ss_wrsmdp->wrsmd_param.wrsmd_buffer_size - - WRSMD_CACHELINE_SIZE; - } else { - ether_copy(&wrsmdbadaddr, &(dlap->dl_addr)); - mutex_enter(&wrsmddevlock); - ASSERT(wrsmdminbuflen != 0); - dlip->dl_max_sdu = wrsmdminbuflen - WRSMD_CACHELINE_SIZE; - mutex_exit(&wrsmddevlock); - } - dlap->dl_sap = ssp->ss_sap; - - /* - * fill in the broadcast address; it's at least short aligned - */ - dlbcastap = (void *)(mp->b_rptr + dlip->dl_brdcst_addr_offset); - ether_copy(&wrsmdbcastaddr, dlbcastap); - - ASSERT(((unsigned char *)dlbcastap + WRSMD_BCAST_ADDRL) == - (mp->b_rptr + size)); - - qreply(wq, mp); - - D1("wrsmdireq: done"); -} - -/* - * DLPI enable promiscuous mode request - * - * We only snoop and deliver messages that are generated by this node - * or received by this mode. Unlike promiscuous mode on a bus-based - * network, we do not see (and therefore cannot deliver) messages - * destined for other nodes. - */ -static void -wrsmdponreq(queue_t *wq, mblk_t *mp) -{ - wrsmdstr_t *ssp; - - D1("wrsmdponreq: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - - if (MBLKL(mp) < DL_PROMISCON_REQ_SIZE) { - dlerrorack(wq, mp, DL_PROMISCON_REQ, DL_BADPRIM, 0); - D1("wrsmdponreq: bad size, done"); - return; - } - - switch (((dl_promiscon_req_t *)mp->b_rptr)->dl_level) { - case DL_PROMISC_PHYS: - if (!(ssp->ss_flags & WRSMD_SLALLPHYS)) { - ssp->ss_flags |= WRSMD_SLALLPHYS; - if (ssp->ss_wrsmdp) { - mutex_enter( - &ssp->ss_wrsmdp->wrsmd_lock); - ssp->ss_wrsmdp->wrsmd_promisc++; - mutex_exit(&ssp->ss_wrsmdp->wrsmd_lock); - } - } - break; - - case DL_PROMISC_SAP: - ssp->ss_flags |= WRSMD_SLALLSAP; - break; - - default: - dlerrorack(wq, mp, DL_PROMISCON_REQ, - DL_NOTSUPPORTED, 0); - D1("wrsmdponreq: option not supported, done"); - return; - } - - if (ssp->ss_wrsmdp) - wrsmdsetipq(ssp->ss_wrsmdp); - - dlokack(wq, mp, DL_PROMISCON_REQ); - - D1("wrsmdponreq: done"); -} - -/* - * DLPI disable promiscuous mode request - */ -static void -wrsmdpoffreq(queue_t *wq, mblk_t *mp) -{ - wrsmdstr_t *ssp; - int flag; - - D1("wrsmdpoffreq: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - - if (MBLKL(mp) < DL_PROMISCOFF_REQ_SIZE) { - dlerrorack(wq, mp, DL_PROMISCOFF_REQ, DL_BADPRIM, 0); - D1("wrsmdpoffreq: bad size, done"); - return; - } - - switch (((dl_promiscoff_req_t *)mp->b_rptr)->dl_level) { - case DL_PROMISC_PHYS: - flag = WRSMD_SLALLPHYS; - break; - - case DL_PROMISC_SAP: - flag = WRSMD_SLALLSAP; - break; - - default: - dlerrorack(wq, mp, DL_PROMISCOFF_REQ, - DL_NOTSUPPORTED, 0); - D1("wrsmdpoffreq: option not supported, done"); - return; - } - - if ((ssp->ss_flags & flag) == 0) { - dlerrorack(wq, mp, DL_PROMISCOFF_REQ, DL_NOTENAB, 0); - D1("wrsmdpoffreq: mode not on, done"); - return; - } - - ssp->ss_flags &= ~flag; - - if ((flag & WRSMD_SLALLPHYS) && ssp->ss_wrsmdp) { - mutex_enter(&ssp->ss_wrsmdp->wrsmd_lock); - ssp->ss_wrsmdp->wrsmd_promisc--; - mutex_exit(&ssp->ss_wrsmdp->wrsmd_lock); - } - - if (ssp->ss_wrsmdp) - wrsmdsetipq(ssp->ss_wrsmdp); - - dlokack(wq, mp, DL_PROMISCOFF_REQ); - - D1("wrsmdpoffreq: done"); -} - -/* - * DLPI get physical address request - * - * Return the PPA (RSM hardware address) of the WRSMD device (RSM controller) - * to which this stream is attached. - */ -static void -wrsmdpareq(queue_t *wq, mblk_t *mp) -{ - wrsmdstr_t *ssp; - union DL_primitives *dlp; - uint32_t type; - wrsmd_t *wrsmdp; - - D1("wrsmdpareq: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - - if (MBLKL(mp) < DL_PHYS_ADDR_REQ_SIZE) { - dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_BADPRIM, 0); - D1("wrsmdpareq: bad size, done"); - return; - } - - dlp = (union DL_primitives *)mp->b_rptr; - type = dlp->physaddr_req.dl_addr_type; - wrsmdp = ssp->ss_wrsmdp; - - if (wrsmdp == NULL) { - dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_OUTSTATE, 0); - D1("wrsmdpareq: bad state, done"); - return; - } - - switch (type) { - case DL_FACT_PHYS_ADDR: - case DL_CURR_PHYS_ADDR: - dlphysaddrack(wq, mp, - (void *)&(wrsmdp->wrsmd_rsm_addr.m.ether.addr), - sizeof (wrsmdp->wrsmd_rsm_addr.m.ether.addr)); - D1("wrsmdpareq: done"); - return; - - default: - dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, - DL_NOTSUPPORTED, 0); - D1("wrsmdpoffreq: option not supported, done"); - return; - } -} - -/* - * DLPI unit data send request - */ -static void -wrsmdudreq(queue_t *wq, mblk_t *mp) -{ - wrsmdstr_t *ssp; - register wrsmd_t *wrsmdp; - register dl_unitdata_req_t *dludp; - mblk_t *nmp; - wrsmddladdr_t *dlap; - uint32_t off, len; - - ushort_t sap; - dl_rsm_addr_t addr; - - D1("wrsmdudreq: wq 0x%p, mp 0x%p", (void *)wq, (void *)mp); - - ssp = (wrsmdstr_t *)wq->q_ptr; - wrsmdp = ssp->ss_wrsmdp; - - if (wrsmdp == NULL) { - dlerrorack(wq, mp, DL_UNITDATA_REQ, DL_OUTSTATE, 0); - D1("wrsmdudreq: bad state, done"); - return; - } - - dludp = (dl_unitdata_req_t *)mp->b_rptr; - - off = dludp->dl_dest_addr_offset; - len = dludp->dl_dest_addr_length; - - /* - * Validate destination address format. - */ - if (!MBLKIN(mp, off, len) || (len != WRSMD_DEVICE_ADDRL)) { - dluderrorind(wq, mp, (uchar_t *)(mp->b_rptr + off), len, - DL_BADADDR, 0); -#ifdef DEBUG_WRSMD - dlap = (wrsmddladdr_t *)(mp->b_rptr + off); - ether_copy(&(dlap->dl_addr), &(addr.m.ether.addr)); - addr.m.ether.zero = 0; - sap = (uint16_t)((((uchar_t *)(&dlap->dl_sap))[0] << 8) | - ((uchar_t *)(&dlap->dl_sap))[1]); - D2("wrsmdudreq bad addr: ADDRL %ld addr len %d, rsm addr 0x%lx " - "sap 0x%x", - WRSMD_DEVICE_ADDRL, len, addr.m.rsm, sap); - D1("wrsmdudreq: bad addr, done"); -#endif - return; - } - - /* - * Error if no M_DATA follows. - */ - nmp = mp->b_cont; - if (nmp == NULL) { - dluderrorind(wq, mp, (uchar_t *)(mp->b_rptr + off), len, - DL_BADDATA, 0); - D1("wrsmdudreq: bad data, done"); - return; - } - - /* Extract address information. */ - - dlap = (wrsmddladdr_t *)(mp->b_rptr + off); - - ether_copy(&(dlap->dl_addr), &(addr.m.ether.addr)); - addr.m.ether.zero = 0; - sap = (uint16_t)((((uchar_t *)(&dlap->dl_sap))[0] << 8) | - ((uchar_t *)(&dlap->dl_sap))[1]); - - /* Discard DLPI header. */ - - freeb(mp); - - /* - * Transmit message. - */ - wrsmdstart(wrsmdp, nmp, addr, sap, 0); - - D1("wrsmdudreq: done"); -} - - - -/* - * **************************************************************** - * * - * E N D DLPI OPERATIONS * - * * - * **************************************************************** - */ - - -/* - * **************************************************************** - * * - * B E G I N HIGH LEVEL PROTOCOL INTERFACE AND UTILITIES * - * * - * **************************************************************** - */ - - -/* - * An outgoing raw packet has a header at the beginning, telling us the - * destination address and SAP. Since this header is not used by the - * Wildcat hardware in this form, we call it the "fake hardware header". - * - * This routine parses the fake hardware header at the start of mp, strips - * the header from mp then returns address and sap. It returns a pointer - * to the stripped mblk, which may or may not be the same pointer which was - * passed in, or NULL if there's no data to send. - */ - -static mblk_t * -wrsmdstrip( - mblk_t *mp, /* Packet to parse & strip header from */ - dl_rsm_addr_t *addrp, /* Address packet addressed to (returned) */ - ushort_t *sapp) /* SAP packet addressed to (returned) */ -{ - D1("wrsmdstrip: mp 0x%p", (void *)mp); - - if (MBLKIN(mp, 0, sizeof (struct ether_header))) { - struct ether_header *mh = (struct ether_header *)mp->b_rptr; - - /* - * Parse header; it's at least short aligned. - */ - - ether_copy(&(mh->ether_dhost), &(addrp->m.ether.addr)); - addrp->m.ether.zero = 0; - *sapp = mh->ether_type; - - /* Strip off header */ - - mp->b_rptr += sizeof (struct ether_header); - - /* - * If there's nothing left in this mblk, and there are more - * following, get rid of it. If there's nothing left, and - * there aren't more following, we have a zero-length - * message; return an error. (A following mblk might - * conceivably be empty, giving us a zero-length message as - * well; we don't check for this.) - */ - if (mp->b_rptr == mp->b_wptr) { - if (mp->b_cont != NULL) { - mblk_t *nmp; - - nmp = mp->b_cont; - freeb(mp); - D1("wrsmdstrip: returning 1"); - return (nmp); - } else { - freemsg(mp); - D1("wrsmdstrip: returning 0"); - return (NULL); - } - } else { - D1("wrsmdstrip: returning 1"); - return (mp); - } - } else { - D1("wrsmdstrip: returning 0"); - freemsg(mp); - return (NULL); - } -} - - - -/* - * Queue the message to the proper destination structure, creating the - * destination if necessary. Discard the message if required. - * If from_put is true, and there are no other messages queued to this - * destination or being transmitted, start this message transmitting. - * Schedule destination for service, if necessary. The function returns - * true is message was successfully queued. - */ -boolean_t -wrsmdqueuemsg(wrsmd_t *wrsmdp, mblk_t *orig_mp, dl_rsm_addr_t addr, - ushort_t sap, int from_put, boolean_t copy) -{ - wrsmd_dest_t *rd; - int isdel = 0; - int isnew = 0; - timeout_id_t tmoid; - mblk_t *mp; - - if (copy) { - mp = dupmsg(orig_mp); - if (!mp) - return (B_FALSE); - } else { - mp = orig_mp; - } - - /* Find destination structure for this message */ - D1("wrsmdqueuemsg: ctlr %d\n", wrsmdp->wrsmd_ctlr_id); - - MAKEDEST(rd, isdel, isnew, wrsmdp, addr.m.wrsm.addr); - - if (isdel) { - wrsmdp->wrsmd_oerrors++; - if (copy) { - freemsg(mp); - } - DERR("wrsmdqueuemsg: TOSS!!! dest being deleted, " - "toss packet, done"); - TNF_PROBE_1(wrsmdqueuemsg_end, "RSMPI", - "wrsmdqueuemsg end; failure destbeingdel", - tnf_string, failure, "destbeingdel"); - return (B_FALSE); - } else if (isnew) { - if (rd == NULL) { - wrsmdp->wrsmd_oerrors++; - if (copy) { - freemsg(mp); - } - DERR("wrsmdqueuemsg: TOSS!!! can't mkdest, " - "toss packet, done"); - TNF_PROBE_1(wrsmdqueuemsg_end, "RSMPI", - "wrsmdqueuemsg end; failure cantmkdest", - tnf_string, failure, "cantmkdest"); - return (B_FALSE); - } - } - - /* if state was new, move to req_connect */ - (void) wrsmdmovestate(rd, WRSMD_STATE_NEW, WRSMD_STATE_S_REQ_CONNECT); - - mutex_enter(&rd->rd_xmit_lock); - - /* Make sure we don't have too many queued already */ - - if (rd->rd_queue_len >= - wrsmdp->wrsmd_param.wrsmd_max_queued_pkts) { - if (copy) { - freemsg(mp); - } - wrsmdp->wrsmd_oerrors++; - wrsmdp->wrsmd_maxq_drops++; - DERR("wrsmdqueuemsg: TOSS!!! too many queued (%d), " - "toss packet, done", - rd->rd_queue_len); - mutex_exit(&rd->rd_xmit_lock); - UNREFDEST(rd); - TNF_PROBE_1(wrsmdqueuemsg_end, "RSMPI", - "wrsmdqueuemsg end; failure 2manyqueued", - tnf_string, failure, "2manyqueued"); - return (B_FALSE); - } - - if (rd->rd_queue_h == NULL) - rd->rd_queue_h = mp; - else - rd->rd_queue_t->b_next = mp; - rd->rd_queue_t = mp; - rd->rd_queue_len++; - - /* - * Since we're making a singly-linked list of mblks hanging off the - * destination structure, we can get away with stashing the destination - * SAP in the b_prev pointer of the mblk. This is pretty disgusting, - * but is much more efficient than the alternative: allocating a new - * structure with space for the SAP and a pointer to the mblk, and - * making a list of those instead. - */ - - mp->b_prev = (mblk_t *)(uintptr_t)sap; - - wrsmdp->wrsmd_starts++; - - if (wrsmdisstate(rd, WRSMD_STATE_W_READY)) { - if (from_put) { - wrsmdp->wrsmd_start_xfers++; - wrsmdxfer(wrsmdp, rd); - } else - wrsmdsetstate_nosrv(rd, WRSMD_STATE_S_XFER); - - } else if (wrsmdisstate(rd, WRSMD_STATE_W_FQE)) { - if (wrsmdavailfqe(rd)) { - tmoid = rd->rd_fqe_tmo_id; - rd->rd_fqe_tmo_id = 0; - rd->rd_tmo_int = 0; - mutex_exit(&rd->rd_xmit_lock); - if (tmoid) - (void) untimeout(tmoid); - mutex_enter(&rd->rd_xmit_lock); - - if (from_put) { - wrsmdp->wrsmd_start_xfers++; - wrsmdxfer(wrsmdp, rd); - } else - wrsmdsetstate_nosrv(rd, WRSMD_STATE_S_XFER); - } else { - /* - * no FQEs available, return to waiting state - */ - wrsmdsetstate(rd, WRSMD_STATE_W_FQE); - } - } - - mutex_exit(&rd->rd_xmit_lock); - - UNREFDEST(rd); - - return (B_TRUE); -} - - -/* - * Verify whether this is a valid message. Determine whether this is a - * broadcast message; send message to each recipient. Handle promiscuous - * mode. - */ -static void -wrsmdstart(wrsmd_t *wrsmdp, mblk_t *mp, dl_rsm_addr_t addr, ushort_t sap, - int from_put) -{ - int i; - boolean_t retval; - - D1("wrsmdstart: wrsmdp 0x%p (cltr %d), mp 0x%p, rsmaddr %ld, sap 0x%x, " - "from_put %d", (void *)wrsmdp, wrsmdp ? wrsmdp->wrsmd_ctlr_id : -1, - (void *)mp, addr.m.rsm, sap, from_put); - TNF_PROBE_5(wrsmdstart_start, "RSMPI", "wrsmdstart start", - tnf_ulong, wrsmdp, (ulong_t)wrsmdp, tnf_ulong, mp, - (ulong_t)mp, tnf_uint, addr.m.rsm, addr.m.rsm, tnf_uint, - sap, sap, tnf_int, from_put, from_put); - - /* Make sure we're not sending to ourselves */ - - if (addr.m.rsm == wrsmdp->wrsmd_rsm_addr.m.rsm) { - wrsmdp->wrsmd_oerrors++; - freemsg(mp); - DERR("wrsmdstart: TOSS!!! sending to ourselves, toss packet, " - "done"); - TNF_PROBE_1(wrsmdstart_end, "RSMPI", - "wrsmdstart end; failure sendtoself", - tnf_string, failure, "sendtoself"); - return; - } - - /* Make sure message is contiguous in memory */ - - if (mp->b_cont) { - mblk_t *nmp; - - nmp = msgpullup(mp, -1); - freemsg(mp); - - if (nmp == NULL) { - wrsmdp->wrsmd_pullup_fail++; - wrsmdp->wrsmd_oerrors++; - DERR("wrsmdstart: TOSS!!! can't pullup message, " - "toss packet, " - "done"); - return; - } - wrsmdp->wrsmd_pullup++; - mp = nmp; - } - - /* Make sure message isn't too big */ - - if (MBLKL(mp) > (wrsmdp->wrsmd_param.wrsmd_buffer_size - - WRSMD_CACHELINE_SIZE)) { - wrsmdp->wrsmd_oerrors++; - freemsg(mp); - DERR("wrsmdstart: TOSS!!! message too big, toss packet, done"); - TNF_PROBE_1(wrsmdstart_end, "RSMPI", - "wrsmdstart end; failure msgtoobig", - tnf_string, failure, "msgtoobig"); - return; - } - - /* - * Send message to each addressee (normally there is just one). - */ - - /* Loop message back up if we're in promiscuous mode */ - if (wrsmdp->wrsmd_promisc) { - mblk_t *nmp; - - if (nmp = dupmsg(mp)) - wrsmdpromsendup(wrsmdp, nmp, addr, - wrsmdp->wrsmd_rsm_addr, sap); - } - - if (addr.m.rsm > RSM_MAX_DESTADDR) { - /* - * handle broadcast and multicast messages - */ - rsm_addr_t addr_list[RSM_MAX_DESTADDR]; - uint_t num_addrs; - boolean_t copy; - - D1("wrsmdstart: broadcast message; collect peers"); - - if (RSM_GET_PEERS(wrsmdp->wrsmd_ctlr, - addr_list, RSM_MAX_DESTADDR, &num_addrs) != RSM_SUCCESS) { - D1("wrsmdstart: cannot collect list of peers " - "for broadcast"); - wrsmdp->wrsmd_oerrors++; - freemsg(mp); - return; - } - - ASSERT(num_addrs <= RSM_MAX_DESTADDR); - - /* - * Make a copy of the message for all but the last - * recipient. Don't broadcast to the local node. - */ - for (i = 0; i < num_addrs; i++) { - if (addr_list[i] == wrsmdp->wrsmd_rsm_addr.m.rsm) - continue; - /* - * If this is the last node or if this is the - * second to last and the last is ourselves, - * don't make a copy of the message. - */ - if ((i == (num_addrs - 1)) || - ((i == (num_addrs - 2)) && - addr_list[i+1] == wrsmdp->wrsmd_rsm_addr.m.rsm)) { - copy = B_FALSE; - } else { - copy = B_TRUE; - } - addr.m.rsm = addr_list[i]; - retval = wrsmdqueuemsg(wrsmdp, mp, addr, sap, - from_put, copy); - if (copy == B_FALSE && retval == B_FALSE) { - freemsg(mp); - } - } - - } else { - retval = wrsmdqueuemsg(wrsmdp, mp, addr, sap, - from_put, B_FALSE); - if (retval == B_FALSE) { - freemsg(mp); - } - } - - D1("wrsmdstart: done"); - TNF_PROBE_1(wrsmdstart_end, "RSMPI", "wrsmdstart end", - tnf_string, completed, ""); -} - - -/* - * These macros are used in several places in wrsmdsendup(). - */ - -/* - * Return 1 if the stream pointed to by wrsmdstr is connected to wrsmdp and - * interested in this sap. - */ -#define WRSMDSAPMATCH(wrsmdp, wrsmdstr, sap) \ - (((wrsmdstr)->ss_wrsmdp == wrsmdp) && \ - ((wrsmdstr)->ss_sap == (sap) || \ - ((wrsmdstr)->ss_flags & WRSMD_SLALLSAP))) - -/* - * Return 1 if the stream pointed to by wrsmdstr is connected to wrsmdp, - * interested in all saps, and in physical promiscuous mode. - */ -#define WRSMDPROMMATCH(wrsmdp, wrsmdstr) \ - (((wrsmdstr)->ss_wrsmdp == wrsmdp) && \ - ((wrsmdstr)->ss_flags & WRSMD_SLALLSAP) && \ - ((wrsmdstr)->ss_flags & WRSMD_SLALLPHYS)) -/* - * Do appropriate processing to send message msg up stream wrsmdstr. - * "name" is the name of the calling routine, used for debugging messages; - * to, from and sap are the packet's to address, from address, and SAP. - */ -#define WRSMDMSGPROC(wrsmdp, wrsmdstr, msg, name, to, from, sap) { \ - D2(name " : checking msg 0x%p queue 0x%p", \ - (void *)(msg), (void *)(wrsmdstr)->ss_rq); \ - if ((wrsmdstr)->ss_flags & WRSMD_SLFAST) { \ - (void) putnext((wrsmdstr)->ss_rq, (msg)); \ - } else if ((wrsmdstr)->ss_flags & WRSMD_SLRAW) { \ - if ((msg) = wrsmdaddhdr(wrsmdp, (msg), (to), \ - (from), (sap))) \ - (void) putnext((wrsmdstr)->ss_rq, \ - (msg)); \ - } else if ((msg) = wrsmdaddudind(wrsmdp, (msg), (to), \ - (from), (sap))) { \ - D2(name " : sending msg 0x%p up queue 0x%p", \ - (void *)(msg), (void *)(wrsmdstr)->ss_rq); \ - (void) putnext((wrsmdstr)->ss_rq, (msg)); \ - } \ -} - -/* - * Send packet upstream. - */ -static void -wrsmdsendup( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - mblk_t *mp, /* Message to send up */ - dl_rsm_addr_t to, /* Address packet was sent to */ - dl_rsm_addr_t from, /* Address packet was received from */ - ushort_t sap) /* Packet's SAP */ -{ - wrsmdstr_t *ssp, *nssp; - mblk_t *nmp; - - D1("wrsmdsendup: wrsmdp 0x%p (cltr %d), mp 0x%p, to %ld, from %ld, " - "sap 0x%x", (void *)wrsmdp, wrsmdp->wrsmd_ctlr_id, (void *)mp, - to.m.rsm, from.m.rsm, sap); - TNF_PROBE_5(wrsmdsendup_start, "RSMPI", "wrsmdsendup start", - tnf_ulong, wrsmdp, (ulong_t)wrsmdp, tnf_ulong, mp, (ulong_t)mp, - tnf_long, to.m.rsm, to.m.rsm, tnf_long, from.m.rsm, from.m.rsm, - tnf_long, sap, sap); - - /* - * While holding a reader lock on the linked list of streams - * structures, attempt to match the address criteria for each stream - * and pass up the DL_UNITDATA_IND. - */ - - rw_enter(&wrsmdstruplock, RW_READER); - - /* - * This is pretty tricky. If there are multiple streams that want - * this packet, we have to make a new copy for all but one of them - * (we can send the original packet up one of the streams). However, - * if we do things the straightforward way: - * - * while (stream wants packet) - * newmsg = copy (msg); - * send newmsg up stream - * go to next stream - * free oldmsg - * - * we end up always doing a copy, even if (as is usually the case) - * the packet only goes to one stream. This is bad. Thus what we do - * is the following: - * - * Find a stream that wants this packet. If there aren't any, - * we're done. - * For each other stream that wants this packet, make a copy of - * it and send it up. - * Finally, send the original packet up the first stream we found. - */ - - for (ssp = wrsmdstrup; ssp; ssp = ssp->ss_nextp) { - D1("wrsmdsendup ssp->ss_sap 0x%x flags 0x%x", ssp->ss_sap, - ssp->ss_flags); - if (WRSMDSAPMATCH(wrsmdp, ssp, sap)) - break; - } - - if (ssp) { - TNF_PROBE_3(wrsmdsendup_SMPfor, "RSMPI", - "wrsmdsendup SMPfor", tnf_long, to.m.rsm, to.m.rsm, - tnf_long, from.m.rsm, from.m.rsm, tnf_long, sap, sap); - for (nssp = ssp->ss_nextp; nssp; nssp = nssp->ss_nextp) { - D1("wrsmdsendup nssp->ss_sap 0x%x flags 0x%x", - nssp->ss_sap, ssp->ss_flags); - if (WRSMDSAPMATCH(wrsmdp, nssp, sap) && - canputnext((queue_t *)nssp->ss_rq) && - (nmp = dupmsg(mp))) { - WRSMDMSGPROC(wrsmdp, nssp, nmp, "wrsmdsendup", - to, from, sap); - } - } - TNF_PROBE_1(wrsmdsendup_SMPforend, "RSMPI", - "wrsmdsendup SMPforend", tnf_string, completed, ""); - /* - * Do the last one. - */ - if (canputnext((queue_t *)ssp->ss_rq)) { - TNF_PROBE_5(wrsmdsendup_SMPlast, "RSMPI", - "wrsmdsendup SMPlast", tnf_ulong, ssp, (ulong_t)ssp, - tnf_ulong, mp, (ulong_t)mp, tnf_long, to.m.rsm, - to.m.rsm, tnf_long, from.m.rsm, from.m.rsm, - tnf_long, sap, sap); - WRSMDMSGPROC(wrsmdp, ssp, mp, "wrsmdsendup", to, from, - sap); - TNF_PROBE_1(wrsmdsendup_SMPlastend, "RSMPI", - "wrsmdsendup SMPlastend", tnf_string, completed, - ""); - } else - freemsg(mp); - } else - freemsg(mp); - - rw_exit(&wrsmdstruplock); - - D1("wrsmdsendup: done"); - TNF_PROBE_1(wrsmdsendup_end, "RSMPI", "wrsmdsendup end", - tnf_string, completed, ""); -} - -/* - * Send outgoing packet upstream to promiscuous mode readers. This routine - * is an exact duplicate of wrsmdsendup(), above, except that we use - * WRSMDPROMMATCH instead of WRSMDSAPMATCH. (The difference is that - * the latter only selects streams which are in promiscuous mode; this - * keeps IP from getting its own packets back, since we don't check the - * destination addresses when sending packets upstream.) - */ -static void -wrsmdpromsendup( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - mblk_t *mp, /* Message to send up */ - dl_rsm_addr_t to, /* Address packet was sent to */ - dl_rsm_addr_t from, /* Address packet was received from */ - ushort_t sap) /* Packet's SAP */ -{ - wrsmdstr_t *ssp, *nssp; - mblk_t *nmp; - - D1("wrsmdpromsendup: wrsmdp 0x%p (cltr %d), mp 0x%p, to %ld, from %ld, " - "sap 0x%x", (void *)wrsmdp, wrsmdp ? wrsmdp->wrsmd_ctlr_id : -1, - (void *)mp, to.m.rsm, - from.m.rsm, sap); - - /* - * While holding a reader lock on the linked list of streams structures, - * attempt to match the address criteria for each stream - * and pass up the DL_UNITDATA_IND. - */ - - rw_enter(&wrsmdstruplock, RW_READER); - - /* - * See explanation above of why this is somewhat less than - * straightforward. - */ - - for (ssp = wrsmdstrup; ssp; ssp = ssp->ss_nextp) { - if (WRSMDPROMMATCH(wrsmdp, ssp)) - break; - } - - if (ssp) { - for (nssp = ssp->ss_nextp; nssp; nssp = nssp->ss_nextp) - if (WRSMDPROMMATCH(wrsmdp, nssp) && - canputnext((queue_t *)nssp->ss_rq) && - (nmp = dupmsg(mp))) - WRSMDMSGPROC(wrsmdp, nssp, nmp, - "wrsmdpromsendup", to, from, sap); - /* - * Do the last one. - */ - if (canputnext((queue_t *)ssp->ss_rq)) { - WRSMDMSGPROC(wrsmdp, ssp, mp, "wrsmdpromsendup", - to, from, sap); - } else - freemsg(mp); - } else - freemsg(mp); - - rw_exit(&wrsmdstruplock); - - D1("wrsmdpromsendup: done"); -} - -/* - * Prefix msg with a DL_UNITDATA_IND mblk and return the new msg. If we - * can't, free the msg and return NULL. - */ -static mblk_t * -wrsmdaddudind( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - mblk_t *mp, /* Message to add indication to */ - dl_rsm_addr_t to, /* Address packet was sent to */ - dl_rsm_addr_t from, /* Address packet was received from */ - ushort_t sap) /* Packet's SAP */ -{ - dl_unitdata_ind_t *dludindp; - wrsmddladdr_t *dlap; - mblk_t *nmp; - size_t size; - - D1("wrsmdaddudind: wrsmdp 0x%p (cltr %d), mp 0x%p, to %ld, from %ld, " - "sap 0x%x", (void *)wrsmdp, wrsmdp->wrsmd_ctlr_id, (void *)mp, - to.m.rsm, from.m.rsm, sap); - - /* - * Allocate an M_PROTO mblk for the DL_UNITDATA_IND. - * Allocate enough room in mblk that IP/TCP can prepend their - * own headers as well. - */ - size = sizeof (dl_unitdata_ind_t) + WRSMD_DEVICE_ADDRL + - WRSMD_DEVICE_ADDRL; - if ((nmp = allocb(WRSMDHEADROOM + size, BPRI_LO)) == NULL) { - wrsmdp->wrsmd_ierrors++; - freemsg(mp); - D1("wrsmdaddudind: bad allocb, returning NULL"); - return (NULL); - } - DB_TYPE(nmp) = M_PROTO; - nmp->b_wptr = nmp->b_datap->db_lim; - nmp->b_rptr = nmp->b_wptr - size; - - /* - * Construct a DL_UNITDATA_IND primitive. - */ - dludindp = (dl_unitdata_ind_t *)nmp->b_rptr; - dludindp->dl_primitive = DL_UNITDATA_IND; - dludindp->dl_dest_addr_length = WRSMD_DEVICE_ADDRL; - dludindp->dl_dest_addr_offset = sizeof (dl_unitdata_ind_t); - dludindp->dl_src_addr_length = WRSMD_DEVICE_ADDRL; - dludindp->dl_src_addr_offset = sizeof (dl_unitdata_ind_t) + - WRSMD_DEVICE_ADDRL; - - dludindp->dl_group_address = 0; - - /* plug in dest addr */ - dlap = (wrsmddladdr_t *)(nmp->b_rptr + sizeof (dl_unitdata_ind_t)); - ether_copy(&(to.m.ether.addr), &(dlap->dl_addr)); - dlap->dl_sap = sap; - - /* plug in src addr */ - dlap = (wrsmddladdr_t *) - (nmp->b_rptr + sizeof (dl_unitdata_ind_t) + WRSMD_DEVICE_ADDRL); - ether_copy(&(from.m.ether.addr), &(dlap->dl_addr)); - dlap->dl_sap = 0; /* we don't have this info */ - - /* - * Link the M_PROTO and M_DATA together. - */ - linkb(nmp, mp); - - D1("wrsmdaddudind: new header follows"); - - D3D(nmp->b_rptr, MBLKL(nmp)); - D1("wrsmdaddudind: returning 0x%p", (void *)nmp); - - return (nmp); -} - -/* - * Prefix msg with a "fake hardware header" (either in-place, or in a - * separate mblk)and return the new msg. If we can't, free the msg and - * return NULL. - */ -static mblk_t * -wrsmdaddhdr( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - mblk_t *mp, /* Message to add indication to */ - dl_rsm_addr_t to, /* Address packet was sent to */ - dl_rsm_addr_t from, /* Address packet was received from */ - ushort_t sap) /* Packet's SAP */ -{ - mblk_t *nmp; - struct ether_header *headerp; - - D1("wrsmdaddhdr: wrsmdp 0x%p (cltr %d), mp 0x%p, to %ld, from %ld, " - "sap 0x%x", (void *)wrsmdp, wrsmdp ? wrsmdp->wrsmd_ctlr_id : -1, - (void *)mp, to.m.rsm, from.m.rsm, sap); - - /* - * Create link-level header by either prepending it onto the - * data if possible, or allocating a new mblk if not. - */ - if ((DB_REF(mp) == 1) && - (MBLKHEAD(mp) >= sizeof (struct ether_header)) && - (((uintptr_t)mp->b_rptr & 0x1) == 0)) { - mp->b_rptr -= sizeof (struct ether_header); - headerp = (struct ether_header *)mp->b_rptr; - } else { - /* Allocate an M_DATA mblk for the header. */ - if ((nmp = allocb(sizeof (struct ether_header), - BPRI_LO)) == NULL) { - wrsmdp->wrsmd_ierrors++; - freemsg(mp); - D1("wrsmdaddhdr: bad allocb, returning NULL"); - return (NULL); - } - DB_TYPE(nmp) = M_DATA; - linkb(nmp, mp); - mp = nmp; - headerp = (struct ether_header *)mp->b_rptr; - mp->b_wptr += sizeof (*headerp); - } - - /* - * Fill in header. It is at least short aligned. - */ - - ether_copy(&(to.m.ether.addr), &(headerp->ether_dhost)); - ether_copy(&(from.m.ether.addr), &(headerp->ether_shost)); - headerp->ether_type = sap; - - D1("wrsmdaddhdr: returning 0x%p", (void *)mp); - - return (mp); -} - - - -/* - * Callback routine, called when an desballoc'ed buffer is eventually freed. - */ -static void -wrsmdfreebuf( - wrsmdbuf_t *rbp) /* Structure describing freed buffer */ -{ - wrsmd_dest_t *rd = rbp->rb_rd; - int delflg, zerflg; - - D1("wrsmdfreebuf: rbp 0x%p", (void *)rbp); - - /* - * Find out if this is the last outstanding buffer, and whether we're - * being deleted. - */ - mutex_enter(&rd->rd_nlb_lock); - - rd->rd_nlb--; - delflg = rd->rd_nlb_del; - zerflg = (rd->rd_nlb == 0); - - mutex_exit(&rd->rd_nlb_lock); - - /* - * If we're being deleted, we don't put this buffer on the free queue. - * Also, if we're being deleted, and this was the last outstanding - * buffer, we do an UNREF. Otherwise we send this buffer to the other - * system for reuse. - */ - if (delflg) { - if (zerflg) - UNREFDEST(rd); - } else { - wrsmdputfqe(rd, rbp->rb_bufnum); - mutex_enter(&rd->rd_net_lock); - wrsmdsyncfqe(rd); - mutex_exit(&rd->rd_net_lock); - } - - D1("wrsmdfreebuf: done"); -} - -/* - * wrsmdread() takes the packet described by the arguments and sends it - * upstream. - */ -static int -wrsmdread( - wrsmd_dest_t *rd, /* Destination pointer */ - int bufnum, /* Index of buffer containing packet */ - int offset, /* Offset of packet within buffer */ - int length, /* Length of packet */ - ushort_t sap) /* SAP for packet */ -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - mblk_t *mp; - dl_rsm_addr_t from; - int canloan = B_FALSE; - caddr_t bufptr; - queue_t *ipq; - int buffree = 0; - - D1("wrsmdread: rd 0x%p, bufnum %d, offset %d, length %d, sap 0x%x", - (void *)rd, bufnum, offset, length, sap); - - TNF_PROBE_5(wrsmdread_start, "RSMPI", "wrsmdread start", - tnf_long, rd, (tnf_long_t)rd, tnf_long, bufnum, bufnum, - tnf_long, offset, offset, tnf_long, length, length, - tnf_long, sap, sap); - - bufptr = (caddr_t)rd->rd_lbuf + (bufnum * rd->rd_lbuflen); - from.m.rsm = rd->rd_rsm_addr; - - /* Figure out if we can loan this buffer up or not */ - - mutex_enter(&rd->rd_nlb_lock); - if (rd->rd_nlb < (wrsmdp->wrsmd_param.wrsmd_buffers - - wrsmdp->wrsmd_param.wrsmd_buffers_retained)) { - rd->rd_nlb++; - canloan = B_TRUE; - } - mutex_exit(&rd->rd_nlb_lock); - - - if (canloan) { - /* - * We make the mblk cover the whole buffer in case anybody - * wants the leading/trailing space; below we adjust the - * rptr/wptr to describe the actual packet. - */ - mp = desballoc((uchar_t *)bufptr, rd->rd_lbuflen, - BPRI_LO, &(rd->rd_bufbase+bufnum)->rb_frtn); - - if (mp == NULL) { - mutex_enter(&rd->rd_nlb_lock); - rd->rd_nlb--; - mutex_exit(&rd->rd_nlb_lock); - - wrsmdputfqe(rd, bufnum); - buffree = 1; - - wrsmdp->wrsmd_ierrors++; - D1("wrsmdread: can't desballoc, done"); - TNF_PROBE_1(wrsmdread_end, "RSMPI", - "wrsmdread end; failure desballoc", - tnf_string, failure, "desballoc"); - return (1); - } - mp->b_rptr += offset; - mp->b_wptr = mp->b_rptr + length; - - wrsmdp->wrsmd_lbufs++; - D3D(mp->b_rptr, length); - } else { - /* - * We make the destination (within the new mblk) have the - * same address mod 64 as our source, so that the kernel - * bcopy is as efficient as possible. (This is a sun4u - * bcopy optimization, not a Wildcat/RSM optimization.) - */ - mp = allocb(length + 0x40, BPRI_LO); - if (mp) { - intptr_t dstoffset = (intptr_t)mp->b_rptr; - - dstoffset = offset - (dstoffset & 0x3f); - if (dstoffset < 0) - dstoffset += 0x40; - - mp->b_rptr += dstoffset; - mp->b_wptr = mp->b_rptr + length; - bcopy((void *)(bufptr + offset), (void *)mp->b_rptr, - length); - - D3D(mp->b_rptr, length); - - wrsmdp->wrsmd_nlbufs++; - wrsmdputfqe(rd, bufnum); - buffree = 1; - } else { - wrsmdputfqe(rd, bufnum); - buffree = 1; - wrsmdp->wrsmd_ierrors++; - D1("wrsmdread: can't allocb, done"); - TNF_PROBE_1(wrsmdread_end, "RSMPI", - "wrsmdread end; failure allocb", - tnf_string, failure, "allocb"); - return (1); - } - } - - wrsmdp->wrsmd_ipackets++; - wrsmdp->wrsmd_in_bytes += length; - - - /* - * IP shortcut - */ - rw_enter(&wrsmdp->wrsmd_ipq_rwlock, RW_READER); - ipq = wrsmdp->wrsmd_ipq; - - if (ipq && (sap == WRSMD_IP_SAP)) { - if (canputnext(ipq)) { - TNF_PROBE_2(wrsmdread_IPscut, "RSMPI", - "wrsmdread IPscut", tnf_long, ipq, (tnf_long_t)ipq, - tnf_long, mp, (tnf_long_t)mp); - putnext(ipq, mp); - TNF_PROBE_1(wrsmdread_IPscutend, "RSMPI", - "wrsmdread IPscutend", tnf_string, completed, ""); - } else - freemsg(mp); - } else - wrsmdsendup(wrsmdp, mp, wrsmdp->wrsmd_rsm_addr, from, - sap); - - rw_exit(&wrsmdp->wrsmd_ipq_rwlock); - - D1("wrsmdread: canloan was %d, done", canloan); - TNF_PROBE_1(wrsmdread_end, "RSMPI", "wrsmdread end", - tnf_string, completed, ""); - - return (buffree); -} - -/* - * **************************************************************** - * * - * E N D HIGH LEVEL PROTOCOL INTERFACE AND UTILITIES * - * * - * **************************************************************** - */ - - -/* - * **************************************************************** - * * - * B E G I N RSM SETUP/TAKEDOWN * - * * - * **************************************************************** - */ - -/* - * Initialize WRSMD resources. Return 0 on success, nonzero on error. - */ -static int -wrsmdinit(wrsmd_t *wrsmdp) /* WRSMD device (RSM controller) pointer */ -{ - int stat; - - D1("wrsmdinit: wrsmdp 0x%p (cltr %d)", (void *)wrsmdp, - wrsmdp->wrsmd_ctlr_id); - - ASSERT(MUTEX_HELD(&wrsmdp->wrsmd_lock)); - - /* LINTED: E_TRUE_LOGICAL_EXPR */ - ASSERT(sizeof (dl_rsm_addr_t) == sizeof (rsm_addr_t)); - - wrsmdp->wrsmd_flags = 0; - - /* - * Preceding teardown may not have released controller. - * If so, do so now to avoid multiple reference counts. - */ - if (wrsmdp->wrsmd_flags & WRSMDGOTCTLR) { - D1("wrsmdinit: controller still held, " - "call rsm_release_controller()"); - rsm_release_controller(WRSM_NAME, wrsmdp->wrsmd_ctlr_id, - &(wrsmdp->wrsmd_ctlr)); - wrsmdp->wrsmd_ctlr.handle = NULL; - wrsmdp->wrsmd_flags &= ~WRSMDGOTCTLR; - } - - if ((stat = rsm_get_controller(WRSM_NAME, wrsmdp->wrsmd_ctlr_id, - &(wrsmdp->wrsmd_ctlr), RSM_VERSION)) != RSM_SUCCESS) { - D1("wrsmdinit: bad get_controller error %d", stat); - return (1); - } - if ((stat = rsm_get_controller_attr(wrsmdp->wrsmd_ctlr.handle, - &(wrsmdp->wrsmd_ctlr_attr))) != RSM_SUCCESS) { - D1("wrsmdinit: bad get_controller_attr error %d", stat); - rsm_release_controller(WRSM_NAME, wrsmdp->wrsmd_ctlr_id, - &(wrsmdp->wrsmd_ctlr)); - wrsmdp->wrsmd_ctlr.handle = NULL; - return (1); - } - - /* - * We only support RSM addresses that fit into 6 bytes. This - * will always be the case on Wildcat. (Address range is 0-255.) - */ - ASSERT(wrsmdp->wrsmd_ctlr_attr->attr_controller_addr <= - (rsm_addr_t)0xffffffffffffLL); - wrsmdp->wrsmd_rsm_addr.m.rsm = - wrsmdp->wrsmd_ctlr_attr->attr_controller_addr; - /* - * Since this address is locally generated, turn on the locally - * administered bit in the ethernet address to comply with IEEE 802. - */ - wrsmdp->wrsmd_rsm_addr.m.ether.addr.ether_addr_octet[0] |= 0x02; - - wrsmdp->wrsmd_flags |= WRSMDGOTCTLR; - - if ((stat = RSM_REGISTER_HANDLER(wrsmdp->wrsmd_ctlr, - RSM_INTR_T_SUN_BASE, wrsmd_rsm_intr_handler, - (rsm_intr_hand_arg_t)wrsmdp, NULL, 0)) != - RSM_SUCCESS) { - D1("wrsmdinit: cannot register interrupt handler: %d", stat); - rsm_release_controller(WRSM_NAME, wrsmdp->wrsmd_ctlr_id, - &(wrsmdp->wrsmd_ctlr)); - wrsmdp->wrsmd_ctlr.handle = NULL; - wrsmdp->wrsmd_flags &= ~WRSMDGOTCTLR; - return (1); - } - - wrsmdp->wrsmd_flags |= WRSMDREGHANDLER; - - /* - * Clear any leftover junk from run queue. (We could have destinations - * here if the user detached from a device, then reattached before - * the destinations got deleted.) These destination structures will - * eventually be freed when the deletion process completes. - */ - mutex_enter(&wrsmdp->wrsmd_runq_lock); - wrsmdp->wrsmd_runq = NULL; - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - D1("wrsmdinit: returning 0"); - - return (0); -} - -/* - * Un-initialize WRSMD resources. Returns 0 if completely successful. - * Returns -1 if not in a state where uninitialize makes sense. Returns >0 - * if uninitialize was started, but hasn't completed because not all - * connections have been torn down yet. - */ -static int -wrsmduninit(wrsmd_t *wrsmdp) -{ - int dests_not_cleaned_up; - int i; - rsm_controller_object_t ctlr; - - D1("wrsmduninit: wrsmdp 0x%p (cltr %d)", (void *)wrsmdp, - wrsmdp->wrsmd_ctlr_id); - - mutex_enter(&wrsmdp->wrsmd_lock); - - if (wrsmdp->wrsmd_attached_streams) { - /* - * don't uninitialize device while streams are attached to it - */ - D1("wrsmduninit: %d streams still attached, failing", - wrsmdp->wrsmd_attached_streams); - mutex_exit(&wrsmdp->wrsmd_lock); - return (-1); - } - - if (wrsmdp->wrsmd_flags & WRSMDREGHANDLER) { - /* - * Must release the mutex here to avoid a potential deadlock. - * The wrsm_unregister_handler() code acquires the wrsm - * service->handler_mutex. If an inbound interrupt occurs, - * the wrsm service_callback grabs the service->handler_mutex, - * and calls back into the wrsmd_rsm_intr_handler() routine, - * which attempts to grab the wrsmdp->wrsmd_lock. If at the - * time we invoke RSM_UNREGISTER_HANDLER() while holding the - * wrsmdp->wrsmd_lock, we get a circular lock deadlock. - */ - ctlr = wrsmdp->wrsmd_ctlr; - mutex_exit(&wrsmdp->wrsmd_lock); - RSM_UNREGISTER_HANDLER(ctlr, RSM_INTR_T_SUN_BASE, - wrsmd_rsm_intr_handler, (rsm_intr_hand_arg_t)wrsmdp); - mutex_enter(&wrsmdp->wrsmd_lock); - wrsmdp->wrsmd_flags &= ~WRSMDREGHANDLER; - } - - for (i = 0; i < RSM_MAX_DESTADDR; i++) - wrsmdfreedest(wrsmdp, i); - - mutex_enter(&wrsmdp->wrsmd_dest_lock); - dests_not_cleaned_up = wrsmdp->wrsmd_numdest; - mutex_exit(&wrsmdp->wrsmd_dest_lock); - - if ((wrsmdp->wrsmd_flags & WRSMDGOTCTLR) && - (dests_not_cleaned_up == 0)) { - /* - * there will be no more RSMPI calls, so - * it's safe to release the controller - */ - D1("wrsmduninit: call rsm_release_controller()"); - rsm_release_controller(WRSM_NAME, wrsmdp->wrsmd_ctlr_id, - &(wrsmdp->wrsmd_ctlr)); - wrsmdp->wrsmd_ctlr.handle = NULL; - wrsmdp->wrsmd_flags &= ~WRSMDGOTCTLR; - } - mutex_exit(&wrsmdp->wrsmd_lock); - - D1("wrsmduninit: returning %d", - dests_not_cleaned_up); - - return (dests_not_cleaned_up); -} - -/* - * Get all the wrsmd parameters out of the device tree and store them in a - * WRSMD device (RSM controller) structure. - */ -static void -wrsmdgetparam( - dev_info_t *dip, /* Device's info pointer */ - wrsmd_t *wrsmdp) /* WRSMD device (RSM controller) pointer */ -{ - struct wrsmd_param *sp = &wrsmdp->wrsmd_param; - boolean_t modified_bufsize = B_FALSE; - - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*sp)) - - /* Get parameters */ - - sp->wrsmd_buffers = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-buffers", WRSMD_BUFFERS_DFLT); - sp->wrsmd_buffer_size = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-buffer-size", WRSMD_BUFFER_SIZE_DFLT); - sp->wrsmd_queue_size = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-queue-size", WRSMD_QUEUE_SIZE_DFLT); - sp->wrsmd_buffers_retained = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-buffers-retained", WRSMD_BUFFERS_RETAINED_DFLT); - sp->wrsmd_idle_reclaim_time = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-idle-reclaim-time", WRSMD_IDLE_RECLAIM_TIME_DFLT); - sp->wrsmd_err_retries = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-err-retries", WRSMD_ERR_RETRIES_DFLT); - sp->wrsmd_max_queued_pkts = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-max-queued-pkts", WRSMD_MAX_QUEUED_PKTS_DFLT); - sp->wrsmd_nobuf_init_tmo = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-nobuf-init-tmo", WRSMD_NOBUF_INIT_TMO_DFLT); - sp->wrsmd_nobuf_max_tmo = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-nobuf-max-tmo", WRSMD_NOBUF_MAX_TMO_DFLT); - sp->wrsmd_nobuf_drop_tmo = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-nobuf-drop-tmo", WRSMD_NOBUF_DROP_TMO_DFLT); - sp->wrsmd_msg_init_tmo = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-msg-init-tmo", WRSMD_MSG_INIT_TMO_DFLT); - sp->wrsmd_msg_max_tmo = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-msg-max-tmo", WRSMD_MSG_MAX_TMO_DFLT); - sp->wrsmd_msg_drop_tmo = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-msg-drop-tmo", WRSMD_MSG_DROP_TMO_DFLT); - sp->wrsmd_ack_tmo = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-ack-tmo", WRSMD_ACK_TMO_DFLT); - sp->wrsmd_sync_tmo = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-sync-tmo", WRSMD_SYNC_TMO_DFLT); - sp->wrsmd_teardown_tmo = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-teardown-tmo", WRSMD_TEARDOWN_TMO_DFLT); - sp->wrsmd_train_size = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-train-size", WRSMD_TRAIN_SIZE_DFLT); - sp->wrsmd_fqe_sync_size = ddi_getprop(DDI_DEV_T_ANY, dip, 0, - "wrsmd-fqe-sync-size", WRSMD_FQE_SYNC_SIZE_DFLT); - - /* - * Sanity check parameters, modify if needed. Note that we mainly - * check to make sure parameters won't make the driver malfunction; - * we don't necessarily prevent them from being stupid. - */ - - /* Need to have at least one buffer. */ - - if (sp->wrsmd_buffers == 0) - sp->wrsmd_buffers = 1; - -#ifdef RESTRICT_MAX_BUFFER_SIZE - /* Can't put more than 64K in a buffer (IP max packet length). */ - - if (sp->wrsmd_buffer_size > (64 * 1024)) { - sp->wrsmd_buffer_size = (64 * 1024); - modified_bufsize = B_TRUE; - } -#endif - - /* - * Have to be able to send at least a 576-byte packet (IP reqmnt). - * Add 2 cachelines so that packet will fit no matter how it is - * aligned. - */ - - if (sp->wrsmd_buffer_size < - (576+WRSMD_CACHELINE_SIZE+WRSMD_CACHELINE_SIZE)) { - sp->wrsmd_buffer_size = - 576+WRSMD_CACHELINE_SIZE+WRSMD_CACHELINE_SIZE; - modified_bufsize = B_TRUE; - } - - /* Buffer length must be multiple of 64 (0x40). */ - - if (sp->wrsmd_buffer_size & ~WRSMD_CACHELINE_MASK) { - sp->wrsmd_buffer_size &= WRSMD_CACHELINE_MASK; - modified_bufsize = B_TRUE; - } - - if (modified_bufsize) { - cmn_err(CE_NOTE, "adjusted wrsmd-buffer-size value from " - "wrsmd.conf to 0x%x", sp->wrsmd_buffer_size); - } - - /* - * Must have at least one more queue element then the number of - * buffers. This is so that we can track when all queue elements - * need to be flushed to remote. - */ - - if (sp->wrsmd_queue_size <= sp->wrsmd_buffers) { - sp->wrsmd_queue_size = sp->wrsmd_buffers + 1; - cmn_err(CE_NOTE, "adjusted wrsmd-queue-size value from " - "wrsmd.conf to 0x%x", sp->wrsmd_queue_size); - } - - /* Can't retain more buffers than we have. */ - - if (sp->wrsmd_buffers_retained > sp->wrsmd_buffers) { - sp->wrsmd_buffers_retained = sp->wrsmd_buffers; - cmn_err(CE_NOTE, "adjusted wrsmd-buffers-retained value " - "from wrsmd.conf to 0x%x", sp->wrsmd_buffers_retained); - } - - /* Have to be able to send at least 1 packet at a time. */ - - if (sp->wrsmd_train_size < 1) { - sp->wrsmd_train_size = 1; - cmn_err(CE_NOTE, "adjusted wrsmd-train-size value " - "from wrsmd.conf to 0x%x", sp->wrsmd_train_size); - } - - /* Have to be able to queue at least 1 packet. */ - - if (sp->wrsmd_max_queued_pkts < 1) { - sp->wrsmd_max_queued_pkts = 1; - cmn_err(CE_NOTE, "adjusted wrsmd-max-queued-packets " - "value from wrsmd.conf to 0x%x", - sp->wrsmd_max_queued_pkts); - } - - /* - * Convert timeout parameters in milliseconds to - * absolute clock ticks, depending on clock hertz. - */ - sp->wrsmd_idle_reclaim_time = WRSMD_TICKS(sp->wrsmd_idle_reclaim_time); - sp->wrsmd_nobuf_init_tmo = WRSMD_TICKS(sp->wrsmd_nobuf_init_tmo); - sp->wrsmd_nobuf_max_tmo = WRSMD_TICKS(sp->wrsmd_nobuf_max_tmo); - sp->wrsmd_nobuf_drop_tmo = WRSMD_TICKS(sp->wrsmd_nobuf_drop_tmo); - sp->wrsmd_msg_init_tmo = WRSMD_TICKS(sp->wrsmd_msg_init_tmo); - sp->wrsmd_msg_max_tmo = WRSMD_TICKS(sp->wrsmd_msg_max_tmo); - sp->wrsmd_msg_drop_tmo = WRSMD_TICKS(sp->wrsmd_msg_drop_tmo); - sp->wrsmd_ack_tmo = WRSMD_TICKS(sp->wrsmd_ack_tmo); - sp->wrsmd_sync_tmo = WRSMD_TICKS(sp->wrsmd_sync_tmo); - sp->wrsmd_teardown_tmo = WRSMD_TICKS(sp->wrsmd_teardown_tmo); - - /* Can't sleep for less than 1 tick. */ - - if (sp->wrsmd_nobuf_init_tmo < 1) { - sp->wrsmd_nobuf_init_tmo = 1; - cmn_err(CE_NOTE, "adjusted wrsm-nobuf-init-tmo " - "value from wrsmd.conf to 0x%x", - sp->wrsmd_nobuf_init_tmo); - } - if (sp->wrsmd_nobuf_max_tmo < 1) { - sp->wrsmd_nobuf_max_tmo = 1; - cmn_err(CE_NOTE, "adjusted wrsm-nobuf-max-tmo " - "value from wrsmd.conf to 0x%x", - sp->wrsmd_nobuf_max_tmo); - } - if (sp->wrsmd_msg_init_tmo < 1) { - sp->wrsmd_msg_init_tmo = 1; - cmn_err(CE_NOTE, "adjusted wrsm-msg-init-tmo " - "value from wrsmd.conf to 0x%x", - sp->wrsmd_msg_init_tmo); - } - if (sp->wrsmd_msg_max_tmo < 1) { - sp->wrsmd_msg_max_tmo = 1; - cmn_err(CE_NOTE, "adjusted wrsm-msg-max-tmo " - "value from wrsmd.conf to 0x%x", - sp->wrsmd_msg_max_tmo); - } - if (sp->wrsmd_ack_tmo < 1) { - sp->wrsmd_ack_tmo = 1; - cmn_err(CE_NOTE, "adjusted wrsm-ack-tmo " - "value from wrsmd.conf to 0x%x", - sp->wrsmd_ack_tmo); - } - if (sp->wrsmd_sync_tmo < 1) { - sp->wrsmd_sync_tmo = 1; - cmn_err(CE_NOTE, "adjusted wrsm-sync-tmo " - "value from wrsmd.conf to 0x%x", - sp->wrsmd_sync_tmo); - } - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*sp)) -} - -/* - * **************************************************************** - * * - * E N D RSM SETUP/TAKEDOWN * - * * - * **************************************************************** - */ - - -/* - * **************************************************************** - * * - * B E G I N CONNECTION DATA STRUCTURE MANAGEMENT * - * * - * **************************************************************** - */ - - -/* - * Create the indicated destination structure, and return a pointer to it. - * NOTE: this should never be called directly; use the MAKEDEST macro - * instead. The macro checks that the destination structure does not yet - * exist before calling this function. - */ -static wrsmd_dest_t * -wrsmdmkdest(wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - rsm_addr_t rsm_addr) /* Address of destination to find/create */ -{ - wrsmd_dest_t *rd; - clock_t lbolt; - - D1("wrsmdmkdest: wrsmdp 0x%p (cltr %d), rsmaddr %ld", (void *)wrsmdp, - wrsmdp->wrsmd_ctlr_id, rsm_addr); - - /* Is the destination reasonable? */ - - if (rsm_addr >= RSM_MAX_DESTADDR) { - D1("wrsmdmkdest: too big, returning NULL"); - return (NULL); - } - - if ((rd = wrsmdp->wrsmd_desttbl[rsm_addr]) != NULL) { - return (rd); - } - - ASSERT(MUTEX_HELD(&wrsmdp->wrsmd_dest_lock)); - - if ((rd = kmem_zalloc(sizeof (*rd), KM_NOSLEEP)) == NULL) { - D1("wrsmdmkdest: can't alloc, returning NULL"); - return (NULL); - } - - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rd)); - rd->rd_wrsmdp = wrsmdp; - rd->rd_rsm_addr = rsm_addr; - - mutex_init(&rd->rd_net_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&rd->rd_xmit_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&rd->rd_lock, NULL, MUTEX_DRIVER, NULL); - - /* - * Use the time to generate a pseudo-random initial sequence - * number. - */ - (void) drv_getparm(LBOLT, &lbolt); - rd->rd_nseq = (ushort_t)lbolt; - - rd->rd_state = WRSMD_STATE_NEW; - rd->rd_refcnt = 1; - - wrsmdp->wrsmd_desttbl[rsm_addr] = rd; - wrsmdp->wrsmd_numdest++; - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rd)) - - D1("wrsmdmkdest: created new dest, returning 0x%p", (void *)rd); - - return (rd); -} - -/* - * Destination deletion - * - * As mentioned above (way above), we maintain a reference count on all - * destinations, which is incremented and decremented around uses of the - * destination structure. When this reference count goes to zero, we delete - * the destination. - * - * Because of the possibility of other threads trying to use the destination - * while we're deleting it, deletion is actually a multiple-step process, - * which works as follows. - * - * 1. When a destination is created, its dstate (deletion state) is set to - * zero, and its reference count is set to one. - * - * 2. When the service routine or some other routine decides that a destination - * should be deleted, it calls wrsmdfreedest(). That routine sets dstate - * to 1 and cancels any pending sync timeouts. It then decrements the - * destination's reference count. This deletes the reference set in - * wrsmdmkdest. (Note that since dstate is now 1, the FINDDEST and REFDEST - * macros will now note that the destination is being deleted; thus, any - * interrupt referring to the destination will no longer modify the - * reference count.) - * - * 3. Soon after this, wrsmddest_refcnt_0 is called. (This may either be - * directly from wrsmdfreedest(), or perhaps from another routine if it - * was running concurrently with freedest() and its UNREF happened last). - * This routine sees that dstate is 1, and immediately queues an event - * which will execute wrsmdfreedestevt(). (This is necessary because we - * may not be able to do everything in the phase 1 deletion from the routine - * that we're currently in.) - * - * 4. wrsmdfreedestevt() runs, it checks if there are any outstanding - * loaned-up buffers. If so, it sets a flag to cause the loan returning - * code to decrement the refcnt, and returns without performing cleanup. - * When all loaned buffers are returned and the refcnt is decremented, we - * go back to step 3, above. When wrsmdfreedestevt() finally runs with - * no loaned buffers, gets rid of most of the WRSMD resources attached - * to the destination. It also throws away any queued packets, gets - * rid of any allocated DVMA resources. It changes dstate to 2, takes - * this destination structure out of the base-ID => destination table. - * It then decrements the reference count that had been added by - * wrsmddest_refcnt_0(). - * - * 5. When the reference count becomes 0, wrsmddest_refcnt_0 is again called. - * It notices that dstate is 2, and frees the destination structure. - */ - -/* - * A destination's reference count went to 0, deal with it. - */ -static boolean_t -wrsmddest_refcnt_0( - wrsmd_dest_t *rd) /* Destination pointer */ -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - boolean_t freed = B_FALSE; - - mutex_enter(&wrsmdp->wrsmd_dest_lock); - - D1("wrsmddest_refcnt_0: rd 0x%p (addr %ld ctlr %d), refcnt %d, " - "dstate %d", - (void *)rd, rd->rd_rsm_addr, wrsmdp->wrsmd_ctlr_id, - rd->rd_refcnt, rd->rd_dstate); - - if (rd->rd_dstate == 1) { - rd->rd_refcnt++; /* Inline REFDEST */ - - /* - * We may be called from a routine that can't actually do the - * work that needs to be done, so we schedule an event - * to do the rest of the work. This can not be a timeout. - */ - - wrsmd_add_event(wrsmdp, WRSMD_EVT_FREEDEST, (void *)rd); - - } else if (rd->rd_dstate == 2) { - - /* Destroy all the mutexes */ - - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rd)) - - mutex_destroy(&rd->rd_lock); - mutex_destroy(&rd->rd_net_lock); - mutex_destroy(&rd->rd_xmit_lock); - mutex_destroy(&rd->rd_nlb_lock); - - /* - * Free any allocated memory hanging off the dest structure. - */ - - if (rd->rd_cached_fqr) { - kmem_free(rd->rd_cached_fqr, - sizeof (*rd->rd_cached_fqr) * rd->rd_num_fqrs); - } - if (rd->rd_shdwfqw_f_addr) { - kmem_free(rd->rd_shdwfqw_f_addr, - (sizeof (*rd->rd_shdwfqw_f_addr) * rd->rd_num_fqws) + - WRSMD_CACHELINE_SIZE); - } - if (rd->rd_shdwdqw_f_addr) { - kmem_free(rd->rd_shdwdqw_f_addr, - (sizeof (*rd->rd_shdwdqw_f_addr) * rd->rd_num_dqws) + - WRSMD_CACHELINE_SIZE); - } - if (rd->rd_bufbase) { - kmem_free(rd->rd_bufbase, - wrsmdp->wrsmd_param.wrsmd_buffers * - sizeof (*rd->rd_bufbase)); - } - if (rd->rd_rawmem_base_addr) { - kmem_free(rd->rd_rawmem_base_addr, - rd->rd_rawmem_base_size); - } - - /* Finally free the dest structure */ - - kmem_free(rd, sizeof (*rd)); - freed = B_TRUE; - - wrsmdp->wrsmd_numdest--; - - D1("wrsmddest_refcnt_0: freed rd data structures"); - } - - mutex_exit(&wrsmdp->wrsmd_dest_lock); - - D1("wrsmddest_refcnt_0: done"); - - return (freed); -} - -/* - * Do deletion work. - */ -static void -wrsmdfreedestevt(void * arg) -{ - wrsmd_dest_t *rd = (wrsmd_dest_t *)arg; - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - mblk_t *mp, *nmp; - int err; - int count = 0, tmpmask; - - D1("wrsmdfreedestevt: rd 0x%p (addr %ld ctlr %d)", (void *)rd, - rd->rd_rsm_addr, wrsmdp->wrsmd_ctlr_id); - - /* Get rid of any queued outgoing buffers */ - - mutex_enter(&rd->rd_xmit_lock); - - mp = rd->rd_queue_h; - rd->rd_queue_h = NULL; - - while (mp) { - nmp = mp->b_next; - mp->b_next = mp->b_prev = NULL; - wrsmdp->wrsmd_oerrors++; - freemsg(mp); - mp = nmp; - } - rd->rd_queue_len = 0; - - mutex_exit(&rd->rd_xmit_lock); - - /* - * See if there are any more outstanding loaned buffers. If so, - * set flag so that freebuf will eventually do an UNREF when it - * frees the last buffer. This removes the reference added in - * wrsmddest_refcnt_0(), causing the count to again go to 0. - * wrsmddest_refcnt_0() will again be called, increment the refcnt - * and cause this routine to be called to complete cleanup. - */ - - mutex_enter(&rd->rd_nlb_lock); - - rd->rd_nlb_del = 1; - if (rd->rd_nlb != 0) { - DERR("wrsmdfreedestevt: loaned buffers outstanding %d, dest " - "%ld", rd->rd_nlb, rd->rd_rsm_addr); - mutex_exit(&rd->rd_nlb_lock); - return; - } - - mutex_exit(&rd->rd_nlb_lock); - - /* - * Retry for up to 10 times to clean up, pausing slightly each - * iteration. This gives the remote side a chance to clean up - * in the case of unpublish, and allows us to catch other errors - * now as well. - */ - - tmpmask = WRSMD_RSMS_RXFER_S | WRSMD_RSMS_RXFER_C | - WRSMD_RSMS_LXFER_P | WRSMD_RSMS_LXFER_C; - while ((count < 10) && (rd->rd_sstate & tmpmask)) { - /* - * Perform the sendq destroy first -- this notifies the - * remote side that the connection is going away, so - * it can immediately start cleaning up. This helps - * to avoid a situation where a segment is unpublished - * while there is still a connection to it (which is legal, - * but causes overhead in the Wildcat RSM driver). - */ - if (rd->rd_sstate & WRSMD_RSMS_RXFER_S) { - ASSERT(rd->rsm_sendq); - D1("wrsmdfreedestevt: destroying sendq\n"); - err = RSM_SENDQ_DESTROY(wrsmdp->wrsmd_ctlr, - rd->rsm_sendq); - if (err) { - D1("RSM_SENDQ_DESTROY failed! err %d\n", err); - } else { - rd->rd_sstate &= ~WRSMD_RSMS_RXFER_S; - } - } - - if (rd->rd_sstate & WRSMD_RSMS_RXFER_C) { - ASSERT(rd->rd_rxferhand); - D1("wrsmdfreedestevt: disconn from remote segment\n"); - err = RSM_DISCONNECT(wrsmdp->wrsmd_ctlr, - rd->rd_rxferhand); - if (err) { - D1("RSM_DISCONNECT failed! err %d\n", err); - } else { - rd->rd_sstate &= ~WRSMD_RSMS_RXFER_C; - } - } - - if (rd->rd_sstate & WRSMD_RSMS_LXFER_P) { - ASSERT(rd->rd_lxferhand); - D1("wrsmdfreedestevt: unpublishing local segment\n"); - err = RSM_UNPUBLISH(wrsmdp->wrsmd_ctlr, - rd->rd_lxferhand); - if (err) { - D1("RSM_UNPUBLISH failed! err %d\n", err); - } else { - rd->rd_sstate &= ~WRSMD_RSMS_LXFER_P; - } - } - - if (rd->rd_sstate & WRSMD_RSMS_LXFER_C) { - ASSERT(rd->rd_lxferhand); - D1("wrsmdfreedestevt: destroying local segment\n"); - err = RSM_SEG_DESTROY(wrsmdp->wrsmd_ctlr, - rd->rd_lxferhand); - if (err) { - D1("RSM_SEG_DESTROY failed! err %d\n", err); - } else { - rd->rd_sstate &= ~WRSMD_RSMS_LXFER_C; - } - } - - count++; - - if (rd->rd_sstate & tmpmask) { - D1("freedestevt: Pass %d, (sstate & mask)=0x%x\n", - count, (rd->rd_sstate & tmpmask)); - - /* Busy wait for a few microseconds */ - drv_usecwait(5000); - } - } - - if (count >= 10) { - D1("freedestevt: sstate&mask !0 after %d tries. 0x%x\n", - count, (rd->rd_sstate & tmpmask)); - D0("freedestevt: Clearing state but status != 0, stat=%x\n", - (rd->rd_sstate & tmpmask)); - rd->rd_sstate &= ~tmpmask; - } - - /* Take out of desttbl */ - - mutex_enter(&wrsmdp->wrsmd_dest_lock); - - rd->rd_wrsmdp->wrsmd_desttbl[rd->rd_rsm_addr] = NULL; - - ASSERT(rd->rd_dstate == 1); - rd->rd_dstate = 2; - - mutex_exit(&wrsmdp->wrsmd_dest_lock); - - - /* Make sure dest isn't on service queue */ - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - - if (wrsmdp->wrsmd_runq == rd) - wrsmdp->wrsmd_runq = rd->rd_next; - else { - wrsmd_dest_t *lastrd = wrsmdp->wrsmd_runq; - - while (lastrd) { - if (lastrd->rd_next == rd) { - lastrd->rd_next = rd->rd_next; - break; - } - lastrd = lastrd->rd_next; - } - } - - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - - ASSERT(rd->rd_sstate == 0); - - /* - * Removes the reference added in wrsmddest_refcnt_0(). - */ - UNREFDEST(rd); - - D1("wrsmdfreedestevt: done"); -} - - -/* - * Start the deletion process for a destination. - */ -static void -wrsmdfreedest(wrsmd_t *wrsmdp, rsm_addr_t rsm_addr) -{ - wrsmd_dest_t *rd; - timeout_id_t tmoid, fqe_tmoid; - - D1("wrsmdfreedest: ctlr %d remote rsmaddr %ld", - wrsmdp->wrsmd_ctlr_id, rsm_addr); - - mutex_enter(&wrsmdp->wrsmd_dest_lock); - - rd = wrsmdp->wrsmd_desttbl[rsm_addr]; - if (rd == NULL || rd->rd_dstate != 0) { - mutex_exit(&wrsmdp->wrsmd_dest_lock); - return; - } - - ASSERT((wrsmdp->wrsmd_attached_streams == 0) || - (rd->rd_state == WRSMD_STATE_DELETING)); - - D1("wrsmdfreedest: wrsmdp 0x%p (cltr %d) rsmaddr %ld", (void *)wrsmdp, - wrsmdp->wrsmd_ctlr_id, rsm_addr); - - rd->rd_dstate = 1; - - mutex_exit(&wrsmdp->wrsmd_dest_lock); - - /* - * Turn off any timeouts. The sync timeout reschedules itself, so we - * have to go to great lengths to kill it. - */ - - mutex_enter(&rd->rd_xmit_lock); - tmoid = rd->rd_tmo_id; - rd->rd_tmo_id = 0; - - fqe_tmoid = rd->rd_fqe_tmo_id; - rd->rd_fqe_tmo_id = 0; - - mutex_exit(&rd->rd_xmit_lock); - if (tmoid) - (void) untimeout(tmoid); - - if (fqe_tmoid) - (void) untimeout(fqe_tmoid); - - mutex_enter(&rd->rd_net_lock); - - /* - * Flush any outstanding events from the event thread. Since the - * freedestevt() will be queued after any pending syncs, we - * should be OK; but will start the ball rolling just in case. - */ - - mutex_enter(&wrsmdp->event_lock); - cv_broadcast(&wrsmdp->event_cv); - mutex_exit(&wrsmdp->event_lock); - - mutex_exit(&rd->rd_net_lock); - - D1("wrsmdfreedest: done"); - - /* remove reference added in wrsmdmkdest() */ - UNREFDEST(rd); -} - -/* - * **************************************************************** - * * - * E N D CONNECTION DATA STRUCTURE MANAGEMENT * - * * - * **************************************************************** - */ - - - - -/* - * **************************************************************** - * * - * B E G I N MAIN STATE MACHINE * - * * - * **************************************************************** - */ - - -/* - * We change a destination's state in a number of routines; we define these - * macros to make sure it gets done the same way every time. - */ -#define WRSMD_SETSTATE(rd, wrsmdp, routine, newstate) \ - rd->rd_state = (ushort_t)newstate; \ - if (WRSMD_SCHED_STATE(newstate)) { \ - rd->rd_next = wrsmdp->wrsmd_runq; \ - wrsmdp->wrsmd_runq = rd; \ - D1(routine ": added to runq"); \ - if (wrsmdp->wrsmd_wq) { \ - qenable(wrsmdp->wrsmd_wq); \ - D1(routine ": enabled 0x%p", \ - (void *)wrsmdp->wrsmd_wq); \ - } \ - } \ - _NOTE(CONSTCOND); - - -#define WRSMD_SETSTATE_NOSRV(rd, wrsmdp, routine, newstate) \ - rd->rd_state = (ushort_t)newstate; \ - if (WRSMD_SCHED_STATE(newstate)) { \ - rd->rd_next = wrsmdp->wrsmd_runq; \ - wrsmdp->wrsmd_runq = rd; \ - D1(routine ": added to runq"); \ - } \ - _NOTE(CONSTCOND); - - -/* - * This routine processes a notification that a destination has become - * unreachable. Delete our record of it, so that when it comes back up we - * will re-establish our association. We do this by changing its state to - * S_DELETE; the service routine will then start the deletion - * process. - * - * Since other parts of the driver may have operations in progress that - * involve this destination, most of the time we cannot just whack the - * state to the new value. Instead, we record (in rd_estate) that the - * connection was lost. The next time someone else attempts to change the - * state, the state change routines recognize that there is a pending event - * and change the state to the one we wanted instead. (There are - * exceptions in cases where the new state indicates that we've enabled - * some sort of timeout; in this case, we may wait until the following - * state change to take note of the event.) - */ -static void -wrsmd_lostconn(wrsmd_dest_t *rd) -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - - D1("wrsmd_lostconn: rd 0x%p (addr %ld ctlr %d)", (void *)rd, - rd->rd_rsm_addr, wrsmdp->wrsmd_ctlr_id); - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - if ((rd->rd_state == WRSMD_STATE_W_READY) || - (rd->rd_state == WRSMD_STATE_NEW) || - (rd->rd_state == WRSMD_STATE_W_ACCEPT) || - (rd->rd_state == WRSMD_STATE_W_ACK) || - (rd->rd_state == WRSMD_STATE_W_FQE)) { - /* LINTED: E_CONSTANT_CONDITION */ - WRSMD_SETSTATE(rd, wrsmdp, "wrsmd_lostconn", - WRSMD_STATE_S_DELETE); - } else { - rd->rd_estate = WRSMD_STATE_S_DELETE; - } - D1("wrsmd_lostconn: state now %s, estate now %s", - WRSMD_STATE_STR(rd->rd_state), WRSMD_STATE_STR(rd->rd_estate)); - - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - /* - * Stop trying to flush queue entries to the other side. - * - * stopq doesn't really need a lock to protect its state, as the - * only thing that happens to it is that it is set to true just - * prior to deleting rd, and the only purpose of this is to avoid - * unnecessary work. Other threads can read the state of this - * variable at any time, without taking a special lock. - * - * Note that rd itself is protected from going away from the - * REFDEST/FINDDEST performed by the caller of this routine. - */ - rd->rd_stopq = B_TRUE; - - D1("wrsmd_lostconn: done"); -} - - -/* - * Figure out what state transition should actually occur after an event - * has happened. - */ -static int -wrsmdestate_newstate(wrsmd_dest_t *rd, int newstate) -{ - int retval = newstate; - - /* - * If we're going to a state where we've just set a timeout, don't - * mess with the state. When the timeout happens, it will change - * state again, and we'll nab 'em there. If we're about to delete - * rd, don't bother worrying about the event. - */ - switch (newstate) { - case WRSMD_STATE_W_SCONNTMO: - case WRSMD_STATE_W_ACCEPT: - case WRSMD_STATE_W_ACK: - case WRSMD_STATE_W_FQE: - case WRSMD_STATE_DELETING: - case WRSMD_STATE_S_DELETE: - return (retval); - } - - if (rd->rd_estate) { - retval = rd->rd_estate; - rd->rd_estate = WRSMD_STATE_NEW; /* clear event state */ - } - - D1("wrsmdestate_newstate: %d %d -> %d", rd->rd_estate, - newstate, retval); - - return (retval); -} - - -/* - * If this destination's state is equal to state, set its state to INPROGRESS - * and return 1, otherwise return 0. - */ -static int -wrsmdisstate( - wrsmd_dest_t *rd, /* Destination pointer */ - int state) /* State to check for */ -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - int retval; - - D1("wrsmdisstate: rd 0x%p, state %s", (void *)rd, - WRSMD_STATE_STR(state)); - - /* - * We check first without the lock to save time in a common case, - * namely, we're called from the wrsmdmsghdlr_syncdqe() routine and - * we want to know if we're waiting for an FQE. - */ - -#ifndef __lock_lint - if (state != rd->rd_state) { - D1("wrsmdisstate: state was %s, returning 0", - WRSMD_STATE_STR(rd->rd_state)); - return (0); - } -#endif /* __lock_lint */ - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - - if (state == rd->rd_state) { - rd->rd_state = WRSMD_STATE_INPROGRESS; - retval = 1; - D1("wrsmdisstate: returning 1"); - } else { - retval = 0; - D1("wrsmdisstate: state was %s, returning 0", - WRSMD_STATE_STR(rd->rd_state)); - } - - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - return (retval); -} - -/* - * Return destination's state, then set its state to INPROGRESS. - */ -static int -wrsmdgetstate( - wrsmd_dest_t *rd) /* Destination pointer */ -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - int state; - - D1("wrsmdgetstate: rd 0x%p", (void *)rd); - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - - state = rd->rd_state; - rd->rd_state = WRSMD_STATE_INPROGRESS; - - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - D1("wrsmdgetstate: returning %s", WRSMD_STATE_STR(state)); - - return (state); -} - -/* - * Set destination's state; must be preceded by a getstate call. (i.e., - * destination's current state must be INPROGRESS.) - */ -static void -wrsmdsetstate( - wrsmd_dest_t *rd, /* Destination pointer */ - int newstate) /* State to set */ -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - - D1("wrsmdsetstate: rd 0x%p, newstate %s", (void *)rd, - WRSMD_STATE_STR(newstate)); - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - - if (rd->rd_state == WRSMD_STATE_INPROGRESS) { - if (rd->rd_estate) - newstate = wrsmdestate_newstate(rd, newstate); - WRSMD_SETSTATE(rd, wrsmdp, "wrsmdsetstate", newstate); - } else { - D1("wrsmd: setstate without getstate"); - cmn_err(CE_PANIC, "wrsmd: setstate without getstate"); - } - - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - D1("wrsmdsetstate: done"); -} - -/* - * Special case of wrsmdsetstate, designed to be called from the service - * routine. Does everything wrsmdsetstate does _except_ qenable the service - * routine. - */ -static void -wrsmdsetstate_nosrv( - wrsmd_dest_t *rd, /* Destination pointer */ - int newstate) /* State to set */ -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - - D1("wrsmdsetstate_nosrv: rd 0x%p, newstate %s", (void *)rd, - WRSMD_STATE_STR(newstate)); - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - - if (rd->rd_state == WRSMD_STATE_INPROGRESS) { - if (rd->rd_estate) - newstate = wrsmdestate_newstate(rd, newstate); - WRSMD_SETSTATE_NOSRV(rd, wrsmdp, "wrsmdsetstate_nosrv", - newstate); - } else { - D1("wrsmd: setstate without getstate"); - cmn_err(CE_PANIC, "wrsmd: setstate without getstate"); - } - - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - D1("wrsmdsetstate_nosrv: done"); -} - -/* - * Set state to newstate iff state is oldstate. Return 1 if move happened, - * else 0. - */ -static int -wrsmdmovestate( - wrsmd_dest_t *rd, /* Destination pointer */ - int oldstate, /* State to check against */ - int newstate) /* State to set if check succeeds */ -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - int retval; - - D1("wrsmdmovestate: rd 0x%p, oldstate %s, newstate %s", - (void *)rd, WRSMD_STATE_STR(oldstate), WRSMD_STATE_STR(newstate)); - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - - if (rd->rd_state == oldstate) { - if (rd->rd_estate) - newstate = wrsmdestate_newstate(rd, newstate); - WRSMD_SETSTATE(rd, wrsmdp, "wrsmdmovestate", newstate); - retval = 1; - D1("wrsmdmovestate: state changed, returning 1"); - } else { - retval = 0; - D1("wrsmdmovestate: oldstate really %s, returning 0", - WRSMD_STATE_STR(rd->rd_state)); - } - - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - return (retval); -} - - - -/* - * **************************************************************** - * * - * E N D MAIN STATE MACHINE * - * * - * **************************************************************** - */ - - - -/* - * **************************************************************** - * * - * B E G I N HANDLERS FOR INCOMING RSM MESSAGES * - * * - * **************************************************************** - */ - - -/* - * Handlers for the various messages that may arrive. All of these happen - * during interrupt handling, and will not actually use RSMPI calls. - * Rather, they will schedule actions to happen. - */ - - -/* - * Received CONNECT REQUEST message. Cause this side to set up - * connection to xfer segment and send back an ACCEPT message. - * - * We must have everything set up before sending the ACCEPT. - * However, we must not transmit any data until we receive the ACK - * of the ACCEPT. - */ -static void -wrsmdmsghdlr_req_connect(wrsmd_dest_t *rd, wrsmd_msg_t *msg) -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - boolean_t utmo = B_FALSE; - timeout_id_t tmoid; - - D1("wrsmdmsghdlr_req_connect: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id); - - /* - * xmit lock guarantees that timeout has really been set - * for any wait conditions. - */ - mutex_enter(&rd->rd_xmit_lock); - mutex_enter(&wrsmdp->wrsmd_runq_lock); - - if (rd->rd_segid_valid) { - /* - * Another connect message - is it a duplicate? - * If so, just ignore. Otherwise, there is a - * problem, so force a connection teardown. - */ - - mutex_exit(&wrsmdp->wrsmd_runq_lock); - mutex_exit(&rd->rd_xmit_lock); - - if ((rd->rd_rxfersegid != msg->p.m.con_request.send_segid) || - (rd->rd_lastconnmsg_seq != msg->p.hdr.seqno)) { - /* Not the same connect request, drop connection */ - wrsmd_lostconn(rd); - } - - return; - } - - /* remember the message sequence number of this connection request */ - rd->rd_lastconnmsg_seq = msg->p.hdr.seqno; - - if (rd->rd_state == WRSMD_STATE_W_ACCEPT) { - /* - * Crossed connection requests. If we're the higher - * numbered address, cancel the ACCEPT timeout and accept - * the remote request. If we're the lower numbered - * address, ignore this request because the remote side - * will accept ours. If the W_ACCEPT timeout expires prior - * to cancelling the timeout, the timeout function will - * notice the state is no longer W_ACCEPT, and will not - * cause the connection to be torn down. If the timeout - * has already occurred (and the rd state is S_DELETE), - * we're out of luck, and will have to wait for a new - * connection request from the remote side. - */ - if (rd->rd_rsm_addr > wrsmdp->wrsmd_rsm_addr.m.rsm) { - rd->rd_segid_valid = B_TRUE; - rd->rd_rxfersegid = msg->p.m.con_request.send_segid; - /* LINTED: E_CONSTANT_CONDITION */ - WRSMD_SETSTATE(rd, wrsmdp, "wrsmdmsghdlr_req_connect", - WRSMD_STATE_S_CONNXFER_ACCEPT); - utmo = B_TRUE; - tmoid = rd->rd_tmo_id; - rd->rd_tmo_id = 0; - rd->rd_tmo_int = 0; - } - } else { - - /* - * Save away the connection information. If possible, - * change the state to cause the request to be immediately - * acted upon. If the state is currently INPROGRESS - * in the early stages of connection (during crexfer - * or the start of sconn), then this request will - * eventually be noticed when sconn() is called. The - * sconn() function will notice that the segid is valid, - * and perform the CONNXER_ACCEPT tasks instead. - * - * If this rd's state was in a later stage of the - * connection dance (or after a connection exists), a - * previous connection request should have been received, - * the new connection request will not be expected, and - * this will have been caught by noticing the segid was - * already valid, and cause a failure, above. - */ - - rd->rd_segid_valid = B_TRUE; - rd->rd_rxfersegid = msg->p.m.con_request.send_segid; - - if (rd->rd_state == WRSMD_STATE_NEW) { - /* - * No connection was in progress. Start a new - * connection setup process. - */ - /* LINTED: E_CONSTANT_CONDITION */ - WRSMD_SETSTATE(rd, wrsmdp, "wrsmdmsghdlr_req_connect", - WRSMD_STATE_S_NEWCONN); - - } else if (rd->rd_state == WRSMD_STATE_W_SCONNTMO) { - /* - * Accept this request instead of resending our - * connect request. Cancel the timeout. If the - * SCONNTMO timeout function is called prior to - * cancelling the timeout, it will notice the state - * is no longer W_SCONNTMO, and will not cause a - * new connection request to be sent. If the - * timeout already occurred (and rd is in the - * S_SCONN state), the sconn() function will notice - * that the segid is valid, and perform the - * CONNXER_ACCEPT tasks instead. - */ - /* LINTED: E_CONSTANT_CONDITION */ - WRSMD_SETSTATE(rd, wrsmdp, "wrsmdmsghdlr_req_connect", - WRSMD_STATE_S_CONNXFER_ACCEPT); - utmo = B_TRUE; - tmoid = rd->rd_tmo_id; - rd->rd_tmo_id = 0; - rd->rd_tmo_int = 0; - } - } - - mutex_exit(&wrsmdp->wrsmd_runq_lock); - mutex_exit(&rd->rd_xmit_lock); - - if (utmo) - (void) untimeout(tmoid); -} - - - -/* - * Received ACCEPT message. Cause this side to set up a connection - * to the remote transfer segment and send back an ACK message. - */ -static void -wrsmdmsghdlr_con_accept(wrsmd_dest_t *rd, wrsmd_msg_t *msg) -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - boolean_t utmo = B_FALSE; - timeout_id_t tmoid; - - D1("wrsmdmsghdlr_con_accept: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id); - - /* - * xmit lock protects segid field - */ - mutex_enter(&rd->rd_xmit_lock); - mutex_enter(&wrsmdp->wrsmd_runq_lock); - - if (rd->rd_state == WRSMD_STATE_W_ACCEPT && - rd->rd_lxfersegid == msg->p.m.con_accept.rcv_segid) { - rd->rd_segid_valid = B_TRUE; - rd->rd_rxfersegid = msg->p.m.con_accept.send_segid; - utmo = B_TRUE; - tmoid = rd->rd_tmo_id; - rd->rd_tmo_id = 0; - /* LINTED: E_CONSTANT_CONDITION */ - WRSMD_SETSTATE(rd, wrsmdp, "wrsmdmsghdlr_con_accept", - WRSMD_STATE_S_CONNXFER_ACK); - mutex_exit(&wrsmdp->wrsmd_runq_lock); - mutex_exit(&rd->rd_xmit_lock); - - if (utmo) - (void) untimeout(tmoid); - } else { - mutex_exit(&wrsmdp->wrsmd_runq_lock); - mutex_exit(&rd->rd_xmit_lock); - wrsmd_lostconn(rd); - return; - } - -} - - -/* - * Received ACK message. Now ok to proceed with DLPI data transfer. - */ -static void -wrsmdmsghdlr_con_ack(wrsmd_dest_t *rd, wrsmd_msg_t *msg) -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - boolean_t utmo = B_FALSE; - timeout_id_t tmoid; - - D1("wrsmdmsghdlr_con_ack: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id); - - mutex_enter(&wrsmdp->wrsmd_runq_lock); - - if (rd->rd_state == WRSMD_STATE_W_ACK && - msg->p.m.con_ack.rcv_segid == rd->rd_lxfersegid && - msg->p.m.con_ack.send_segid == rd->rd_rxfersegid) { - utmo = B_TRUE; - tmoid = rd->rd_tmo_id; - rd->rd_tmo_id = 0; - /* LINTED: E_CONSTANT_CONDITION */ - WRSMD_SETSTATE(rd, wrsmdp, "wrsmdmsghdlr_con_ack", - WRSMD_STATE_S_XFER); - mutex_exit(&wrsmdp->wrsmd_runq_lock); - - if (utmo) - (void) untimeout(tmoid); - } else { - mutex_exit(&wrsmdp->wrsmd_runq_lock); - wrsmd_lostconn(rd); - return; - } -} - - -/* - * Remote side has just sync'ed up the local DQE with its copy, so there - * may be buffers to deliver. - */ -static void -wrsmdmsghdlr_syncdqe(wrsmd_dest_t *rd, wrsmd_msg_t *msg) -{ - - - D1("wrsmdmsghdlr_syncdqe: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id); - - TNF_PROBE_1(wrsmdmsghdlr_syncdqe_start, "RSMPI", - "wrsmdmsghdlr_syncdqe start", - tnf_long, rd, (tnf_long_t)rd); - - ASSERT(rd->rd_sstate == WRSMD_RSMS_ALL); - - /* - * message sanity check - */ - if (msg->p.m.syncdqe.rcv_segid != rd->rd_lxfersegid) { - D1("wrsmdmsghdlr_syncdqe: bad rcv_segid"); - TNF_PROBE_1(wrsmdmsghdlr_syncdqe_end, "RSMPI", - "wrsmdmsghdlr_syncdqe end; failure bad msg", - tnf_string, failure, "bad msg"); - wrsmd_lostconn(rd); - return; - } - - /* - * Since we'll eventually call RSM_PUT, and we're - * in interrupt context, we need to process this - * from the event thread - */ - - wrsmd_add_event(rd->rd_wrsmdp, WRSMD_EVT_SYNC_DQE, (void *)rd); - -} - - -static void -wrsmdmsghdlr_syncdqe_evt(wrsmd_dest_t *rd) -{ - int bufnum, offset, length; - ushort_t sap; - timeout_id_t tmoid; - int freebufs = 0; - - - /* Loop through all valid DQE's and process their packets. */ - - D5("msghdlr_syncdqe 1: time 0x%llx", gethrtime()); - while (wrsmdgetdqe(rd, &bufnum, &offset, &length, &sap)) { - - D5("msghdlr_syncdqe 2: time 0x%llx", gethrtime()); - - /* Don't try to send up DQE with zero length */ - - if (length) - freebufs += wrsmdread(rd, bufnum, offset, length, sap); - else { - wrsmdputfqe(rd, bufnum); - freebufs++; - } - D5("msghdlr_syncdqe 3: time 0x%llx", gethrtime()); - - if (freebufs == - rd->rd_wrsmdp->wrsmd_param.wrsmd_fqe_sync_size) { - freebufs = 0; - mutex_enter(&rd->rd_net_lock); - wrsmdsyncfqe(rd); - mutex_exit(&rd->rd_net_lock); - } - - } - if (freebufs) { - mutex_enter(&rd->rd_net_lock); - wrsmdsyncfqe(rd); - mutex_exit(&rd->rd_net_lock); - } - - mutex_enter(&rd->rd_xmit_lock); - - if (wrsmdisstate(rd, WRSMD_STATE_W_FQE)) { - int avail = wrsmdavailfqe(rd); - - /* - * We hold xmit_lock to keep wrsmdfqetmo() from running while - * we're deciding what to do. In the case where we're waiting - * for FQE's but don't have any, if we let fqetmo run before we - * set the state back to W_FQE, it won't do anything and we - * could hang in that state until another packet came in - * (which could be forever). - */ - - if (avail) { - tmoid = rd->rd_fqe_tmo_id; - rd->rd_fqe_tmo_id = 0; - rd->rd_tmo_int = 0; - rd->rd_wrsmdp->wrsmd_fqetmo_hint++; - mutex_exit(&rd->rd_xmit_lock); - /* - * Note: since the fqetmo gets xmit_lock, we have - * to release it before we call untimeout() to prevent - * a deadlock from occurring. - */ - (void) untimeout(tmoid); - wrsmdsetstate(rd, WRSMD_STATE_S_XFER); - } else { - wrsmdsetstate(rd, WRSMD_STATE_W_FQE); - mutex_exit(&rd->rd_xmit_lock); - } - } else { - mutex_exit(&rd->rd_xmit_lock); - } - - D1("wrsmdmsghdlr_syncdqe: success"); - TNF_PROBE_0(wrsmd_msg_hdlr_syncdqe_end, "RSMPI", - "wrsmd_msg_hdlr_syncdqe end: success"); -} - - -static void -wrsmdmsghdlr_default(wrsmd_dest_t *rd, wrsmd_msg_t *msg) -{ - wrsmderror(rd->rd_wrsmdp->wrsmd_dip, "Unknown message type %d", - msg->p.hdr.reqtype); -} - - -/* - * Handler for connection-related RSMPI messages from remote WRSMD drivers - */ -/* ARGSUSED */ -static rsm_intr_hand_ret_t -wrsmd_rsm_intr_handler(rsm_controller_object_t *controller, - rsm_intr_q_op_t operation, - rsm_addr_t sender, - void *data, - size_t size, - rsm_intr_hand_arg_t handler_arg) -{ - wrsmd_t *wrsmdp = (wrsmd_t *)handler_arg; - wrsmd_dest_t *rd; - wrsmd_msg_t *msg; - int isdel = 0; - /* LINTED E_FUNC_SET_NOT_USED */ - int isnew = 0; - dl_rsm_addr_t addr; - - - /* - * We only handle RSM addresses that fit in 48 bits. - * This is no problem for Wildcat. - */ - ASSERT(sender <= (rsm_addr_t)0xffffffffffffLL); - addr.m.rsm = sender; - - D1("wrsmd_intr_handle: wrsmdp 0x%p (cltr %d) sender-addr %ld", - (void *)wrsmdp, - wrsmdp ? wrsmdp->wrsmd_ctlr_id : -1, sender); - TNF_PROBE_0(wrsmdintrhdlr_start, "RSMPI", "wrsmdintrhdlr start"); - - /* Is this our interrupt? */ - mutex_enter(&wrsmdp->wrsmd_lock); - if (controller->handle != wrsmdp->wrsmd_ctlr.handle) { - mutex_exit(&wrsmdp->wrsmd_lock); - D1("wrsmd_intr_handle: bad controller handle"); - return (RSM_INTR_HAND_UNCLAIMED); - } - mutex_exit(&wrsmdp->wrsmd_lock); - - /* - * We don't really care about anything but a received packet - * or a queue destroy - */ - switch (operation) { - - case RSM_INTR_Q_OP_CREATE: { - /* - * Create a dest structure, on the assumption that - * somebody's about to communicate with us. - */ - MAKEDEST(rd, isdel, isnew, wrsmdp, addr.m.wrsm.addr); - if (isdel || !rd) { - TNF_PROBE_1(wrsmdintrhdlr_end, "RSMPI", - "wrsmdintrhdlr end; failure cantfindormkdest", - tnf_string, failure, "cantfindormkdest"); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } - UNREFDEST(rd); - D1("wrsmd_intr_handle: op-create/config mkdset for addr %ld", - addr.m.rsm); - TNF_PROBE_2(wrsmdintrhdlr_end, "RSMPI", "wrsmdintrhdlr end", - tnf_string, success, "queue created", - tnf_long, rval, DDI_SUCCESS); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } - - case RSM_INTR_Q_OP_CONFIGURE: - /* ignore configure messages */ - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - - case RSM_INTR_Q_OP_DROP: - case RSM_INTR_Q_OP_DESTROY: { - /* - * The remote side has shut down the connection. We need - * to shut local side of the connection down as well. - */ - FINDDEST(rd, isdel, wrsmdp, addr.m.rsm); - if (isdel || !rd) { - TNF_PROBE_1(wrsmdintrhdlr_end, "RSMPI", - "wrsmdintrhdlr end; failure cantfinddest", - tnf_string, failure, "cantfinddest"); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } - D1("wrsmd_intr_handle: op-destroy for addr %ld", addr.m.rsm); - wrsmd_lostconn(rd); - UNREFDEST(rd); - TNF_PROBE_2(wrsmdintrhdlr_end, "RSMPI", "wrsmdintrhdlr end", - tnf_string, success, "queue destroyed", - tnf_long, rval, DDI_SUCCESS); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } - - case RSM_INTR_Q_OP_RECEIVE: - /* - * A DLPI message from the remote node. Handle in the main - * body. - */ - break; - - default: - /* ignore */ - TNF_PROBE_0(wrsmdintrhdlr_end, "RSMPI", - "wrsmdintrhdlr end; unknown message type"); - return (RSM_INTR_HAND_UNCLAIMED); - } - - /* - * Dest should already exist, having been created by the - * RSM_INTR_Q_OP_CREATE, above. - */ - - FINDDEST(rd, isdel, wrsmdp, addr.m.rsm); - if (isdel) { - TNF_PROBE_1(wrsmdintrhdlr_end, "RSMPI", - "wrsmdintrhdlr end; failure dest deleting", - tnf_string, failure, "deleting"); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } else if (rd == NULL) { - D1("wrsmd_rsm_intr_handler: can't finddest"); - TNF_PROBE_1(wrsmdintrhdlr_end, "RSMPI", - "wrsmdintrhdlr end; failure cantfinddest", - tnf_string, failure, "cantfinddest"); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } - - - msg = (wrsmd_msg_t *)data; - - if (msg->p.hdr.wrsmd_version != WRSMD_VERSION) { - /* - * Non-matching driver version! - * Toss message. - */ - wrsmderror(wrsmdp->wrsmd_dip, - "non-matching wrsmd version (%d) in " - "message", msg->p.hdr.wrsmd_version); - UNREFDEST(rd); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); - } - - switch (msg->p.hdr.reqtype) { - - case WRSMD_MSG_REQ_CONNECT: - wrsmdmsghdlr_req_connect(rd, msg); - break; - - case WRSMD_MSG_CON_ACCEPT: - wrsmdmsghdlr_con_accept(rd, msg); - break; - - case WRSMD_MSG_CON_ACK: - wrsmdmsghdlr_con_ack(rd, msg); - break; - - /* - * Maybe scan the incoming queue at this time? - */ - case WRSMD_MSG_SYNC_DQE: - wrsmdmsghdlr_syncdqe(rd, msg); - break; - - default: - wrsmdmsghdlr_default(rd, msg); - break; - } - - UNREFDEST(rd); - - TNF_PROBE_2(wrsmdintrhdlr_end, "RSMPI", "wrsmdintrhdlr end", - tnf_string, success, "", - tnf_long, rval, DDI_SUCCESS); - return (RSM_INTR_HAND_CLAIMED_EXCLUSIVE); -} - -/* - * **************************************************************** - * * - * E N D HANDLERS FOR INCOMING RSM MESSAGES * - * * - * **************************************************************** - */ - - - -/* - * **************************************************************** - * * - * B E G I N CONNECTION MANAGEMENT * - * * - * **************************************************************** - */ - -/* - * Create and initialize a transfer segment for the remote destination. If - * successful, return 0, else 1. The destination's state must be - * INPROGRESS. In remains INPROGRESS during this function. - */ -static int -wrsmdcrexfer(wrsmd_t *wrsmdp, wrsmd_dest_t *rd) -{ - volatile wrsmd_xfer_hdr_t *xfer; - wrsmd_fqe_t fqe; - volatile wrsmd_fqe_t *fqep; - wrsmd_dqe_t dqe; - volatile wrsmd_dqe_t *dqep; - wrsmdbuf_t *rbp; - uint_t bufsize; - int i, stat; - uint32_t buf_offset, fq_offset, dq_offset; - size_t xfer_size; - caddr_t xfer_start; - size_t roundup; - size_t transport_pgsize = 0; - rsm_access_entry_t perms; - - D1("wrsmdcrexfer: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, wrsmdp->wrsmd_ctlr_id); - TNF_PROBE_2(wrsmdcrexfer_start, "RSMPI", "wrsmdcrexfer start", - tnf_long, wrsmdp, (tnf_long_t)wrsmdp, tnf_long, rd, (tnf_long_t)rd); - - ASSERT(rd->rd_rawmem_base_addr == NULL); - ASSERT(rd->rd_rawmem_base_size == 0); - - bufsize = wrsmdp->wrsmd_param.wrsmd_buffer_size; - - for (i = 0; i < (sizeof (size_t) * 8); i++) { - if (wrsmdp->wrsmd_ctlr_attr->attr_page_size & - ((size_t)1 << i)) { - transport_pgsize = 1024 << i; - break; - } - } - if (transport_pgsize == 0) { - cmn_err(CE_CONT, "?wrsmd: crexfer, invalid transport " - "page sizes (attr_page_size is 0x%lx)", - wrsmdp->wrsmd_ctlr_attr->attr_page_size); - return (1); - } - - - /* - * Make sure the remote side is responding before setting - * up the local xfer segment. - */ - stat = RSM_SENDQ_CREATE(wrsmdp->wrsmd_ctlr, rd->rd_rsm_addr, - RSM_INTR_T_SUN_BASE, RSM_DLPI_QPRI, RSM_DLPI_QDEPTH, - RSM_DLPI_QFLAGS, RSM_RESOURCE_DONTWAIT, 0, &(rd->rsm_sendq)); - - if (stat != RSM_SUCCESS) { - D1("wrsmdcrexfer: can't create send queue, stat 0x%x, " - "returning 1", stat); - TNF_PROBE_2(wrsmdcrexfer_end, "RSMPI", - "wrsmdcrexfer end; failure RSM_SENDQ_CREATE", - tnf_string, failure, "RSM_SENDQ_CREATE", - tnf_long, stat, stat); - cmn_err(CE_CONT, "?wrsmd: crexfer create send queue, " - "stat 0x%x", stat); - return (1); - } - rd->rd_sstate |= WRSMD_RSMS_RXFER_S; - - - /* - * Allocate memory for segment. Allow for alignment of DQE list - * and FQE list. Also allow buffers to be aligned on - * RSM-page-sized boundaries. - */ - xfer_size = sizeof (*xfer) + 64 + - (sizeof (wrsmd_dqe_t) * wrsmdp->wrsmd_param.wrsmd_queue_size) - + 64 + - (sizeof (wrsmd_fqe_t) * wrsmdp->wrsmd_param.wrsmd_queue_size) - + 64 + - (bufsize * wrsmdp->wrsmd_param.wrsmd_buffers) - + (transport_pgsize -1); - - xfer_start = kmem_alloc(xfer_size, KM_NOSLEEP); - if (!xfer_start) { - D1("wrsmdcrexfer: can't allocate memory, returning 1"); - TNF_PROBE_1(wrsmdcrexfer_end, "RSMPI", - "wrsmdcrexfer end; failure kmem_alloc", - tnf_string, failure, "kmem_alloc"); - cmn_err(CE_CONT, "?wrsmd: crexfer, failed to alloc"); - return (1); - } - rd->rd_rawmem_base_addr = xfer_start; - rd->rd_rawmem_base_size = xfer_size; - - /* - * Round up memory pointer and round down size to allow alignment - * within the transport's supported page size. - */ - roundup = transport_pgsize - ((uint64_t)xfer_start & - (transport_pgsize -1)); - if (roundup != transport_pgsize) { - xfer_size -= roundup; - xfer_start += roundup; - } - xfer_size = xfer_size & ~(transport_pgsize - 1); - rd->rd_memory.ms_type = RSM_MEM_VADDR; - rd->rd_memory.ms_memory.vr.length = xfer_size; - rd->rd_memory.ms_memory.vr.as = NULL; /* kas */ - rd->rd_memory.ms_memory.vr.vaddr = xfer_start; - - D2("wrsmdcrexfer: rawsize 0x%lx rawmem 0x%p xfersize 0x%lx " - "xfermem 0x%p pgsize 0x%lx\n", - rd->rd_rawmem_base_size, - (void *)rd->rd_rawmem_base_addr, - xfer_size, - (void *)xfer_start, - transport_pgsize); - - xfer = (volatile struct wrsmd_xfer_hdr *)xfer_start; - - /* Force FQ to start on a 64-byte boundary. */ - fq_offset = sizeof (struct wrsmd_xfer_hdr); - fq_offset = WRSMD_CACHELINE_ROUNDUP(fq_offset); - - /* Force DQ to start on a 64-byte boundary. */ - dq_offset = fq_offset + (sizeof (wrsmd_fqe_t) * - wrsmdp->wrsmd_param.wrsmd_queue_size); - dq_offset = WRSMD_CACHELINE_ROUNDUP(dq_offset); - - /* Force buffers to start on a 64-byte boundary. */ - buf_offset = dq_offset + (sizeof (wrsmd_dqe_t) * - wrsmdp->wrsmd_param.wrsmd_queue_size); - buf_offset = WRSMD_CACHELINE_ROUNDUP(buf_offset); - - /* - * Note that while we set the _f and _n queue pointers and the - * queue lengths here, the _l pointers will be set (and the lengths - * may be adjusted) when we connect to the remote xfer segment (see - * connxfer). - */ - mutex_enter(&rd->rd_net_lock); - - rd->rd_fqr_f = rd->rd_fqr_n = (volatile wrsmd_fqe_t *) (xfer_start + - fq_offset); - rd->rd_fqr_seq = 1; - rd->rd_num_fqrs = wrsmdp->wrsmd_param.wrsmd_queue_size; - - rd->rd_dqr_f = rd->rd_dqr_n = (volatile wrsmd_dqe_t *) (xfer_start + - dq_offset); - rd->rd_dqr_seq = 1; - rd->rd_num_dqrs = wrsmdp->wrsmd_param.wrsmd_queue_size; - - rd->rd_lbuf = xfer_start + buf_offset; - rd->rd_lbuflen = bufsize; - rd->rd_numlbufs = wrsmdp->wrsmd_param.wrsmd_buffers; - - /* - * Initialize the delivery and free queues: elements in the free - * queue are valid, and elements in the delivery queue are invalid - * (seqno == 0). - */ - fqep = rd->rd_fqr_f; - dqep = rd->rd_dqr_f; - - dqe.s.dq_seqnum = 0; - dqe.s.dq_bufnum = (ushort_t)~0; - - fqe.s.fq_seqnum = 1; - - for (i = 0; i < wrsmdp->wrsmd_param.wrsmd_queue_size; i++) { - fqe.s.fq_bufnum = (ushort_t)i; - - *fqep++ = fqe; - *dqep++ = dqe; - } - - mutex_exit(&rd->rd_net_lock); - - /* - * Allocate and init our structures to describe loaned-up buffers. - */ - - rbp = rd->rd_bufbase = kmem_zalloc(wrsmdp->wrsmd_param.wrsmd_buffers * - sizeof (*rd->rd_bufbase), KM_NOSLEEP); - - if (rbp == NULL) { - D1("wrsmdcrexfer: can't alloc rbp structs, returning 1"); - TNF_PROBE_2(wrsmdcrexfer_end, "RSMPI", - "wrsmdcrexfer end; failure kmem_zalloc bufbase", - tnf_string, failure, "kmem_zalloc", - tnf_long, stat, (tnf_long_t)rbp); - cmn_err(CE_CONT, "?wrsmd: abuf"); - return (1); - } - - for (i = 0; i < rd->rd_numlbufs; i++) { - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*rbp)) - rbp->rb_rd = rd; - rbp->rb_frtn.free_func = wrsmdfreebuf; - rbp->rb_frtn.free_arg = (char *)rbp; - rbp->rb_bufnum = i; - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*rbp)) - rbp++; - } - - mutex_init(&rd->rd_nlb_lock, NULL, MUTEX_DRIVER, NULL); - mutex_enter(&rd->rd_nlb_lock); - rd->rd_nlb = 0; - mutex_exit(&rd->rd_nlb_lock); - - /* - * Set everything in the header of the segment. - */ - - xfer->rx_segsize = xfer_size; - xfer->rx_buf_offset = buf_offset; - xfer->rx_fq_offset = fq_offset; - xfer->rx_dq_offset = dq_offset; - xfer->rx_numbufs = rd->rd_numlbufs; - xfer->rx_bufsize = rd->rd_lbuflen; - xfer->rx_numfqes = rd->rd_num_fqrs; - xfer->rx_numdqes = rd->rd_num_dqrs; - - D1("wrsmdcrexfer: rx_buf_offset 0x%x fq_offset 0x%x dq_offset 0x%x " - "rd_numlbufs 0x%x rd_lbuflen 0x%x rd_num_fqrs 0x%x " - "rd_num_dqrs 0x%x\n", - buf_offset, - fq_offset, - dq_offset, - rd->rd_numlbufs, - rd->rd_lbuflen, - rd->rd_num_fqrs, - rd->rd_num_dqrs); - - xfer->rx_cookie = WRSMD_XFER_COOKIE; - - /* - * Local xfer segment is now initialized; make it available to the - * remote node. - */ - - stat = RSM_SEG_CREATE(wrsmdp->wrsmd_ctlr, &(rd->rd_lxferhand), - xfer_size, 0, &(rd->rd_memory), RSM_RESOURCE_DONTWAIT, 0); - - if (stat != RSM_SUCCESS) { - D1("wrsmdcrexfer: can't create RSM segment, stat 0x%x, " - "return 1", stat); - TNF_PROBE_2(wrsmdcrexfer_end, "RSMPI", - "wrsmdcrexfer end; failure RSM_SEG_CREATE", - tnf_string, failure, "RSM_SEG_CREATE", - tnf_long, stat, stat); - cmn_err(CE_CONT, "?wrsmd: crexfer, stat 0x%x", stat); - return (1); - } - rd->rd_sstate |= WRSMD_RSMS_LXFER_C; - - - /* - * Publish this segment. First try using an id that is likely - * to be unique. - */ - perms.ae_addr = rd->rd_rsm_addr; - perms.ae_permission = RSM_PERM_RDWR; - stat = RSMERR_SEGID_IN_USE; - if (rd->rd_rsm_addr <= (RSM_DLPI_ID_END - RSM_DLPI_ID_BASE)) { - rd->rd_lxfersegid = RSM_DLPI_ID_BASE + - (uint32_t)rd->rd_rsm_addr; - stat = (RSM_PUBLISH(wrsmdp->wrsmd_ctlr, rd->rd_lxferhand, - &perms, 1, rd->rd_lxfersegid, NULL, 0)); - } - if (stat == RSMERR_SEGID_IN_USE) { - /* Couldn't use default id; try other ids in allowed range */ - rd->rd_lxfersegid = RSM_DLPI_ID_BASE; - while ((stat = (RSM_PUBLISH(wrsmdp->wrsmd_ctlr, - rd->rd_lxferhand, - &perms, 1, rd->rd_lxfersegid, NULL, 0))) == - RSMERR_SEGID_IN_USE && rd->rd_lxfersegid < RSM_DLPI_ID_END) - rd->rd_lxfersegid++; - } - - if (stat != RSM_SUCCESS) { - D1("wrsmdcrexfer: can't publish, stat 0x%x, returning 1", - stat); - TNF_PROBE_2(wrsmdcrexfer_end, "RSMPI", - "wrsmdcrexfer end; failure wrsmd_export_segment", - tnf_string, failure, "wrsmd_export_segment", - tnf_long, stat, stat); - cmn_err(CE_CONT, "?wrsmd: expxfer, stat 0x%x", stat); - return (1); - } - rd->rd_sstate |= WRSMD_RSMS_LXFER_P; - - D1("wrsmdcrexfer: returning 0"); - TNF_PROBE_2(wrsmdcrexfer_end, "RSMPI", "wrsmdcrexfer end", - tnf_string, completed, "", - tnf_long, stat, 0); - return (0); -} - -/* - * Send a connect request to the remote. - * - * If we've received a Connect message from the destination, connect to the - * remote transfer segment. Otherwise, send them a Connect Request - * message. On success, return 0. If the connect fails return 1. A - * failure in sending a Connect Request message will result in a retry - * timeout being scheduled, but will not return 1 unless the total timeout - * period has expired. Destination's state must be INPROGRESS when called. - * Destination's state is set to a new state prior to returning. - */ -static int -wrsmdsconn( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - wrsmd_dest_t *rd, /* Destination pointer */ - int fromtmo) /* 0 if this is our first attempt; nonzero if this */ - /* is a retry, requested by a timeout routine. */ -{ - int stat; - - D1("wrsmdsconn: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, wrsmdp->wrsmd_ctlr_id); - TNF_PROBE_3(wrsmdsconn_start, "RSMPI", "wrsmdsconn start", - tnf_long, wrsmdp, (tnf_long_t)wrsmdp, tnf_long, rd, (tnf_long_t)rd, - tnf_long, fromtmo, fromtmo); - - if (rd->rd_segid_valid) { - /* - * We've gotten a Connect Request from the remote side - * while in INPROGRESS state. Don't send our request; - * instead, connect to the remote transfer segment. - */ - - if ((stat = wrsmdconnxfer(wrsmdp, rd)) != 0) { - return (stat); - } - return (wrsmdsaccept(wrsmdp, rd)); - } - - /* - * We haven't gotten a Connect Request from them, so we - * need to send one of our own. - */ - - /* - * If this is a timeout retry, send the same Connect Request - * message we sent the first time. - */ - if (fromtmo) { - stat = wrsmdsendmsg(rd, WRSMD_REXMIT, 0); - } else { - wrsmd_msg_t msg; - msg.p.m.con_request.send_segid = rd->rd_lxfersegid; - stat = wrsmdsendmsg(rd, WRSMD_MSG_REQ_CONNECT, &msg); - } - - /* - * xmit lock guarantees new state and timeout setup both occur - * without an intervening state change. See - * wrsmdmsghdlr_req_connect(). - */ - mutex_enter(&rd->rd_xmit_lock); - - if (stat == RSM_SUCCESS) { /* Success */ - /* - * Set up a timeout to remind us if an ACCEPT never - * shows up. This is only a 1-time timeout, no - * backoff is needed. - */ - - wrsmdsetstate(rd, WRSMD_STATE_W_ACCEPT); - - rd->rd_tmo_int = wrsmdp->wrsmd_param.wrsmd_ack_tmo; - rd->rd_tmo_tot = 0; - rd->rd_tmo_id = timeout(wrsmdaccepttmo, (caddr_t)rd, - rd->rd_tmo_int); - } else { - /* - * We couldn't send the message, set up a timeout to - * try again a little later. - */ - - wrsmdsetstate(rd, WRSMD_STATE_W_SCONNTMO); - - if (!fromtmo) { - rd->rd_tmo_int = - wrsmdp->wrsmd_param.wrsmd_msg_init_tmo; - rd->rd_tmo_tot = 0; - D2("wrsmdsconn: !fromtmo, tmo_int %d, " - "tmo_tot %d", rd->rd_tmo_int, - rd->rd_tmo_tot); - } else { - /* Do exponential backoff */ - - rd->rd_tmo_tot += rd->rd_tmo_int; - rd->rd_tmo_int *= 2; - - /* If we've waited too long, fail */ - - if (rd->rd_tmo_tot >= - wrsmdp->wrsmd_param.wrsmd_msg_drop_tmo) { - TNF_PROBE_2(wrsmdsconn_end, "RSMPI", - "wrsmdsconn end; failure timeout", - tnf_string, failure, "timeout", - tnf_long, stat, rd->rd_tmo_tot); - mutex_exit(&rd->rd_xmit_lock); - (void) wrsmdgetstate(rd); - D1("wrsmdsconn: tmo limit reached, " - "returning 1"); - return (1); - } - - /* Clip timeout to maximum */ - - if (rd->rd_tmo_int > - wrsmdp->wrsmd_param.wrsmd_msg_max_tmo) - rd->rd_tmo_int = - wrsmdp->wrsmd_param.wrsmd_msg_max_tmo; - - D2("wrsmdsconn: tmo_int %d, tmo_tot %d", - rd->rd_tmo_int, rd->rd_tmo_tot); - } - - rd->rd_tmo_id = timeout(wrsmdsconntmo, (caddr_t)rd, - rd->rd_tmo_int); - } - - mutex_exit(&rd->rd_xmit_lock); - - D1("wrsmdsconn: returning 0"); - TNF_PROBE_2(wrsmdsconn_end, "RSMPI", "wrsmdsconn end", - tnf_string, completed, "", - tnf_long, stat, 0); - return (0); -} - - -/* - * Connect to the transfer segment on the destination machine. If an error - * occurs, return 1. Destination state must be INPROGRESS. It remains - * INPROGRESS during this function. - */ -static int -wrsmdconnxfer(wrsmd_t *wrsmdp, wrsmd_dest_t *rd) -{ - uint_t num_rbufs; - int stat; - int i; - wrsmd_fqe_t fqe; - volatile wrsmd_fqe_t *fqep; - wrsmd_dqe_t dqe; - volatile wrsmd_dqe_t *dqep; - size_t segsize; - - D1("wrsmdconnxfer: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, wrsmdp->wrsmd_ctlr_id); - TNF_PROBE_2(wrsmdconnxfer_start, "RSMPI", "wrsmdconnxfer start", - tnf_long, wrsmdp, (tnf_long_t)wrsmdp, tnf_long, rd, (tnf_long_t)rd); - - mutex_enter(&rd->rd_xmit_lock); - - stat = RSM_CONNECT(wrsmdp->wrsmd_ctlr, rd->rd_rsm_addr, - rd->rd_rxfersegid, &(rd->rd_rxferhand)); - if (stat != RSM_SUCCESS) { - D1("wrsmdconnxfer: can't connxfer, stat 0x%x, returning 1", - stat); - cmn_err(CE_CONT, "?wrsmd: connxfer, stat 0x%x", stat); - TNF_PROBE_2(wrsmdconnxfer_end, "RSMPI", - "wrsmdconnxfer end; failure RSM_CONNECT", - tnf_string, failure, "RSM_CONNECT", - tnf_long, stat, stat); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - - rd->rd_sstate |= WRSMD_RSMS_RXFER_C; - - - /* - * Copy entire header struct into local memory - */ - - stat = RSM_GET(wrsmdp->wrsmd_ctlr, rd->rd_rxferhand, 0, - &(rd->rd_rxferhdr), sizeof (wrsmd_xfer_hdr_t)); - if (stat != RSM_SUCCESS) { - D1("wrsmdconnxfer: can't read xfer header, returning 1"); - TNF_PROBE_2(wrsmdconnxfer, "RSMPI", - "wrsmdconnxfer end; failure timeout", - tnf_string, failure, "timeout", - tnf_long, stat, 1); - cmn_err(CE_CONT, "?wrsmd: read xfer header failed, err=%d", - stat); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - - - - /* - * Validate header structure, extract some values from it - */ - if (rd->rd_rxferhdr.rx_cookie != WRSMD_XFER_COOKIE) { - D1("wrsmdconnxfer: badxfer, cookie 0x%x, returning 1", - rd->rd_rxferhdr.rx_cookie); - TNF_PROBE_1(wrsmdconnxfer, "RSMPI", - "wrsmdconnxfer end; failure 'bad xfer'", - tnf_string, failure, "bad xfer"); - cmn_err(CE_CONT, "?wrsmd: badxfer, cookie 0x%x", - (uint_t)rd->rd_rxferhdr.rx_cookie); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - - D1("wrsmdconnxfer: remote buf_offset 0x%x fq_offset 0x%x " - "dq_offset 0x%x rd_numbufs 0x%x rd_lbuflen 0x%x " - "rd_numfqes 0x%x rd_numdqes 0x%x\n", - rd->rd_rxferhdr.rx_buf_offset, - rd->rd_rxferhdr.rx_fq_offset, - rd->rd_rxferhdr.rx_dq_offset, - rd->rd_rxferhdr.rx_numbufs, - rd->rd_rxferhdr.rx_bufsize, - rd->rd_rxferhdr.rx_numfqes, - rd->rd_rxferhdr.rx_numdqes); - - segsize = rd->rd_rxferhdr.rx_segsize; - - num_rbufs = rd->rd_rxferhdr.rx_numbufs; - - D1("num_rbufs 0x%x wrsmd_queue_size 0x%x\n", num_rbufs, - wrsmdp->wrsmd_param.wrsmd_queue_size); - /* - * Must be at least one more element in queue than the - * number of buffers, so that we can track when all queue - * elements need to be flushed to remote side. - */ - if (num_rbufs >= wrsmdp->wrsmd_param.wrsmd_queue_size) - num_rbufs = wrsmdp->wrsmd_param.wrsmd_queue_size - 1; - - mutex_enter(&rd->rd_net_lock); - - rd->rd_rbufoff = rd->rd_rxferhdr.rx_buf_offset; - rd->rd_rbuflen = rd->rd_rxferhdr.rx_bufsize; - rd->rd_numrbuf = num_rbufs; - if ((rd->rd_rbufoff + (rd->rd_rbuflen * num_rbufs)) > segsize) { - D1("wrsmd: badxfer, rbufoff too big"); - cmn_err(CE_CONT, "?wrsmd: badxfer, rbufoff too big"); - mutex_exit(&rd->rd_net_lock); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - - rd->rd_fqw_f_off = rd->rd_rxferhdr.rx_fq_offset; - rd->rd_num_fqws = rd->rd_rxferhdr.rx_numfqes; - - if ((rd->rd_fqw_f_off + (sizeof (wrsmd_fqe_t) * rd->rd_num_fqws)) - > segsize) { - D1("wrsmd: badxfer, fqw_f_off too big"); - cmn_err(CE_CONT, "?wrsmd: badxfer, fqw_f_off too big"); - mutex_exit(&rd->rd_net_lock); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - - rd->rd_dqw_f_off = rd->rd_rxferhdr.rx_dq_offset; - rd->rd_num_dqws = rd->rd_rxferhdr.rx_numdqes; - - if ((rd->rd_dqw_f_off + (sizeof (wrsmd_dqe_t) * rd->rd_num_dqws)) - > segsize) { - D1("wrsmd: badxfer, dqw_f_off too big"); - cmn_err(CE_CONT, "?wrsmd: badxfer, dqw_f_off too big"); - mutex_exit(&rd->rd_net_lock); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - - /* - * Now that we know the number of remote buffers and queue elements, - * shrink everything to fit and calculate the ends of all queues. - */ - - - D1("rd_numlbufs 0x%x rd_num_fqws 0x%x rd_num_dqrs 0x%x\n", - rd->rd_numlbufs, rd->rd_num_fqws, rd->rd_num_dqrs); - rd->rd_numlbufs = - min(rd->rd_numlbufs, min(rd->rd_num_fqws - 1, - rd->rd_num_dqrs - 1)); - rd->rd_num_fqws = rd->rd_num_dqrs = - min(rd->rd_numlbufs + 1, min(rd->rd_num_fqws, rd->rd_num_dqrs)); - - D1("rd_numrbuf 0x%x rd_num_fqrs 0x%x rd_num_dqws 0x%x\n", - rd->rd_numrbuf, rd->rd_num_fqrs, rd->rd_num_dqws); - rd->rd_numrbuf = - min(rd->rd_numrbuf, min(rd->rd_num_fqrs - 1, - rd->rd_num_dqws - 1)); - rd->rd_num_fqrs = rd->rd_num_dqws = - min(rd->rd_numrbuf + 1, min(rd->rd_num_fqrs, rd->rd_num_dqws)); - - rd->rd_fqr_l = rd->rd_fqr_f + rd->rd_num_fqrs - 1; - /* mark last entry of free queue as invalid */ - rd->rd_fqr_l->s.fq_seqnum = 0; - rd->rd_fqr_l->s.fq_bufnum = (ushort_t)~0; - rd->rd_dqr_l = rd->rd_dqr_f + rd->rd_num_dqrs - 1; - - /* Create FQE cache, outgoing FQE/DQE queues */ - - D1("wrsmdconnxfer: num_fqrs 0x%x num_fqws 0x%x num_dqws 0x%x", - rd->rd_num_fqrs, rd->rd_num_fqws, rd->rd_num_dqws); - - if ((rd->rd_rbufoff + (rd->rd_rbuflen * num_rbufs)) > segsize) { - D1("wrsmd: badxfer, bufsize * num buf too big"); - cmn_err(CE_CONT, "?wrsmd: badxfer, bufsize * num buf too big"); - mutex_exit(&rd->rd_net_lock); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - if ((rd->rd_fqw_f_off + (sizeof (wrsmd_fqe_t) * rd->rd_num_fqws)) - > segsize) { - D1("wrsmd: badxfer, fqesize * num fqe too big"); - cmn_err(CE_CONT, "?wrsmd: badxfer, fqesize * num fqe too big"); - mutex_exit(&rd->rd_net_lock); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - if ((rd->rd_dqw_f_off + (sizeof (wrsmd_dqe_t) * rd->rd_num_dqws)) - > segsize) { - D1("wrsmd: badxfer, dqesize * num dqe too big"); - cmn_err(CE_CONT, "?wrsmd: badxfer, dqesize * num dqe too big"); - mutex_exit(&rd->rd_net_lock); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - - rd->rd_cached_fqr = kmem_alloc(sizeof (*rd->rd_cached_fqr) * - rd->rd_num_fqrs, KM_NOSLEEP); - - /* - * Make sure any local queue that will be transferred or sync'd is - * WRSMD_CACHLINE_SIZE'd aligned. This means that when the data is - * loaded into the FPU registers for transfer,it is already aligned. - * This is a minor optimisation. For FireLink, only the remote - * (destination) side needs to be aligned for interconnect - * performance. - */ - - rd->rd_shdwfqw_f_addr = kmem_alloc((sizeof (wrsmd_fqe_t) * - rd->rd_num_fqws) + WRSMD_CACHELINE_SIZE, KM_NOSLEEP); - - rd->rd_shdwdqw_f_addr = kmem_alloc((sizeof (wrsmd_dqe_t) * - rd->rd_num_dqws) + WRSMD_CACHELINE_SIZE, KM_NOSLEEP); - - if (rd->rd_cached_fqr == NULL || rd->rd_shdwfqw_f_addr == NULL || - rd->rd_shdwdqw_f_addr == NULL) { - D1("wrsmdconnxfer: can't alloc memory for shadow queues, " - "returning 1"); - TNF_PROBE_2(wrsmdconnxfer, "RSMPI", - "wrsmdconnxfer end; failure kmem_alloc", - tnf_string, failure, "kmem_alloc", - tnf_long, stat, 1); - cmn_err(CE_CONT, "?wrsmd: can't get memory in connxfer"); - mutex_exit(&rd->rd_net_lock); - mutex_exit(&rd->rd_xmit_lock); - return (1); - } - - rd->rd_shdwfqw_f = (wrsmd_fqe_t *) - WRSMD_CACHELINE_ROUNDUP(rd->rd_shdwfqw_f_addr); - rd->rd_shdwdqw_f = (wrsmd_dqe_t *) - WRSMD_CACHELINE_ROUNDUP(rd->rd_shdwdqw_f_addr); - - /* - * Initialize the shadow delivery and free queues: all elements in - * the free queue are valid except the last entry, and all elements in - * the delivery queue are invalid. It is necessary to initialize - * because when we do an wrsmdsyncfqe() or wrsmdsyncdqe(), we may do - * an RSM_PUT of more than the newly changed entries (because we - * round up/down to 64 byte boundaries). - */ - - rd->rd_shdwfqw_l = rd->rd_shdwfqw_f + rd->rd_num_fqws - 1; - rd->rd_shdwfqw_i = rd->rd_shdwfqw_o = rd->rd_shdwfqw_l; - /* still in first round, on last element */ - rd->rd_fqw_seq = 1; - - fqep = rd->rd_shdwfqw_f; - fqe.s.fq_seqnum = 1; - i = 0; - while (fqep <= rd->rd_shdwfqw_l - 1) { - fqe.s.fq_bufnum = (ushort_t)i++; - *fqep++ = fqe; - } - /* last entry is not valid */ - fqep->s.fq_seqnum = 0; - fqep->s.fq_bufnum = (ushort_t)~0; - - rd->rd_shdwfqw_errflag = 0; - - D1("wrsmdconnxfer: initialized %d fqe shadow entries", i); - - - rd->rd_shdwdqw_l = rd->rd_shdwdqw_f + rd->rd_num_dqws - 1; - rd->rd_shdwdqw_i = rd->rd_shdwdqw_o = rd->rd_shdwdqw_f; - /* in first round, on first element */ - rd->rd_dqw_seq = 1; - - dqep = rd->rd_shdwdqw_f; - dqe.s.dq_seqnum = 0; - dqe.s.dq_bufnum = (ushort_t)~0; - while (dqep <= rd->rd_shdwdqw_l) { - *dqep++ = dqe; - } - - rd->rd_shdwdqw_errflag = 0; - - mutex_exit(&rd->rd_net_lock); - - - D1("wrsmdconnxfer: returning 0"); - TNF_PROBE_2(wrsmdconnxfer_end, "RSMPI", "wrsmdconnxfer end", - tnf_string, completed, "", tnf_long, stat, 0); - - mutex_exit(&rd->rd_xmit_lock); - return (0); -} - - - -/* - * Send an ACCEPT message to the destination. - * Return 1 if this send fails, else set state to W_ACK and return 0. - * Destination's state must be INPROGRESS. - * Destination's state is set to a new state on success. - */ -static int -wrsmdsaccept( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - wrsmd_dest_t *rd) /* Destination pointer */ -{ - int stat; - wrsmd_msg_t msg; - int retval = 0; - - D1("wrsmdsaccept: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, wrsmdp->wrsmd_ctlr_id); - TNF_PROBE_2(wrsmdsaccept_start, "RSMPI", "wrsmdsaccept start", - tnf_long, wrsmdp, (tnf_long_t)wrsmdp, tnf_long, rd, (tnf_long_t)rd); - - msg.p.m.con_accept.send_segid = rd->rd_lxfersegid; - msg.p.m.con_accept.rcv_segid = rd->rd_rxfersegid; - stat = wrsmdsendmsg(rd, WRSMD_MSG_CON_ACCEPT, &msg); - - mutex_enter(&rd->rd_xmit_lock); - - if (stat == RSM_SUCCESS) { /* Success */ - wrsmdsetstate(rd, WRSMD_STATE_W_ACK); - - rd->rd_tmo_int = - wrsmdp->wrsmd_param.wrsmd_ack_tmo; - rd->rd_tmo_tot = 0; - rd->rd_tmo_id = timeout(wrsmdacktmo, (caddr_t)rd, - rd->rd_tmo_int); - - } else { /* Failure */ - retval = 1; - } - mutex_exit(&rd->rd_xmit_lock); - - D1("wrsmdsaccept: returning %d", retval); - TNF_PROBE_2(wrsmdsaccept_end, "RSMPI", "wrsmdaccept end", - tnf_string, completed, "", tnf_long, stat, retval); - return (retval); -} - - -/* - * Send an ACK response to the destination. - * Return 1 if this send fails, else set state to READY and return 0. - * Destination's state must be INPROGRESS. - * Destination's state is set to a new state on success. - */ -static int -wrsmdsack( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - wrsmd_dest_t *rd) /* Destination pointer */ -{ - int stat; - wrsmd_msg_t msg; - int retval = 0; - - D1("wrsmdsack: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, wrsmdp->wrsmd_ctlr_id); - TNF_PROBE_2(wrsmdsack_start, "RSMPI", "wrsmdsack start", - tnf_long, wrsmdp, (tnf_long_t)wrsmdp, tnf_long, rd, (tnf_long_t)rd); - - msg.p.m.con_ack.send_segid = rd->rd_lxfersegid; - msg.p.m.con_ack.rcv_segid = rd->rd_rxfersegid; - stat = wrsmdsendmsg(rd, WRSMD_MSG_CON_ACK, &msg); - - mutex_enter(&rd->rd_xmit_lock); - - if (stat == RSM_SUCCESS) { /* Success */ - - if (rd->rd_queue_h) - wrsmdxfer(wrsmdp, rd); - else - wrsmdsetstate(rd, WRSMD_STATE_W_READY); - - } else { /* Failure */ - retval = 1; - } - - mutex_exit(&rd->rd_xmit_lock); - - D1("wrsmdsack: returning %d", retval); - TNF_PROBE_2(wrsmdsack_end, "RSMPI", "wrsmdsack end", - tnf_string, completed, "", tnf_long, stat, retval); - return (retval); -} - -/* - * **************************************************************** - * * - * E N D CONNECTION MANAGEMENT * - * * - * **************************************************************** - */ - - - -/* - * **************************************************************** - * * - * B E G I N FREE/DELIVERY QUEUE MANAGEMENT * - * * - * **************************************************************** - */ - -/* - * Queue an FQE with the specified buffer number onto the shadow FQ for - * transmission to the remote system. - */ -static void -wrsmdputfqe( - wrsmd_dest_t *rd, /* Destination pointer */ - int bufnum) /* Number of free buffer */ -{ - wrsmd_fqe_t fqe; - - mutex_enter(&rd->rd_net_lock); - - D1("wrsmdputfqe: rd 0x%p (addr %ld ctlr %d), bufnum %d", (void *)rd, - rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id, bufnum); - D2("wrsmdputfqe: start shdwfqw_i 0x%p (index %ld) shdwfqw_f 0x%p " - "shdwfqw_l 0x%p", - (void *)rd->rd_shdwfqw_i, - ((char *)rd->rd_shdwfqw_i - (char *)rd->rd_shdwfqw_f) - / sizeof (fqe), - (void *)rd->rd_shdwfqw_f, (void *)rd->rd_shdwfqw_l); - - fqe.s.fq_filler = 0; - fqe.s.fq_bufnum = (ushort_t)bufnum; - - *rd->rd_shdwfqw_i = fqe; - - rd->rd_shdwfqw_i = (rd->rd_shdwfqw_i == rd->rd_shdwfqw_l) ? - rd->rd_shdwfqw_f : rd->rd_shdwfqw_i + 1; - - ASSERT(rd->rd_shdwfqw_i != rd->rd_shdwfqw_o); - - D1("wrsmdputfqe: done"); - D2("wrsmdputfqe: end shdwfqw_i 0x%p shdwfqw_f 0x%p shdwfqw_l 0x%p", - (void *)rd->rd_shdwfqw_i, (void *)rd->rd_shdwfqw_f, - (void *)rd->rd_shdwfqw_l); - - mutex_exit(&rd->rd_net_lock); -} - -/* - * Flush any queued FQEs (free queue entries) from the local shadow copy to - * the remote system's copy. - */ -static void -wrsmdsyncfqe( - wrsmd_dest_t *rd) /* Destination pointer */ -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - uint64_t start_offset, end_offset; - int stat = RSM_SUCCESS; - - ASSERT(MUTEX_HELD(&rd->rd_net_lock)); - - D1("wrsmdsyncfqe: rd 0x%p (addr %ld ctlr %d) index %ld to %ld", - (void *)rd, - rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id, - ((char *)rd->rd_shdwfqw_o - (char *)rd->rd_shdwfqw_f) / - sizeof (*(rd->rd_shdwfqw_o)), - ((char *)rd->rd_shdwfqw_i - (char *)rd->rd_shdwfqw_f) / - sizeof (*(rd->rd_shdwfqw_i))); - D2("wrsmdsyncfqe: shdwfqw_i 0x%p shdwfqw_f 0x%p shdwfqw_l 0x%p", - (void *)rd->rd_shdwfqw_i, (void *)rd->rd_shdwfqw_f, - (void *)rd->rd_shdwfqw_l); - - /* If nothing's queued, nothing to do */ - - if (rd->rd_shdwfqw_i == rd->rd_shdwfqw_o) { - D1("wrsmdsyncfqe: no work, done"); - return; - } - - /* If network down, nothing to do either */ - - if (rd->rd_stopq) { - D1("wrsmdsyncfqe: stopq on, done"); - return; - } - - /* - * Send each element in the queue separately. Since each - * element is WRSMD_CACHELINE_SIZE, then we know that - * each PUT is atomic, and we won't corrupt the remote - * side's free queue if we get a transient error and retry. - * - * If we try to put more then one element at a time, then it is - * possible for some elements to succeed while others fail. - * If this is the case then the remote side could possibly consume - * those new buffers before the local side retries the put, and - * thus the FQ could get corrupted (buffer listed as free when - * it really isn't). - * - */ - while (rd->rd_shdwfqw_o != rd->rd_shdwfqw_i) { - - /* Set the sequence number for this FQE */ - rd->rd_shdwfqw_o->s.fq_seqnum = - rd->rd_fqw_seq & WRSMD_FQE_SEQ_MASK; - - /* - * Set the offset to transfer one fqe at a time. - * - * NOTE: We already know we are aligned because - * we allocated the remote buffer on a WRSMD_CACHELINE_SIZE'd - * boundary, and each fqe is WRSMD_CACHELINE_SIZE long. - */ - start_offset = (char *)rd->rd_shdwfqw_o - - (char *)rd->rd_shdwfqw_f; - end_offset = start_offset + sizeof (wrsmd_fqe_t); - - /* Push FQE to remote side */ - stat = RSM_PUT(wrsmdp->wrsmd_ctlr, rd->rd_rxferhand, - rd->rd_fqw_f_off + start_offset, - (char *)rd->rd_shdwfqw_o, end_offset - start_offset); - - if (stat == RSM_SUCCESS) { - /* Write was sucessful */ - if (rd->rd_shdwfqw_o == rd->rd_shdwfqw_l) { - /* - * Wrap, and update sequence number if - * this the is the last fqe - */ - rd->rd_shdwfqw_o = rd->rd_shdwfqw_f; - - rd->rd_fqw_seq++; - if (rd->rd_fqw_seq == 0) - rd->rd_fqw_seq++; - - } else { - rd->rd_shdwfqw_o ++; - } - - rd->rd_shdwfqw_errflag = 0; - - } else { - - wrsmdp->wrsmd_errs++; - D0("wrsmdsyncfqe: RSM_PUT failed error %d", stat); - - if (stat == RSMERR_CONN_ABORTED) { - /* permanent connection loss */ - wrsmd_lostconn(rd); - } else { - /* - * Schedule an event to retry. Can't do a - * timeout here because it would require - * calling RSM_PUT from a callback. - */ - - wrsmd_add_event(wrsmdp, WRSMD_EVT_SYNC, - (void *)rd); - - rd->rd_shdwfqw_errflag = 1; - } - - return; - } - - } - - D1("wrsmdsyncfqe: done"); - D2("wrsmdsyncfqe: shdwfqw_i 0x%p shdwfqw_f 0x%p shdwfqw_l 0x%p", - (void *)rd->rd_shdwfqw_i, (void *)rd->rd_shdwfqw_f, - (void *)rd->rd_shdwfqw_l); -} - -/* - * Queue a DQE with the specified buffer description onto the shadow DQ for - * transmission to the remote system. - */ -static void -wrsmdputdqe( - wrsmd_dest_t *rd, /* Destination pointer */ - int bufnum, /* Number of full buffer */ - int offset, /* Offset of packet from start of buffer */ - uint_t length, /* Length of packet */ - ushort_t sap) /* Packet's SAP */ -{ - wrsmd_dqe_t dqe; - - mutex_enter(&rd->rd_net_lock); - - D1("wrsmdputdqe: rd 0x%p (ctlr %d addr %ld), bufnum %d, offset %d, " - "length %d, sap 0x%x index %ld", - (void *)rd, rd->rd_wrsmdp->wrsmd_ctlr_id, rd->rd_rsm_addr, - bufnum, offset, length, sap, - ((char *)rd->rd_shdwdqw_i - (char *)rd->rd_shdwdqw_f) / - sizeof (dqe)); - D2("wrsmdputdqe: start shdwdqw_i 0x%p (index %ld) shdwdqw_f 0x%p " - "shdwdqw_l 0x%p", - (void *)rd->rd_shdwdqw_i, - ((char *)rd->rd_shdwdqw_i - (char *)rd->rd_shdwdqw_f) / - sizeof (dqe), - (void *)rd->rd_shdwdqw_f, - (void *)rd->rd_shdwdqw_l); - - dqe.s.dq_offset = (uchar_t)offset; - dqe.s.dq_bufnum = (ushort_t)bufnum; - dqe.s.dq_length = (ushort_t)length; - dqe.s.dq_sap = sap; - - *rd->rd_shdwdqw_i = dqe; - - rd->rd_shdwdqw_i = (rd->rd_shdwdqw_i == rd->rd_shdwdqw_l) ? - rd->rd_shdwdqw_f : rd->rd_shdwdqw_i + 1; - - ASSERT(rd->rd_shdwdqw_i != rd->rd_shdwdqw_o); - - D1("wrsmdputdqe: done"); - D2("wrsmdputdqe: end shdwdqw_i 0x%p shdwdqw_o 0x%p shdwdqw_f 0x%p " - "shdwdqw_l 0x%p", - (void *)rd->rd_shdwdqw_i, - (void *)rd->rd_shdwdqw_o, - (void *)rd->rd_shdwdqw_f, - (void *)rd->rd_shdwdqw_l); - - mutex_exit(&rd->rd_net_lock); -} - -/* - * Flush any queued DQEs from local shadow copy to the remote system. - */ -static void -wrsmdsyncdqe(wrsmd_dest_t *rd) -{ - wrsmd_t *wrsmdp = rd->rd_wrsmdp; - uint64_t start_offset, end_offset; - int stat = RSM_SUCCESS; - int any_transfers = 0; - int old_error_flag; - - ASSERT(MUTEX_HELD(&rd->rd_net_lock)); - - old_error_flag = rd->rd_shdwdqw_errflag; - - D1("wrsmdsyncdqe: rd 0x%p (addr %ld ctlr %d) index %ld to %ld", - (void *)rd, rd->rd_rsm_addr, - rd->rd_wrsmdp->wrsmd_ctlr_id, - ((char *)rd->rd_shdwdqw_o - (char *)rd->rd_shdwdqw_f) / - sizeof (*(rd->rd_shdwdqw_o)), - ((char *)rd->rd_shdwdqw_i - (char *)rd->rd_shdwdqw_f) / - sizeof (*(rd->rd_shdwdqw_i))); - - D2("wrsmdsyncdqe: shdwdqw_i 0x%p shdwdqw_o 0x%p shdwdqw_f 0x%p " - "shdwdqw_l 0x%p", - (void *)rd->rd_shdwdqw_i, - (void *)rd->rd_shdwdqw_o, - (void *)rd->rd_shdwdqw_f, - (void *)rd->rd_shdwdqw_l); - - /* If nothing's queued, nothing to do */ - - if (rd->rd_shdwdqw_i == rd->rd_shdwdqw_o) { - D1("wrsmdsyncdqe: no work, done"); - return; - } - - /* If network down, nothing to do either */ - - if (rd->rd_stopq) { - D1("wrsmdsyncdqe: stopq on, done"); - return; - } - - /* - * Send each element in the queue separately. Since each - * element is WRSMD_CACHELINE_SIZE, then we know that - * each PUT is atomic, and we won't corrupt the remote - * side's free queue if we get a transient error and retry. - * - * (see explination in wrsmdsyncfqe() ) - * - * This is needed on the DQ as well as the FQ because even though - * DQ sends an interrupt when it's complete, there is a small window - * of opportunity if the local side adds more DQ's with the same - * sequence number while the remote side is still consuming them. - * - */ - while (rd->rd_shdwdqw_o != rd->rd_shdwdqw_i) { - - /* Set the sequence number for this DQE */ - rd->rd_shdwdqw_o->s.dq_seqnum = - rd->rd_dqw_seq & WRSMD_DQE_SEQ_MASK; - - /* - * Set the offset to transfer one dqe at a time. - * - * NOTE: We already know we are aligned because - * we allocated the remote buffer on a WRSMD_CACHELINE_SIZE'd - * boundary, and each dqe is WRSMD_CACHELINE_SIZE long. - */ - start_offset = (char *)rd->rd_shdwdqw_o - - (char *)rd->rd_shdwdqw_f; - end_offset = start_offset + sizeof (wrsmd_dqe_t); - - /* Push FQE to remote side */ - stat = RSM_PUT(wrsmdp->wrsmd_ctlr, rd->rd_rxferhand, - rd->rd_dqw_f_off + start_offset, - (char *)rd->rd_shdwdqw_o, end_offset - start_offset); - - if (stat == RSM_SUCCESS) { - /* Write was sucessful */ - - any_transfers++; - - if (rd->rd_shdwdqw_o == rd->rd_shdwdqw_l) { - /* - * Wrap, and update sequence number if - * this the is the last dqe - */ - rd->rd_shdwdqw_o = rd->rd_shdwdqw_f; - - rd->rd_dqw_seq++; - if (rd->rd_dqw_seq == 0) - rd->rd_dqw_seq++; - - } else { - rd->rd_shdwdqw_o ++; - } - - rd->rd_shdwdqw_errflag = 0; - - } else { - - wrsmdp->wrsmd_errs++; - D0("wrsmdsyncdqe: RSM_PUT failed error %d", stat); - - if (stat == RSMERR_CONN_ABORTED) { - /* permanent connection loss */ - wrsmd_lostconn(rd); - } else { - /* - * Schedule an event to retry. Can't do a - * timeout here because it would require - * calling RSM_PUT from a callback. - */ - - wrsmd_add_event(wrsmdp, WRSMD_EVT_SYNC, - (void *)rd); - - rd->rd_shdwdqw_errflag = 1; - } - - if (!any_transfers) - return; - } - - } - - /* If error flag was previously set, retry the interrupt */ - if (any_transfers || old_error_flag) { - wrsmd_msg_t msg; - msg.p.m.syncdqe.rcv_segid = rd->rd_rxfersegid; - stat = wrsmdsendmsg(rd, WRSMD_MSG_SYNC_DQE, &msg); - if (stat != RSM_SUCCESS) { /* Failure */ - /* send failed */ - wrsmdp->wrsmd_errs++; - - if (stat == RSMERR_CONN_ABORTED) { - /* permanent connection loss */ - wrsmd_lostconn(rd); - } else { - /* - * Schedule an event to retry. Can't do a - * timeout here because it would require - * calling RSM_PUT from a callback. - */ - - wrsmd_add_event(wrsmdp, WRSMD_EVT_SYNC, - (void *)rd); - - rd->rd_shdwdqw_errflag = 1; - } - - } else { - wrsmdp->wrsmd_syncdqes++; - } - } - D1("wrsmdsyncdqe: done"); - D2("wrsmdsyncdqe: shdwdqw_i 0x%p shdwdqw_o 0x%p shdwdqw_f 0x%p " - "shdwdqw_l 0x%p", - (void *)rd->rd_shdwdqw_i, - (void *)rd->rd_shdwdqw_o, - (void *)rd->rd_shdwdqw_f, - (void *)rd->rd_shdwdqw_l); -} - -/* - * Determine whether there are any available FQEs. If so, return 1; if none - * are available, return 0. - */ -static int -wrsmdavailfqe( - wrsmd_dest_t *rd) /* Destination pointer */ -{ - wrsmd_fqe_t fqe; - - mutex_enter(&rd->rd_net_lock); - - D1("wrsmdavailfqe: rd 0x%p", (void *)rd); - - if (rd->rd_cached_fqr_cnt) { - D1("wrsmdavailfqe: (cached) returning 1"); - - mutex_exit(&rd->rd_net_lock); - return (1); - } - - fqe = *rd->rd_fqr_n; - - if (fqe.s.fq_seqnum == (rd->rd_fqr_seq & WRSMD_FQE_SEQ_MASK)) { - D1("wrsmdavailfqe: returning 1"); - - mutex_exit(&rd->rd_net_lock); - return (1); - } else { - D1("wrsmdavailfqe: seq %d, expecting %d, returning 0", - fqe.s.fq_seqnum, rd->rd_fqr_seq & WRSMD_FQE_SEQ_MASK); - - mutex_exit(&rd->rd_net_lock); - return (0); - } -} - -/* - * Attempt to retrieve the next available FQE from the queue. If successful, - * return 1; if none are available, return 0. - */ -static int -wrsmdgetfqe( - wrsmd_dest_t *rd, /* Destination pointer */ - int *bufnum) /* Set to number of free buffer, if we got one */ -{ - wrsmd_fqe_t fqe; - - mutex_enter(&rd->rd_net_lock); - - D1("wrsmdgetfqe: rd 0x%p (addr %ld ctlr %d) index %ld", (void *)rd, - rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id, - ((char *)rd->rd_fqr_n - (char *)rd->rd_fqr_f) / sizeof (fqe)); - - /* If we have FQE's cached, return one of those */ - - if (rd->rd_cached_fqr_cnt) { - *bufnum = rd->rd_cached_fqr[--rd->rd_cached_fqr_cnt]; - D1("wrsmdgetfqe: (cached) returning 1, *bufnum %d", - *bufnum); - - mutex_exit(&rd->rd_net_lock); - return (1); - } - - D2("wrsmdgetfqe: start fqr_n 0x%p (index %ld) fqr_f 0x%p fqr_l 0x%p " - "fqr_seq %d", - (void *)rd->rd_fqr_n, - ((char *)rd->rd_fqr_n - (char *)rd->rd_fqr_f) / sizeof (fqe), - (void *)rd->rd_fqr_f, (void *)rd->rd_fqr_l, - rd->rd_fqr_seq & WRSMD_FQE_SEQ_MASK); - - /* Get next FQE */ - - fqe = *rd->rd_fqr_n; - - /* Is it valid? */ - - if (fqe.s.fq_seqnum == (rd->rd_fqr_seq & WRSMD_FQE_SEQ_MASK)) { - /* Yup, return number */ - - *bufnum = fqe.s.fq_bufnum; - - /* Bump pointer, wrap if needed */ - - if (rd->rd_fqr_n == rd->rd_fqr_l) { - rd->rd_fqr_n = rd->rd_fqr_f; - rd->rd_fqr_seq++; - if (rd->rd_fqr_seq == 0) - rd->rd_fqr_seq++; - } else - rd->rd_fqr_n++; - - /* Exercise some paranoia */ - - if (*bufnum >= rd->rd_numrbuf) { - D1("wrsmdgetfqe: bogus buffer %d in FQE " - "at 0x%lx (max %d)", *bufnum, - (uintptr_t)rd->rd_fqr_n, rd->rd_numrbuf); - cmn_err(CE_NOTE, - "wrsmdgetfqe: bogus buffer %d in FQE " - "at 0x%lx (max %d)", *bufnum, - (uintptr_t)rd->rd_fqr_n, rd->rd_numrbuf); - mutex_exit(&rd->rd_net_lock); - return (0); - } - - D1("wrsmdgetfqe: returning 1, *bufnum %d", *bufnum); - D2("wrsmdgetfqe: end fqr_n 0x%p fqr_f 0x%p fqr_l 0x%p " - "fqr_seq %d", (void *)rd->rd_fqr_n, (void *)rd->rd_fqr_f, - (void *)rd->rd_fqr_l, rd->rd_fqr_seq & WRSMD_FQE_SEQ_MASK); - - mutex_exit(&rd->rd_net_lock); - return (1); - } else { - D1("wrsmdgetfqe: seq %d, expecting %d, returning 0", - fqe.s.fq_seqnum, rd->rd_fqr_seq & WRSMD_FQE_SEQ_MASK); - D2("wrsmdgetfqe: end fqr_n 0x%p fqr_f 0x%p fqr_l 0x%p " - "fqr_seq %d", (void *)rd->rd_fqr_n, (void *)rd->rd_fqr_f, - (void *)rd->rd_fqr_l, rd->rd_fqr_seq); - - - mutex_exit(&rd->rd_net_lock); - return (0); - } -} - -/* - * Unget an FQE, making it available to be gotten again. Unlike the C - * ungetc, there is guaranteed to be enough buffering to unget all of the - * FQE's that the remote system can have available. (We do this if we - * get an FQE and then later find that we can't transmit the packet we wanted - * to use it for; for example, if we can't get DMA resources.) - */ -static void -wrsmdungetfqe( - wrsmd_dest_t *rd, /* Destination pointer */ - int bufnum) /* Number of buffer we want to save for later */ -{ - mutex_enter(&rd->rd_net_lock); - - D1("wrsmdungetfqe: rd 0x%p, bufnum %d", (void *)rd, bufnum); - - rd->rd_cached_fqr[rd->rd_cached_fqr_cnt++] = (ushort_t)bufnum; - - D1("wrsmdungetfqe: done"); - - mutex_exit(&rd->rd_net_lock); -} - -/* - * Attempt to retrieve the next available DQE from the queue. If successful, - * return 1; if none are available, return 0. - */ -static int -wrsmdgetdqe( - wrsmd_dest_t *rd, /* Destination pointer */ - int *bufnum, /* Buffer number, set if we find a DQE */ - int *offset, /* Packet offset, set if we find a DQE */ - int *length, /* Packet length, set if we find a DQE */ - ushort_t *sap) /* Packet SAP, set if we find a DQE */ -{ - wrsmd_dqe_t dqe; - - - mutex_enter(&rd->rd_net_lock); - - D1("wrsmdgetdqe: rd 0x%p (addr %ld ctlr %d) index %ld", (void *)rd, - rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id, - ((char *)rd->rd_dqr_n - (char *)rd->rd_dqr_f) / sizeof (dqe)); - D2("wrsmdgetdqe: dqr_n 0x%p (index %ld) dqr_f 0x%p dqr_l 0x%p seq %d", - (void *)rd->rd_dqr_n, - ((char *)rd->rd_dqr_n - (char *)rd->rd_dqr_f) / sizeof (dqe), - (void *)rd->rd_dqr_f, (void *)rd->rd_dqr_l, - rd->rd_dqr_seq & WRSMD_DQE_SEQ_MASK); - - - /* Get next DQE */ - - dqe = *rd->rd_dqr_n; - - /* Is it valid? */ - - if (dqe.s.dq_seqnum == (rd->rd_dqr_seq & WRSMD_DQE_SEQ_MASK)) { - *bufnum = dqe.s.dq_bufnum; - *offset = dqe.s.dq_offset; - *length = dqe.s.dq_length; - *sap = dqe.s.dq_sap; - - /* Exercise some paranoia */ - - if (*bufnum >= rd->rd_numlbufs) { - D1("wrsmdgetdqe: bogus buffer %d " - "in DQE at 0x%p (max %d)", *bufnum, - (void *) &dqe, rd->rd_numlbufs); - cmn_err(CE_NOTE, "wrsmdgetdqe: bogus buffer %d " - "in DQE at 0x%p (max %d)", *bufnum, - (void *) &dqe, rd->rd_numlbufs); - mutex_exit(&rd->rd_net_lock); - return (0); - } - - if (*offset > WRSMD_CACHELINE_OFFSET) { - D1("wrsmdgetdqe: bogus offset %d " - "in DQE at 0x%lx (max %d)", *offset, - (uintptr_t)&dqe, WRSMD_CACHELINE_OFFSET); - cmn_err(CE_NOTE, "wrsmdgetdqe: bogus offset %d " - "in DQE at 0x%lx (max %d)", *offset, - (uintptr_t)&dqe, WRSMD_CACHELINE_OFFSET); - mutex_exit(&rd->rd_net_lock); - return (0); - } - - if (*offset + *length >= rd->rd_lbuflen) { - D1("wrsmdgetdqe: bogus " - "offset+length %d+%d in DQE at 0x%lx (max %d)", - *offset, *length, (uintptr_t)&dqe, - rd->rd_lbuflen); - cmn_err(CE_NOTE, "wrsmdgetdqe: bogus " - "offset+length %d+%d in DQE at 0x%lx (max %d)", - *offset, *length, (uintptr_t)&dqe, - rd->rd_lbuflen); - mutex_exit(&rd->rd_net_lock); - return (0); - } - - if (rd->rd_dqr_n == rd->rd_dqr_l) { - rd->rd_dqr_n = rd->rd_dqr_f; - rd->rd_dqr_seq++; - if (rd->rd_dqr_seq == 0) - rd->rd_dqr_seq++; - } else - rd->rd_dqr_n++; - - D1("wrsmdgetdqe: returning 1, *bufnum %d, *offset %d, " - "*length %d, *sap 0x%x", *bufnum, *offset, *length, *sap); - - mutex_exit(&rd->rd_net_lock); - return (1); - } else { - D1("wrsmdgetdqe: seq %d, expecting %d, returning 0", - dqe.s.dq_seqnum, rd->rd_dqr_seq & WRSMD_DQE_SEQ_MASK); - - mutex_exit(&rd->rd_net_lock); - return (0); - } -} - -/* - * We've tried to get an FQE and failed. Set this destination up to retry - * on a timeout. Destination's state must be INPROGRESS. - */ -static void -wrsmdsetupfqewait( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - wrsmd_dest_t *rd) /* Destination pointer */ -{ - wrsmdsetstate(rd, WRSMD_STATE_W_FQE); - - /* Do exponential backoff */ - - if (rd->rd_tmo_int <= 0) { - rd->rd_tmo_int = - wrsmdp->wrsmd_param.wrsmd_nobuf_init_tmo; - rd->rd_tmo_tot = 0; - } else { - rd->rd_tmo_tot += rd->rd_tmo_int; - rd->rd_tmo_int *= 2; - } - - /* If we've waited too long, dump queue and drop connection */ - - if (rd->rd_tmo_tot >= wrsmdp->wrsmd_param.wrsmd_nobuf_drop_tmo) { - wrsmddumpqueue(wrsmdp, rd); - - wrsmdp->wrsmd_collisions++; - - wrsmd_lostconn(rd); - - /* - * If lostconn() couldn't go to S_DELETE directly, - * then this movestate call will get it noticed. - */ - (void) wrsmdmovestate(rd, WRSMD_STATE_W_FQE, - WRSMD_STATE_S_DELETE); - - return; - } - - /* Clip timeout to maximum */ - - if (rd->rd_tmo_int > wrsmdp->wrsmd_param.wrsmd_nobuf_max_tmo) - rd->rd_tmo_int = wrsmdp->wrsmd_param.wrsmd_nobuf_max_tmo; - - /* - * Only schedule a timeout if there isn't one already. - * We hold rd_xmit_lock, so if the timeout has fired, - * it's blocked on the lock. - */ - if (rd->rd_fqe_tmo_id == 0) - rd->rd_fqe_tmo_id = timeout(wrsmdfqetmo, - (caddr_t)rd, rd->rd_tmo_int); - - wrsmdp->wrsmd_collisions++; -} - -/* - * **************************************************************** - * * - * E N D FREE/DELIVERY QUEUE MANAGEMENT * - * * - * **************************************************************** - */ - - - -/* - * **************************************************************** - * * - * B E G I N COMMUNICATION * - * * - * **************************************************************** - */ - -/* - * Attempt to send one or more packets, currently queued on a destination - * structure, to their actual destination. Destination's state must be - * INPROGRESS. - * - * This function gets called holding rd_xmit_lock. - * This code assumes implicit barriers for puts and gets. - */ -static void -wrsmdxfer( - wrsmd_t *wrsmdp, /* WRSMD device (RSM controller) pointer */ - wrsmd_dest_t *rd) /* Destination pointer */ -{ - int bufnum; - int write_err; - mblk_t *mp; - uint_t pktlen; - uint_t start_offset, end_offset; - int pkts_queued = 0; - - D1("wrsmdxfer: rd 0x%p (addr %ld ctlr %d)", - (void *)rd, rd->rd_rsm_addr, wrsmdp->wrsmd_ctlr_id); - D5("wrsmdxfer 1: time 0x%llx", gethrtime()); - TNF_PROBE_2(wrsmdxfer_start, "RSMPI", "wrsmdxfer start", - tnf_long, wrsmdp, (tnf_long_t)wrsmdp, tnf_long, rd, (tnf_long_t)rd); - - ASSERT(MUTEX_HELD(&rd->rd_xmit_lock)); - - - do { - while ((mp = rd->rd_queue_h) != NULL) { - ushort_t sap; - uchar_t *srcaddr, *endaddr; - int retries; - pktlen = MBLKL(mp); - - /* - * Try to get an FQE. If we can't, and this is the - * first packet we've tried to send on this - * invocation of wrsmdxfer then set up a timeout to - * try again. If we've successfully prepped some - * packets for sending, then go ahead and finish - * the job, on the theory that when they're done - * there may be more FQEs available. - */ - if (wrsmdgetfqe(rd, &bufnum) == 0) { - if (pkts_queued == 0) { - wrsmdsetupfqewait(wrsmdp, rd); - D1("wrsmdxfer: no FQEs, start timeout, " - "done"); - TNF_PROBE_1(wrsmdxfer_end, "RSMPI", - "wrsmdxfer end; failure noFQEs", - tnf_string, failure, "noFQEs"); - return; - } else - break; - } - - /* Take packet off the queue. */ - - rd->rd_queue_h = mp->b_next; - rd->rd_queue_len--; - sap = (ushort_t)(uintptr_t)mp->b_prev; - mp->b_next = mp->b_prev = NULL; - - /* - * Adjust the start pointer and packet length so - * we're copying to and from a 64 byte aligned - * address, if it'll fit in the buffer that way. - * (Note -- this means we may actually be copying - * data that doesn't belong to us!!!) - */ - srcaddr = mp->b_rptr; - start_offset = (uint_t) - ((uint64_t)srcaddr & WRSMD_CACHELINE_OFFSET); - endaddr = srcaddr + pktlen; - end_offset = (uint_t) - (WRSMD_CACHELINE_ROUNDUP(endaddr) - - (uint64_t)endaddr); - - if ((pktlen + start_offset + end_offset) > - rd->rd_rbuflen) { - start_offset = 0; - } - ASSERT((pktlen + start_offset + end_offset) <= - rd->rd_rbuflen); - - D6("wrsmdxfer: srcaddr 0x%p endaddr 0x%p " - "start_offset 0x%x end_offset 0x%x pktlen 0x%x", - (void *)srcaddr, (void *)endaddr, start_offset, - end_offset, pktlen); - TNF_PROBE_3(wrsmdxfer_XFERstart, "RSMPI", - "wrsmdxfer XFERstart", - tnf_long, srcaddr, (tnf_long_t)srcaddr, - tnf_long, pktlen, pktlen, - tnf_long, sap, sap); - - - /* Do the packet copy, check for errors. */ - ASSERT(((rd->rd_rbufoff + (bufnum * rd->rd_rbuflen)) & - WRSMD_CACHELINE_OFFSET) == 0); - - for (retries = wrsmdp->wrsmd_param.wrsmd_err_retries, - write_err = ~RSM_SUCCESS; - retries >= 0 && write_err != RSM_SUCCESS; - retries--) { - D6("wrsmdxfer: put 0x%x bytes at " - "segoffset 0x%lx from addr 0x%p", - pktlen + start_offset + end_offset, - rd->rd_rbufoff + (bufnum * rd->rd_rbuflen), - (void *)(srcaddr - start_offset)); - write_err = RSM_PUT(wrsmdp->wrsmd_ctlr, - rd->rd_rxferhand, - rd->rd_rbufoff + (bufnum * rd->rd_rbuflen), - srcaddr - start_offset, - pktlen + start_offset + end_offset); - if (write_err != RSM_SUCCESS) - wrsmdp->wrsmd_errs++; - if (write_err == RSMERR_CONN_ABORTED) - break; - } - - if (write_err != RSM_SUCCESS) { - wrsmdungetfqe(rd, bufnum); - freemsg(mp); - wrsmdp->wrsmd_oerrors++; - TNF_PROBE_1(wrsmdxfer_XFERend, - "RSMPI", "wrsmdxfer XFERend", - tnf_string, failure, "XFER failed"); - D1("wrsmdxfer: RSM_PUT failed error %d", - write_err); - - if (write_err == RSMERR_CONN_ABORTED) { - wrsmd_lostconn(rd); - wrsmdsetstate(rd, WRSMD_STATE_S_DELETE); - return; - } - } else { - /* - * Ditch the spent packet, send a DQE, - * adjust stats. - */ - - freemsg(mp); - - wrsmdputdqe(rd, bufnum, start_offset, pktlen, - sap); - - pkts_queued++; - - if (pkts_queued == - wrsmdp->wrsmd_param.wrsmd_train_size) { - pkts_queued = 0; - mutex_enter(&rd->rd_net_lock); - wrsmdsyncdqe(rd); - mutex_exit(&rd->rd_net_lock); - } - - wrsmdp->wrsmd_xfer_pkts++; - wrsmdp->wrsmd_opackets++; - wrsmdp->wrsmd_out_bytes += pktlen; - - TNF_PROBE_1(wrsmdxfer_XFERend, "RSMPI", - "wrsmdxfer XFERend", tnf_string, - completed, ""); - } - } - - /* - * We've prepped all the packets we're going to, now finish - * up. - */ - if (pkts_queued) { - mutex_enter(&rd->rd_net_lock); - wrsmdsyncdqe(rd); - mutex_exit(&rd->rd_net_lock); - } - - /* - * If there are more packets to send, and FQE's have become - * available during wrsmdsyncdqe(), try sending them now. - */ - } while ((rd->rd_queue_h != NULL) && wrsmdavailfqe(rd)); - - if (rd->rd_queue_h != NULL) { - /* - * We weren't able to send all packets. - * Schedule a timeout to retry sending them. - */ - wrsmdsetupfqewait(wrsmdp, rd); - D1("wrsmdxfer: no FQEs, start timeout, done"); - TNF_PROBE_1(wrsmdxfer_end, "RSMPI", - "wrsmdxfer end; failure noFQEs", - tnf_string, failure, "noFQEs"); - } else { - wrsmdsetstate(rd, WRSMD_STATE_W_READY); - } - - wrsmdp->wrsmd_xfers++; - - D1("wrsmdxfer: done"); - TNF_PROBE_1(wrsmdxfer_end, "RSMPI", "wrsmdxfer", - tnf_string, complete, ""); -} - - -/* - * Send a message to a remote system. Returns the sequence number of the - * message if one was successfully sent, or -1 if the caller needs to retry - * later. The special message type WRSMD_REXMIT causes us to retransmit the - * last message we sent (unsuccessfully or successfully), without - * incrementing the sequence number. This cannot be called from an - * interrupt. - */ -static int -wrsmdsendmsg(wrsmd_dest_t *rd, uint8_t msg_type, wrsmd_msg_t *msg) -{ - rsm_send_t send_obj; - int status; - - if (msg_type == WRSMD_REXMIT) { - if (rd->rsm_previous_msg_valid) { - msg = &rd->rsm_previous_msg; - } else { - return (-2); - } - } else { - bcopy(msg, &rd->rsm_previous_msg, - sizeof (rd->rsm_previous_msg)); - rd->rsm_previous_msg.p.hdr.reqtype = msg_type; - /* rd_nseq is a ushort, and will wrap when it gets too big. */ - rd->rsm_previous_msg.p.hdr.seqno = rd->rd_nseq++; - rd->rsm_previous_msg.p.hdr.wrsmd_version = WRSMD_VERSION; - } - - /* - * Send fails immediately if message can't be queued. - * On Wildcat, message is sent as soon as it is queued, so - * network failures are reported immediately. - */ - send_obj.is_data = &rd->rsm_previous_msg; - send_obj.is_size = sizeof (wrsmd_msg_t); - send_obj.is_flags = (RSM_INTR_SEND_QUEUE | RSM_INTR_SEND_POLL); - send_obj.is_wait = 1; - - status = RSM_SEND(rd->rd_wrsmdp->wrsmd_ctlr, rd->rsm_sendq, - &send_obj, NULL); - -#ifdef DEBUG - if (status != RSM_SUCCESS) { - D1("wrsmdsendmsg RSM_SEND FAILED!! status %d\n", status); - } else { - D2("wrsmdsendmsg: succeeded\n"); - } -#endif - - return (status); -} - -/* - * **************************************************************** - * * - * E N D COMMUNICATION * - * * - * **************************************************************** - */ - - - - -/* - * **************************************************************** - * * - * B E G I N TIMEOUT-FUNCTIONS * - * * - * **************************************************************** - */ - -/* - * Timeout functions - */ - -/* - * FQE timeout expired. Try sending any packets that were waiting - * for Free Queue Entries. - */ -static void -wrsmdfqetmo(void * arg) -{ - wrsmd_dest_t *rd = (wrsmd_dest_t *)arg; - - D1("wrsmdfqetmo: rd 0x%p (addr %ld ctlr %d)", (void *)rd, - rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id); - - /* - * This mutex doesn't really protect a particular data item in this - * case, it just keeps the movestate from running while we have the - * state messed up in wrsmdmsghdlr_syncdqe(). See that routine for - * more explanation. - */ - mutex_enter(&rd->rd_xmit_lock); - - (void) wrsmdmovestate(rd, WRSMD_STATE_W_FQE, WRSMD_STATE_S_XFER); - - rd->rd_fqe_tmo_id = 0; - - mutex_exit(&rd->rd_xmit_lock); - - - D1("wrsmdfqetmo: done"); -} - -/* - * Connect retransmit backoff timer has expired. Retransmit the connect - * request. - */ -static void -wrsmdsconntmo(void * arg) -{ - wrsmd_dest_t *rd = (wrsmd_dest_t *)arg; - - D1("wrsmdsconntmo: rd 0x%p (addr %ld ctlr %d)", (void *)rd, - rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id); - - rd->rd_tmo_id = 0; - - /* - * If the timeout was cancelled, the state will have also change - * from W_SCONNTMO, and wrsmdmovestate() will have no effect. - */ - (void) wrsmdmovestate(rd, WRSMD_STATE_W_SCONNTMO, - WRSMD_STATE_S_SCONN); - - D1("wrsmdsconntmo: done"); -} - - -/* - * Timer to wait for ACCEPT message from remote has expired. - * This indicates the remote side is not reachable, so tear - * down the WRSMD device (controller). - */ -static void -wrsmdaccepttmo(void * arg) -{ - wrsmd_dest_t *rd = (wrsmd_dest_t *)arg; - - D1("wrsmdaccepttmo: rd 0x%p (addr %ld ctlr %d)", (void *)rd, - rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id); - - rd->rd_tmo_id = 0; - - /* - * If the timeout was cancelled, the state will have also changed - * from W_ACCEPT, and wrsmdmovestate() will have no effect. - */ - (void) wrsmdmovestate(rd, WRSMD_STATE_W_ACCEPT, - WRSMD_STATE_S_DELETE); - - D1("wrsmdaccepttmo: done"); -} - - - -/* - * Timer to wait for ACK message from remote expired. - * This indicates the remote side is not reachable, so tear - * down the WRSMD device (controller). - */ -static void -wrsmdacktmo(void * arg) -{ - wrsmd_dest_t *rd = (wrsmd_dest_t *)arg; - - D1("wrsmdacktmo: rd 0x%p (addr %ld ctlr %d)", (void *)rd, - rd->rd_rsm_addr, rd->rd_wrsmdp->wrsmd_ctlr_id); - - rd->rd_tmo_id = 0; - - /* - * If the timeout was cancelled, the state will have also changed - * from W_ACK, and wrsmdmovestate() will have no effect. - */ - (void) wrsmdmovestate(rd, WRSMD_STATE_W_ACK, - WRSMD_STATE_S_DELETE); - - D1("wrsmdacktmo: done"); -} - - -/* - * Timer to teardown the WRSMD device (RSM controller) has expired. - * Tear down the connection. - */ -static void -wrsmdteardown_tmo(void * arg) -{ - wrsmd_t *wrsmdp = (wrsmd_t *)arg; - - D1("wrsmdteardown_tmo: wrsmd 0x%p (ctlr %d)", (void *)wrsmdp, - wrsmdp->wrsmd_ctlr_id); - - mutex_enter(&wrsmdp->wrsmd_lock); - if (wrsmdp->wrsmd_teardown_tmo_id != 0) { - mutex_exit(&wrsmdp->wrsmd_lock); - if (wrsmduninit(wrsmdp) != 0) { - /* - * If wrsmduninit() does not complete, - * reschedule timeout to retry later. - */ - mutex_enter(&wrsmdp->wrsmd_lock); - wrsmdp->wrsmd_teardown_tmo_id = - timeout(wrsmdteardown_tmo, - (caddr_t)wrsmdp, - wrsmdp->wrsmd_param.wrsmd_teardown_tmo); - } else { - mutex_enter(&wrsmdp->wrsmd_lock); - wrsmdp->wrsmd_teardown_tmo_id = 0; - } - } - mutex_exit(&wrsmdp->wrsmd_lock); - - D1("wrsmdteardown_tmo: done"); -} - - -/* - * **************************************************************** - * * - * E N D TIMEOUT-FUNCTIONS * - * * - * **************************************************************** - */ - -/* - * **************************************************************** - * * - * B E G I N EVENT-FUNCTIONS * - * * - * **************************************************************** - */ - -/* - * The wrsmd event thread. We can't make RSM_ calls that can block - * from either callbacks (timeouts) or interrupts. Use this thread - * (one thread/wrsmd device) to make those calls for us. Currently - * handles freedest and sync events - */ -static void -wrsmd_event_thread(void *arg) -{ - wrsmd_t *wrsmdp = (wrsmd_t *)arg; - callb_cpr_t cprinfo; - - CALLB_CPR_INIT(&cprinfo, &wrsmdp->event_lock, - callb_generic_cpr, "wrsmd_event_thread"); - - /* LINTED: E_CONSTANT_CONDITION */ - while (1) { - wrsmd_process_event(wrsmdp); - - mutex_enter(&wrsmdp->event_lock); - CALLB_CPR_SAFE_BEGIN(&cprinfo); - cv_wait(&wrsmdp->event_cv, &wrsmdp->event_lock); - CALLB_CPR_SAFE_END(&cprinfo, &wrsmdp->event_lock); - mutex_exit(&wrsmdp->event_lock); - - if (wrsmdp->stop_events) { - wrsmd_process_event(wrsmdp); - - mutex_enter(&wrsmdp->event_lock); - cv_broadcast(&wrsmdp->event_thread_exit_cv); - - /* - * CALLB_CPR_EXIT() calls mutex_exit() on the - * lock passed into CALLB_CPR_INIT() above, therefore - * we don't want to call mutex_exit() here. See - * common/sys/callb.h and common/sys/cpr.h. - */ - CALLB_CPR_EXIT(&cprinfo); - - thread_exit(); - return; - } - } -} - -/* - * Helper thread to process events off of the queue. Handles both sync and - * freedest events. - */ -static void -wrsmd_process_event(wrsmd_t *wrsmdp) -{ - wrsmd_event_t *evt; - wrsmd_dest_t *rd; - - mutex_enter(&wrsmdp->event_lock); - - while (wrsmdp->events) { - evt = wrsmdp->events; - mutex_exit(&wrsmdp->event_lock); - - switch (evt->type) { - case WRSMD_EVT_SYNC: - rd = (wrsmd_dest_t *)evt->arg; - - mutex_enter(&rd->rd_net_lock); - /* Try sync'ing again */ - wrsmdsyncdqe(rd); - wrsmdsyncfqe(rd); - mutex_exit(&rd->rd_net_lock); - - break; - - case WRSMD_EVT_SYNC_DQE: - rd = (wrsmd_dest_t *)evt->arg; - wrsmdmsghdlr_syncdqe_evt(rd); - break; - - case WRSMD_EVT_FREEDEST: - - wrsmdfreedestevt(evt->arg); - - break; - default: - break; - } - - mutex_enter(&wrsmdp->event_lock); - wrsmdp->events = evt->next; - kmem_free(evt, sizeof (wrsmd_event_t)); - } - - mutex_exit(&wrsmdp->event_lock); -} - -/* Allocates and adds an event to the event queue */ -static void -wrsmd_add_event(wrsmd_t *wrsmdp, int type, void *arg) -{ - wrsmd_event_t *evt, *newevt; - - mutex_enter(&wrsmdp->event_lock); - - if (wrsmdp->stop_events) { - mutex_exit(&wrsmdp->event_lock); - return; - } - - newevt = kmem_alloc(sizeof (wrsmd_event_t), KM_SLEEP); - newevt->type = type; - newevt->arg = arg; - newevt->next = (wrsmd_event_t *)NULL; - - evt = wrsmdp->events; - if (evt) { - while (evt->next) - evt = evt->next; - - evt->next = newevt; - } else { - wrsmdp->events = newevt; - } - - cv_broadcast(&wrsmdp->event_cv); - mutex_exit(&wrsmdp->event_lock); -} - -/* - * **************************************************************** - * * - * E N D EVENT-FUNCTIONS * - * * - * **************************************************************** - */ - - -#ifdef __lock_lint - -void -freemsg(mblk_t *mp) -{ - freeb(mp); -} - -void -freeb(mblk_t *bp) -{ - wrsmdbuf_t z; - - wrsmdfreebuf(&z); -} - -#endif /* __lock_lint */ diff --git a/usr/src/uts/sun4u/io/wrsmd.conf b/usr/src/uts/sun4u/io/wrsmd.conf deleted file mode 100644 index 89b7273803..0000000000 --- a/usr/src/uts/sun4u/io/wrsmd.conf +++ /dev/null @@ -1,80 +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 2001 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" - -# -# For each Wildcat RSM network controller, you must have a corresponding -# instance of the wrsmd driver with the same instance number as the -# network controller id. -# - -name="wrsmd" parent="pseudo" instance=0; -name="wrsmd" parent="pseudo" instance=1; -name="wrsmd" parent="pseudo" instance=2; -name="wrsmd" parent="pseudo" instance=3; -name="wrsmd" parent="pseudo" instance=4; -name="wrsmd" parent="pseudo" instance=5; -name="wrsmd" parent="pseudo" instance=6; -name="wrsmd" parent="pseudo" instance=7; -name="wrsmd" parent="pseudo" instance=8; -name="wrsmd" parent="pseudo" instance=9; -name="wrsmd" parent="pseudo" instance=10; -name="wrsmd" parent="pseudo" instance=11; -name="wrsmd" parent="pseudo" instance=12; -name="wrsmd" parent="pseudo" instance=13; -name="wrsmd" parent="pseudo" instance=14; -name="wrsmd" parent="pseudo" instance=15; - -# -# Number of packet buffers exported to each communicating peer -# -wrsmd-buffers = 32; - -# -# Size of packet buffers (must be multiple of 64 bytes). For best performance, -# this should be slightly larger than the normal amount of data your network -# application reads or writes in one system call (your "application data -# transfer size"). If it's more than two times your application data transfer -# size, the driver will end up doing internal data copying to coalesce writes -# together, which will reduce performance. Note also that your TCP window -# size should be set to at least twice this buffer size for best performance. -# -# Note: (wrsmd-buffers * wrsmd-buffer-size) is allocated by the driver for -# each remote node with which communication takes place. -# -wrsmd-buffer-size = 16384; - -# -# Size of communications queues (must be at least as large as wrsmd-buffers). -# -wrsmd-queue-size = 64; - -# -# Maximum number of packets which will be queued for a remote destination -# before we start throwing them away. This should be something like -# (# of concurrent tcp connections) * (tcp window size) / (interface mtu). -# -wrsmd-max-queued-pkts = 100; diff --git a/usr/src/uts/sun4u/serengeti/Makefile.serengeti.shared b/usr/src/uts/sun4u/serengeti/Makefile.serengeti.shared index d7a3d50d3c..a822481917 100644 --- a/usr/src/uts/sun4u/serengeti/Makefile.serengeti.shared +++ b/usr/src/uts/sun4u/serengeti/Makefile.serengeti.shared @@ -97,7 +97,7 @@ include $(UTSTREE)/sun4u/Makefile.sun4u # Define modules # SERENGETI_KMODS = cheetah cheetahplus -SERENGETI_KMODS += platmod sbdp sgcn sghsc sgsbbc ssm wrsm wrsmplat +SERENGETI_KMODS += platmod sbdp sgcn sghsc sgsbbc ssm # # Everybody needs to know how to build modstubs.o and to locate unix.o diff --git a/usr/src/uts/sun4u/serengeti/io/wrsmplat.c b/usr/src/uts/sun4u/serengeti/io/wrsmplat.c deleted file mode 100644 index 2a1f282d92..0000000000 --- a/usr/src/uts/sun4u/serengeti/io/wrsmplat.c +++ /dev/null @@ -1,1582 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Serengeti WRSM platform-specific module - */ - - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/ddi.h> -#include <sys/cmn_err.h> -#include <sys/modctl.h> -#include <sys/kmem.h> -#include <sys/disp.h> -#include <sys/int_fmtio.h> -#include <sys/cpuvar.h> -#include <sys/cpu_module.h> - -#include <sys/wrsm_config.h> -#include <sys/wrsm_plat_impl.h> -#include <sys/wci_regs.h> -#include <sys/wci_offsets.h> -#include <sys/wci_common.h> -#include <sys/sgsbbc.h> -#include <sys/sgsbbc_mailbox.h> - -#ifdef DEBUG -#define WP_DEBUG 1 -#define WP_QUEUE 2 -#define WP_LINK 4 -#define WP_THREAD 8 -#define WP_MBOX 16 - -static uint_t wrsm_plat_debug = 0; - -#define DPRINTF(a, b) { if (wrsm_plat_debug & a) cmn_err b; } -#else -#define DPRINTF(a, b) { } -#endif - -static wrsm_node_types_t node_type = wrsm_node_serengeti; - -/* this variable allows for runtime changes of the use of the mailbox */ -boolean_t wrsm_use_sgsbbc = B_TRUE; - -static uint64_t read_reg(volatile uchar_t *regs, uint64_t offset); -static void write_reg(volatile uchar_t *regs, uint64_t offset, uint64_t value); - -/* Converts a 10-bit safari port id to its 4-bit SSM node id */ -#define PORT2NODE(p) (((p) >> 5) & 0xf) - -/* - * Module linkage information for the kernel. - */ -static struct modlmisc modlmisc = { - &mod_miscops, - "Sun Fire wrsm platmod %I%" -}; - -static struct modlinkage modlinkage = { - MODREV_1, (void *)&modlmisc, NULL -}; - - -typedef struct wrsmplat_mbox_msg { - uint32_t msg_type; - boolean_t loopback; - void *msg_data; - size_t msg_size; - struct wrsmplat_mbox_msg *next; -} wrsmplat_mbox_msg_t; - -/* - * If stop_thread is set for a particular link of a wci, that means that - * the thread trying to bringup that link should give up and exit. - */ -typedef struct wrsmplat_link { - kmutex_t mutex; - boolean_t thread_active; - boolean_t stop_thread; - kcondvar_t cv; -} wrsmplat_link_t; - -typedef struct wrsmplat_wci { - safari_port_t wci_id; - boolean_t valid; - boolean_t suspended; - wrsmplat_link_t link[WRSM_MAX_LINKS_PER_WCI]; -} wrsmplat_wci_t; - -static struct wrsmplat_state { - boolean_t thread_stop; - wrsmplat_mbox_msg_t *msg_queue; - kmutex_t queue_lock; - wrsm_plat_ops_t *cb_ops; - kcondvar_t msg_cv; - kmutex_t cv_lock; - uint_t thread_count; - - sbbc_msg_t junk_message; /* for asynchronous mailbox */ - wrsm_linkisup_msg_t junk_stuff; /* buffer for incoming message */ - kmutex_t intr_lock; - uint_t intr_state; - wrsmplat_wci_t wci[WRSM_MAX_WCIS]; - kmutex_t thread_count_lock; - kmutex_t tnid_map_lock; -} wrsmplat_state = {0}; - -/* - * serengeti implementations of these functions are empty since - * for serengeti cesr ids can be specified in 6 bits given the - * maximum of 48 cores - */ - -void -wrsmplat_set_asi_cesr_id(void) -{ -} - -void -wrsmplat_clr_asi_cesr_id(void) -{ -} - -/* support when SC is not available */ -static void -stop_thread(safari_port_t wci_id, int link) -{ - int i; - wrsmplat_link_t *l; - - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci_id) { - l = &wrsmplat_state.wci[i].link[link]; - mutex_enter(&l->mutex); - while (l->thread_active) { - DPRINTF(WP_THREAD, (CE_CONT, - "stop_thread: wci %d link %d " - "waiting for thread to stop", - wci_id, link)); - l->stop_thread = B_TRUE; - cv_wait(&l->cv, &l->mutex); - } - mutex_exit(&l->mutex); - DPRINTF(WP_THREAD, (CE_CONT, "stop_thread: " - "wci %d link %d thread stopped", - wci_id, link)); - break; - } - } -} - -static void -start_thread(safari_port_t wci_id, int link, void (*proc)(), caddr_t arg) -{ - int i; - boolean_t found = B_FALSE; - wrsmplat_link_t *l; - - /* First, look to see if WCI already exists */ - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci_id) { - /* Don't start the thread if wci was suspended */ - if (wrsmplat_state.wci[i].suspended) { - DPRINTF(WP_THREAD, (CE_CONT, "wci %d is " - "suspended, can't start thread", wci_id)); - return; - } - l = &wrsmplat_state.wci[i].link[link]; - mutex_enter(&l->mutex); - if (l->thread_active) { - mutex_exit(&l->mutex); - DPRINTF(WP_THREAD, (CE_CONT, "wci %d link %d " - "thread already running", wci_id, link)); - return; - } - l->thread_active = B_TRUE; - l->stop_thread = B_FALSE; - mutex_exit(&l->mutex); - found = B_TRUE; - DPRINTF(WP_THREAD, (CE_CONT, "wci %d exists", wci_id)); - break; - } - } - - /* If not, then search for free space and add wci to the list */ - if (!found) { - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (!wrsmplat_state.wci[i].valid) { - wrsmplat_state.wci[i].wci_id = wci_id; - l = &wrsmplat_state.wci[i].link[link]; - mutex_init(&l->mutex, NULL, MUTEX_DRIVER, - NULL); - cv_init(&l->cv, NULL, CV_DEFAULT, NULL); - l->thread_active = B_TRUE; - l->stop_thread = B_FALSE; - wrsmplat_state.wci[i].valid = B_TRUE; - wrsmplat_state.wci[i].suspended = B_FALSE; - found = B_TRUE; - DPRINTF(WP_THREAD, (CE_CONT, "created wci %d", - wci_id)); - break; - } - } - } - - if (found || wci_id == -1) { - mutex_enter(&wrsmplat_state.thread_count_lock); - ++wrsmplat_state.thread_count; - DPRINTF(WP_THREAD, (CE_CONT, - "start_thread: wci %d, link %d, thread #%d", - wci_id, link, wrsmplat_state.thread_count)); - mutex_exit(&wrsmplat_state.thread_count_lock); - (void) thread_create(NULL, 0, proc, arg, - 0, &p0, TS_RUN, minclsyspri); - /* LINTED - E_NOP_ELSE_STMT */ - } else { - DPRINTF(WP_DEBUG, (CE_WARN, "start_thread: bad wci/link: " - "wci %d link %d", wci_id, link)); - } -} - -static void -exit_thread(safari_port_t wci_id, int link) -{ - int i; - wrsmplat_link_t *l; - - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci_id) { - l = &wrsmplat_state.wci[i].link[link]; - mutex_enter(&l->mutex); - l->thread_active = B_FALSE; - cv_broadcast(&l->cv); - mutex_exit(&l->mutex); - } - } - mutex_enter(&wrsmplat_state.thread_count_lock); - --wrsmplat_state.thread_count; - DPRINTF(WP_THREAD, (CE_CONT, "exit_thread: thread " - "exiting for wci %d link %d. There are %d threads left", - wci_id, link, wrsmplat_state.thread_count)); - mutex_exit(&wrsmplat_state.thread_count_lock); - - thread_exit(); -} - -static boolean_t -check_stop_thread(safari_port_t wci_id, int link) -{ - int i; - - if (wrsmplat_state.thread_stop) { - return (B_TRUE); - } - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci_id) { - return (wrsmplat_state.wci[i].link[link].stop_thread); - } - } - return (B_FALSE); -} - -/* Use default timeout */ -#define SC_TIMEOUT_SEC MBOX_DEFAULT_TIMEOUT - -static uint_t wrsmplat_handler(caddr_t arg); - -static void queue_message(uint32_t msg_type, boolean_t loopback, - void *msg_data, size_t msg_size); -static wrsmplat_mbox_msg_t *dequeue_msg(void); -static void process_message(void); -static void wrsmplat_thread(void *arg); - -/* used to start a thread */ -typedef struct wrsmplat_thread_data { - wrsm_uplink_msg_t *msg; - volatile uchar_t *wrsm_regs; - boolean_t loopback; - fmnodeid_t remote_fmnodeid; - gnid_t remote_gnid; -} wrsmplat_thread_data_t; - -static void activate_link(wrsmplat_thread_data_t *data); -static void deactivate_link(safari_port_t portid, - volatile uchar_t *wrsm_regs, linkid_t link_num); -static int try_activate(wrsm_uplink_msg_t *msg, volatile uchar_t *wrsm_regs); - -int -_init(void) -{ - int rc = 0; - DPRINTF(WP_DEBUG, (CE_CONT, "serengeti:wrsmplat _init")); - - wrsmplat_state.msg_queue = NULL; - mutex_init(&wrsmplat_state.queue_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&wrsmplat_state.cv_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&wrsmplat_state.intr_lock, NULL, MUTEX_DRIVER, NULL); - cv_init(&wrsmplat_state.msg_cv, NULL, CV_DRIVER, NULL); - - if (!wrsm_use_sgsbbc) { - cmn_err(CE_WARN, "wrsm in test mode, not using SC\n"); - } - - wrsmplat_state.intr_state = SBBC_INTR_IDLE; - wrsmplat_state.junk_message.msg_type.type = WILDCAT_RSM_MBOX; - wrsmplat_state.junk_message.msg_buf = - (caddr_t)&wrsmplat_state.junk_stuff; - wrsmplat_state.junk_message.msg_len = - sizeof (wrsmplat_state.junk_stuff); - if ((rc = sbbc_mbox_reg_intr(WILDCAT_RSM_MBOX, - &wrsmplat_handler, &wrsmplat_state.junk_message, - &wrsmplat_state.intr_state, &wrsmplat_state.intr_lock)) - != 0) { - cmn_err(CE_WARN, "sbbc_mbox_reg_intr failed %d", rc); - mutex_destroy(&wrsmplat_state.queue_lock); - mutex_destroy(&wrsmplat_state.cv_lock); - mutex_destroy(&wrsmplat_state.intr_lock); - cv_destroy(&wrsmplat_state.msg_cv); - return (rc); - } - DPRINTF(WP_DEBUG, (CE_CONT, "sbbc_mbox_reg_intr SUCCESS!")); - mutex_init(&wrsmplat_state.thread_count_lock, NULL, - MUTEX_DRIVER, NULL); - mutex_init(&wrsmplat_state.tnid_map_lock, NULL, - MUTEX_DRIVER, NULL); - - if ((rc = mod_install(&modlinkage)) != 0) { - sbbc_mbox_unreg_intr(WILDCAT_RSM_MBOX, &wrsmplat_handler); - mutex_destroy(&wrsmplat_state.queue_lock); - mutex_destroy(&wrsmplat_state.cv_lock); - mutex_destroy(&wrsmplat_state.intr_lock); - cv_destroy(&wrsmplat_state.msg_cv); - mutex_destroy(&wrsmplat_state.thread_count_lock); - mutex_destroy(&wrsmplat_state.tnid_map_lock); - return (rc); - } - return (0); -} - -int -_fini(void) -{ - int rc; - - DPRINTF(WP_DEBUG, (CE_CONT, "serengeti:wrsmplat _fini")); - - if ((rc = mod_remove(&modlinkage)) != 0) { - return (rc); - } - /* - * This blocks waiting for all the child threads to die - */ - (void) wrsmplat_unreg_callbacks(); - - mutex_destroy(&wrsmplat_state.queue_lock); - mutex_destroy(&wrsmplat_state.cv_lock); - cv_destroy(&wrsmplat_state.msg_cv); - - mutex_destroy(&wrsmplat_state.intr_lock); - sbbc_mbox_unreg_intr(WILDCAT_RSM_MBOX, &wrsmplat_handler); - - mutex_destroy(&wrsmplat_state.thread_count_lock); - mutex_destroy(&wrsmplat_state.tnid_map_lock); - - return (0); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - - -/* - * Handle asynchronous messages from the SC up to the kernel - */ -/* ARGSUSED */ -uint_t -wrsmplat_handler(caddr_t arg) -{ - wrsm_linkisup_msg_t *linkisup_msg; - - mutex_enter(&wrsmplat_state.intr_lock); - wrsmplat_state.intr_state = SBBC_INTR_RUNNING; - mutex_exit(&wrsmplat_state.intr_lock); - - - DPRINTF(WP_MBOX, (CE_CONT, "wrsmplat_handler: received message," - " type=%d, sub-type: %d status = %d, length= %d, data=%x %x", - wrsmplat_state.junk_message.msg_type.type, - wrsmplat_state.junk_message.msg_type.sub_type, - wrsmplat_state.junk_message.msg_status, - wrsmplat_state.junk_message.msg_bytes, - wrsmplat_state.junk_message.msg_data[0], - wrsmplat_state.junk_message.msg_data[1])); - - - if (wrsmplat_state.junk_message.msg_type.type != WILDCAT_RSM_MBOX) { - cmn_err(CE_WARN, "wrsmplat_handler: wrong message type"); - } else { - linkisup_msg = (wrsm_linkisup_msg_t *) - wrsmplat_state.junk_message.msg_buf; - - switch (linkisup_msg->async_msg_type) { - - case LINKISUP: - DPRINTF(WP_MBOX, (CE_CONT, "_handler: LINKISUP " - "wci %d link %d", - linkisup_msg->link_info.wci_port_id, - linkisup_msg->link_info.link_num)); - - /* put this message on a queue to be handled later */ - queue_message(LINKISUP, B_FALSE, - &linkisup_msg->link_info, - sizeof (linkisup_msg->link_info)); - - break; - default: - cmn_err(CE_WARN, "wrsmplat_handler:" - " unhandled async_msg_type"); - } - } - - mutex_enter(&wrsmplat_state.intr_lock); - wrsmplat_state.intr_state = SBBC_INTR_IDLE; - mutex_exit(&wrsmplat_state.intr_lock); - - return (0); -} - -wrsm_node_types_t -wrsmplat_get_node_type(void) -{ - return (node_type); -} - - -int -wrsmplat_uplink(safari_port_t wci, linkid_t link, gnid_t gnid, - fmnodeid_t fmnodeid, uint64_t partition_version, uint32_t controller_id, - boolean_t loopback) -{ - wrsm_uplink_msg_t msg = {0}; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_uplink wci %d link %d", - wci, link)); - - msg.config_data.partition_version = partition_version; - msg.config_data.partition_id = controller_id; - msg.config_data.fmnodeid = fmnodeid; - msg.config_data.gnid = gnid; - msg.wci_port_id = wci; - msg.link_num = link; - - queue_message(UPLINK, loopback, &msg, sizeof (msg)); - return (0); -} - -int -wrsmplat_downlink(safari_port_t wci, linkid_t link, boolean_t loopback) -{ - wrsm_link_msg_t msg = {0}; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_downlink wci %d link %d", - wci, link)); - msg.wci_port_id = wci; - msg.link_num = link; - - queue_message(DOWNLINK, loopback, &msg, sizeof (msg)); - return (0); -} - -int -wrsmplat_linktest(safari_port_t wci, wrsm_linktest_arg_t *linktest) -{ - fmnodeid_t remote_fmnodeid; - gnid_t remote_gnid; - linkid_t remote_link; - safari_port_t remote_port; - volatile unsigned char *wrsm_regs = NULL; - wci_sw_link_control_u link_control; - wci_sw_link_status_u link_status; - uint64_t offset = linktest->link_num * STRIDE_WCI_SW_LINK_CONTROL; - - if (linktest->link_num >= WRSM_LINKS_PER_WCI) - return (EINVAL); - - (*wrsmplat_state.cb_ops->get_remote_data)(wci, linktest->link_num, - &remote_fmnodeid, &remote_gnid, &remote_link, &remote_port, - &wrsm_regs); - - if (!wrsm_regs) - return (ENXIO); - - link_control.val = read_reg(wrsm_regs, - ADDR_WCI_SW_LINK_CONTROL + offset); - if (link_control.bit.link_state != LINK_STATE_IN_USE) - return (EAGAIN); - - link_control.val = read_reg(wrsm_regs, - ADDR_WCI_SW_LINK_CONTROL + offset); - linktest->link_control = link_control.val; - link_control.bit.usr_data_1 = linktest->pattern & 0xffff; - link_control.bit.usr_data_2 = ((linktest->pattern >> 16) & 0x3); - write_reg(wrsm_regs, ADDR_WCI_SW_LINK_CONTROL + offset, - link_control.val); - linktest->link_error_count = read_reg(wrsm_regs, - ADDR_WCI_SW_LINK_ERROR_COUNT + offset); - linktest->link_esr = read_reg(wrsm_regs, ADDR_WCI_LINK_ESR); - linktest->sw_esr = read_reg(wrsm_regs, ADDR_WCI_SW_ESR); - link_status.val = read_reg(wrsm_regs, - ADDR_WCI_SW_LINK_STATUS + offset); - linktest->link_status = link_status.val; - linktest->pattern = link_status.bit.farend_ustat_1 | - (link_status.bit.farend_ustat_2 << 16); - - return (0); -} - -int -wrsmplat_set_led(safari_port_t wci, linkid_t link, int led_state) -{ - wrsm_link_led_msg_t msg = {0}; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_set_led, mode = %d", led_state)); - msg.wci_port_id = wci; - msg.link_num = link; - msg.led_state = led_state; - queue_message(SETLEDSTATE, B_FALSE, &msg, sizeof (msg)); - return (0); -} - -int -wrsmplat_alloc_slices(ncslice_bitmask_t requested, ncslice_bitmask_t *granted) -{ - - wrsm_ncslice_claim_msg_t msg = {0}; - wrsm_ncslice_claim_msg_t answer = {0}; - - sbbc_msg_t request = {0}; - sbbc_msg_t response = {0}; - int rc; - int i; - ncslice_bitmask_t allocated = {0}; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_alloc_slices")); - - if (wrsm_use_sgsbbc) { - msg.requested_ncslices = requested; - - request.msg_type.type = WILDCAT_RSM_MBOX; - request.msg_type.sub_type = NCSLICE; - request.msg_len = sizeof (msg); - request.msg_buf = (caddr_t)&msg; - - response.msg_type.type = WILDCAT_RSM_MBOX; - response.msg_type.sub_type = NCSLICE; - response.msg_len = sizeof (answer); - response.msg_buf = (caddr_t)&answer; - - if ((rc = sbbc_mbox_request_response(&request, &response, - SC_TIMEOUT_SEC)) != 0) { - cmn_err(CE_WARN, "sbbc_mbox_request failed rc=%d", rc); - } else { - if (response.msg_status) { - cmn_err(CE_WARN, "error status %d " - "from NCSLICE request", - response.msg_status); - } - *granted = answer.requested_ncslices; - } - return (rc); - } else { - /* - * We are only allowed to use NC slices 161 to 254, - * and 0 is reserved. - */ - for (i = 161; i < (WRSM_MAX_NCSLICES - 1); ++i) - if (WRSM_IN_SET(requested, i)) - WRSMSET_ADD(allocated, i); - WRSMSET_COPY(allocated, *granted); - return (0); - } -} - -int -wrsmplat_set_seprom(safari_port_t wci_id, uchar_t *seprom_data, - size_t length) -{ - wrsm_wib_seprom_msg_t msg; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_set_seprom")); - if (length > WIB_SEPROM_MSG_SIZE) - return (EINVAL); - msg.wci_port_id = wci_id; - bcopy(seprom_data, &msg.seprom_data, length); - - queue_message(SETSEPROM, B_FALSE, &msg, sizeof (msg)); - return (0); -} - -int -wrsmplat_reg_callbacks(wrsm_plat_ops_t *ops) -{ - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_reg_callbacks")); - - wrsmplat_state.cb_ops = ops; - wrsmplat_state.thread_stop = B_FALSE; - - if (!wrsm_use_sgsbbc && (wrsmplat_state.thread_count != 0)) { - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_reg_callbacks: " - "called more than once")); - return (EEXIST); - } - - /* - * no need to lock the thread count: - * when using the mailbox : only one thread exists - * not using the mailbox : the wrsmplat thread starts other threads - */ - wrsmplat_state.thread_count = 1; - (void) thread_create(NULL, 0, wrsmplat_thread, NULL, 0, &p0, - TS_RUN, minclsyspri); - return (0); -} - -int -wrsmplat_unreg_callbacks(void) -{ - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_unreg_callbacks")); - - wrsmplat_state.thread_stop = B_TRUE; - - /* Wake up the message thread */ - mutex_enter(&wrsmplat_state.cv_lock); - cv_signal(&wrsmplat_state.msg_cv); - mutex_exit(&wrsmplat_state.cv_lock); - - /* - * Eventually, all of the threads should wake up, notice the - * thread_stop flag is set and exit. When they have all - * finished, the count should go to zero and it is safe to - * proceed. In case of not using SBBC ther is only one thread. - */ - while (wrsmplat_state.thread_count > 0) { - DPRINTF(WP_THREAD, (CE_CONT, "unreg_callbacks: waiting for " - "%d threads to finish", wrsmplat_state.thread_count)); - delay(drv_usectohz(1000 * 1000)); - } - wrsmplat_state.cb_ops = NULL; - return (0); -} - -static void -queue_message(uint32_t msg_type, boolean_t loopback, void *msg_data, - size_t msg_size) -{ - wrsmplat_mbox_msg_t *entry, *p; - DPRINTF(WP_QUEUE, (CE_CONT, "queue_message: msg_type = %d nthreads=%d", - msg_type, wrsmplat_state.thread_count)); - entry = kmem_alloc(sizeof (wrsmplat_mbox_msg_t), KM_SLEEP); - entry->msg_type = msg_type; - entry->loopback = loopback; - entry->msg_data = kmem_alloc(msg_size, KM_SLEEP); - bcopy(msg_data, entry->msg_data, msg_size); - entry->msg_size = msg_size; - entry->next = NULL; - mutex_enter(&wrsmplat_state.queue_lock); - if (wrsmplat_state.msg_queue == NULL) - wrsmplat_state.msg_queue = entry; - else { - p = wrsmplat_state.msg_queue; - while (p->next != NULL) - p = p->next; - p->next = entry; - } - mutex_exit(&wrsmplat_state.queue_lock); - - DPRINTF(WP_QUEUE, (CE_CONT, "queue_message: queued msg_type = %d\n", - msg_type)); - - mutex_enter(&wrsmplat_state.cv_lock); - cv_signal(&wrsmplat_state.msg_cv); - mutex_exit(&wrsmplat_state.cv_lock); - - DPRINTF(WP_QUEUE, (CE_CONT, "queue_message: signaled msg_type = %d\n", - msg_type)); -} - -static wrsmplat_mbox_msg_t * -dequeue_msg(void) -{ - wrsmplat_mbox_msg_t *msg; - - mutex_enter(&wrsmplat_state.queue_lock); - msg = wrsmplat_state.msg_queue; - if (msg != NULL) - wrsmplat_state.msg_queue = msg->next; - mutex_exit(&wrsmplat_state.queue_lock); - - return (msg); -} - -/* ARGSUSED */ -static void -wrsmplat_thread(void *arg) -{ - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_thread starting")); - - /* LINTED */ - while (1) { - process_message(); - - /* go to sleep waiting for the next message */ - mutex_enter(&wrsmplat_state.cv_lock); - cv_wait(&wrsmplat_state.msg_cv, &wrsmplat_state.cv_lock); - mutex_exit(&wrsmplat_state.cv_lock); - - if (wrsmplat_state.thread_stop) { - process_message(); /* finish any waiting messages */ - if (!wrsm_use_sgsbbc) { /* there > 1 thread */ - mutex_enter(&wrsmplat_state.thread_count_lock); - } - /* in SBBC case there is only one thread */ - --wrsmplat_state.thread_count; - if (!wrsm_use_sgsbbc) { - mutex_exit(&wrsmplat_state.thread_count_lock); - } - thread_exit(); - } - } -} - -static void -process_message(void) -{ - wrsmplat_mbox_msg_t *entry; - wrsm_link_msg_t *msg; - - wrsm_link_msg_t question = {0}; - wrsm_uplink_msg_t answer = {0}; - - sbbc_msg_t request = {0}; - sbbc_msg_t response = {0}; - int rc = 0; - - boolean_t free_msg = B_TRUE; - linkid_t remote_link; - safari_port_t remote_port; - gnid_t remote_gnid; - /* LINTED */ - fmnodeid_t remote_fmnodeid; - - while (entry = dequeue_msg()) { - switch (entry->msg_type) { - - case LINKISUP: { - /* this is the message from SC, need to get more data */ - msg = (wrsm_link_msg_t *)(entry->msg_data); - question.wci_port_id = msg->wci_port_id; - question.link_num = msg->link_num; - - request.msg_len = sizeof (question); - request.msg_buf = (caddr_t)&question; - response.msg_len = sizeof (answer); - response.msg_buf = (caddr_t)&answer; - - request.msg_type.sub_type = LINKDATA; - request.msg_type.type = WILDCAT_RSM_MBOX; - response.msg_type.sub_type = LINKDATA; - response.msg_type.type = WILDCAT_RSM_MBOX; - - if ((rc = sbbc_mbox_request_response(&request, - &response, SC_TIMEOUT_SEC)) != 0) { - cmn_err(CE_WARN, "sbbc_mbox_request_response " - "failed rc=%d", rc); - break; - } - if (response.msg_status) { - cmn_err(CE_WARN, "error status %d " - "from LINKDATA request", - response.msg_status); - } - - DPRINTF(WP_MBOX, (CE_CONT, "process_message: wci %d " - "link %d fmnid %d gnid %d alink %d port %d " - "parver %ld parid %d", msg->wci_port_id, - msg->link_num, - answer.config_data.fmnodeid, - answer.config_data.gnid, - answer.link_num, - answer.wci_port_id, - answer.config_data.partition_version, - answer.config_data.partition_id)); - - (*wrsmplat_state.cb_ops->link_up) - (msg->wci_port_id, - (linkid_t)msg->link_num, - answer.config_data.fmnodeid, - answer.config_data.gnid, - (linkid_t)answer.link_num, - answer.wci_port_id, - answer.config_data.partition_version, - answer.config_data.partition_id); - - break; - } - - case UPLINK: { - /* this is a message to be sent to SC */ - if (wrsm_use_sgsbbc) { - request.msg_len = sizeof (wrsm_uplink_msg_t); - request.msg_buf = (caddr_t)(entry->msg_data); - response.msg_len = 0; - response.msg_buf = NULL; - - request.msg_type.sub_type = UPLINK; - request.msg_type.type = WILDCAT_RSM_MBOX; - response.msg_type.sub_type = UPLINK; - response.msg_type.type = WILDCAT_RSM_MBOX; - - if ((rc = sbbc_mbox_request_response(&request, - &response, SC_TIMEOUT_SEC)) != 0) { - cmn_err(CE_WARN, - "sbbc_mbox_request_response " - "failed rc=%d", rc); - } - if (response.msg_status == - SG_MBOX_STATUS_ILLEGAL_PARAMETER) { - cmn_err(CE_WARN, - "SC reports mismatch fmnodeid"); - } else if (response.msg_status) { - cmn_err(CE_WARN, - "unrecognized error status %d " - "from UPLINK request", - response.msg_status); - } - } else { - - wrsm_uplink_msg_t *umsg; - wrsmplat_thread_data_t *thread_data; - - thread_data = kmem_alloc( - sizeof (wrsmplat_thread_data_t), KM_SLEEP); - umsg = (wrsm_uplink_msg_t *)(entry->msg_data); - thread_data->msg = umsg; - thread_data->loopback = entry->loopback; - - (*wrsmplat_state.cb_ops->get_remote_data) - (umsg->wci_port_id, - (linkid_t)umsg->link_num, - &thread_data->remote_fmnodeid, - &thread_data->remote_gnid, - &remote_link, &remote_port, - &thread_data->wrsm_regs); - if (!thread_data->wrsm_regs) { - DPRINTF(WP_DEBUG, (CE_WARN, "mp " - "UPLINK: failed to get register " - "base")); - return; - } - stop_thread(umsg->wci_port_id, - umsg->link_num); - start_thread(umsg->wci_port_id, - umsg->link_num, - activate_link, - (caddr_t)thread_data); - free_msg = B_FALSE; - } - break; - } - case DOWNLINK: { - /* this is a message to be sent to SC */ - if (wrsm_use_sgsbbc) { - msg = (wrsm_link_msg_t *)(entry->msg_data); - - request.msg_len = sizeof (wrsm_link_msg_t); - request.msg_buf = (caddr_t)(entry->msg_data); - response.msg_len = 0; - response.msg_buf = NULL; - - request.msg_type.type = WILDCAT_RSM_MBOX; - request.msg_type.sub_type = DOWNLINK; - response.msg_type.sub_type = DOWNLINK; - response.msg_type.type = WILDCAT_RSM_MBOX; - - if ((rc = sbbc_mbox_request_response(&request, - &response, SC_TIMEOUT_SEC)) != 0) { - cmn_err(CE_WARN, - "sbbc_mbox_request_response failed " - "rc=%d", rc); - } - if (response.msg_status == - SG_MBOX_STATUS_HARDWARE_FAILURE) { - cmn_err(CE_WARN, - "SC reports hardware failure for " - "DOWNLINK request"); - } else if (response.msg_status) { - cmn_err(CE_WARN, "error status %d for " - "DOWNLINK request", - response.msg_status); - } - - /* should not call link_down for loopback */ - if ((rc == 0) && (!entry->loopback)) - (*wrsmplat_state.cb_ops->link_down) - (msg->wci_port_id, - msg->link_num); - } else { - - volatile unsigned char *wrsm_regs = NULL; - msg = (wrsm_link_msg_t *)(entry->msg_data); - - (*wrsmplat_state.cb_ops->get_remote_data) - (msg->wci_port_id, - (linkid_t)msg->link_num, - &remote_fmnodeid, - &remote_gnid, - &remote_link, - &remote_port, - &wrsm_regs); - - stop_thread(msg->wci_port_id, - msg->link_num); - - if (wrsm_regs) { - deactivate_link(msg->wci_port_id, - wrsm_regs, msg->link_num); - /* LINTED - E_NOP_ELSE_STMT */ - } else { - DPRINTF(WP_DEBUG, (CE_WARN, "mp " - "DOWNLINK: failed to get register " - "base")); - } - - /* should not call link_down for loopback */ - if (!entry->loopback) - (*wrsmplat_state.cb_ops->link_down) - (msg->wci_port_id, - (linkid_t)msg->link_num); - } - break; - } - case SETLEDSTATE: { - /* this is a message to be sent to SC */ - if (wrsm_use_sgsbbc) { - request.msg_len = sizeof (wrsm_link_led_msg_t); - request.msg_buf = (caddr_t)(entry->msg_data); - response.msg_len = 0; - response.msg_buf = NULL; - - request.msg_type.type = WILDCAT_RSM_MBOX; - request.msg_type.sub_type = SETLEDSTATE; - response.msg_type.sub_type = SETLEDSTATE; - response.msg_type.type = WILDCAT_RSM_MBOX; - - if ((rc = sbbc_mbox_request_response(&request, - &response, SC_TIMEOUT_SEC)) != 0) { - cmn_err(CE_WARN, - "sbbc_mbox_request_response failed " - "rc=%d", rc); - } - if (response.msg_status == - SG_MBOX_STATUS_HARDWARE_FAILURE) { - cmn_err(CE_WARN, - "SC reports hardware failure for " - "SETLEDSTATE request"); - } else if (response.msg_status) { - cmn_err(CE_WARN, "error status %d for " - "SETLEDSTATE request", - response.msg_status); - } - } - break; - } - case SETSEPROM: { - /* this is a message to be sent to SC */ - if (wrsm_use_sgsbbc) { - request.msg_len = - sizeof (wrsm_wib_seprom_msg_t); - request.msg_buf = (caddr_t)(entry->msg_data); - response.msg_len = 0; - response.msg_buf = NULL; - - request.msg_type.type = WILDCAT_RSM_MBOX; - request.msg_type.sub_type = SETSEPROM; - response.msg_type.type = WILDCAT_RSM_MBOX; - response.msg_type.sub_type = SETSEPROM; - - if ((rc = sbbc_mbox_request_response(&request, - &response, SC_TIMEOUT_SEC)) != 0) { - cmn_err(CE_WARN, - "sbbc_mbox_request_response failed " - "rc=%d", rc); - } - if (response.msg_status == - SG_MBOX_STATUS_HARDWARE_FAILURE) { - cmn_err(CE_WARN, - "SC reports hardware failure for " - "SETSEPROM request"); - } else if (response.msg_status) { - cmn_err(CE_WARN, "error status %d for " - "SETSEPROM request", - response.msg_status); - } - } - break; - } - case NCSLICE: { - /* NOT HANDLED HERE */ - break; - } - default : - cmn_err(CE_WARN, "process_message: unknown message"); - } - if (free_msg) - kmem_free(entry->msg_data, entry->msg_size); - kmem_free(entry, sizeof (wrsmplat_mbox_msg_t)); - } -} - -static uint64_t -read_reg(volatile uchar_t *regs, uint64_t offset) -{ - return (*((uint64_t *)(regs + offset))); -} - -static void -write_reg(volatile uchar_t *regs, uint64_t offset, uint64_t value) -{ - *((uint64_t *)(regs + offset)) = value; -} - -/* ARGSUSED */ -void -wrsmplat_wci_init(volatile uchar_t *wrsm_regs) -{ - /* - * wci_qlim_3req_priority, wci_qlim_2req_priority, - * wci_qlim_sort_ciq, wci_qlim_sort_niq, and wci_qlim_sort_piq - * need to be updated if this cluster node is part of a - * wildcat SSM. - */ -} - - -void -deactivate_link(safari_port_t portid, volatile uchar_t *wrsm_regs, - linkid_t link_num) - -{ - wci_sw_link_control_u link_control; - uint64_t offset = link_num * STRIDE_WCI_SW_LINK_CONTROL; - uint64_t cntlAddr = ADDR_WCI_SW_LINK_CONTROL + offset; - - DPRINTF(WP_DEBUG, (CE_CONT, "wci %d deactivate_link %d regs %p", - portid, link_num, (void *)wrsm_regs)); - - link_control.val = read_reg(wrsm_regs, cntlAddr); - - link_control.bit.usr_data_1 = 0; - link_control.bit.usr_data_2 = 0; - link_control.bit.xmit_enable = 0; - link_control.bit.laser_enable = 0; - link_control.bit.link_state = LINK_STATE_OFF; - - write_reg(wrsm_regs, cntlAddr, link_control.val); -} - -void -activate_link(wrsmplat_thread_data_t *data) -{ - wrsm_uplink_msg_t *msg = data->msg; - volatile uchar_t *wrsm_regs = data->wrsm_regs; - wci_sw_link_control_u link_control; - wci_sw_link_status_u link_status; - wci_sw_link_error_count_u error_count; - wci_id_u wci_id_reg; - uint64_t offset = msg->link_num * STRIDE_WCI_SW_LINK_CONTROL; - uint64_t cntlAddr = ADDR_WCI_SW_LINK_CONTROL + offset; - uint64_t statAddr = ADDR_WCI_SW_LINK_STATUS + offset; - uint64_t eCntAddr = ADDR_WCI_SW_LINK_ERROR_COUNT + offset; -#ifdef DEBUG - uint64_t pa, kpf; -#endif /* DEBUG */ - gnid_t remote_gnid; - /* LINTED */ - fmnodeid_t remote_fmnodeid; - linkid_t remote_link; - safari_port_t remote_port; - safari_port_t wci_id = msg->wci_port_id; - linkid_t link_id = msg->link_num; - - link_control.val = read_reg(wrsm_regs, cntlAddr); - - link_control.bit.usr_data_1 = 0; - link_control.bit.usr_data_2 = 0; - link_control.bit.ustat_src = 0; - link_control.bit.xmit_enable = 0; - link_control.bit.paroli_tck_enable = 0; - link_control.bit.near_end_shutdown_lock = 0; - link_control.bit.laser_enable = 1; - link_control.bit.error_inducement = 0; - link_control.bit.auto_shut_en = 0; - link_control.bit.rexmit_shutdown_en = 0; - write_reg(wrsm_regs, cntlAddr, link_control.val); - - wci_id_reg.val = read_reg(wrsm_regs, ADDR_WCI_ID); - if (wci_id_reg.val != WCI_ID_WCI2) { - write_reg(wrsm_regs, ADDR_WCI_SW_LINK_REXMIT + offset, 0); - } - -#ifdef DEBUG - kpf = hat_getkpfnum((caddr_t)wrsm_regs); - pa = (kpf << 13) | (((uint64_t)wrsm_regs) & 0x1fff); - DPRINTF(WP_DEBUG, (CE_CONT, "trying to bring up wci %d link %d " - "regs=%p pa=%p", wci_id, link_id, (void *)wrsm_regs, - (void *)pa)); -#endif - - while (try_activate(msg, wrsm_regs) != 0) { - delay(drv_usectohz(250 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - } - - /* - * Set the link to in use mode and, turn on the transmitters, - * and clear out the error count. - */ - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.xmit_enable = 1; - write_reg(wrsm_regs, cntlAddr, link_control.val); - error_count.val = 0; - write_reg(wrsm_regs, eCntAddr, error_count.val); - - DPRINTF(WP_DEBUG, (CE_NOTE, "link %d wci %d is up", - msg->link_num, msg->wci_port_id)); - - - /* - * We can send 16 bits to the far side via usr_data_1, it is - * encoded as follows: - * 0-7: gnid - * 8-12: portid - * 13-15: linknum - */ - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.usr_data_1 = (msg->config_data.gnid & 0xff) | - ((msg->wci_port_id & 0x1f) << 8) | - ((msg->link_num & 0x7) << 13); - link_control.bit.usr_data_2 = 1; - write_reg(wrsm_regs, cntlAddr, link_control.val); - - DPRINTF(WP_LINK, (CE_NOTE, "link %d sending discovery data %x", - msg->link_num, link_control.bit.usr_data_1)); - - /* - * Spin waiting for the remote side to set the user_data_2 - */ - link_status.val = read_reg(wrsm_regs, statAddr); - while (link_status.bit.farend_ustat_2 < 1) { - delay(drv_usectohz(100 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - - link_status.val = read_reg(wrsm_regs, statAddr); - } - - DPRINTF(WP_LINK, (CE_NOTE, "link %d got discovery data %x", - msg->link_num, link_status.bit.farend_ustat_1)); - - remote_gnid = link_status.bit.farend_ustat_1 & 0xff; - remote_port = (link_status.bit.farend_ustat_1 >> 8) & 0x1f; - remote_link = (link_status.bit.farend_ustat_1 >> 13) & 0x7; - - DPRINTF(WP_DEBUG, (CE_NOTE, "wci %d remote side responds " - "gnid %d port %d link %d", msg->wci_port_id, remote_gnid, - remote_port, remote_link)); - - /* XXX - just to be sure the link settles down */ - delay(drv_usectohz(200 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.usr_data_2 = 2; - link_control.bit.link_state = LINK_STATE_IN_USE; - link_control.bit.auto_shut_en = 1; - link_control.bit.rexmit_shutdown_en = 1; - - write_reg(wrsm_regs, cntlAddr, link_control.val); - link_status.val = read_reg(wrsm_regs, statAddr); - while (link_status.bit.farend_ustat_2 < 2) { - delay(drv_usectohz(100 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - link_status.val = read_reg(wrsm_regs, statAddr); - } - - /* - * Don't make the callback if the link is supposed to - * be in loopback mode. - */ - if (!data->loopback) { - (*wrsmplat_state.cb_ops->link_up)(msg->wci_port_id, - (linkid_t)msg->link_num, msg->config_data.fmnodeid, - remote_gnid, - (linkid_t)remote_link, remote_port, - msg->config_data.partition_version, - msg->config_data.partition_id); - } else { - DPRINTF(WP_DEBUG, (CE_WARN, "Setting wci %d link %d IN_USE", - msg->wci_port_id, msg->link_num)); - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.link_state = LINK_STATE_IN_USE; - write_reg(wrsm_regs, cntlAddr, link_control.val); - } - - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - kmem_free(data, sizeof (wrsmplat_thread_data_t)); - exit_thread(wci_id, link_id); -} - - -void -set_tnid(volatile uchar_t *regs, int link, int tnid) -{ - wci_fo_tnid_map_u tnid_map; - - mutex_enter(&wrsmplat_state.tnid_map_lock); - tnid_map.val = read_reg(regs, ADDR_WCI_FO_TNID_MAP); - switch (link) { - case 0: - tnid_map.bit.link0_tnid = tnid; - break; - case 1: - tnid_map.bit.link1_tnid = tnid; - break; - case 2: - tnid_map.bit.link2_tnid = tnid; - break; - default: - DPRINTF(WP_DEBUG, (CE_WARN, "set_tnid: illegal link num: %d", - link)); - break; - } - write_reg(regs, ADDR_WCI_FO_TNID_MAP, tnid_map.val); - /* read back to commit the write */ - tnid_map.val = read_reg(regs, ADDR_WCI_FO_TNID_MAP); - mutex_exit(&wrsmplat_state.tnid_map_lock); -} - -int -try_activate(wrsm_uplink_msg_t *msg, volatile uchar_t *wrsm_regs) -{ - wci_sw_link_control_u link_control; - wci_sw_link_status_u link_status; - wci_sw_link_error_count_u error_count; - wci_sw_esr_u sw_esr, sw_esr_mask; - uint64_t offset = msg->link_num * STRIDE_WCI_SW_LINK_CONTROL; - uint64_t cntlAddr = ADDR_WCI_SW_LINK_CONTROL + offset; - uint64_t statAddr = ADDR_WCI_SW_LINK_STATUS + offset; - uint64_t eCntAddr = ADDR_WCI_SW_LINK_ERROR_COUNT + offset; - int count, retry; - int checks; - int good_tnid; - int tnid; - safari_port_t wci_id = msg->wci_port_id; - linkid_t link_id = msg->link_num; - - if (link_id >= WRSM_LINKS_PER_WCI) { - DPRINTF(WP_DEBUG, (CE_NOTE, "try_activate: bad data link=%d " - "offset = %" PRIx64, link_id, offset)); - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - - /* Clear error bits corresponding to this link */ - sw_esr_mask.val = 0; - switch (msg->link_num) { - case 0: - sw_esr_mask.bit.acc_link_0_auto_shut = 1; - sw_esr_mask.bit.acc_link_0_failover = 1; - break; - case 1: - sw_esr_mask.bit.acc_link_1_auto_shut = 1; - sw_esr_mask.bit.acc_link_1_failover = 1; - break; - case 2: - sw_esr_mask.bit.acc_link_2_auto_shut = 1; - sw_esr_mask.bit.acc_link_2_failover = 1; - break; - } - sw_esr.val = read_reg(wrsm_regs, ADDR_WCI_SW_ESR); - sw_esr.val &= sw_esr_mask.val; - write_reg(wrsm_regs, ADDR_WCI_SW_ESR, sw_esr.val); - - /* Toggle the link state OFF/SEEK */ - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.link_state = LINK_STATE_OFF; - write_reg(wrsm_regs, cntlAddr, link_control.val); - - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.link_state = LINK_STATE_SEEK; - write_reg(wrsm_regs, cntlAddr, link_control.val); - /* read it back to make sure the write happened */ - link_control.val = read_reg(wrsm_regs, cntlAddr); - DPRINTF(WP_DEBUG, (CE_CONT, "try_activate: " - "Trying to bring up link %d wci %d", - msg->link_num, msg->wci_port_id)); - - /* - * The max paroli reset setup time is 100ms. Putting the link - * into STATE_SEEK brings the paroli out of reset, so we have - * to wait 100ms before we can expect anything useful from the - * status register - */ - delay(drv_usectohz(100 * 1000)); - - /* Wait for optical_signal_detect to come on */ - link_status.val = read_reg(wrsm_regs, statAddr); - count = 0; - while (link_status.bit.optical_signal_detect == 0) { - DPRINTF(WP_THREAD, (CE_CONT, "try_activate: no opt sig")); - ++count; - if (count >= 200) { - DPRINTF(WP_LINK, (CE_CONT, "Waiting for optical " - "signal detect link %d wci %d", - msg->link_num, msg->wci_port_id)); - return (-1); - } - /* sleep 250ms */ - delay(drv_usectohz(250 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - link_status.val = read_reg(wrsm_regs, statAddr); - } - DPRINTF(WP_LINK, (CE_CONT, "try_activate: opt sig detect: %u", - link_status.bit.optical_signal_detect)); - - good_tnid = B_FALSE; - - for (tnid = 0; tnid < 16; ++tnid) { - DPRINTF(WP_LINK, (CE_CONT, "try_activate: " - "Trying tnid %d", tnid)); - set_tnid(wrsm_regs, msg->link_num, tnid); - /* - * There is some probability <1 that the end_status - * will be reported correctly in the link_status - * register. Dave Saterfield guesses ~60% but it - * could be a lot worse if there is much clock skew - * between machines. It should only give false - * negative, not false positive results. So we try a - * few times and if it ever says "ready" then we declare - * success. - */ - for (retry = 0; retry < 5; ++retry) { - link_status.val = read_reg(wrsm_regs, statAddr); - if (link_status.bit.end_status == - END_STATUS_NEAR_READY || - link_status.bit.end_status == - END_STATUS_ALL_READY) { - good_tnid = B_TRUE; - break; - } - } - if (good_tnid) { - DPRINTF(WP_THREAD, (CE_CONT, "Good tnid found!")); - break; - } - } -#ifdef DEBUG - if (tnid == 16) { - DPRINTF(WP_LINK, (CE_CONT, "Didn't find good tnid status %u " - "link %d wci %d", link_status.bit.end_status, - msg->link_num, msg->wci_port_id)); - } else { - DPRINTF(WP_LINK, (CE_CONT, "Set tnid to %d, status %u " - "link %d wci %d retries %d", tnid, - link_status.bit.end_status, msg->link_num, - msg->wci_port_id, retry)); - } -#endif /* DEBUG */ - - /* - * If we didn't find the right tnid, the link must be in a bad - * state, so reset and try again. - */ - if (!good_tnid) - return (-1); - - for (checks = 15; checks > 0; checks--) { - link_status.val = read_reg(wrsm_regs, statAddr); - if (link_status.bit.end_status == END_STATUS_ALL_READY) { - error_count.val = 0; - write_reg(wrsm_regs, eCntAddr, error_count.val); -#ifndef NEW_PAROLIS_ONLY - delay(drv_usectohz(3000 * 1000)); -#endif /* NEW_PAROLIS_ONLY */ - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - - for (checks = 5; checks > 0; checks--) { - link_status.val = read_reg(wrsm_regs, - statAddr); - if (link_status.bit.end_status != - END_STATUS_ALL_READY) - continue; - - error_count.val = read_reg(wrsm_regs, - eCntAddr); - /* - * if it's still up and error count is - * not too high, declare success - */ - if (error_count.bit.error_count < 10) { - return (0); - } else { - DPRINTF(WP_DEBUG, (CE_CONT, - "high error count %" PRIx64 - " status = %" PRIx64, - error_count.val, - link_status.val)); - return (-1); - } - } - } - delay(drv_usectohz(100 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - } - return (-1); -} - -/* - * Verifies valid stripegroup. For Serengeti, all wcis must be in same - * SSM node. - */ -int -wrsmplat_stripegroup_verify(const wrsm_stripe_group_t *sg) -{ - int ssmnode; - int i; - - if (sg->nwcis < 2) { - return (0); - } - ssmnode = PORT2NODE(sg->wcis[0]); - for (i = 0; i < sg->nwcis; i++) { - if (ssmnode != PORT2NODE(sg->wcis[i])) { - return (ENOTSUP); - } - } - return (0); -} - -/* - * If in an SSM, configures SSM-mode WCIs to route appropriate ncslices - * to the right local domain. For non-SSM Serengeti, no action is required. - */ -/* ARGSUSED */ -void -wrsmplat_ncslice_setup(wrsm_ncowner_map_t owner[WRSM_MAX_NCSLICES]) -{ - /* XXX - SSM case not yet implemented */ -} - -/* - * Enter ncslice update critical section - no action for non-SSM Serengeti. - */ -void -wrsmplat_ncslice_enter(void) -{ -} - -/* - * Exit ncslice update critical section - no action for non-SSM Serengeti. - */ -void -wrsmplat_ncslice_exit(void) -{ -} - -/* Does a cross-trap sync */ -void -wrsmplat_xt_sync(int cpu_id) -{ - cpuset_t cpuset; - CPUSET_ZERO(cpuset); - CPUSET_ADD(cpuset, cpu_id); - xt_sync(cpuset); -} - -/* Support for suspend/resume */ - -void -wrsmplat_suspend(safari_port_t wci) -{ - if (!wrsm_use_sgsbbc) { - int i; - int link; - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci) { - if (wrsmplat_state.wci[i].suspended) { - return; - } - wrsmplat_state.wci[i].suspended = B_TRUE; - break; - } - } - for (link = 0; link < WRSM_MAX_LINKS_PER_WCI; link++) { - stop_thread(wci, link); - } - } -} - -void -wrsmplat_resume(safari_port_t wci) -{ - /* - * No need to restart link bring-up thread, since driver will - * eventually time-out and retry later. - */ - if (!wrsm_use_sgsbbc) { - int i; - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci) { - wrsmplat_state.wci[i].suspended = B_FALSE; - break; - } - } - } -} diff --git a/usr/src/uts/sun4u/serengeti/wrsm/Makefile b/usr/src/uts/sun4u/serengeti/wrsm/Makefile deleted file mode 100644 index 034fb95a3f..0000000000 --- a/usr/src/uts/sun4u/serengeti/wrsm/Makefile +++ /dev/null @@ -1,188 +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 2004 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" -# -# This makefile drives the production of the wrsm driver kernel module. -# -# sun4u implementation architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../../.. - -# -# Define the module and object file sets. -# -MODULE = wrsm -OBJECTS = $(WRSM_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WRSM_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_SERENGETI_DRV_DIR)/$(MODULE) -CONF_SRCDIR = $(UTSBASE)/sun4u/io/wrsm - -# -# Include common rules. -# -include $(UTSBASE)/sun4u/serengeti/Makefile.serengeti - -# -# Starcat platform directory names -# -ROOT_STARCAT_DIR = $(ROOT_PLAT_DIR)/SUNW,Sun-Fire-15000 -ROOT_STARCAT_MOD_DIR = $(ROOT_STARCAT_DIR)/kernel -ROOT_STARCAT_DRV_DIR_32 = $(ROOT_STARCAT_MOD_DIR)/drv -ROOT_STARCAT_DRV_DIR_64 = $(ROOT_STARCAT_MOD_DIR)/drv/$(SUBDIR64) -ROOT_STARCAT_DRV_DIR = $(ROOT_STARCAT_DRV_DIR_$(CLASS)) - - -ROOT_CONFFILE = $(ROOT_SERENGETI_DRV_DIR_32)/$(MODULE).conf -STARCAT_CONFFILE = $(ROOT_STARCAT_DRV_DIR_32)/$(MODULE).conf -STARCAT_DRV_LINK = $(ROOT_STARCAT_DRV_DIR)/$(MODULE) - -# -# Define targets -# -ALL_TARGET = $(BINARY) $(SRC_CONFILE) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE) \ - $(STARCAT_CONFFILE) $(STARCAT_DRV_LINK) - -WRSM_OFFSETS = $(UTSBASE)/sun4u/io/wrsm/wrsm_offsets.in -WRSM_OFFSETS_H = $(OBJS_DIR)/wrsm_offsets.h - -# -# Include path for rsm header files -# -INC_PATH += -I$(CODEMGR_WS)/usr/src/uts/common - -# -# Path to netdb.h -# -INC_PATH += -I$(CODEMGR_WS)/usr/src/head - -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - -# -# module dependencies -# -LDFLAGS += -dy -Nmisc/wrsmplat -Nmisc/rsmops - - -# -# Turn on doubleword alignment for 64 bit registers -# - -CFLAGS += -dalign $(WRSM_FLAGS) -ASFLAGS += $(WRSM_FLAGS) - -ALL_DEFS += $(WRSM_WORKAROUND_DEFS) - -LINT_DEFS += -DRSMPI -DWRSM_MB -DFAKEREGS -DRSMAPI - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Special rules for generating assym.h for inclusion in assembly files -# -$(DSF_DIR)/$(OBJS_DIR)/assym.h: FRC - @cd $(DSF_DIR); $(MAKE) all.targ - -AS_INC_PATH += -I$(OBJS_DIR) - -WRSM_DEPS += wrsm_trap.o - -WRSM_DEPS += wrsm_copy.o - -CLEANFILES += $(WRSM_OFFSETS_H) $(WRSM_OFFSETS_OUT) - -$(WRSM_DEPS:%=$(OBJS_DIR)/%): $(WRSM_OFFSETS_H) - -$(WRSM_OFFSETS_H): $(WRSM_OFFSETS) - $(OFFSETS_CREATE) <$(WRSM_OFFSETS) >$@ - -# -# Include common targets. -# -include $(UTSBASE)/sun4u/Makefile.targ - -$(ROOT_SERENGETI_DIR): $(ROOT_PLAT_DIR) - -$(INS.dir.root.sys) - -$(ROOT_SERENGETI_MOD_DIR): $(ROOT_SERENGETI_DIR) - -$(INS.dir.root.sys) - -$(ROOT_SERENGETI_DRV_DIR_32): $(ROOT_SERENGETI_MOD_DIR) - -$(INS.dir.root.sys) - -$(ROOT_SERENGETI_DRV_DIR): $(ROOT_SERENGETI_DRV_DIR_32) - -$(INS.dir.root.sys) - -$(ROOT_SERENGETI_DRV_DIR)/%: $(OBJS_DIR)/% $(ROOT_SERENGETI_DRV_DIR) - $(INS.file) - -$(ROOT_STARCAT_DIR): $(ROOT_PLAT_DIR) - -$(INS.dir.root.sys) - -$(ROOT_STARCAT_MOD_DIR): $(ROOT_STARCAT_DIR) - -$(INS.dir.root.sys) - -$(ROOT_STARCAT_DRV_DIR_32): $(ROOT_STARCAT_MOD_DIR) - -$(INS.dir.root.sys) - -$(ROOT_STARCAT_DRV_DIR): $(ROOT_STARCAT_DRV_DIR_32) - -$(INS.dir.root.sys) - -$(ROOT_STARCAT_DRV_DIR)/%: $(OBJS_DIR)/% $(ROOT_STARCAT_DRV_DIR) - $(INS.file) - -$(STARCAT_CONFFILE): $(SRC_CONFFILE) $(STARCAT_CONFFILE:%/$(CONFFILE)=%) $(ROOT_STARCAT_DRV_DIR) - $(INS.conffile) - -$(STARCAT_DRV_LINK): $(ROOTMODULE) $(ROOT_STARCAT_DRV_DIR) - $(RM) -r $@; $(LN) $(ROOTMODULE) $@ diff --git a/usr/src/uts/sun4u/serengeti/wrsmplat/Makefile b/usr/src/uts/sun4u/serengeti/wrsmplat/Makefile deleted file mode 100644 index 4ade8b8d97..0000000000 --- a/usr/src/uts/sun4u/serengeti/wrsmplat/Makefile +++ /dev/null @@ -1,111 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" -# -# This makefile drives the production of the wrsmplat kernel module. - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../../.. - -# -# Define the module and object file sets. -# -WRSMPLAT_OBJS = wrsmplat.o -MODULE = wrsmplat -OBJECTS = $(WRSMPLAT_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WRSMPLAT_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_SERENGETI_MISC_DIR)/$(MODULE) - -# -# Include common rules. -# -include $(UTSBASE)/sun4u/serengeti/Makefile.serengeti - -# -# Include path for rsm header files -# -INC_PATH += -I$(UTSBASE)/common - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# Overrides -# -ALL_BUILDS = $(ALL_BUILDSONLY64) -DEF_BUILDS = $(DEF_BUILDSONLY64) -CLEANLINTFILES += $(LINT32_FILES) - -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - -# -# Turn on doubleword alignment for 64 bit registers -# -CFLAGS += -dalign - -# -# module dependencies -# -LDFLAGS += -dy -Ndrv/sgsbbc - -# -# Support for SC mailbox communication (using SC to bring up links) -# -CFLAGS += -DWRSM_RUNTIME_DEFINE_SBBC - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sun4u/serengeti/Makefile.targ diff --git a/usr/src/uts/sun4u/starcat/Makefile.files b/usr/src/uts/sun4u/starcat/Makefile.files index 2aec0b298c..81f1501aee 100644 --- a/usr/src/uts/sun4u/starcat/Makefile.files +++ b/usr/src/uts/sun4u/starcat/Makefile.files @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #pragma ident "%Z%%M% %I% %E% SMI" @@ -46,7 +46,6 @@ DMAN_OBJS += dman.o dman_domain.o DRMACH_OBJS += drmach.o drmach_asm.o dr_util.o drmach_err.o FCGP2_OBJS += fcgp2.o GPTWO_PCI_OBJS += gptwo_pci.o -GPTWO_WCI_OBJS += gptwo_wci.o IOSRAM_OBJS += iosram.o MBOXSC_OBJS += mboxsc.o SC_GPTWO_OBJS += sc_gptwocfg.o diff --git a/usr/src/uts/sun4u/starcat/Makefile.starcat.shared b/usr/src/uts/sun4u/starcat/Makefile.starcat.shared index bb5a84b732..15581dc1a4 100644 --- a/usr/src/uts/sun4u/starcat/Makefile.starcat.shared +++ b/usr/src/uts/sun4u/starcat/Makefile.starcat.shared @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -90,7 +90,6 @@ STARCAT_KMODS += dr STARCAT_KMODS += drmach STARCAT_KMODS += fcgp2 STARCAT_KMODS += gptwo_pci -STARCAT_KMODS += gptwo_wci STARCAT_KMODS += iosram STARCAT_KMODS += mboxsc STARCAT_KMODS += platmod @@ -98,7 +97,6 @@ STARCAT_KMODS += sc_gptwocfg STARCAT_KMODS += schpc STARCAT_KMODS += sckmdrv STARCAT_KMODS += scosmb -STARCAT_KMODS += wrsmplat # # Define CPU modules. diff --git a/usr/src/uts/sun4u/starcat/gptwo_wci/Makefile b/usr/src/uts/sun4u/starcat/gptwo_wci/Makefile deleted file mode 100644 index b834003739..0000000000 --- a/usr/src/uts/sun4u/starcat/gptwo_wci/Makefile +++ /dev/null @@ -1,96 +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" -# -# This makefile drives the production of the wci/schizo portion of -# of the Safari Configurator. -# -# sun4u implementation architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../../.. - -# -# Define the module and object file sets. -# -MODULE = gptwo_wci -OBJECTS = $(GPTWO_WCI_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(GPTWO_WCI_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_STARCAT_MISC_DIR)/$(MODULE) - -# -# Include common rules. -# -include $(UTSBASE)/sun4u/starcat/Makefile.starcat - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# Turn this on once compiler understands v9 in it's backend -#INLINES += $(UTSBASE)/sun4u/starcat/io/gptwo_wci.il - -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - -# -# Turn on doubleword alignment for 64 bit registers -# -CFLAGS += -dalign - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sun4u/starcat/Makefile.targ diff --git a/usr/src/uts/sun4u/starcat/io/gptwo_wci.c b/usr/src/uts/sun4u/starcat/io/gptwo_wci.c deleted file mode 100644 index 211fb37aac..0000000000 --- a/usr/src/uts/sun4u/starcat/io/gptwo_wci.c +++ /dev/null @@ -1,314 +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" - -/* - * WCI Functions to the Safari Configurator - * - */ - -#include <sys/types.h> -#include <sys/cred.h> -#include <sys/mman.h> -#include <sys/kmem.h> -#include <sys/conf.h> -#include <sys/ddi.h> -#include <sys/sunddi.h> -#include <sys/sunndi.h> -#include <sys/modctl.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <sys/autoconf.h> -#include <sys/ksynch.h> -#include <sys/promif.h> -#include <sys/ndi_impldefs.h> -#include <sys/ddi_impldefs.h> -#include <sys/machsystm.h> -#include <sys/gp2cfg.h> -#include <sys/gptwo_wci.h> - -#ifdef DEBUG -int gptwo_wci_debug = 0; - -static void debug(char *, uintptr_t, uintptr_t, - uintptr_t, uintptr_t, uintptr_t); - -#define GPTWO_DEBUG0(level, flag, s) if (gptwo_wci_debug >= level) \ - cmn_err(flag, s) -#define GPTWO_DEBUG1(level, flag, fmt, a1) if (gptwo_wci_debug >= level) \ - debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0); -#define GPTWO_DEBUG2(level, flag, fmt, a1, a2) if (gptwo_wci_debug >= level) \ - debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0); -#define GPTWO_DEBUG3(level, flag, fmt, a1, a2, a3) \ - if (gptwo_wci_debug >= level) \ - debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), (uintptr_t)(a3), 0, 0); -#else -#define GPTWO_DEBUG0(level, flag, s) -#define GPTWO_DEBUG1(level, flag, fmt, a1) -#define GPTWO_DEBUG2(level, flag, fmt, a1, a2) -#define GPTWO_DEBUG3(level, flag, fmt, a1, a2, a3) -#endif - -void gptwocfg_devi_attach_to_parent(dev_info_t *); - -/* - * Module linkage information for the kernel. - */ - -extern struct mod_ops mod_miscops; - -static struct modlmisc modlmisc = { - &mod_miscops, /* Type of module */ - "gptwo->wci configurator %I%", -}; - -static struct modlinkage modlinkage = { - MODREV_1, (void *)&modlmisc, NULL -}; - -#ifndef lint -char _depends_on[] = "misc/gptwocfg misc/fcgp2 misc/fcodem misc/busra"; -#endif - -int -_init(void) -{ - int err = 0; - - /* register devices with the configurator */ - gptwocfg_register_ops(SAFPTYPE_WCI, gptwo_configure_wci, - gptwo_unconfigure_wci); - - if ((err = mod_install(&modlinkage)) != 0) { - GPTWO_DEBUG1(1, CE_WARN, "gptwo_wci (WCI Functions) " - "failed to load, error=%d\n", err); - gptwocfg_unregister_ops(SAFPTYPE_WCI); - } else { - GPTWO_DEBUG0(1, CE_WARN, "gptwo_wci (WCI Functions) " - "has been loaded.\n"); - } - return (err); -} - -int -_fini(void) -{ - gptwocfg_unregister_ops(SAFPTYPE_WCI); - return (mod_remove(&modlinkage)); -} - -int -_info(modinfop) -struct modinfo *modinfop; -{ - return (mod_info(&modlinkage, modinfop)); -} - -/*ARGSUSED*/ -static int -set_name_prop(dev_info_t *dip, void *arg, uint_t flags) -{ - if (ndi_prop_update_string(DDI_DEV_T_NONE, dip, - "name", "wci") != DDI_SUCCESS) { - return (DDI_WALK_ERROR); - } - - return (DDI_WALK_TERMINATE); -} - -/*ARGSUSED*/ -static void -get_new_child(dev_info_t *rdip, void *arg, uint_t flags) -{ - dev_info_t **dipp = (dev_info_t **)arg; - - ASSERT(dipp && (*dipp == NULL)); - - *dipp = rdip; -} - -gptwo_new_nodes_t * -gptwo_configure_wci(dev_info_t *ap, spcd_t *pcd, uint_t id) -{ - fco_handle_t fco_handle; - int error, circ; - dev_info_t *new_child; - char unit_address[64]; - gptwo_new_nodes_t *new_nodes; - devi_branch_t b = {0}; - - GPTWO_DEBUG2(1, CE_CONT, "gptwo_configure_wci: id=%x pcd=%lx\n", - id, pcd); - - new_nodes = gptwocfg_allocate_node_list(1); - - if (pcd->spcd_prsv != SPCD_RSV_PASS) { - - cmn_err(CE_WARN, "gptwo_configure_wci: saf id=0x%x " - "Can not be probed\n", id); - - gptwocfg_free_node_list(new_nodes); - return (NULL); - } - - new_child = NULL; - - b.arg = &new_child; - b.type = DEVI_BRANCH_SID; - b.create.sid_branch_create = set_name_prop; - b.devi_branch_callback = get_new_child; - - /* - * Prevent any changes to new_child - * until we have bound it to the correct driver. - */ - ndi_devi_enter(ap, &circ); - - if (e_ddi_branch_create(ap, &b, NULL, 0) != NDI_SUCCESS) { - ASSERT(new_child == NULL); - - GPTWO_DEBUG0(1, CE_CONT, - "gptwo_configure_wci: failed " - "to alloc child node\n"); - - if (new_nodes->gptwo_nodes[0] == NULL) { - GPTWO_DEBUG0(1, CE_CONT, "gptwo_configure_wci: " - "No nodes configured - " - "removing new_nodes\n"); - gptwocfg_free_node_list(new_nodes); - new_nodes = NULL; - } - - ndi_devi_exit(ap, circ); - - return (new_nodes); - } - - /* - * The platform DR interfaces created the dip in - * bound state. Bring devinfo node down to linked - * state and hold it there until compatible - * properties are created. - */ - e_ddi_branch_rele(new_child); - (void) i_ndi_unconfig_node(new_child, DS_LINKED, 0); - ASSERT(i_ddi_node_state(new_child) == DS_LINKED); - e_ddi_branch_hold(new_child); - - mutex_enter(&DEVI(new_child)->devi_lock); - DEVI(new_child)->devi_flags |= DEVI_NO_BIND; - mutex_exit(&DEVI(new_child)->devi_lock); - - /* - * Drop the busy-hold on parent before calling - * fcode_interpreter to prevent potential deadlocks - */ - ndi_devi_exit(ap, circ); - - (void) snprintf(unit_address, sizeof (unit_address), "%x", id); - - fco_handle = gp2_fc_ops_alloc_handle(ap, new_child, NULL, NULL, - unit_address, NULL); - - GPTWO_DEBUG0(1, CE_CONT, - "gptwocfg: Calling Fcode Interpeter...\n"); - - error = fcode_interpreter(ap, &gp2_fc_ops, fco_handle); - - GPTWO_DEBUG1(1, CE_CONT, - "gptwo_configure_wci: fcode_interpreter " - " returned %x\n", error); - - if (error) { - cmn_err(CE_WARN, "gptwo_wci: Unable to probe wci leaf " - "%s\n", unit_address); - - gp2_fc_ops_free_handle(fco_handle); - - (void) e_ddi_branch_destroy(new_child, NULL, 0); - } else { - gptwocfg_save_handle(new_child, fco_handle); - - /* - * Compatible properties (if any) have been created, - * so bind driver. - */ - ndi_devi_enter(ap, &circ); - ASSERT(i_ddi_node_state(new_child) <= DS_LINKED); - - mutex_enter(&DEVI(new_child)->devi_lock); - DEVI(new_child)->devi_flags &= ~DEVI_NO_BIND; - mutex_exit(&DEVI(new_child)->devi_lock); - - ndi_devi_exit(ap, circ); - - if (ndi_devi_bind_driver(new_child, 0) != DDI_SUCCESS) { - cmn_err(CE_WARN, "gptwo_wci: Unable to bind" - " new wci child at dip=0x%p\n", new_child); - } - } - - if (new_nodes->gptwo_nodes[0] == NULL) { - GPTWO_DEBUG0(1, CE_CONT, "gptwo_configure_wci: " - "No nodes configured - removing new_nodes\n"); - gptwocfg_free_node_list(new_nodes); - new_nodes = NULL; - } - - GPTWO_DEBUG1(1, CE_CONT, "gptwo_configure_wci: " - "Returning new_nodes=%p\n", new_nodes); - - return (new_nodes); -} - -dev_info_t * -gptwo_unconfigure_wci(dev_info_t *dip) -{ - fco_handle_t fco_handle; - - fco_handle = gptwocfg_get_handle(dip); - - if (fco_handle != NULL) { - /* - * If there is a handle, there may be resources - * that need to be freed from when the - * devices's fcode ran. - */ - GPTWO_DEBUG1(1, CE_CONT, "fco_handle=%lx\n", fco_handle); - gp2_fc_ops_free_handle(fco_handle); - } - return (NULL); -} - -#ifdef DEBUG -static void -debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3, - uintptr_t a4, uintptr_t a5) -{ - cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5); -} -#endif diff --git a/usr/src/uts/sun4u/starcat/io/sc_gptwocfg.c b/usr/src/uts/sun4u/starcat/io/sc_gptwocfg.c index 3974a75105..7f938b2434 100644 --- a/usr/src/uts/sun4u/starcat/io/sc_gptwocfg.c +++ b/usr/src/uts/sun4u/starcat/io/sc_gptwocfg.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -46,7 +46,6 @@ #include <sys/gp2cfg.h> #include <sys/gptwo_cpu.h> #include <sys/gptwo_pci.h> -#include <sys/gptwo_wci.h> #include <sys/sc_gptwocfg.h> #include <post/scat_dcd.h> #include <sys/machsystm.h> diff --git a/usr/src/uts/sun4u/starcat/io/wrsmplat.c b/usr/src/uts/sun4u/starcat/io/wrsmplat.c deleted file mode 100644 index 9a8791b049..0000000000 --- a/usr/src/uts/sun4u/starcat/io/wrsmplat.c +++ /dev/null @@ -1,1684 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Starcat WRSM platform-specific module - */ - - -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/ddi.h> -#include <sys/cmn_err.h> -#include <sys/modctl.h> -#include <sys/kmem.h> -#include <sys/disp.h> -#include <sys/int_fmtio.h> -#include <sys/cpuvar.h> -#include <sys/cpu_module.h> -#include <sys/axq.h> -#include <sys/mboxsc.h> - -#include <sys/wrsm_config.h> -#include <sys/wrsm_plat_impl.h> -#include <sys/wci_regs.h> -#include <sys/wci_offsets.h> -#include <sys/wci_common.h> -#include <sys/cheetahregs.h> -#include <sys/cpuvar.h> -#include <sys/starcat.h> -#include <sys/machcpuvar.h> -#include <sys/wrsmplat.h> - - -#ifdef DEBUG -#define WP_DEBUG 1 -#define WP_QUEUE 2 -#define WP_LINK 4 -#define WP_THREAD 8 -#define WP_MBOX 16 - -static uint_t wrsm_plat_debug = 0; - -#define DPRINTF(a, b) { if (wrsm_plat_debug & a) cmn_err b; } -#else -#define DPRINTF(a, b) { } -#endif - -static wrsm_node_types_t node_type = wrsm_node_starcat; -static boolean_t wrsm_use_sgsbbc = B_TRUE; - -static uint64_t read_reg(volatile uchar_t *regs, uint64_t offset); -static void write_reg(volatile uchar_t *regs, uint64_t offset, uint64_t value); -static void mbox_event_handler(void); -static int send_mbox_msg(uint32_t cmd, void *msg, uint32_t msg_length, - void *reply, uint32_t reply_length); - -/* Converts a 10-bit safari port id to its 5-bit expander id */ -#define PORT2EXP(p) (((p) >> 5) & 0x1f) - -/* IOSRAM Keys for Wildcat */ -#define IOSRAM_KEY_SCWC (('S'<<24)|('C'<<16)|('W'<<8)|'C') -#define IOSRAM_KEY_WCSC (('W'<<24)|('C'<<16)|('S'<<8)|'C') - -/* - * Module linkage information for the kernel. - */ -static struct modlmisc modlmisc = { - &mod_miscops, - "Sun Fire 15K wrsm platmod %I%" -}; - -static struct modlinkage modlinkage = { - MODREV_1, (void *)&modlmisc, NULL -}; - - -typedef struct wrsmplat_mbox_msg { - uint32_t msg_type; - boolean_t loopback; - void *msg_data; - size_t msg_size; - struct wrsmplat_mbox_msg *next; -} wrsmplat_mbox_msg_t; - -/* - * If stop_thread is set for a particular link of a wci, that means that - * the thread trying to bringup that link should give up and exit. - */ -typedef struct wrsmplat_link { - kmutex_t mutex; - boolean_t thread_active; - boolean_t stop_thread; - kcondvar_t cv; -} wrsmplat_link_t; - -typedef struct wrsmplat_wci { - safari_port_t wci_id; - boolean_t valid; - boolean_t suspended; - wrsmplat_link_t link[WRSM_MAX_LINKS_PER_WCI]; -} wrsmplat_wci_t; - -static struct wrsmplat_state { - boolean_t thread_stop; - wrsmplat_mbox_msg_t *msg_queue; - kmutex_t queue_lock; - wrsm_plat_ops_t *cb_ops; - kcondvar_t msg_cv; - kmutex_t cv_lock; - uint_t thread_count; - wrsmplat_wci_t wci[WRSM_MAX_WCIS]; - kmutex_t thread_count_lock; - kmutex_t tnid_map_lock; -} wrsmplat_state = {0}; - -/* - * version is 8 bits in the low byte of an int, high 4 bits are - * major version number - */ -#define IS_PRE_V3_JAGUAR(cpu) \ -((IS_JAGUAR((cpu).implementation)) && ((((cpu).version) >> 4) < 3)) - -static uint16_t pre_calculated_cesr_ids[NCPU]; - -/* - * - * wrsmplat_set_asi_cesr_id and wrsmplat_clr_asi_cesr_id set and clear the - * ASI_CESR_ID per per-core registers on Jaguar 2.X processors - * - * The problem is that both Schizo and XMITS(Safari-PCI bridges) require - * bits [5:4] of the safari address to be 0 on a WBIO. They are copied to - * the PCI bus as is, which will cause the write to be issued to the wrong - * address on PCI. This can cause data corruption. - * - * -- TERMINOLOGY -- - * - * WCI - WildCat Interface: an asic that implements WildCat Clustering. - * Operation is defined by the WildCat Programmer's Reference - * Manual for WCI-4.1(Part No.: 950-3825-01) - * - * CESR - Cluster Error Status Register: A register with 256 entries to - * record per core WildCat errors(see WCI PRM above) - * - * CESR index: Used by the WCI to store the result of a cluster - * transaction to the appropriate entry in the CESR. Up to and - * including Cheetah+ this number was generated as a function of the - * processors Safari port.(See WCI PRM for how StarCat AXQ deals with - * this). - * - * ASI_CESR_ID: A new per-core register introduced with Jaguar. The cesr - * id is in bits [7:0] of ASI_CESR_ID. This is now required because - * two cpu cores share a safari agent id. - * - * Jaguar 3.X and Panther processors do not require this workaround since - * they address the above problem in hardware by only driving the bits in - * ASI_CESR_ID onto the safari bus for ncslices in [64, 254] and otherwise - * 0 for PCI devices which are mapped into ncslices [1, 63]. - * - * The implementation of these functions for Serengeti is null because - * there is a maximum of 2 x 24 = 48 cores on a serengeeti and 48 cores - * can be named by 6 bits of the cesr id name space and so, the low 2 bits - * of ASI_CESR_ID driven to GA[5:4](above) can be always 0 and the - * ASI_CESR_ID can be set by CPU POST. This plan wont work for starcat - * which can have more than 2^6 = 64 cores. - * - * For StarCat we calculate the cesr index in calculate_starcat_cesr_id() - * when the platform specific module is loaded and then use the cpu_id of - * the thread executing send() in wrsm_intr.c so set the ASI_CESR_ID before - * sending a WildCat interrupt and clearing it after the interrupt has - * completed. We can do this because: - * - * - Currently sending a remote interrupt is the only transaction for - * which the wrsm software checks the CESR - * - * - Preemption is disabled during this time so the cpu_id of the - * thread executing this section cant change - * - * -- BIG WARNINGS -- - * - * 1) This workaround must be maintained until the business decision that - * WildCat is no longer to be supported on Jaguar 2.X processors is - * taken. - * - * 2) This workaround assumes that the cesr id's are initially 0 from - * POST. They'll be 0 anyway after the first interrupt on a core though. - * - * 3) It is assumed that Jaguar 3.X and Panther processors' POST code will - * set the CESR equivalently to what is done in - * calculate_starcat_cesr_id() - * - */ -void -wrsmplat_set_asi_cesr_id(void) -{ - processorid_t cpu_id; - - cpu_id = CPU->cpu_id; - if (IS_PRE_V3_JAGUAR(cpunodes[cpu_id])) { - asi_cesr_id_wr((uint64_t)pre_calculated_cesr_ids[cpu_id]); - } -} - -void -wrsmplat_clr_asi_cesr_id(void) { - processorid_t cpu_id; - - cpu_id = CPU->cpu_id; - if (IS_PRE_V3_JAGUAR(cpunodes[cpu_id])) { - asi_cesr_id_wr(0); - } -} - -static void -calculate_starcat_cesr_id(void) -{ - uint16_t cpuid; - - for (cpuid = 0; cpuid < NCPU; cpuid++) { - uint8_t aid, nid, core, slot; - - nid = STARCAT_CPUID_TO_EXPANDER(cpuid); - core = STARCAT_CPUID_TO_COREID(cpuid); - aid = STARCAT_CPUID_TO_AGENT(cpuid) - & ~STARCAT_CPUID_TO_CORE_BIT(cpuid); - slot = STARCAT_CPUID_TO_BOARDSLOT(cpuid); - - if (core == 0) { - /* - * core 0 cesr is same as what axq calulates for - * cheetah - */ - pre_calculated_cesr_ids[cpuid] - = (aid | (slot << 2) | (nid << 3)); - } else if (slot == 0) { - /* for core 1 slot0, use space above last expander */ - pre_calculated_cesr_ids[cpuid] = aid | - ((nid % 2) << 2) - | ((18 + nid/2) << 3); - } else { - /* core 1 slot 1, set bits 1 & 2 */ - pre_calculated_cesr_ids[cpuid] = aid | 0x6 | (nid << 3); - } - - /* - * shuffle bits to work around jaguar error where if - * bits 01234567 are stored in the cesr_id, bit 67012345 - * are what gets driven onto the safari bus - */ - pre_calculated_cesr_ids[cpuid] - = ((pre_calculated_cesr_ids[cpuid] & 0xc0) >> 6) - | ((pre_calculated_cesr_ids[cpuid] & 0x3f) << 2); - } -} - -/* support when SC is not available */ -static void -stop_thread(safari_port_t wci_id, int link) -{ - int i; - wrsmplat_link_t *l; - - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci_id) { - l = &wrsmplat_state.wci[i].link[link]; - mutex_enter(&l->mutex); - while (l->thread_active) { - DPRINTF(WP_THREAD, (CE_CONT, - "stop_thread: wci %d link %d " - "waiting for thread to stop", - wci_id, link)); - l->stop_thread = B_TRUE; - cv_wait(&l->cv, &l->mutex); - } - mutex_exit(&l->mutex); - DPRINTF(WP_THREAD, (CE_CONT, "stop_thread: " - "wci %d link %d thread stopped", - wci_id, link)); - break; - } - } -} - -static void -start_thread(safari_port_t wci_id, int link, void (*proc)(), caddr_t arg) -{ - int i; - boolean_t found = B_FALSE; - wrsmplat_link_t *l; - - /* First, look to see if WCI already exists */ - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci_id) { - /* Don't start the thread if wci was suspended */ - if (wrsmplat_state.wci[i].suspended) { - DPRINTF(WP_THREAD, (CE_CONT, "wci %d is " - "suspended, can't start thread", wci_id)); - return; - } - l = &wrsmplat_state.wci[i].link[link]; - mutex_enter(&l->mutex); - if (l->thread_active) { - mutex_exit(&l->mutex); - DPRINTF(WP_THREAD, (CE_CONT, "wci %d link %d " - "thread already running", wci_id, link)); - return; - } - l->thread_active = B_TRUE; - l->stop_thread = B_FALSE; - mutex_exit(&l->mutex); - found = B_TRUE; - DPRINTF(WP_THREAD, (CE_CONT, "wci %d exists", wci_id)); - break; - } - } - - /* If not, then search for free space and add wci to the list */ - if (!found) { - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (!wrsmplat_state.wci[i].valid) { - wrsmplat_state.wci[i].wci_id = wci_id; - l = &wrsmplat_state.wci[i].link[link]; - mutex_init(&l->mutex, NULL, MUTEX_DRIVER, - NULL); - cv_init(&l->cv, NULL, CV_DEFAULT, NULL); - l->thread_active = B_TRUE; - l->stop_thread = B_FALSE; - wrsmplat_state.wci[i].valid = B_TRUE; - wrsmplat_state.wci[i].suspended = B_FALSE; - found = B_TRUE; - DPRINTF(WP_THREAD, (CE_CONT, "created wci %d", - wci_id)); - break; - } - } - } - - if (found || wci_id == -1) { - mutex_enter(&wrsmplat_state.thread_count_lock); - ++wrsmplat_state.thread_count; - DPRINTF(WP_THREAD, (CE_CONT, - "start_thread: wci %d, link %d, thread #%d", - wci_id, link, wrsmplat_state.thread_count)); - mutex_exit(&wrsmplat_state.thread_count_lock); - (void) thread_create(NULL, 0, proc, arg, - 0, &p0, TS_RUN, minclsyspri); - /* LINTED - E_NOP_ELSE_STMT */ - } else { - DPRINTF(WP_DEBUG, (CE_WARN, "start_thread: bad wci/link: " - "wci %d link %d", wci_id, link)); - } -} - -static void -exit_thread(safari_port_t wci_id, int link) -{ - int i; - wrsmplat_link_t *l; - - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci_id) { - l = &wrsmplat_state.wci[i].link[link]; - mutex_enter(&l->mutex); - l->thread_active = B_FALSE; - cv_broadcast(&l->cv); - mutex_exit(&l->mutex); - } - } - mutex_enter(&wrsmplat_state.thread_count_lock); - --wrsmplat_state.thread_count; - DPRINTF(WP_THREAD, (CE_CONT, "exit_thread: thread " - "exiting for wci %d link %d. There are %d threads left", - wci_id, link, wrsmplat_state.thread_count)); - mutex_exit(&wrsmplat_state.thread_count_lock); - - thread_exit(); -} - -static boolean_t -check_stop_thread(safari_port_t wci_id, int link) -{ - int i; - - if (wrsmplat_state.thread_stop) { - return (B_TRUE); - } - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci_id) { - return (wrsmplat_state.wci[i].link[link].stop_thread); - } - } - return (B_FALSE); -} - - - -static void queue_message(uint32_t msg_type, boolean_t loopback, - void *msg_data, size_t msg_size); -static wrsmplat_mbox_msg_t *dequeue_msg(void); -static void process_message(void); -static void wrsmplat_thread(void *arg); - -/* used to start a thread */ -typedef struct wrsmplat_thread_data { - wrsm_uplink_msg_t *msg; - volatile uchar_t *wrsm_regs; - boolean_t loopback; - fmnodeid_t remote_fmnodeid; - gnid_t remote_gnid; -} wrsmplat_thread_data_t; - -static void activate_link(wrsmplat_thread_data_t *data); -static void deactivate_link(safari_port_t portid, - volatile uchar_t *wrsm_regs, linkid_t link_num); -static int try_activate(wrsm_uplink_msg_t *msg, volatile uchar_t *wrsm_regs); - -int -_init(void) -{ - int rc; - - DPRINTF(WP_DEBUG, (CE_CONT, "starcat:wrsmplat _init")); - - calculate_starcat_cesr_id(); - wrsmplat_state.msg_queue = NULL; - mutex_init(&wrsmplat_state.queue_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&wrsmplat_state.cv_lock, NULL, MUTEX_DRIVER, NULL); - cv_init(&wrsmplat_state.msg_cv, NULL, CV_DRIVER, NULL); - - mutex_init(&wrsmplat_state.thread_count_lock, NULL, - MUTEX_DRIVER, NULL); - mutex_init(&wrsmplat_state.tnid_map_lock, NULL, - MUTEX_DRIVER, NULL); - - rc = mboxsc_init(IOSRAM_KEY_WCSC, MBOXSC_MBOX_OUT, NULL); - if (rc) { - DPRINTF(WP_DEBUG, (CE_WARN, "mboxsc_init of WCSC failed " - "rc=%d", rc)); - mutex_destroy(&wrsmplat_state.queue_lock); - mutex_destroy(&wrsmplat_state.cv_lock); - cv_destroy(&wrsmplat_state.msg_cv); - mutex_destroy(&wrsmplat_state.thread_count_lock); - mutex_destroy(&wrsmplat_state.tnid_map_lock); - return (rc); - } - - rc = mboxsc_init(IOSRAM_KEY_SCWC, MBOXSC_MBOX_IN, &mbox_event_handler); - if (rc) { - DPRINTF(WP_DEBUG, (CE_WARN, "mboxsc_init of SCWC failed " - "rc=%d", rc)); - mboxsc_fini(IOSRAM_KEY_WCSC); - mutex_destroy(&wrsmplat_state.queue_lock); - mutex_destroy(&wrsmplat_state.cv_lock); - cv_destroy(&wrsmplat_state.msg_cv); - mutex_destroy(&wrsmplat_state.thread_count_lock); - mutex_destroy(&wrsmplat_state.tnid_map_lock); - return (rc); - } - - if ((rc = mod_install(&modlinkage)) != 0) { - DPRINTF(WP_DEBUG, (CE_WARN, "mod_install failed rc=%d", rc)); - mboxsc_fini(IOSRAM_KEY_WCSC); - mboxsc_fini(IOSRAM_KEY_SCWC); - mutex_destroy(&wrsmplat_state.queue_lock); - mutex_destroy(&wrsmplat_state.cv_lock); - cv_destroy(&wrsmplat_state.msg_cv); - mutex_destroy(&wrsmplat_state.thread_count_lock); - mutex_destroy(&wrsmplat_state.tnid_map_lock); - return (rc); - } - - return (0); -} - -int -_fini(void) -{ - int rc; - - DPRINTF(WP_DEBUG, (CE_CONT, "starcat:wrsmplat _fini")); - - if ((rc = mod_remove(&modlinkage)) != 0) { - return (rc); - } - /* - * This blocks waiting for all the child threads to die - */ - (void) wrsmplat_unreg_callbacks(); - - mboxsc_fini(IOSRAM_KEY_WCSC); - mboxsc_fini(IOSRAM_KEY_SCWC); - - mutex_destroy(&wrsmplat_state.queue_lock); - mutex_destroy(&wrsmplat_state.cv_lock); - cv_destroy(&wrsmplat_state.msg_cv); - - mutex_destroy(&wrsmplat_state.thread_count_lock); - mutex_destroy(&wrsmplat_state.tnid_map_lock); - - return (0); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - -static void -mbox_event_handler(void) -{ - int rc; - uint32_t type = 0; - uint32_t cmd = 0; - uint64_t transid = 0; - wrsm_linkisup_msg_t isup_msg = {0}; - uint32_t length = sizeof (wrsm_linkisup_msg_t); - - rc = mboxsc_getmsg(IOSRAM_KEY_SCWC, &type, &cmd, &transid, - &length, &isup_msg, MBOXSC_PUTMSG_DEF_TIMEOUT); - DPRINTF(WP_MBOX, (CE_NOTE, "mbox_event: type=%d cmd=%d transid=0x%lx " - "length=%d rc=%d", type, cmd, transid, length, rc)); - if (rc == 0 && cmd == LINKISUP) { - - DPRINTF(WP_MBOX, (CE_NOTE, "mbox_event: LINKISUP wci %d " - "link %d", isup_msg.link_info.wci_port_id, - isup_msg.link_info.link_num)); - - queue_message(LINKISUP, B_FALSE, &isup_msg, sizeof (isup_msg)); - return; - } - DPRINTF(WP_MBOX, (CE_NOTE, "mbox_event: unrecognized event type")); -} - -wrsm_node_types_t -wrsmplat_get_node_type(void) -{ - return (node_type); -} - - -int -wrsmplat_uplink(safari_port_t wci, linkid_t link, gnid_t gnid, - fmnodeid_t fmnodeid, uint64_t partition_version, uint32_t controller_id, - boolean_t loopback) -{ - wrsm_uplink_msg_t msg = {0}; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_uplink wci %d link %d", - wci, link)); - - msg.config_data.partition_version = partition_version; - msg.config_data.partition_id = controller_id; - msg.config_data.fmnodeid = fmnodeid; - msg.config_data.gnid = gnid; - msg.wci_port_id = wci; - msg.link_num = link; - - queue_message(UPLINK, loopback, &msg, sizeof (msg)); - return (0); -} - -int -wrsmplat_downlink(safari_port_t wci, linkid_t link, boolean_t loopback) -{ - wrsm_link_msg_t msg = {0}; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_downlink wci %d link %d", - wci, link)); - msg.wci_port_id = wci; - msg.link_num = link; - - queue_message(DOWNLINK, loopback, &msg, sizeof (msg)); - return (0); -} - -int -wrsmplat_linktest(safari_port_t wci, wrsm_linktest_arg_t *linktest) -{ - fmnodeid_t remote_fmnodeid; - gnid_t remote_gnid; - linkid_t remote_link; - safari_port_t remote_port; - volatile unsigned char *wrsm_regs = NULL; - wci_sw_link_control_u link_control; - wci_sw_link_status_u link_status; - uint64_t offset = linktest->link_num * STRIDE_WCI_SW_LINK_CONTROL; - - if (linktest->link_num >= WRSM_LINKS_PER_WCI) - return (EINVAL); - - (*wrsmplat_state.cb_ops->get_remote_data)(wci, linktest->link_num, - &remote_fmnodeid, &remote_gnid, &remote_link, &remote_port, - &wrsm_regs); - - if (!wrsm_regs) - return (ENXIO); - - link_control.val = read_reg(wrsm_regs, - ADDR_WCI_SW_LINK_CONTROL + offset); - if (link_control.bit.link_state != LINK_STATE_IN_USE) - return (EAGAIN); - - link_control.val = read_reg(wrsm_regs, - ADDR_WCI_SW_LINK_CONTROL + offset); - linktest->link_control = link_control.val; - link_control.bit.usr_data_1 = linktest->pattern & 0xffff; - link_control.bit.usr_data_2 = ((linktest->pattern >> 16) & 0x3); - write_reg(wrsm_regs, ADDR_WCI_SW_LINK_CONTROL + offset, - link_control.val); - linktest->link_error_count = read_reg(wrsm_regs, - ADDR_WCI_SW_LINK_ERROR_COUNT + offset); - linktest->link_esr = read_reg(wrsm_regs, ADDR_WCI_LINK_ESR); - linktest->sw_esr = read_reg(wrsm_regs, ADDR_WCI_SW_ESR); - link_status.val = read_reg(wrsm_regs, - ADDR_WCI_SW_LINK_STATUS + offset); - linktest->link_status = link_status.val; - linktest->pattern = link_status.bit.farend_ustat_1 | - (link_status.bit.farend_ustat_2 << 16); - - return (0); -} - -int -wrsmplat_set_led(safari_port_t wci, linkid_t link, int led_state) -{ - wrsm_link_led_msg_t msg = {0}; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_set_led, mode = %d", led_state)); - msg.wci_port_id = wci; - msg.link_num = link; - msg.led_state = led_state; - queue_message(SETLEDSTATE, B_FALSE, &msg, sizeof (msg)); - return (0); -} - -int -wrsmplat_alloc_slices(ncslice_bitmask_t requested, ncslice_bitmask_t *granted) -{ - int i, rc; - ncslice_bitmask_t allocated = {0}; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_alloc_slices")); - - if (wrsm_use_sgsbbc) { - wrsm_ncslice_claim_msg_t msg = {0}; - wrsm_ncslice_claim_msg_t reply = {0}; - - msg.requested_ncslices = requested; - rc = send_mbox_msg(NCSLICE, &msg, sizeof (msg), &reply, - sizeof (reply)); - if (rc) { - DPRINTF(WP_MBOX, (CE_WARN, "wrsmplat_alloc_slices: " - "send_mbox_msg failed %d", rc)); - return (rc); - } else if (reply.status) { - DPRINTF(WP_MBOX, (CE_WARN, "SC reports status %d on " - "NCSLICE request", reply.status)); - return (reply.status); - } - - *granted = reply.requested_ncslices; - -#ifdef DEBUG - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_alloc_slices: granted")); - for (i = 0; i < WRSM_MAX_NCSLICES - 1; ++i) - if (WRSM_IN_SET(requested, i)) { - DPRINTF(WP_DEBUG, (CE_CONT, " ncslice %d", i)); - } -#endif - } else { - /* - * We are only allowed to use NC slices 161 to 254. - */ - for (i = 161; i < (WRSM_MAX_NCSLICES - 1); ++i) - if (WRSM_IN_SET(requested, i)) - WRSMSET_ADD(allocated, i); - WRSMSET_COPY(allocated, *granted); - } - - return (0); -} - -int -wrsmplat_set_seprom(safari_port_t wci_id, uchar_t *seprom_data, - size_t length) -{ - wrsm_wib_seprom_msg_t msg; - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_set_seprom")); - if (length > WIB_SEPROM_MSG_SIZE) - return (EINVAL); - msg.wci_port_id = wci_id; - bcopy(seprom_data, &msg.seprom_data, length); - - queue_message(SETSEPROM, B_FALSE, &msg, sizeof (msg)); - return (0); -} - -int -wrsmplat_reg_callbacks(wrsm_plat_ops_t *ops) -{ - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_reg_callbacks")); - - wrsmplat_state.cb_ops = ops; - wrsmplat_state.thread_stop = B_FALSE; - - if (wrsmplat_state.thread_count != 0) { - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_reg_callbacks: " - "called more than once")); - return (EEXIST); - } - - /* - * no need to lock the thread count: - * when using the mailbox : only one thread exists - * not using the mailbox : the wrsmplat thread starts other threads - */ - wrsmplat_state.thread_count = 1; - (void) thread_create(NULL, 0, wrsmplat_thread, NULL, 0, &p0, - TS_RUN, minclsyspri); - return (0); -} - -int -wrsmplat_unreg_callbacks(void) -{ - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_unreg_callbacks")); - - wrsmplat_state.thread_stop = B_TRUE; - - /* Wake up the message thread */ - mutex_enter(&wrsmplat_state.cv_lock); - cv_signal(&wrsmplat_state.msg_cv); - mutex_exit(&wrsmplat_state.cv_lock); - - /* - * Eventually, all of the threads should wake up, notice the - * thread_stop flag is set and exit. When they have all - * finished, the count should go to zero and it is safe to - * proceed. In case of not using SBBC ther is only one thread. - */ - while (wrsmplat_state.thread_count > 0) { - DPRINTF(WP_THREAD, (CE_CONT, "unreg_callbacks: waiting for " - "%d threads to finish", wrsmplat_state.thread_count)); - delay(drv_usectohz(1000 * 1000)); - } - wrsmplat_state.cb_ops = NULL; - return (0); -} - -static void -queue_message(uint32_t msg_type, boolean_t loopback, void *msg_data, - size_t msg_size) -{ - wrsmplat_mbox_msg_t *entry, *p; - DPRINTF(WP_QUEUE, (CE_CONT, "queue_message: msg_type = %d nthreads=%d", - msg_type, wrsmplat_state.thread_count)); - /* Could be called from interrupt context, so use KM_NOSLEEP */ - entry = kmem_alloc(sizeof (wrsmplat_mbox_msg_t), KM_NOSLEEP); - if (entry == NULL) { - return; - } - entry->msg_type = msg_type; - entry->loopback = loopback; - /* Could be called from interrupt context, so use KM_NOSLEEP */ - entry->msg_data = kmem_alloc(msg_size, KM_NOSLEEP); - if (entry->msg_data == NULL) { - kmem_free(entry, sizeof (wrsmplat_mbox_msg_t)); - return; - } - bcopy(msg_data, entry->msg_data, msg_size); - entry->msg_size = msg_size; - entry->next = NULL; - mutex_enter(&wrsmplat_state.queue_lock); - if (wrsmplat_state.msg_queue == NULL) - wrsmplat_state.msg_queue = entry; - else { - p = wrsmplat_state.msg_queue; - while (p->next != NULL) - p = p->next; - p->next = entry; - } - mutex_exit(&wrsmplat_state.queue_lock); - - DPRINTF(WP_QUEUE, (CE_CONT, "queue_message: queued msg_type = %d\n", - msg_type)); - - mutex_enter(&wrsmplat_state.cv_lock); - cv_signal(&wrsmplat_state.msg_cv); - mutex_exit(&wrsmplat_state.cv_lock); - - DPRINTF(WP_QUEUE, (CE_CONT, "queue_message: signaled msg_type = %d\n", - msg_type)); -} - -static wrsmplat_mbox_msg_t * -dequeue_msg(void) -{ - wrsmplat_mbox_msg_t *msg; - - mutex_enter(&wrsmplat_state.queue_lock); - msg = wrsmplat_state.msg_queue; - if (msg != NULL) - wrsmplat_state.msg_queue = msg->next; - mutex_exit(&wrsmplat_state.queue_lock); - - return (msg); -} - -/* ARGSUSED */ -static void -wrsmplat_thread(void *arg) -{ - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_thread starting")); - - /* LINTED */ - while (1) { - process_message(); - - /* go to sleep waiting for the next message */ - mutex_enter(&wrsmplat_state.cv_lock); - cv_wait(&wrsmplat_state.msg_cv, &wrsmplat_state.cv_lock); - mutex_exit(&wrsmplat_state.cv_lock); - - if (wrsmplat_state.thread_stop) { - process_message(); /* finish any waiting messages */ - mutex_enter(&wrsmplat_state.thread_count_lock); - --wrsmplat_state.thread_count; - mutex_exit(&wrsmplat_state.thread_count_lock); - thread_exit(); - } - } -} - -/* - * Send a message to the SSC and wait for a matching response - */ -static int -send_mbox_msg(uint32_t cmd, void *msg, uint32_t msg_length, - void *reply, uint32_t reply_length) -{ - uint32_t reply_type; - uint32_t reply_cmd; - uint64_t transid = 0; - int rc; - - DPRINTF(WP_MBOX, (CE_NOTE, "wrsmplat send_mbox: cmd %d", cmd)); - - rc = mboxsc_putmsg(IOSRAM_KEY_WCSC, MBOXSC_MSG_REQUEST, - cmd, &transid, msg_length, msg, (6 * MBOXSC_PUTMSG_DEF_TIMEOUT)); - if (rc) { - DPRINTF(WP_MBOX, (CE_WARN, "wrsmplat send_mbox_msg: " - "mboxsc_putmsg failed %d", rc)); - return (rc); - } - DPRINTF(WP_MBOX, (CE_CONT, "wrsmplat send_mbox_msg: " - "putmsg succeeded transid=%lx", transid)); - - reply_type = MBOXSC_MSG_REPLY; - reply_cmd = cmd; - DPRINTF(WP_MBOX, (CE_CONT, "wrsmplat getmsg type=%d cmd=%d " - "transid=%lx length=%d", reply_type, reply_cmd, transid, - reply_length)); - - rc = mboxsc_getmsg(IOSRAM_KEY_SCWC, &reply_type, &reply_cmd, - &transid, &reply_length, reply, (6 * MBOXSC_PUTMSG_DEF_TIMEOUT)); - if (rc) { - DPRINTF(WP_MBOX, (CE_WARN, "wrsmplat send_mbox_msg: " - "mboxsc_getmsg failed %d", rc)); - return (rc); - } - DPRINTF(WP_MBOX, (CE_CONT, "wrsmplat send_mbox_msg: " - "getmsg succeeded transid=%lx type=%d cmd=%d", - transid, reply_type, reply_cmd)); - - return (0); -} - -static void -process_message(void) -{ - wrsmplat_mbox_msg_t *entry; - wrsm_link_msg_t *msg; - boolean_t free_msg = B_TRUE; - linkid_t remote_link; - safari_port_t remote_port; - gnid_t remote_gnid; - fmnodeid_t remote_fmnodeid; - int rc; - - while (entry = dequeue_msg()) { - switch (entry->msg_type) { - case LINKISUP: { - wrsm_uplink_msg_t linkdata_msg = {0}; - wrsm_uplink_msg_t reply = {0}; - wrsm_linkisup_msg_t *isup_msg; - - isup_msg = (wrsm_linkisup_msg_t *)entry->msg_data; - linkdata_msg.wci_port_id = - isup_msg->link_info.wci_port_id; - linkdata_msg.link_num = isup_msg->link_info.link_num; - - rc = send_mbox_msg(LINKDATA, &linkdata_msg, - sizeof (linkdata_msg), &reply, sizeof (reply)); - if (rc) { - cmn_err(CE_WARN, "mbox_event_handler: " - "send_mbox_msg failed for LINKDATA %d", - rc); - break; - } else if (reply.status == EAGAIN) { - cmn_err(CE_WARN, "SC reports link not up " - "on LINKDATA request"); - } else if (reply.status) { - cmn_err(CE_WARN, "SC reports status %d " - "on LINKDATA request", reply.status); - } - - /* - * Call up to wrsm to give notice that the - * link is ready - */ - (*wrsmplat_state.cb_ops->link_up) - (isup_msg->link_info.wci_port_id, - isup_msg->link_info.link_num, - reply.config_data.fmnodeid, - reply.config_data.gnid, reply.link_num, - reply.wci_port_id, - reply.config_data.partition_version, - reply.config_data.partition_id); - break; - } - case UPLINK: { - /* this is a message to be sent to SC */ - wrsm_uplink_msg_t *umsg; - wrsm_status_msg_t status; - wrsmplat_thread_data_t *thread_data; - - thread_data = kmem_alloc( - sizeof (wrsmplat_thread_data_t), KM_SLEEP); - umsg = (wrsm_uplink_msg_t *)(entry->msg_data); - - if (wrsm_use_sgsbbc) { - if ((rc = send_mbox_msg(UPLINK, umsg, - sizeof (wrsm_uplink_msg_t), &status, - sizeof (wrsm_status_msg_t))) != 0) { - cmn_err(CE_NOTE, "send_mbox_msg " - "failed for UPLINK rc=%d", rc); - } else if (status.status == EINVAL) { - cmn_err(CE_WARN, "SC reports mismatch " - "fmnodeid on UPLINK request"); - } else if (status.status != 0) { - cmn_err(CE_WARN, "SC reports status " - "%d on UPLINK request", - status.status); - } - } else { - thread_data->msg = umsg; - thread_data->loopback = entry->loopback; - - (*wrsmplat_state.cb_ops->get_remote_data) - (umsg->wci_port_id, - (linkid_t)umsg->link_num, - &thread_data->remote_fmnodeid, - &thread_data->remote_gnid, - &remote_link, &remote_port, - &thread_data->wrsm_regs); - if (!thread_data->wrsm_regs) { - DPRINTF(WP_DEBUG, (CE_WARN, "mp " - "UPLINK: failed to get register " - "base")); - return; - } - stop_thread(umsg->wci_port_id, - umsg->link_num); - start_thread(umsg->wci_port_id, - umsg->link_num, - activate_link, - (caddr_t)thread_data); - free_msg = B_FALSE; - } - break; - } - case DOWNLINK: { - /* this is a message to be sent to SC */ - volatile unsigned char *wrsm_regs = NULL; - wrsm_status_msg_t status = {0}; - - msg = (wrsm_link_msg_t *)(entry->msg_data); - - if (wrsm_use_sgsbbc) { - if ((rc = send_mbox_msg(DOWNLINK, msg, - sizeof (wrsm_link_msg_t), &status, - sizeof (wrsm_status_msg_t))) != 0) { - cmn_err(CE_NOTE, "send_mbox_msg " - "failed for DOWNLINK rc=%d", rc); - } else if (status.status) { - cmn_err(CE_WARN, "SC reports status " - "%d on DOWNLINK request", - status.status); - } - } else { - (*wrsmplat_state.cb_ops->get_remote_data) - (msg->wci_port_id, - (linkid_t)msg->link_num, - &remote_fmnodeid, - &remote_gnid, - &remote_link, - &remote_port, - &wrsm_regs); - - stop_thread(msg->wci_port_id, - msg->link_num); - - if (wrsm_regs) { - deactivate_link(msg->wci_port_id, - wrsm_regs, msg->link_num); - /* LINTED - E_NOP_ELSE_STMT */ - } else { - DPRINTF(WP_DEBUG, (CE_WARN, "mp " - "DOWNLINK: failed to get register " - "base")); - } - } - /* should not call link_down for loopback */ - if (!entry->loopback) - (*wrsmplat_state.cb_ops->link_down) - (msg->wci_port_id, - (linkid_t)msg->link_num); - break; - } - case SETLEDSTATE: { - /* this is a message to be sent to SC */ - wrsm_link_led_msg_t *ledmsg; - wrsm_status_msg_t status = {0}; - ledmsg = (wrsm_link_led_msg_t *)entry->msg_data; - - if (wrsm_use_sgsbbc) { - if ((rc = send_mbox_msg(SETLEDSTATE, ledmsg, - sizeof (wrsm_link_led_msg_t), &status, - sizeof (wrsm_status_msg_t))) != 0) { - cmn_err(CE_NOTE, "send_mbox_msg " - "failed for SETLEDSTATE rc=%d", - rc); - } else if (status.status) { - cmn_err(CE_WARN, "SC reports status " - "%d on SETLEDSTATE request", - status.status); - } - } - break; - } - case SETSEPROM: { - /* this is a message to be sent to SC */ - if (wrsm_use_sgsbbc) { - wrsm_wib_seprom_msg_t *seprommsg; - wrsm_status_msg_t status = {0}; - seprommsg = (wrsm_wib_seprom_msg_t *) - entry->msg_data; - - if ((rc = send_mbox_msg(SETSEPROM, seprommsg, - sizeof (wrsm_wib_seprom_msg_t), &status, - sizeof (wrsm_status_msg_t))) != 0) { - cmn_err(CE_WARN, - "send_mbox_msg failed for " - "SETSEPROM rc=%d", rc); - } else if (status.status) { - cmn_err(CE_WARN, "SC reports status " - "%d on SETSEPROM request", - status.status); - } - } - break; - } - case NCSLICE: { - /* NOT HANDLED HERE */ - break; - } - default : - cmn_err(CE_WARN, "process_message: unknown message"); - } - - if (free_msg) - kmem_free(entry->msg_data, entry->msg_size); - kmem_free(entry, sizeof (wrsmplat_mbox_msg_t)); - } -} - -static uint64_t -read_reg(volatile uchar_t *regs, uint64_t offset) -{ - return (*((uint64_t *)(regs + offset))); -} - -static void -write_reg(volatile uchar_t *regs, uint64_t offset, uint64_t value) -{ - *((uint64_t *)(regs + offset)) = value; -} - -/* ARGSUSED */ -void -wrsmplat_wci_init(volatile uchar_t *wrsm_regs) -{ - /* - * wci_qlim_3req_priority, wci_qlim_2req_priority, - * wci_qlim_sort_ciq, wci_qlim_sort_niq, and wci_qlim_sort_piq - * need to be updated if this cluster node is part of a - * wildcat SSM. - */ -} - - -/* ARGSUSED */ -void -deactivate_link(safari_port_t portid, volatile uchar_t *wrsm_regs, - linkid_t link_num) - -{ - wci_sw_link_control_u link_control; - uint64_t offset = link_num * STRIDE_WCI_SW_LINK_CONTROL; - uint64_t cntlAddr = ADDR_WCI_SW_LINK_CONTROL + offset; - - DPRINTF(WP_DEBUG, (CE_CONT, "wci %d deactivate_link %d regs %p", - portid, link_num, (void *)wrsm_regs)); - - link_control.val = read_reg(wrsm_regs, cntlAddr); - - link_control.bit.usr_data_1 = 0; - link_control.bit.usr_data_2 = 0; - link_control.bit.xmit_enable = 0; - link_control.bit.laser_enable = 0; - link_control.bit.link_state = LINK_STATE_OFF; - - write_reg(wrsm_regs, cntlAddr, link_control.val); -} - -void -activate_link(wrsmplat_thread_data_t *data) -{ - wrsm_uplink_msg_t *msg = data->msg; - volatile uchar_t *wrsm_regs = data->wrsm_regs; - wci_sw_link_control_u link_control; - wci_sw_link_status_u link_status; - wci_sw_link_error_count_u error_count; - wci_id_u wci_id_reg; - uint64_t offset = msg->link_num * STRIDE_WCI_SW_LINK_CONTROL; - uint64_t cntlAddr = ADDR_WCI_SW_LINK_CONTROL + offset; - uint64_t statAddr = ADDR_WCI_SW_LINK_STATUS + offset; - uint64_t eCntAddr = ADDR_WCI_SW_LINK_ERROR_COUNT + offset; -#ifdef DEBUG - uint64_t pa, kpf; -#endif /* DEBUG */ - gnid_t remote_gnid; - /* LINTED */ - fmnodeid_t remote_fmnodeid; - linkid_t remote_link; - safari_port_t remote_port; - safari_port_t wci_id = msg->wci_port_id; - linkid_t link_id = msg->link_num; - - link_control.val = read_reg(wrsm_regs, cntlAddr); - - link_control.bit.usr_data_1 = 0; - link_control.bit.usr_data_2 = 0; - link_control.bit.ustat_src = 0; - link_control.bit.xmit_enable = 0; - link_control.bit.paroli_tck_enable = 0; - link_control.bit.near_end_shutdown_lock = 0; - link_control.bit.laser_enable = 1; - link_control.bit.error_inducement = 0; - link_control.bit.auto_shut_en = 0; - link_control.bit.rexmit_shutdown_en = 0; - write_reg(wrsm_regs, cntlAddr, link_control.val); - - wci_id_reg.val = read_reg(wrsm_regs, ADDR_WCI_ID); - if (wci_id_reg.val != WCI_ID_WCI2) { - write_reg(wrsm_regs, ADDR_WCI_SW_LINK_REXMIT + offset, 0); - } - -#ifdef DEBUG - kpf = hat_getkpfnum((caddr_t)wrsm_regs); - pa = (kpf << 13) | (((uint64_t)wrsm_regs) & 0x1fff); - DPRINTF(WP_DEBUG, (CE_CONT, "trying to bring up wci %d link %d " - "regs=%p pa=%p", wci_id, link_id, (void *)wrsm_regs, - (void *)pa)); -#endif - - while (try_activate(msg, wrsm_regs) != 0) { - delay(drv_usectohz(250 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - } - - /* - * Set the link to in use mode and, turn on the transmitters, - * and clear out the error count. - */ - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.xmit_enable = 1; - write_reg(wrsm_regs, cntlAddr, link_control.val); - error_count.val = 0; - write_reg(wrsm_regs, eCntAddr, error_count.val); - - DPRINTF(WP_DEBUG, (CE_NOTE, "link %d wci %d is up", - msg->link_num, msg->wci_port_id)); - - - /* - * We can send 16 bits to the far side via usr_data_1, it is - * encoded as follows: - * 0-7: gnid - * 8-12: portid - * 13-15: linknum - */ - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.usr_data_1 = (msg->config_data.gnid & 0xff) | - ((msg->wci_port_id & 0x1f) << 8) | - ((msg->link_num & 0x7) << 13); - link_control.bit.usr_data_2 = 1; - write_reg(wrsm_regs, cntlAddr, link_control.val); - - DPRINTF(WP_LINK, (CE_NOTE, "link %d sending discovery data %x", - msg->link_num, link_control.bit.usr_data_1)); - - /* - * Spin waiting for the remote side to set the user_data_2 - */ - link_status.val = read_reg(wrsm_regs, statAddr); - while (link_status.bit.farend_ustat_2 < 1) { - delay(drv_usectohz(100 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - - link_status.val = read_reg(wrsm_regs, statAddr); - } - - DPRINTF(WP_LINK, (CE_NOTE, "link %d got discovery data %x", - msg->link_num, link_status.bit.farend_ustat_1)); - - remote_gnid = link_status.bit.farend_ustat_1 & 0xff; - remote_port = (link_status.bit.farend_ustat_1 >> 8) & 0x1f; - remote_link = (link_status.bit.farend_ustat_1 >> 13) & 0x7; - - DPRINTF(WP_DEBUG, (CE_NOTE, "wci %d remote side responds " - "gnid %d port %d link %d", msg->wci_port_id, remote_gnid, - remote_port, remote_link)); - - /* XXX - just to be sure the link settles down */ - delay(drv_usectohz(200 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.usr_data_2 = 2; - link_control.bit.link_state = LINK_STATE_IN_USE; - link_control.bit.auto_shut_en = 1; - link_control.bit.rexmit_shutdown_en = 1; - - write_reg(wrsm_regs, cntlAddr, link_control.val); - link_status.val = read_reg(wrsm_regs, statAddr); - while (link_status.bit.farend_ustat_2 < 2) { - delay(drv_usectohz(100 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - link_status.val = read_reg(wrsm_regs, statAddr); - } - - /* - * Don't make the callback if the link is supposed to - * be in loopback mode. - */ - if (!data->loopback) { - (*wrsmplat_state.cb_ops->link_up)(msg->wci_port_id, - (linkid_t)msg->link_num, msg->config_data.fmnodeid, - remote_gnid, - (linkid_t)remote_link, remote_port, - msg->config_data.partition_version, - msg->config_data.partition_id); - } else { - DPRINTF(WP_DEBUG, (CE_WARN, "Setting wci %d link %d IN_USE", - msg->wci_port_id, msg->link_num)); - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.link_state = LINK_STATE_IN_USE; - write_reg(wrsm_regs, cntlAddr, link_control.val); - } - - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - kmem_free(data, sizeof (wrsmplat_thread_data_t)); - exit_thread(wci_id, link_id); -} - - -void -set_tnid(volatile uchar_t *regs, int link, int tnid) -{ - wci_fo_tnid_map_u tnid_map; - - mutex_enter(&wrsmplat_state.tnid_map_lock); - tnid_map.val = read_reg(regs, ADDR_WCI_FO_TNID_MAP); - switch (link) { - case 0: - tnid_map.bit.link0_tnid = tnid; - break; - case 1: - tnid_map.bit.link1_tnid = tnid; - break; - case 2: - tnid_map.bit.link2_tnid = tnid; - break; - default: - DPRINTF(WP_DEBUG, (CE_WARN, "set_tnid: illegal link num: %d", - link)); - break; - } - write_reg(regs, ADDR_WCI_FO_TNID_MAP, tnid_map.val); - /* read back to commit the write */ - tnid_map.val = read_reg(regs, ADDR_WCI_FO_TNID_MAP); - mutex_exit(&wrsmplat_state.tnid_map_lock); -} - -int -try_activate(wrsm_uplink_msg_t *msg, volatile uchar_t *wrsm_regs) -{ - wci_sw_link_control_u link_control; - wci_sw_link_status_u link_status; - wci_sw_link_error_count_u error_count; - wci_sw_esr_u sw_esr, sw_esr_mask; - uint64_t offset = msg->link_num * STRIDE_WCI_SW_LINK_CONTROL; - uint64_t cntlAddr = ADDR_WCI_SW_LINK_CONTROL + offset; - uint64_t statAddr = ADDR_WCI_SW_LINK_STATUS + offset; - uint64_t eCntAddr = ADDR_WCI_SW_LINK_ERROR_COUNT + offset; - int count, retry; - int checks; - int good_tnid; - int tnid; - safari_port_t wci_id = msg->wci_port_id; - linkid_t link_id = msg->link_num; - - if (link_id >= WRSM_LINKS_PER_WCI) { - DPRINTF(WP_DEBUG, (CE_NOTE, "try_activate: bad data link=%d " - "offset = %" PRIx64, link_id, offset)); - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - - /* Clear error bits corresponding to this link */ - sw_esr_mask.val = 0; - switch (msg->link_num) { - case 0: - sw_esr_mask.bit.acc_link_0_auto_shut = 1; - sw_esr_mask.bit.acc_link_0_failover = 1; - break; - case 1: - sw_esr_mask.bit.acc_link_1_auto_shut = 1; - sw_esr_mask.bit.acc_link_1_failover = 1; - break; - case 2: - sw_esr_mask.bit.acc_link_2_auto_shut = 1; - sw_esr_mask.bit.acc_link_2_failover = 1; - break; - } - sw_esr.val = read_reg(wrsm_regs, ADDR_WCI_SW_ESR); - sw_esr.val &= sw_esr_mask.val; - write_reg(wrsm_regs, ADDR_WCI_SW_ESR, sw_esr.val); - - /* Toggle the link state OFF/SEEK */ - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.link_state = LINK_STATE_OFF; - write_reg(wrsm_regs, cntlAddr, link_control.val); - - link_control.val = read_reg(wrsm_regs, cntlAddr); - link_control.bit.link_state = LINK_STATE_SEEK; - write_reg(wrsm_regs, cntlAddr, link_control.val); - /* read it back to make sure the write happened */ - link_control.val = read_reg(wrsm_regs, cntlAddr); - DPRINTF(WP_DEBUG, (CE_CONT, "try_activate: " - "Trying to bring up link %d wci %d", - msg->link_num, msg->wci_port_id)); - - /* - * The max paroli reset setup time is 100ms. Putting the link - * into STATE_SEEK brings the paroli out of reset, so we have - * to wait 100ms before we can expect anything useful from the - * status register - */ - delay(drv_usectohz(100 * 1000)); - - /* Wait for optical_signal_detect to come on */ - link_status.val = read_reg(wrsm_regs, statAddr); - count = 0; - while (link_status.bit.optical_signal_detect == 0) { - DPRINTF(WP_THREAD, (CE_CONT, "try_activate: no opt sig")); - ++count; - if (count >= 200) { - DPRINTF(WP_LINK, (CE_CONT, "Waiting for optical " - "signal detect link %d wci %d", - msg->link_num, msg->wci_port_id)); - return (-1); - } - /* sleep 250ms */ - delay(drv_usectohz(250 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - link_status.val = read_reg(wrsm_regs, statAddr); - } - DPRINTF(WP_LINK, (CE_CONT, "try_activate: opt sig detect: %u", - link_status.bit.optical_signal_detect)); - - good_tnid = B_FALSE; - - for (tnid = 0; tnid < 16; ++tnid) { - DPRINTF(WP_LINK, (CE_CONT, "try_activate: " - "Trying tnid %d", tnid)); - set_tnid(wrsm_regs, msg->link_num, tnid); - /* - * There is some probability <1 that the end_status - * will be reported correctly in the link_status - * register. Dave Saterfield guesses ~60% but it - * could be a lot worse if there is much clock skew - * between machines. It should only give false - * negative, not false positive results. So we try a - * few times and if it ever says "ready" then we declare - * success. - */ - for (retry = 0; retry < 5; ++retry) { - link_status.val = read_reg(wrsm_regs, statAddr); - if (link_status.bit.end_status == - END_STATUS_NEAR_READY || - link_status.bit.end_status == - END_STATUS_ALL_READY) { - good_tnid = B_TRUE; - break; - } - } - if (good_tnid) { - DPRINTF(WP_THREAD, (CE_CONT, "Good tnid found!")); - break; - } - } -#ifdef DEBUG - if (tnid == 16) { - DPRINTF(WP_LINK, (CE_CONT, "Didn't find good tnid status %u " - "link %d wci %d", link_status.bit.end_status, - msg->link_num, msg->wci_port_id)); - } else { - DPRINTF(WP_LINK, (CE_CONT, "Set tnid to %d, status %u " - "link %d wci %d retries %d", tnid, - link_status.bit.end_status, msg->link_num, - msg->wci_port_id, retry)); - } -#endif /* DEBUG */ - - /* - * If we didn't find the right tnid, the link must be in a bad - * state, so reset and try again. - */ - if (!good_tnid) - return (-1); - - for (checks = 15; checks > 0; checks--) { - link_status.val = read_reg(wrsm_regs, statAddr); - if (link_status.bit.end_status == END_STATUS_ALL_READY) { - error_count.val = 0; - write_reg(wrsm_regs, eCntAddr, error_count.val); -#ifndef NEW_PAROLIS_ONLY - delay(drv_usectohz(3000 * 1000)); -#endif /* NEW_PAROLIS_ONLY */ - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - - for (checks = 5; checks > 0; checks--) { - link_status.val = read_reg(wrsm_regs, - statAddr); - if (link_status.bit.end_status != - END_STATUS_ALL_READY) - continue; - - error_count.val = read_reg(wrsm_regs, - eCntAddr); - /* - * if it's still up and error count is - * not too high, declare success - */ - if (error_count.bit.error_count < 10) { - return (0); - } else { - DPRINTF(WP_DEBUG, (CE_CONT, - "high error count %" PRIx64 - " status = %" PRIx64, - error_count.val, - link_status.val)); - return (-1); - } - } - } - delay(drv_usectohz(100 * 1000)); - if (check_stop_thread(wci_id, link_id)) { - kmem_free(msg, sizeof (wrsm_uplink_msg_t)); - exit_thread(wci_id, link_id); - } - } - return (-1); -} - -/* - * Verifies valid stripegroup. For starcat, we support only 2 way WCI - * striping and those WCIs must be in adjacent even/odd pairs of expander - * boards. - */ -int -wrsmplat_stripegroup_verify(const wrsm_stripe_group_t *sg) -{ - int expander1, expander2; - - if (sg->nwcis < 2) { - return (0); - } - if (sg->nwcis > 2) { - return (ENOTSUP); - } - expander1 = PORT2EXP(sg->wcis[0]); - expander2 = PORT2EXP(sg->wcis[1]); - /* expander1 should be even and 1 less than expander 2 */ - if ((expander1 & ~1) != expander1 || - (expander1 + 1) != expander2) - return (ENOTSUP); - return (0); -} - -/* - * Program AXQ nasm tables to route appropriate ncslices to the - * right expander. - * Note: other CPUs are paused when this function is called. - */ -/* ARGSUSED */ -void -wrsmplat_ncslice_setup(wrsm_ncowner_map_t owner[WRSM_MAX_NCSLICES]) -{ - int i; - uint32_t nasm_data = 0; - - for (i = 0; i < WRSM_MAX_NCSLICES; ++i) { - if (owner[i].owner_type == WRSM_NCOWNER_NOT_CLAIMED) - continue; - - if (owner[i].owner_type == WRSM_NCOWNER_NONE) { - nasm_data = AXQ_NASM_TYPE_IO << AXQ_NASM_TYPE_SHIFT; - } else if (owner[i].owner_type == WRSM_NCOWNER_WCI) { - nasm_data = AXQ_NASM_TYPE_WIB << AXQ_NASM_TYPE_SHIFT; - nasm_data |= PORT2EXP(owner[i].owner.wci_id); - } else if (owner[i].owner_type == WRSM_NCOWNER_STRIPEGROUP) { - wrsm_stripe_group_t *stripe_group; - stripe_group = owner[i].owner.stripe_group; - ASSERT(stripe_group); - ASSERT(stripe_group->nwcis <= 2); - nasm_data = AXQ_NASM_TYPE_WIB_STRIPED << - AXQ_NASM_TYPE_SHIFT; - nasm_data |= PORT2EXP(stripe_group->wcis[0]); - } - - DPRINTF(WP_DEBUG, (CE_CONT, "wrsmplat_ncslice_setup: " - "owner type %d slice %d nasm_data %d", - owner[i].owner_type, i, nasm_data)); - - (void) axq_nasm_write_all(i, nasm_data); - } - -} - -/* - * Enter ncslice update critical section - take AXQ internal lock for Starcat - * before other CPUs are paused. Otherwise a paused thread could be holding - * this lock when axq_nasm_write_all() is called from wrsmplat_ncslice_setup(), - * and if the former attempted to acquire the lock there, deadlock would result. - */ -void -wrsmplat_ncslice_enter(void) -{ - axq_array_rw_enter(); -} - -/* - * Exit ncslice update critical section - release AXQ internal lock for Starcat, - * after other paused CPUs are restarted. - */ -void -wrsmplat_ncslice_exit(void) -{ - axq_array_rw_exit(); -} - -/* Does a cross-trap sync */ -void -wrsmplat_xt_sync(int cpu_id) -{ - cpuset_t cpuset; - CPUSET_ZERO(cpuset); - CPUSET_ADD(cpuset, cpu_id); - xt_sync(cpuset); -} - -/* Support for suspend/resume */ - -void -wrsmplat_suspend(safari_port_t wci) -{ - if (!wrsm_use_sgsbbc) { - int i; - int link; - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci) { - if (wrsmplat_state.wci[i].suspended) { - return; - } - wrsmplat_state.wci[i].suspended = B_TRUE; - break; - } - } - for (link = 0; link < WRSM_MAX_LINKS_PER_WCI; link++) { - stop_thread(wci, link); - } - } -} - -void -wrsmplat_resume(safari_port_t wci) -{ - /* - * No need to restart link bring-up thread, since driver will - * eventually time-out and retry later. - */ - if (!wrsm_use_sgsbbc) { - int i; - for (i = 0; i < WRSM_MAX_WCIS; i++) { - if (wrsmplat_state.wci[i].valid && - wrsmplat_state.wci[i].wci_id == wci) { - wrsmplat_state.wci[i].suspended = B_FALSE; - break; - } - } - } -} diff --git a/usr/src/uts/sun4u/starcat/ml/wrsmplat_asm.s b/usr/src/uts/sun4u/starcat/ml/wrsmplat_asm.s deleted file mode 100644 index b69cb5a3a6..0000000000 --- a/usr/src/uts/sun4u/starcat/ml/wrsmplat_asm.s +++ /dev/null @@ -1,63 +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 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - - -#if defined(lint) -#include <sys/types.h> -#else -#include "assym.h" -#endif /* lint */ - -#include <sys/asm_linkage.h> -#include <sys/asi.h> -#include <sys/cmpregs.h> -#include <sys/cheetahregs.h> -#include <sys/wrsmplat.h> - -#if defined(lint) - -/* ARGSUSED */ - -/* - * This function sets the ASI_CESR_ID per core register and - * is only used by wrsmplat on StarCat - */ -void -asi_cesr_id_wr(uint64_t cesr_id) -{} - -#else /* lint */ - !jaguar: write cesr id - ENTRY(asi_cesr_id_wr) - set ASI_CESR_ID_VA, %o1 - stxa %o0, [%o1]ASI_CMP_PER_CORE - membar #Sync - retl - nop - SET_SIZE(asi_cesr_id_wr) -#endif /* lint */ diff --git a/usr/src/uts/sun4u/starcat/sc_gptwocfg/Makefile b/usr/src/uts/sun4u/starcat/sc_gptwocfg/Makefile index 6b616fcb93..0b1551ce31 100644 --- a/usr/src/uts/sun4u/starcat/sc_gptwocfg/Makefile +++ b/usr/src/uts/sun4u/starcat/sc_gptwocfg/Makefile @@ -20,7 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #pragma ident "%Z%%M% %I% %E% SMI" @@ -64,7 +64,7 @@ CFLAGS += $(CCVERBOSE) -I../sys -I$(UTSBASE)/sun4u/starcat/sys # # module dependencies # -LDFLAGS += -dy -Nmisc/gptwocfg -Nmisc/gptwo_cpu -Nmisc/gptwo_wci -Nmisc/gptwo_pci -Ndrv/iosram +LDFLAGS += -dy -Nmisc/gptwocfg -Nmisc/gptwo_cpu -Nmisc/gptwo_pci -Ndrv/iosram # # Default build targets. diff --git a/usr/src/uts/sun4u/starcat/sys/gptwo_wci.h b/usr/src/uts/sun4u/starcat/sys/gptwo_wci.h deleted file mode 100644 index 554c848a61..0000000000 --- a/usr/src/uts/sun4u/starcat/sys/gptwo_wci.h +++ /dev/null @@ -1,52 +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 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_GPTWO_WCI_H -#define _SYS_GPTWO_WCI_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Header file for the WCI/Schizo component to the - * Safari Configurator (gptwo_cpu). - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/safari_pcd.h> - -gptwocfg_ops_cookie_t gptwocfg_alloc_wci_ops(int, int); -gptwo_new_nodes_t *gptwo_configure_wci(dev_info_t *, spcd_t *, uint_t); -dev_info_t *gptwo_prepare_wci(dev_info_t *); -dev_info_t *gptwo_unconfigure_wci(dev_info_t *); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_GPTWO_WCI_H */ diff --git a/usr/src/uts/sun4u/starcat/sys/wrsmplat.h b/usr/src/uts/sun4u/starcat/sys/wrsmplat.h deleted file mode 100644 index 0ed33ba7e2..0000000000 --- a/usr/src/uts/sun4u/starcat/sys/wrsmplat.h +++ /dev/null @@ -1,51 +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 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_WRSMPLAT_H -#define _SYS_WRSMPLAT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Prototypes for functions - */ - -#if defined(_KERNEL) && !defined(_ASM) -extern void asi_cesr_id_wr(uint64_t); -#endif /* defined(_KERNEL) && !defined(_ASM) */ - - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WRSMPLAT_H */ diff --git a/usr/src/uts/sun4u/starcat/wrsmplat/Makefile b/usr/src/uts/sun4u/starcat/wrsmplat/Makefile deleted file mode 100644 index e9e008f306..0000000000 --- a/usr/src/uts/sun4u/starcat/wrsmplat/Makefile +++ /dev/null @@ -1,110 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" -# -# This makefile drives the production of the wrsmplat kernel module. -# -# sun4u implementation architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../../.. - -# -# Define the module and object file sets. -# -WRSMPLAT_OBJS = wrsmplat.o wrsmplat_asm.o -MODULE = wrsmplat -OBJECTS = $(WRSMPLAT_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WRSMPLAT_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_STARCAT_MISC_DIR)/$(MODULE) - - -# -# Include common rules. -# -include $(UTSBASE)/sun4u/starcat/Makefile.starcat - -# -# Include path for rsm header files -# -INC_PATH += -I$(UTSBASE)/common - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# Overrides -# -ALL_BUILDS = $(ALL_BUILDSONLY64) -DEF_BUILDS = $(DEF_BUILDSONLY64) -CLEANLINTFILES += $(LINT32_FILES) - -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - -# -# Turn on doubleword alignment for 64 bit registers -# -CFLAGS += -dalign - -# -# module dependencies -# -LDFLAGS += -dy -Ndrv/axq -Nmisc/mboxsc - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sun4u/starcat/Makefile.targ diff --git a/usr/src/uts/sun4u/sys/Makefile b/usr/src/uts/sun4u/sys/Makefile index e66151df03..c65314c3a3 100644 --- a/usr/src/uts/sun4u/sys/Makefile +++ b/usr/src/uts/sun4u/sys/Makefile @@ -100,17 +100,7 @@ HDRS= \ sysioerr.h \ sysiosbus.h \ todmostek.h \ - traptrace.h \ - wci_cmmu.h \ - wci_common.h \ - wci_offsets.h \ - wci_regs.h \ - wrsm.h \ - wrsm_config.h \ - wrsm_plugin.h \ - wrsm_plat.h \ - wrsm_common.h \ - wrsm_types.h + traptrace.h $(CLOSED_BUILD)CLOSED_HDRS= \ memtestio_ch.h \ diff --git a/usr/src/uts/sun4u/sys/wci_cmmu.h b/usr/src/uts/sun4u/sys/wci_cmmu.h deleted file mode 100644 index d43d07dd3c..0000000000 --- a/usr/src/uts/sun4u/sys/wci_cmmu.h +++ /dev/null @@ -1,181 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * Automatically Generated file based on CSR definitions - * - */ - -/* - * This file automatically generated from - * wci_sram.csr - * 03/27/2000 13:46:00 - * Using ./csr_filter.pl by pcw - */ - -/* **DO NOT EDIT THIS FILE** */ -/* - * File ../../../design/wci/include/cmmu.h * - */ - -#ifndef _SYS_WCI_CMMU_H -#define _SYS_WCI_CMMU_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Include any headers you depend on. - */ - - - -/* - * wci_sram_array_as_cmmu_1_addr - */ -typedef union { - struct wci_sram_array_as_cmmu_1_addr { - uint32_t error : 1; /* 63 */ - uint32_t filler : 15; /* 62:48 */ - uint32_t ecc_syndrome : 7; /* 47:41 */ - uint32_t ecc_check : 7; /* 40:34 */ - uint32_t reserved1 : 2; /* 33:32 */ - uint32_t reserved2 : 3; /* 31:29 */ - uint32_t lpa_page : 29; /* 28:0 */ - } bit; - uint64_t val; -} wci_sram_array_as_cmmu_1_addr_u; - -#define wci_sram_array_as_cmmu_1_addr_error \ - bit.error -#define wci_sram_array_as_cmmu_1_addr_ecc_syndrome \ - bit.ecc_syndrome -#define wci_sram_array_as_cmmu_1_addr_ecc_check \ - bit.ecc_check -#define wci_sram_array_as_cmmu_1_addr_reserved \ - bit.reserved -#define wci_sram_array_as_cmmu_1_addr_lpa_page \ - bit.lpa_page - - -/* - * wci_sram_array_as_cmmu_1_int - */ -typedef union { - struct wci_sram_array_as_cmmu_1_int { - uint32_t error : 1; /* 63 */ - uint32_t filler : 15; /* 62:48 */ - uint32_t ecc_syndrome : 7; /* 47:41 */ - uint32_t ecc_check : 7; /* 40:34 */ - uint32_t reserved1 : 2; /* 33:32 */ - uint32_t reserved2 : 3; /* 31:29 */ - uint32_t lpa_page_1 : 2; /* 28:27 */ - uint32_t mondo : 16; /* 26:11 */ - uint32_t lpa_page_2 : 11; /* 10:0 */ - } bit; - uint64_t val; -} wci_sram_array_as_cmmu_1_int_u; - -#define wci_sram_array_as_cmmu_1_int_error \ - bit.error -#define wci_sram_array_as_cmmu_1_int_ecc_syndrome \ - bit.ecc_syndrome -#define wci_sram_array_as_cmmu_1_int_ecc_check \ - bit.ecc_check -#define wci_sram_array_as_cmmu_1_int_reserved \ - bit.reserved -#define wci_sram_array_as_cmmu_1_int_lpa_page_1 \ - bit.lpa_page_1 -#define wci_sram_array_as_cmmu_1_int_mondo \ - bit.mondo -#define wci_sram_array_as_cmmu_1_int_lpa_page_2 \ - bit.lpa_page_2 - - -/* - * wci_sram_array_as_cmmu_0 - */ -typedef union { - struct wci_sram_array_as_cmmu_0 { - uint32_t error : 1; /* 63 */ - uint32_t filler : 15; /* 62:48 */ - uint32_t ecc_syndrome : 7; /* 47:41 */ - uint32_t ecc_check : 7; /* 40:34 */ - uint32_t reserved1 : 2; /* 33:31 */ - uint32_t reserved2 : 3; /* 31:29 */ - uint32_t writable : 1; /* 28 */ - uint32_t from_all : 1; /* 27 */ - uint32_t valid : 1; /* 26 */ - uint32_t type : 2; /* 25:24 */ - uint32_t from_node : 8; /* 23:16 */ - uint32_t atomic_orig_id : 12; /* 15:4 */ - uint32_t count_enable : 1; /* 3 */ - uint32_t large_page : 1; /* 2 */ - uint32_t user_err : 1; /* 1 */ - uint32_t lpa_page : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sram_array_as_cmmu_0_u; - -#define wci_sram_array_as_cmmu_0_error \ - bit.error -#define wci_sram_array_as_cmmu_0_ecc_syndrome \ - bit.ecc_syndrome -#define wci_sram_array_as_cmmu_0_ecc_check \ - bit.ecc_check -#define wci_sram_array_as_cmmu_0_reserved \ - bit.reserved -#define wci_sram_array_as_cmmu_0_writable \ - bit.writable -#define wci_sram_array_as_cmmu_0_from_all \ - bit.from_all -#define wci_sram_array_as_cmmu_0_valid \ - bit.valid -#define wci_sram_array_as_cmmu_0_type \ - bit.type -#define wci_sram_array_as_cmmu_0_from_node \ - bit.from_node -#define wci_sram_array_as_cmmu_0_atomic_orig_id \ - bit.atomic_orig_id -#define wci_sram_array_as_cmmu_0_count_enable \ - bit.count_enable -#define wci_sram_array_as_cmmu_0_large_page \ - bit.large_page -#define wci_sram_array_as_cmmu_0_user_err \ - bit.user_err -#define wci_sram_array_as_cmmu_0_lpa_page \ - bit.lpa_page - - - - - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WCI_CMMU_H */ diff --git a/usr/src/uts/sun4u/sys/wci_common.h b/usr/src/uts/sun4u/sys/wci_common.h deleted file mode 100644 index ed2b9a214c..0000000000 --- a/usr/src/uts/sun4u/sys/wci_common.h +++ /dev/null @@ -1,839 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _WCI_COMMON_H -#define _WCI_COMMON_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/kstat.h> -#include <sys/wci_offsets.h> - -/* - * From PRM, 0 indicates a paroli that is present. This is set in - * Wci register: wci_sw_link_status, field: paroli_present - * such that, when paroli_present == 0 the paroli IS present. - */ -#define WCI_PAROLI_PRESENT 0 - -#define WCI_ID_WCI1 0x14776049 -#define WCI_ID_WCI2 0x14147049 -#define WCI_ID_WCI3 0x14063049 -#define WCI_ID_WCI31 0x24063049 -#define WCI_ID_WCI4 0x14478049 -#define WCI_ID_WCI41 0x24478049 - -/* stripe bits */ -#define WCI_OFF 0x0 -#define WCI_STRIPE_NONE 0xf -#define WCI_STRIPE_2WAY_EVEN 0x3 -#define WCI_STRIPE_2WAY_ODD 0xc -#define WCI_STRIPE_4WAY_0 0x1 -#define WCI_STRIPE_4WAY_1 0x2 -#define WCI_STRIPE_4WAY_2 0x4 -#define WCI_STRIPE_4WAY_3 0x8 - -/* For cluster mode striping, WCI uses addr bits 7 and 8, link uses 9 and 10 */ -#define WCI_CLUSTER_STRIPE_STRIDE (1 << 7) -#define WCI_CLUSTER_STRIPE_MASK 0x0780 /* Bits 7-10 set */ - -#define WCI_ERRPAGE_CESR_OFFSET 0 -#define WCI_ERRPAGE_CLUSTER_ERROR_OFFSET 64 /* byte offset into CESR page */ - -/* CESR values */ -#define WCI_CESR_NO_ERRORS 0x0 -#define WCI_CESR_PASSTHRU_CAG_ERROR 0x1 -#define WCI_CESR_CMMU_ACCESS_VIOLATION 0x2 -#define WCI_CESR_DEST_CAG_BUSY 0x3 -#define WCI_CESR_USER_ERROR_BIT_SET 0x4 -#define WCI_CESR_PAUSE_REPLY 0x5 -#define WCI_CESR_PASSTHRU_RAG_ERROR 0x6 -#define WCI_CESR_TOO_MANY_PASSTHRU_HOPS 0x7 -#define WCI_CESR_INTR_DEST_BUSY 0x8 -#define WCI_CESR_INVALID_TRANSACTION 0x9 -#define WCI_CESR_RAG_READ_TIMEOUT 0xA -#define WCI_CESR_RAG_DATA_ERROR 0xB -#define WCI_CESR_RAG_WRITE_TIMEOUT 0xC -#define WCI_CESR_RESERVED_13 0xD -#define WCI_CESR_RESERVED_14 0xE -#define WCI_CESR_RESERVED_15 0xF -#define WCI_CESR_BUSY_TOO_LONG (-1) /* Software can't read CESR */ - -#define WCI_NUM_LINKS ENTRIES_WCI_SW_LINK_ERROR_COUNT - -/* WCI ECC error handling support */ - -/* this is needed for number of errors */ -#define ECC_MAX_CNT 0xff /* maximum ecc count */ -/* - * PA[42:4] represent the address fields defined in Safari interface. - * In cacheable address space or flush address space, PA[41:38] represents - * the SSM node id - */ -#define SAFARI_ADDR_FIELDS_MASK 0x000007FFFFFFFFF0ULL -#define WCI_ECC_NODE_ID_MASK 0x000003C000000000ULL - -/* - * In wci_dco_state, the following bit fields indentify Agent ID. - * - * mtag_ecc_error_aid <41:35> - * data_ecc_error_aid <34:28> - * - * Agent ID for Mtag/data ecc error encoding is in - * binary, where "nnn" denote instance id used by the agent : - * - * 0000000 = rsrvd - * 0000001 = Csr_Agent - * 0000010 = Modifier_Logic - * 0000011-0010111 = rsrvd - * 0011nnn = Slave_Agent - * 01nnnnn = Request_Agent - * 10nnnnn = Cluster_Agent - * 11nnnnn = Home_Agent - * - */ -#define CSR_AGENT_MASK 0x01 -#define SLAVE_AGENT_MASK 0x18 -#define REQUEST_AGENT_MASK 0x20 -#define CLUSTER_AGENT_MASK 0x40 -#define HOME_AGENT_MASK 0x60 -#define REQ_CLUSTER_MASK 0x60 - -#define CSR_AGENT 1 -#define SLAVE_AGENT 2 -#define REQUEST_AGENT 3 -#define CLUSTER_AGENT 4 -#define HOME_AGENT 5 - -#define ECC_MTAG_UE 1 -#define ECC_MTAG_CE 2 -#define ECC_DATA_UE 3 -#define ECC_DATA_CE 4 - - -/* - * define which agent has what type of ECC error so that - * we can log them explicitely in wci_log_ce_error(). - * - * when calling ce_error(), cheetah has to make a distinction when decoding - * the syndrome of the error: data or mtag. in order to comply with cheetah - * semantics, we set the high bits of the flt_stat field similar to afsr reg: - */ - -#define RA_ECC_MTAG_UE (0x1 | C_AFSR_EMU) -#define RA_ECC_MTAG_CE (0x2 | C_AFSR_EMC) -#define RA_ECC_DATA_UE (0x4 | C_AFSR_UE) -#define RA_ECC_DATA_CE (0x8 | C_AFSR_CE) - -#define HA_ECC_MTAG_UE (0x10 | C_AFSR_EMU) -#define HA_ECC_MTAG_CE (0x20 | C_AFSR_EMC) -#define HA_ECC_DATA_UE (0x40 | C_AFSR_UE) -#define HA_ECC_DATA_CE (0x80 | C_AFSR_CE) - -#define SA_ECC_MTAG_UE (0x100 | C_AFSR_EMU) -#define SA_ECC_MTAG_CE (0x200 | C_AFSR_EMC) -#define SA_ECC_DATA_UE (0x400 | C_AFSR_UE) -#define SA_ECC_DATA_CE (0x800 | C_AFSR_CE) - -#define CA_ECC_MTAG_UE (0x1000 | C_AFSR_EMU) -#define CA_ECC_MTAG_CE (0x2000 | C_AFSR_EMC) -#define CA_ECC_DATA_UE (0x4000 | C_AFSR_UE) -#define CA_ECC_DATA_CE (0x8000 | C_AFSR_CE) - -#define CA_ECC_NOTPASS 0x10000 - -/* - * define which type of SRAM error occured - */ -#define SRAM_ECC_CE_DATA 0x20000 -#define SRAM_ECC_UE_ADDR 0x40000 -#define SRAM_ECC_UE_CAG 0x80000 -#define SRAM_ECC_UE_CSRA 0x100000 -#define SRAM_ECC_UE_RAG 0x200000 -#define SRAM_ECC_UE_SAG 0x400000 -#define SRAM_PARITY_HAG 0x800000 - -/* - * need ECC error status - ecc.status for wci, plan to add in async.h, - * for now, we just add here - */ -#define ECC_WCI 0x80 -#define ECC_WCI_SRAM 0x200 -/* - * register wci_dco_state logs only mtag/data first CE (UE overwrites CE) - * syndrome for all agent types. Thus, except 1st error, all other ECC - * errors don't have a syndrome corresponding with them, thus NO_SYNDROME - * for these NO_SYNDROME ECC errors, even we schedule scrubbing, they can't - * be scrubbed i.e, corrected, because of no syndrome - * - */ -#define NO_SYNDROME ((ushort_t)-1) - -/* - * syndrome can be logged in either part of the wci_dco_state register - * depending on which cacheline it came from - */ -#define WCI_MTAG_SYNDROME(r) \ - (r.bit.mtag_syndrome_0 ? r.bit.mtag_syndrome_0 : r.bit.mtag_syndrome_1) -#define WCI_DATA_SYNDROME(r) \ - (r.bit.data_syndrome_0 ? r.bit.data_syndrome_0 : r.bit.data_syndrome_1) - -#define WCI_CTRCTL_KSTAT_NAMED "pcr" /* "wci_ctr_ctl" */ -#define WCI_CTR0_KSTAT_NAMED "pic0" /* "wci_ctr0" */ -#define WCI_CTR1_KSTAT_NAMED "pic1" /* "wci_ctr1" */ - -#define WCI_NUM_PICS 2 -#define WCI_MISC_NUM_EVENTS 350 /* Max number of events in Misc Counter */ -#define WCI_LINK_NUM_EVENTS 0x13 /* Max number of events in Link Counter */ -#define WCI_LPBK_NUM_EVENTS 0x17 /* Max number of events in Lpbk Counter */ - -#define WCI_SFI_NUM_EVENTS 0xb /* Max # of evts in safari histogram counter */ - - -#define WCI_DURATION_BIT 0x100000 - -#define WCI_PIC0_MASK 0x00000000FFFFFFFFULL /* pic0 bits of %pic */ -#define WCI_PIC0_CTR_CTL_MASK 0x000000000000FFFFULL -#define WCI_PIC1_CTR_CTL_MASK 0x00000000FFFF0000ULL -#define WCI_CLUSTER_MASK 0x00000000000000FFULL - -/* - * used to build array of event-names and pcr-mask values - */ -typedef struct wci_event_mask { - char *event_name; - uint64_t pcr_mask; -} wci_event_mask_t; - - -/* common soft state hook for either wrsm or wssm */ -struct wci_common_soft_state { - int instance; /* device instance */ - int node_id; /* ssm node id */ - uint32_t local_aid; /* safari local agent id */ - volatile unsigned char *wci_regs; /* vaddr of wrsm/wssm base regs */ - /* Mapped addresses of registers */ - volatile uint64_t *wci_misc_ctr_vaddr; - volatile uint64_t *wci_misc_ctr_ctl_vaddr; - volatile uint64_t *wci_cluster_ctr_ctl_vaddr; - volatile uint64_t *wci_link_ctr_vaddr[WCI_NUM_LINKS]; - volatile uint64_t *wci_link_ctr_ctl_vaddr[WCI_NUM_LINKS]; - volatile uint64_t *wci_lpbk_ctr_vaddr; - volatile uint64_t *wci_lpbk_ctr_ctl_vaddr; - volatile uint64_t *wci_sfi_ctr0_mask_vaddr; - volatile uint64_t *wci_sfi_ctr0_match_vaddr; - volatile uint64_t *wci_sfi_ctr0_match_transaction_vaddr; - volatile uint64_t *wci_sfi_ctr1_mask_vaddr; - volatile uint64_t *wci_sfi_ctr1_match_vaddr; - volatile uint64_t *wci_sfi_ctr1_match_transaction_vaddr; - /* performace counters kstat */ - kstat_t *wci_misc_counters_ksp; - kstat_t *wci_lpbk_counters_ksp; - kstat_t *wci_link_counters_ksp[WCI_NUM_LINKS]; - /* wci safari histogramming kstat */ - kstat_t *wci_sfi_counters_ksp; - /* - * wci safari histogramming counter control value. It is a - * software simulation of a hardware counter control register - * to make busstat happy. - */ - uint64_t wci_sfi_sw_ctr_ctl; - - - /* A running SUM of the number of link errors since power-on */ - uint64_t wci_sw_link_error_count_sum[WCI_NUM_LINKS]; - -} wci_common_softstate_t; - - -/* - * Global Function prototypes - */ -void wci_add_counters_kstats(struct wci_common_soft_state *, char *drvname); -void wci_add_picN_kstats(char *drvname); -void wci_del_counters_kstats(struct wci_common_soft_state *); -void wci_del_picN_kstats(); -struct async_flt; -void wci_log_ce_error(struct async_flt *ecc, char *unum); - -/* - * Misc Counter - * Agent Type -- 0: SFI, 1: Cluster Agent, 2: DC, 3: Request Agent, - * 4: Home Agent, 5: Slave Agent, 6: Cache Controller, - * 7: SFQ, 8: HLI, 9: LC - */ -/* SFI Event Control --- agent = 0 */ -/* Safari Event Encoding */ -#define SFI_SFI_HISTOGRAM0 0x000 -#define SFI_SFI_HISTOGRAM1 0x001 -#define SFI_ATRANSID_ALLOC_1 0x002 -#define SFI_ATRANSID_ALLOC_4 0x003 -#define SFI_ATRANSID_ALLOC_8 0x004 -#define SFI_ATRANSID_ALLOC_10 0x005 -#define SFI_ATRANSID_ALLOC_12 0x006 -#define SFI_ATRANSID_DEALLOC 0x007 -#define SFI_TARGID_ALLOC_0 0x008 -#define SFI_TARGID_ALLOC_2 0x009 -#define SFI_TARGID_ALLOC_8 0x00a -#define SFI_TARGID_DEALLOC 0x00b -#define SFI_P0_REQ_VALID 0x00c -#define SFI_P1_REQ_VALID 0x00d -#define SFI_P2_REQ_VALID 0x00e -#define SFI_P3_REQ_VALID 0x00f -#define SFI_P4_REQ_VALID 0x010 -#define SFI_P5_REQ_VALID 0x011 -#define SFI_P6_REQ_VALID 0x012 -#define SFI_P7_REQ_VALID 0x013 -#define SFI_P8_REQ_VALID 0x014 -#define SFI_P9_REQ_VALID 0x015 -#define SFI_P10_REQ_VALID 0x016 -#define SFI_P11_REQ_VALID 0x017 -#define SFI_P12_REQ_VALID 0x018 -#define SFI_P0_GRANT 0x019 -#define SFI_P1_GRANT 0x01a -#define SFI_P2_GRANT 0x01b -#define SFI_P3_GRANT 0x01c -#define SFI_P4_GRANT 0x01d -#define SFI_P5_GRANT 0x01e -#define SFI_P6_GRANT 0x01f -#define SFI_P7_GRANT 0x020 -#define SFI_P8_GRANT 0x021 -#define SFI_P9_GRANT 0x022 -#define SFI_P10_GRANT 0x023 -#define SFI_P11_GRANT 0x024 -#define SFI_P12_GRANT 0x025 -#define SFI_SFI_PULL_REQ 0x026 -#define SFI_SFI_PULL_GRANT 0x027 -/* Safari Durations */ -/* cnt1 */ -#define SFI_ATRANSID_ALLOC_1_DURATION 0x00100800 -#define SFI_ATRANSID_ALLOC_4_DURATION 0x00100c00 -#define SFI_ATRANSID_ALLOC_8_DURATION 0x00101000 -#define SFI_ATRANSID_ALLOC_10_DURATION 0x00101400 -#define SFI_ATRANSID_ALLOC_12_DURATION 0x00101800 -#define SFI_TARGID_ALLOC_0_DURATION 0x00102000 -#define SFI_TARGID_ALLOC_2_DURATION 0x00102400 -#define SFI_TARGID_ALLOC_8_DURATION 0x00102800 -/* cnt 0 */ -#define SFI_ATRANSID_DEALLOC_DURATION 0x00100007 -#define SFI_TARGID_DEALLOC_DURATION 0x0010000b - -/* DC Event Control --- agent = 2 */ -/* DC Event Encoding */ -#define DC_DIF_OUTPUT_VALID 0x080 -#define DC_SFI_DATA_GRANT 0x081 - -/* LC Event Count --- agent = 9 */ -/* LC Event Encoding */ -#define LC_DIF_PUSH 0x240 -#define LC_COM_VALID_LINKS_DIF_FULL 0x241 -#define LC_DATA_PKT_FR_NODE 0x242 -#define LC_SFI_DATA_CANCEL 0x243 - -/* SFQ Event Control --- agent = 7 */ -/* SFQ Event Encoding */ -#define SFQ_PIQ_PUSH 0x1c0 -#define SFQ_PIQ_POP 0x1c1 -#define SFQ_NIQ_PUSH 0x1c2 -#define SFQ_NIQ_POP 0x1c3 -#define SFQ_SIQ_PUSH 0x1c4 -#define SFQ_SIQ_POP 0x1c5 - -/* HLI Event Control --- agent = 8 */ -/* HLI Event Encoding */ -#define HLI_SLQ_PUSH 0x200 -#define HLI_SLQ_POP 0x201 -#define HLI_CHQ_PUSH 0x202 -#define HLI_CHQ_POP 0x203 -#define HLI_PHQ_PUSH 0x204 -#define HLI_PHQ_POP 0x205 - -/* Cacahe Controller Event Control --- agent = 6 */ -/* Cache Control Event Encoding */ -#define CACHECTL_CLUST0 0x180 -#define CACHECTL_CLUST1 0x181 -#define CACHECTL_CLUST_CWR 0x01000000ULL -#define CACHECTL_CLUST_CRD 0x02000000ULL -#define CACHECTL_CLUST_CRD_CWR 0x03000000ULL -#define CACHECTL_CLUST_AT 0x04000000 -#define CACHECTL_CLUST_AT_CWR 0x05000000ULL -#define CACHECTL_CLUST_AT_CRD 0x06000000ULL -#define CACHECTL_CLUST_AT_CRD_CWR 0x07000000ULL -#define CACHECTL_CLUST_INT 0x08000000ULL -#define CACHECTL_CLUST_INT_CWR 0x09000000ULL -#define CACHECTL_CLUST_INT_CRD 0x0a000000ULL -#define CACHECTL_CLUST_INT_CRD_CWR 0x0b000000ULL -#define CACHECTL_CLUST_INT_AT 0x0c000000ULL -#define CACHECTL_CLUST_INT_AT_CWR 0x0d000000ULL -#define CACHECTL_CLUST_INT_AT_CRD 0x0e000000ULL -#define CACHECTL_CLUST_INT_AT_CRD_CWR 0x0f000000ULL -#define CACHECTL_CACHE_CYL_USED 0x182 -#define CACHECTL_LPA2GA_LOOKUP 0x183 -#define CACHECTL_GA2LPA_ACCESS 0x184 -#define CACHECTL_GA2LPA_LOOKUP 0x185 -#define CACHECTL_GA2LPA_MISS 0x186 -#define CACHECTL_DIR_LOOKUP 0x187 -#define CACHECTL_DIR_MISS 0x188 -#define CACHECTL_DIR_WRTBK 0x189 -#define CACHECTL_CMMU_ACCESS 0x18a -#define CACHECTL_CMMU_LOOKUP 0x18b -#define CACHECTL_CSR_LOOKUP 0x18c -#define CACHECTL_CNT_ALWYS 0x18d -#define CACHECTL_HAG_REQ_VALID 0x18e -#define CACHECTL_CIQ_REQ_VALID 0x18f -#define CACHECTL_SLQ_REQ_VALID 0x190 - -/* Cluster Agent Event Control --- agent = 1 */ -/* Cluster Agent Event Encoding */ -#define CLUSTER_AGENT_ALLOC 0x040 -#define CLUSTER_AGENT_RETIRED 0x041 -#define CLUSTER_SFI_GRANT_RD 0x042 -#define CLUSTER_SFI_GRANT_WR 0x043 -#define CLUSTER_PULL_SEEN 0x044 -#define CLUSTER_1DC_RCV_ACK 0x045 -#define CLUSTER_2DC_SND_ACK 0x046 -#define CLUSTER_1_CPI_RCV_ACK 0x047 -#define CLUSTER_2_CPI_RCV_ACK 0x048 -#define CLUSTER_PKT_QUE_ODD 0x049 -#define CLUSTER_PKT_QUE_EVEN 0x04a -#define CLUSTER_PKT_SENT_ODD 0x04b -#define CLUSTER_PKT_SENT_EVEN 0x04c -#define CLUSTER_HLI_REQ_0 0x04d -#define CLUSTER_HLI_REQ_1 0x04e -#define CLUSTER_HLI_REQ_2 0x04f -#define CLUSTER_HLI_REQ_3 0x050 -#define CLUSTER_HLI_REQ_4 0x051 -#define CLUSTER_HLI_REQ_5 0x052 -#define CLUSTER_HLI_GRANT_0 0x053 -#define CLUSTER_HLI_GRANT_1 0x054 -#define CLUSTER_HLI_GRANT_2 0x055 -#define CLUSTER_HLI_GRANT_3 0x056 -#define CLUSTER_HLI_GRANT_4 0x057 -#define CLUSTER_HLI_GRANT_5 0x058 -/* Cluster Agent Durations */ -/* cnt1 */ -#define CLUSTER_AGENT_ALLOC_DURATION 0x00110000 -#define CLUSTER_SFI_GRANT_RD_DURATION 0x00110800 -#define CLUSTER_SFI_GRANT_WR_DURATION 0x00110c00 -#define CLUSTER_1DC_RCV_ACK_CNT1_DURATION 0x00111400 -#define CLUSTER_PKT_QUE_ODD_DURATION 0x00112400 -#define CLUSTER_PKT_QUE_EVEN_DURATION 0x00112800 -#define CLUSTER_HLI_GRANT_0_DURATION 0x00114c00 -#define CLUSTER_HLI_GRANT_1_DURATION 0x00115000 -#define CLUSTER_HLI_GRANT_2_DURATION 0x00115400 -#define CLUSTER_HLI_GRANT_3_DURATION 0x00115800 -#define CLUSTER_HLI_GRANT_4_DURATION 0x00115c00 -#define CLUSTER_HLI_GRANT_5_DURATION 0x00116000 -#define CLUSTER_1_CPI_RCV_ACK_CNT1_DURATION 0x00111c00 -/* cnt0 */ -#define CLUSTER_AGENT_RETIRED_DURATION 0x00100041 -#define CLUSTER_PULL_SEEN_DURATION 0x00100044 -#define CLUSTER_1DC_RCV_ACK_CNT0_DURATION 0x00100045 -#define CLUSTER_2DC_SND_ACK_DURATION 0x00100046 -#define CLUSTER_PKT_SENT_ODD_DURATION 0x0010004b -#define CLUSTER_PKT_SENT_EVEN_DURATION 0x0010004c -#define CLUSTER_1_CPI_RCV_ACK_CNT0_DURATION 0x00100047 -#define CLUSTER_2_CPI_RCV_ACK_DURATION 0x00100048 - - -/* Request Agent Event Control --- agent = 3 */ -/* Request Agent Event Encoding */ -#define REQ_AGENT_ALLOC 0x0c0 -#define REQ_AGENT_RETIRED 0x0c1 -#define REQ_SFI_GRANT_P2 0x0c2 -#define REQ_1DC_RCV_ACK 0x0c3 -#define REQ_2DC_SND_ACK 0x0c4 -#define REQ_1_CPI_RCV_ACK 0x0c5 -#define REQ_2_CPI_RCV_ACK 0x0c6 -#define REQ_PKT_QUE 0x0c7 -#define REQ_PKT_SENT 0x0c8 -#define REQ_PKT_SENT_CLUST_RD 0x0c9 -#define REQ_PKT_SENT_CLUST_WR 0x0ca -#define REQ_HLI_REQ_0 0x0cb -#define REQ_HLI_REQ_1 0x0cc -#define REQ_HLI_REQ_2 0x0cd -#define REQ_HLI_REQ_3 0x0ce -#define REQ_HLI_REQ_4 0x0cf -#define REQ_HLI_REQ_5 0x0d0 -#define REQ_HLI_GRANT_0 0x0d1 -#define REQ_HLI_GRANT_1 0x0d2 -#define REQ_HLI_GRANT_2 0x0d3 -#define REQ_HLI_GRANT_3 0x0d4 -#define REQ_HLI_GRANT_4 0x0d5 -#define REQ_HLI_GRANT_5 0x0d6 -#define REQ_LAST_REPLY_RCVD 0x0d7 -#define REQ_SENT_CLUST_RD 0x0d8 -#define REQ_SENT_CLUST_WR 0x0d9 -#define REQ_PIQ_VALID 0x0da -#define REQ_PIQ_DISPATCH 0x0db -#define REQ_CIQ_VALID 0x0dc -#define REQ_CIQ_DISPATCH 0x0dd -#define REQ_NIQ_VALID 0x0de -#define REQ_NIQ_DISPATCH 0x0df -#define REQ_NUMA_BYPASS_DISPATCH 0x0e0 -/* Request Agent Durations */ -/* cnt 1 */ -#define REQ_AGNT_ALLOC_DURATION 0x00130000 -#define REQ_SFI_GRANT_P2_DURATION 0x00130800 -#define REQ_1DC_RCV_ACK_CNT1_DURATION 0x00130c00 -#define REQ_PKT_SENT_CLUST_RD_DURATION 0x00132400 -#define REQ_1_CPI_RCV_ACK_CNT1_DURATION 0x00131400 -#define REQ_PKT_QUE_DURATION 0x00131c00 -#define REQ_PKT_SENT_CNT1_DURATION 0x00132000 -/* cnt 0 */ -#define REQ_AGNT_RETIRED_DURATION 0x001000c1 -#define REQ_1DC_RCV_ACK_CNT0_DURATION 0x001000c3 -#define REQ_2DC_SND_ACK_DURATION 0x001000c4 -#define REQ_1_CPI_RCV_ACK_CNT0_DURATION 0x001000c5 -#define REQ_2_CPI_RCV_ACK_DURATION 0x001000c6 -#define REQ_PKT_SENT_CNT0_DURATION 0x001000c8 -#define REQ_LAST_REPLY_RCVD_DURATION 0x001000d7 - - -/* Home Agent Event Control --- agent = 4 */ -/* Home Agent Event Encoding */ -#define HOME_AGENT_ALLOC 0x100 -#define HOME_AGENT_RETIRED 0x101 -#define HOME_SFI_P8_RD_AUX 0x102 -#define HOME_SFI_P8_RD_MAIN 0x103 -#define HOME_SFI_P8_WR 0x104 -#define HOME_SFI_P9_WR 0x105 -#define HOME_SFI_P10_WR 0x106 -#define HOME_1DC_RCV_ACK_AUX 0x107 -#define HOME_1DC_RCV_ACK_MAIN 0x108 -#define HOME_2DC_SND_ACK 0x109 -#define HOME_SFI_PULL_SEEN 0x10a -#define HOME_LAST_DEMREP_SENT 0x10b -#define HOME_COMP_PKT_SEEN 0x10c -#define HOME_HLI_REQ_LINK_0_A 0x10d -#define HOME_HLI_REQ_LINK_0_B 0x10e -#define HOME_HLI_REQ_LINK_1_A 0x10f -#define HOME_HLI_REQ_LINK_1_B 0x110 -#define HOME_HLI_REQ_LINK_2_A 0x111 -#define HOME_HLI_REQ_LINK_2_B 0x112 -#define HOME_HLI_REQ_LINK_3_A 0x113 -#define HOME_HLI_REQ_LINK_3_B 0x114 -#define HOME_HLI_REQ_LINK_4_A 0x115 -#define HOME_HLI_REQ_LINK_4_B 0x116 -#define HOME_HLI_REQ_LINK_5_A 0x117 -#define HOME_HLI_REQ_LINK_5_B 0x118 -#define HOME_HLI_GRANT_LINK_0_A 0x119 -#define HOME_HLI_GRANT_LINK_0_B 0x11a -#define HOME_HLI_GRANT_LINK_1_A 0x11b -#define HOME_HLI_GRANT_LINK_1_B 0x11c -#define HOME_HLI_GRANT_LINK_2_A 0x11d -#define HOME_HLI_GRANT_LINK_2_B 0x11e -#define HOME_HLI_GRANT_LINK_3_A 0x11f -#define HOME_HLI_GRANT_LINK_3_B 0x120 -#define HOME_HLI_GRANT_LINK_4_A 0x121 -#define HOME_HLI_GRANT_LINK_4_B 0x122 -#define HOME_HLI_GRANT_LINK_5_A 0x123 -#define HOME_HLI_GRANT_LINK_5_B 0x124 -#define HOME_BLK_CAM_HIT 0x125 -#define HOME_DIR_RTNED_BEFORE_RD_GRANT 0x126 -#define HOME_DIR_RTNED_BEFORE_RD_ORDER 0x127 -#define HOME_DIR_RTNED_BEFORE_RD_DATA 0x128 -#define HOME_DIR_RTNED_AFTER_RD_DATA 0x129 -#define HOME_REQ_HOME 0x12a -#define HOME_REQ_SAME_BOX 0x12b -#define HOME_REF_DATA_BACK_HOME 0x12c -#define HOME_DIR_MISS_ALLOC 0x12d -#define HOME_DIR_HIT_GI 0x12e -#define HOME_DIR_HIT_GS 0x12f -#define HOME_DIR_HIT_GM 0x130 -#define HOME_DIR_HIT_RTO_GM 0x131 -#define HOME_DIR_HIT_RTS_GMS 0x132 -#define HOME_DIR_MISS_RTS_GI 0x133 -#define HOME_DIR_MISS_RTS 0x134 -#define HOME_DIR_MISS_RTO_GS_GI 0x135 -#define HOME_DIR_MISS_RTO 0x136 -/* Home Agent Metrics, Durations Mode */ -/* cnt 1 */ -#define HOME_AGENT_ALLOC_DURATION 0x00140000 -#define HOME_SFI_P8_RD_AUX_DURATION 0x00140800 -#define HOME_SFI_P8_RD_MAIN_DURATION 0x00140c00 -#define HOME_1DC_RCV_ACK_AUX_CNT1_DURATION 0x00141c00 -#define HOME_1DC_RCV_ACK_MAIN_CNT1_DURATION 0x00142000 -#define HOME_SFI_P8_WR_DURATION 0x00141000 -#define HOME_SFI_P9_WR_DURATION 0x00141400 -#define HOME_SFI_P10_WR_DURATION 0x00141800 -#define HOME_LAST_DEMREP_SENT_DURATION 0x00142c00 -/* cnt 0 */ -#define HOME_AGENT_RETIRED_DURATION 0x00100101 -#define HOME_1DC_RCV_ACK_AUX_CNT0_DURATION 0x00100107 -#define HOME_1DC_RCV_ACK_MAIN_CNT0_DURATION 0x00100108 -#define HOME_2DC_SND_ACK_DURATION 0x00100109 -#define HOME_SFI_PULL_SEEN_DURATION 0x0010010a -#define HOME_COMP_PKT_SEEN_DURATION 0x0010010c - - -/* Slave Agent Event Control --- agent = 5 */ -#define SLAVE_AGENT_ALLOC 0x140 -#define SLAVE_AGENT_ALLOC_LPA 0x141 -#define SLAVE_AGENT_ALLOC_GA 0x142 -#define SLAVE_AGENT_ALLOC_H_LPA 0x143 -#define SLAVE_AGENT_ALLOC_H_GA 0x144 -#define SLAVE_AGENT_ALLOC_H_MLPA 0x145 -#define SLAVE_AGENT_ALLOC_H_MGA 0x146 -#define SLAVE_AGENT_ALLOC_H_M 0x147 -#define SLAVE_AGENT_ALLOC_H_INV_LPA 0x148 -#define SLAVE_AGENT_ALLOC_H_INV_GA 0x149 -#define SLAVE_AGENT_RETIRED 0x14a -#define SLAVE_REPLY_SENT 0x14b -#define SLAVE_SFI_P6_GRANT_WR 0x14c -#define SLAVE_SFI_P12GT_RLPA 0x14d -#define SLAVE_SFI_P12GT_RGA 0x14e -#define SLAVE_SFI_P12GT_RHLPA 0x14f -#define SLAVE_SFI_P12GT_RHGA 0x150 -#define SLAVE_SFI_P12GT_RHMLPA 0x151 -#define SLAVE_SFI_P12GT_RHMGA 0x152 -#define SLAVE_SFI_P12GT_WR 0x153 -#define SLAVE_1DC_RCV_ACK 0x154 -#define SLAVE_2DC_SND_ACK 0x155 -#define SLAVE_2DC_SND_ACK_REFL 0x156 -#define SLAVE_4DC_SND_ACK 0x157 -#define SLAVE_PULL_SEEN 0x158 -#define SLAVE_H_M_GA_NOT_OWND 0x159 -#define SLAVE_H_M_NO_STATE_CHANGE 0x15a -#define SLAVE_HLI_REQ_0 0x15b -#define SLAVE_HLI_REQ_1 0x15c -#define SLAVE_HLI_REQ_2 0x15d -#define SLAVE_HLI_REQ_3 0x15e -#define SLAVE_HLI_REQ_4 0x15f -#define SLAVE_HLI_REQ_5 0x160 -#define SLAVE_HLI_GRANT_0 0x161 -#define SLAVE_HLI_GRANT_1 0x162 -#define SLAVE_HLI_GRANT_2 0x163 -#define SLAVE_HLI_GRANT_3 0x164 -#define SLAVE_HLI_GRANT_4 0x165 -#define SLAVE_HLI_GRANT_5 0x166 -/* Slave Agent Durations */ -/* cnt 1 (pic1) */ -#define SLAVE_AGENT_ALLOC_DURATION 0x00150000 -#define SLAVE_SFI_P12GT_RLPA_DURATION 0x00153400 -#define SLAVE_SFI_P12GT_RGA_DURATION 0x00153800 -#define SLAVE_SFI_P12GT_RHLPA_DURATION 0x00153c00 -#define SLAVE_SFI_P12GT_RHGA_DURATION 0x00154000 -#define SLAVE_SFI_P12GT_RHMLPA_DURATION 0x00154400 -#define SLAVE_SFI_P12GT_RHMGA_DURATION 0x00154800 -#define SLAVE_1DC_RCV_ACK_CNT1_DURATION 0x00155000 -#define SLAVE_SFI_P6_GRANT_WR_DURATION 0x00153000 -#define SLAVE_SFI_P12GT_WR_DURATION 0x00154c00 -#define SLAVE_AGENT_ALLOC_LPA_DURATION 0x00150400 -#define SLAVE_AGENT_ALLOC_GA_DURATION 0x00150800 -#define SLAVE_AGENT_ALLOC_H_LPA_DURATION 0x00150c00 -#define SLAVE_AGENT_ALLOC_H_GA_DURATION 0x00151000 -#define SLAVE_AGENT_ALLOC_H_MLPA_DURATION 0x00151400 -#define SLAVE_AGENT_ALLOC_H_MGA_DURATION 0x00151800 -#define SLAVE_AGENT_ALLOC_H_M_DURATION 0x00151c00 -#define SLAVE_AGENT_ALLOC_H_INV_LPA_DURATION 0x00152000 -#define SLAVE_AGENT_ALLOC_H_INV_GA_DURATION 0x00152400 -#define SLAVE_2DC_SND_ACK_REFL_DURATION 0x00155800 -/* cnt 0 (pic0) */ -#define SLAVE_AGENT_RETIRED_DURATION 0x0010014a -#define SLAVE_1DC_RCV_ACK_CNT0_DURATION 0x00100154 -#define SLAVE_2DC_SND_ACK_DURATION 0x00100155 -#define SLAVE_PULL_SEEN_DURATION 0x00100158 -#define SLAVE_REPLY_SENT_DURATION 0x0010014b -#define SLAVE_4DC_SND_ACK_DURATION 0x00100157 - -/* Misc counter pic0 clear mask */ -#define MISC_CLEAR_PIC0 ~(0x0f1003ffULL) -/* Misc counter pic1 clear mask */ -#define MISC_CLEAR_PIC1 ~(0xf01ffc00ULL) - - - -/* Link Counter */ -#define LINK_SENDING_ADMIN_PKTS 0x01 -#define LINK_RCVD_MH_DATA_PKT 0x02 -#define LINK_RMHDP_SADM 0x03 -#define LINK_RCVD_DATA_PKT 0x04 -#define LINK_RDP_SADM 0x05 -#define LINK_RDP_RMHDP 0x06 -#define LINK_REJECTED_FLIT 0x08 -#define LINK_REJFLIT_SADM 0x09 -#define LINK_REJFLIT_RMHDP 0x0a -#define LINK_REJFLIT_RMHDP_SADM 0x0b -#define LINK_REJFLIT_RDP 0x0c -#define LINK_REJFLIT_RDP_SADM 0x0d -#define LINK_RCVD_ADMIN_PKT 0x10 -#define LINK_RADMP_SADM 0x11 -#define LINK_RADMP_RMHDP 0x12 -#define LINK_RADMP_RMHDP_SADM 0x13 -#define LINK_RADMP_RDP 0x14 -#define LINK_RADMP_RDP_SADM 0x15 -#define LINK_RADMP_REJFLIT 0x18 -#define LINK_CLEAR_PIC0 ~(0x7fffULL) -#define LINK_CLEAR_PIC1 ~(0x7fffULL << 16) - -/* Loopback Counter */ -#define LPBK_RCVD_DATA_PKT 0x01 -#define LPBK_RCVD_ADDR_2_PKT 0x02 -#define LPBK_RADDR2_RDATA 0x03 -#define LPBK_RCVD_ADDR_1_PKT 0x04 -#define LPBK_RADDR1_RDATA 0x05 -#define LPBK_DATA_LPBK_FULL 0x08 -#define LPBK_DFULL_RDATA 0x09 -#define LPBK_DFULL_RADDR2 0x0a -#define LPBK_DFULL_RADDR2_RDATA 0x0b -#define LPBK_DFULL_RADDR1 0x0c -#define LPBK_DFULL_RADDR1_RDATA 0x0d -#define LPBK_ADDR_LPBK_FULL 0x10 -#define LPBK_AFULL_RDATA 0x11 -#define LPBK_AFULL_RADDR2 0x12 -#define LPBK_AFULL_RADDR2_RDATA 0x13 -#define LPBK_AFULL_RADDR1 0x14 -#define LPBK_AFULL_RADDR1_RDATA 0x15 -#define LPBK_AFULL_DFULL 0x18 -#define LPBK_AFULL_DFULL_RDATA 0x19 -#define LPBK_AFULL_DFULL_RADDR2 0x1a -#define LPBK_AFULL_DFULL_RADDR2_RDATA 0x1b -#define LPBK_AFULL_DFULL_RADDR1 0x1c -#define LPBK_AFULL_DFULL_RADDR1_RDATA 0x1d -#define LPBK_CLEAR_PIC0 ~(0x3ffULL) -#define LPBK_CLEAR_PIC1 ~(0x3ffULL << 16) - - -/* - * WCI Safari Histogramming Counter - * - * NOTE : wci_sfi_sw_ctr_ctl is not a real WCI HW register. It is created - * and manipulated by kernel software to facilitate busstat requiremnets. - * Unlike wci_misc, wci_link & wci_lpbk performance counters, wci_sfi - * histogramming Counter is not a real busstat-style performance counter. - * What we do here is a SW hack to add wci_sfi histogramming Counter support - * into busstat, as requested by Wildcat perfomance group people. - * - * Bits of wci_sfi_sw_ctr_ctl. - * - * +--------------+--------------+--------------------+--------------------+ - * | sfi_hstgrm 1 | sfi_hstgrm 0 | misc_ctr_ctl cnt1 | misc_ctr_ctl cnt0 | - * +--------------+--------------+--------------------+--------------------+ - * 27 24 23 20 19 10 9 0 - * - * - * When user select WCI Safari Histogramming Counter pic0 through busstat, - * the corresponding wci_misc_ctr_ctl <9:0> should be set to : - * wci_misc_ctr_ctl.cnt0_agent_select = 0 - * wci_misc_ctr_ctl.cnt0_event_select = 0 (safari histogram 0) - * the counter value should be read out from wci_misc_ctr.count0. - * - * When user select WCI Safari Histogramming Counter pic1 through busstat, - * the corresponding wci_misc_ctr_ctl <19:10> should be set to : - * wci_misc_ctr_ctl.cnt1_agent_select = 0 - * wci_misc_ctr_ctl.cnt1_event_select = 1 (safari histogram 1) - * the counter value should be read out from wci_misc_ctr.count1. - * - * Note: The event encoding values of Bit <23:20> of wci_sfi_sw_str_ctl - * should start from 1 instead of 0 to avoid the confusion. When user - * selects Safari Histogram Counter pic0, the corresponding misc_ctr_ctl - * register bits <9:0>is 0, as it represents agent 0, event 0. If - * wci_sfi_sw_ctr_ctl bit<23:20> encoding starts from 0, then both - * wci_sfi_sw_ctr_ctl bits <23:20> & <9:0> are all set to 0. This could - * be mis-understood as NO Event Selected. It is also inconvenient for us to - * determine whether a pic counter is selected or not. - * - * WCI Safari Histogramming Counter Event Mask Encoding : - * - */ -#define SFI_HSTGRM_ALL_TRANS 0x00100000ULL -#define SFI_HSTGRM_INT 0x00200000ULL -#define SFI_HSTGRM_LOCAL_INT 0x00300000ULL -#define SFI_HSTGRM_RMT_CLU_INCM_INT 0x00400000ULL -#define SFI_HSTGRM_RMT_SSM_INCM_INT 0x00500000ULL -#define SFI_HSTGRM_IO 0x00600000ULL -#define SFI_HSTGRM_RMT_SSM_INCM_IO 0x00700000ULL -#define SFI_HSTGRM_COHRNT 0x00800000ULL -#define SFI_HSTGRM_RMT_CLU_INCM_COHRNT 0x00900000ULL -#define SFI_HSTGRM_RMT_SSM_OTG_COHRNT 0x00a00000ULL -#define SFI_HSTGRM_RMT_SSM_INCM_COHRNT 0x00b00000ULL -/* WCI Safari Histogramming Counter pic0 clear mask */ -#define WCI_SFI_CLEAR_PIC0 ~(0x00f003ffULL) -/* WCI Safari Histogramming Counter pic1 clear mask */ -#define WCI_SFI_CLEAR_PIC1 ~(0x0f0ffc00ULL) - -/* - * The following mask is used to obtain wci_misc_ctr_ctl bits <19:0> - * and is also used to mask the wci_sfi_sw_ctr_ctl bits <19:0> by - * complementing the same mask. - */ -#define WCI_SFI_SW_CTR_CTL_MASK 0x000FFFFFULL -#define WCI_SFI_CTR0_EVENT_SHIFT 20 -#define WCI_SFI_CTR1_EVENT_SHIFT 24 -#define WCI_SFI_CTR0_EVENT_MASK 0x00F00000ULL -#define WCI_SFI_CTR1_EVENT_MASK 0x0F000000ULL -/* - * wci_sfi_ctr0/1_mask, wci_sfi_ctr0/1_match bits - * - * E.g., For interrupt transaction type, - * - * Address Field <42:4> definition <----> Address Field <38:0> definition - * INT : <38:29> sender <34:25> sender - * <23:14> target <19:10> target - * - * 57 48 47 atransid 39 38 address 0 - * +------+-------+--------+------+------+------+------+------+------+--------+ - * | mask | devID | Seq.ID | | SNID | SAID | | TNID | TAID | | - * +------+-------+--------+------+------+------+------+------+------+--------+ - * 57 48 47 43 42 39 38 35 34 30 29 25 24 20 19 15 14 10 9 0 - * - */ -#define WCI_SFI_ADDR_TNID_SHIFT 15 -#define WCI_SFI_ATRANS_DEVID_SHIFT 43 - -/* - * The following structure is used to define register wci_sfi_ctr#_mask, - * wci_sfi_ctr#_match and wci_sfi_ctr#_match_transaction settings - * for wci safari histogramming counters. - */ - typedef struct wci_sfi_regs_value { - uint64_t wci_sfi_ctr_mask_val; - uint64_t wci_sfi_ctr_match_val; - uint64_t wci_sfi_ctr_match_trans_val; - } wci_sfi_regs_value_t; - -/* - * kstat structures used by wci to pass data to user programs. - * wci_misc_counters_kstat - Misc counters (busstat support) - * - */ - - struct wci_counters_kstat { - kstat_named_t wci_ctr_ctl; /* ctr ctl reg */ - kstat_named_t wci_ctr0; /* ctr0 reg */ - kstat_named_t wci_ctr1; /* ctr1 reg */ - }; - - -#ifdef __cplusplus -} -#endif - -#endif /* _WCI_COMMON_H */ diff --git a/usr/src/uts/sun4u/sys/wci_masks.h b/usr/src/uts/sun4u/sys/wci_masks.h deleted file mode 100644 index e78c059ecc..0000000000 --- a/usr/src/uts/sun4u/sys/wci_masks.h +++ /dev/null @@ -1,1988 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_WCI_MASKS_H -#define _SYS_WCI_MASKS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This file was automatically generated from wci_regs.h - * Each macro is of the form MASK_<register name>_<field name>. - * The definitions are mask-high-word, mask-low-word, shift. - */ - -#define MASK_WCI_BOARD2CNID_ARRAY_RSVD_Z 0xffffffff, 0xffffff00, 8 -#define MASK_WCI_BOARD2CNID_ARRAY_DATA 0x0, 0xff, 0 -#define MASK_WCI_BOARD2CNID_CONTROL_RSVD_Z 0xffffffff, 0xfffffffe, 1 -#define MASK_WCI_BOARD2CNID_CONTROL_BOARD2CNID_ENABLE 0x0, 0x1, 0 -#define MASK_WCI_CA_BUSY_RSVD_Z 0xffffffff, 0x0, 32 -#define MASK_WCI_CA_BUSY_VECTOR 0x0, 0xffffffff, 0 -#define MASK_WCI_CA_CONFIG_RSVD_Z 0xffffffff, 0xffffffc0, 6 -#define MASK_WCI_CA_CONFIG_CLUSTER_DISABLE 0x0, 0x20, 5 -#define MASK_WCI_CA_CONFIG_REUSE_TIMEOUT_LIMIT 0x0, 0x1f, 0 -#define MASK_WCI_CA_ECC_ADDRESS_DATA 0x80000000, 0x0, 63 -#define MASK_WCI_CA_ECC_ADDRESS_UE 0x40000000, 0x0, 62 -#define MASK_WCI_CA_ECC_ADDRESS_PASSTHRU 0x20000000, 0x0, 61 -#define MASK_WCI_CA_ECC_ADDRESS_RSVD_Z 0x1fffffe0, 0x0, 37 -#define MASK_WCI_CA_ECC_ADDRESS_ADDR 0x1f, 0xffffffff, 0 -#define MASK_WCI_CA_ERROR_TRANSACTION_STATUS 0xf0000000, 0x0, 60 -#define MASK_WCI_CA_ERROR_TRANSACTION_ESR_REG 0x8000000, 0x0, 59 -#define MASK_WCI_CA_ERROR_TRANSACTION_ESR_INDEX 0x7800000, 0x0, 55 -#define MASK_WCI_CA_ERROR_TRANSACTION_CTID 0x7c0000, 0x0, 50 -#define MASK_WCI_CA_ERROR_TRANSACTION_TARGID 0x3fe00, 0x0, 41 -#define MASK_WCI_CA_ERROR_TRANSACTION_SECOND_ATRANSID 0x1e0, 0x0, 37 -#define MASK_WCI_CA_ERROR_TRANSACTION_FIRST_ATRANSID 0x1e, 0x0, 33 -#define MASK_WCI_CA_ERROR_TRANSACTION_CMD_GRANT_1 0x1, 0x0, 32 -#define MASK_WCI_CA_ERROR_TRANSACTION_CMD_GRANT_2 0x0, 0x80000000, 31 -#define MASK_WCI_CA_ERROR_TRANSACTION_REISSUE_PENDING_1 0x0, 0x40000000, 30 -#define MASK_WCI_CA_ERROR_TRANSACTION_REISSUE_PENDING_2 0x0, 0x20000000, 29 -#define MASK_WCI_CA_ERROR_TRANSACTION_TRANSID_RELEASED 0x0, 0x10000000, 28 -#define MASK_WCI_CA_ERROR_TRANSACTION_CONST_GRANT 0x0, 0x8000000, 27 -#define MASK_WCI_CA_ERROR_TRANSACTION_MAP_GRANT 0x0, 0x4000000, 26 -#define MASK_WCI_CA_ERROR_TRANSACTION_MAP_QUEUED 0x0, 0x2000000, 25 -#define MASK_WCI_CA_ERROR_TRANSACTION_REUSE_TIMEOUT 0x0, 0x1000000, 24 -#define MASK_WCI_CA_ERROR_TRANSACTION_DATA_TIMEOUT 0x0, 0x800000, 23 -#define MASK_WCI_CA_ERROR_TRANSACTION_APHASE_TIMEOUT 0x0, 0x400000, 22 -#define MASK_WCI_CA_ERROR_TRANSACTION_PKT_SENT 0x0, 0x200000, 21 -#define MASK_WCI_CA_ERROR_TRANSACTION_PKT_QUEUED 0x0, 0x100000, 20 -#define MASK_WCI_CA_ERROR_TRANSACTION_CPI_INVAL 0x0, 0x80000, 19 -#define MASK_WCI_CA_ERROR_TRANSACTION_CPI_QUEUED 0x0, 0x40000, 18 -#define MASK_WCI_CA_ERROR_TRANSACTION_CPI_ERR 0x0, 0x20000, 17 -#define MASK_WCI_CA_ERROR_TRANSACTION_CPI_RCV2 0x0, 0x10000, 16 -#define MASK_WCI_CA_ERROR_TRANSACTION_CPI_RCV1 0x0, 0x8000, 15 -#define MASK_WCI_CA_ERROR_TRANSACTION_DC_ATOM_ERR 0x0, 0x4000, 14 -#define MASK_WCI_CA_ERROR_TRANSACTION_DC_SND2 0x0, 0x2000, 13 -#define MASK_WCI_CA_ERROR_TRANSACTION_DC_RCV2 0x0, 0x1000, 12 -#define MASK_WCI_CA_ERROR_TRANSACTION_DC_ERR1 0x0, 0x800, 11 -#define MASK_WCI_CA_ERROR_TRANSACTION_PULL_LATE 0x0, 0x400, 10 -#define MASK_WCI_CA_ERROR_TRANSACTION_PULL_TIMEOUT 0x0, 0x200, 9 -#define MASK_WCI_CA_ERROR_TRANSACTION_PULL_CLEARED 0x0, 0x100, 8 -#define MASK_WCI_CA_ERROR_TRANSACTION_PULL_ERR 0x0, 0x80, 7 -#define MASK_WCI_CA_ERROR_TRANSACTION_PULL_OK 0x0, 0x40, 6 -#define MASK_WCI_CA_ERROR_TRANSACTION_SNOOP_LATE 0x0, 0x20, 5 -#define MASK_WCI_CA_ERROR_TRANSACTION_SNOOP2 0x0, 0x18, 3 -#define MASK_WCI_CA_ERROR_TRANSACTION_SNOOP1 0x0, 0x7, 0 -#define MASK_WCI_CA_ERROR_TRANSACTION_2_RSVD_Z 0xffffffff, 0xfffffff0, 4 -#define MASK_WCI_CA_ERROR_TRANSACTION_2_SNOOP2_LATE_REISSUE 0x0, 0x8, 3 -#define MASK_WCI_CA_ERROR_TRANSACTION_2_DC_RCV2_BARRIER 0x0, 0x4, 2 -#define MASK_WCI_CA_ERROR_TRANSACTION_2_CPI_BARRIER 0x0, 0x2, 1 -#define MASK_WCI_CA_ERROR_TRANSACTION_2_CPI_RCV2_BARRIER 0x0, 0x1, 0 -#define MASK_WCI_CA_ESR_0_RSVD_Z 0xffffffff, 0x80000000, 31 -#define MASK_WCI_CA_ESR_0_ACC_UNEXPECT_CPI_ACK 0x0, 0x40000000, 30 -#define MASK_WCI_CA_ESR_0_ACC_UNEXPECT_DC_ACK 0x0, 0x20000000, 29 -#define MASK_WCI_CA_ESR_0_ACC_UNEXPECT_PULL 0x0, 0x10000000, 28 -#define MASK_WCI_CA_ESR_0_ACC_UNEXPECT_REISSUE 0x0, 0x8000000, 27 -#define MASK_WCI_CA_ESR_0_ACC_ATOMIC_MAP_MISMATCH 0x0, 0x4000000, 26 -#define MASK_WCI_CA_ESR_0_ACC_UNMAPPED 0x0, 0x2000000, 25 -#define MASK_WCI_CA_ESR_0_ACC_UNCORRECTABLE_MTAG_ERROR 0x0, 0x1000000, 24 -#define MASK_WCI_CA_ESR_0_ACC_UNCORRECTABLE_DATA_ERROR 0x0, 0x800000, 23 -#define MASK_WCI_CA_ESR_0_ACC_CORRECTABLE_MTAG_ERROR 0x0, 0x400000, 22 -#define MASK_WCI_CA_ESR_0_ACC_CORRECTABLE_DATA_ERROR 0x0, 0x200000, 21 -#define MASK_WCI_CA_ESR_0_ACC_DSTAT_INCONSISTENT 0x0, 0x100000, 20 -#define MASK_WCI_CA_ESR_0_ACC_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x80000, 19 -#define MASK_WCI_CA_ESR_0_ACC_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x40000, 18 -#define MASK_WCI_CA_ESR_0_ACC_REMOTE_TIMEOUT 0x0, 0x20000, 17 -#define MASK_WCI_CA_ESR_0_ACC_LOCAL_TIMEOUT 0x0, 0x10000, 16 -#define MASK_WCI_CA_ESR_0_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_CA_ESR_0_UNEXPECT_CPI_ACK 0x0, 0x4000, 14 -#define MASK_WCI_CA_ESR_0_UNEXPECT_DC_ACK 0x0, 0x2000, 13 -#define MASK_WCI_CA_ESR_0_UNEXPECT_PULL 0x0, 0x1000, 12 -#define MASK_WCI_CA_ESR_0_UNEXPECT_REISSUE 0x0, 0x800, 11 -#define MASK_WCI_CA_ESR_0_ATOMIC_MAP_MISMATCH 0x0, 0x400, 10 -#define MASK_WCI_CA_ESR_0_UNMAPPED 0x0, 0x200, 9 -#define MASK_WCI_CA_ESR_0_UNCORRECTABLE_MTAG_ERROR 0x0, 0x100, 8 -#define MASK_WCI_CA_ESR_0_UNCORRECTABLE_DATA_ERROR 0x0, 0x80, 7 -#define MASK_WCI_CA_ESR_0_CORRECTABLE_MTAG_ERROR 0x0, 0x40, 6 -#define MASK_WCI_CA_ESR_0_CORRECTABLE_DATA_ERROR 0x0, 0x20, 5 -#define MASK_WCI_CA_ESR_0_DSTAT_INCONSISTENT 0x0, 0x10, 4 -#define MASK_WCI_CA_ESR_0_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x8, 3 -#define MASK_WCI_CA_ESR_0_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x4, 2 -#define MASK_WCI_CA_ESR_0_REMOTE_TIMEOUT 0x0, 0x2, 1 -#define MASK_WCI_CA_ESR_0_LOCAL_TIMEOUT 0x0, 0x1, 0 -#define MASK_WCI_CA_ESR_1_RSVD_Z 0xffffffff, 0xffe00000, 21 -#define MASK_WCI_CA_ESR_1_ACC_QLIMIT_TIMEOUT 0x0, 0x100000, 20 -#define MASK_WCI_CA_ESR_1_ACC_INTERNAL_ERROR 0x0, 0x80000, 19 -#define MASK_WCI_CA_ESR_1_ACC_CMMU_ECC_ERROR 0x0, 0x40000, 18 -#define MASK_WCI_CA_ESR_1_ACC_WRONG_CMD 0x0, 0x20000, 17 -#define MASK_WCI_CA_ESR_1_ACC_DATA_PHASE_TIMEOUT 0x0, 0x10000, 16 -#define MASK_WCI_CA_ESR_1_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_CA_ESR_1_RSVD_Y 0x0, 0x7fe0, 5 -#define MASK_WCI_CA_ESR_1_QLIMIT_TIMEOUT 0x0, 0x10, 4 -#define MASK_WCI_CA_ESR_1_INTERNAL_ERROR 0x0, 0x8, 3 -#define MASK_WCI_CA_ESR_1_CMMU_ECC_ERROR 0x0, 0x4, 2 -#define MASK_WCI_CA_ESR_1_WRONG_CMD 0x0, 0x2, 1 -#define MASK_WCI_CA_ESR_1_DATA_PHASE_TIMEOUT 0x0, 0x1, 0 -#define MASK_WCI_CA_ESR_MASK_RSVD_Z 0xffffffff, 0xffe00000, 21 -#define MASK_WCI_CA_ESR_MASK_QLIMIT_TIMEOUT 0x0, 0x100000, 20 -#define MASK_WCI_CA_ESR_MASK_INTERNAL_ERROR 0x0, 0x80000, 19 -#define MASK_WCI_CA_ESR_MASK_CMMU_ECC_ERROR 0x0, 0x40000, 18 -#define MASK_WCI_CA_ESR_MASK_WRONG_CMD 0x0, 0x20000, 17 -#define MASK_WCI_CA_ESR_MASK_DATA_PHASE_TIMEOUT 0x0, 0x10000, 16 -#define MASK_WCI_CA_ESR_MASK_RSVD_Y 0x0, 0x8000, 15 -#define MASK_WCI_CA_ESR_MASK_UNEXPECT_CPI_ACK 0x0, 0x4000, 14 -#define MASK_WCI_CA_ESR_MASK_UNEXPECT_DC_ACK 0x0, 0x2000, 13 -#define MASK_WCI_CA_ESR_MASK_UNEXPECT_PULL 0x0, 0x1000, 12 -#define MASK_WCI_CA_ESR_MASK_UNEXPECT_REISSUE 0x0, 0x800, 11 -#define MASK_WCI_CA_ESR_MASK_ATOMIC_MAP_MISMATCH 0x0, 0x400, 10 -#define MASK_WCI_CA_ESR_MASK_UNMAPPED 0x0, 0x200, 9 -#define MASK_WCI_CA_ESR_MASK_UNCORRECTABLE_MTAG_ERROR 0x0, 0x100, 8 -#define MASK_WCI_CA_ESR_MASK_UNCORRECTABLE_DATA_ERROR 0x0, 0x80, 7 -#define MASK_WCI_CA_ESR_MASK_CORRECTABLE_MTAG_ERROR 0x0, 0x40, 6 -#define MASK_WCI_CA_ESR_MASK_CORRECTABLE_DATA_ERROR 0x0, 0x20, 5 -#define MASK_WCI_CA_ESR_MASK_DSTAT_INCONSISTENT 0x0, 0x10, 4 -#define MASK_WCI_CA_ESR_MASK_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x8, 3 -#define MASK_WCI_CA_ESR_MASK_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x4, 2 -#define MASK_WCI_CA_ESR_MASK_REMOTE_TIMEOUT 0x0, 0x2, 1 -#define MASK_WCI_CA_ESR_MASK_LOCAL_TIMEOUT 0x0, 0x1, 0 -#define MASK_WCI_CA_FIRST_PACKET_0_ADDR 0xfc000000, 0x0, 58 -#define MASK_WCI_CA_FIRST_PACKET_0_RSVD_Z 0x3ffe000, 0x0, 45 -#define MASK_WCI_CA_FIRST_PACKET_0_RTRANSID 0x1ff0, 0x0, 36 -#define MASK_WCI_CA_FIRST_PACKET_0_SCNID 0xf, 0xf0000000, 28 -#define MASK_WCI_CA_FIRST_PACKET_0_RSVD_Y 0x0, 0xff00000, 20 -#define MASK_WCI_CA_FIRST_PACKET_0_RTID 0x0, 0xf8000, 15 -#define MASK_WCI_CA_FIRST_PACKET_0_SNID 0x0, 0x7800, 11 -#define MASK_WCI_CA_FIRST_PACKET_0_OPCODE 0x0, 0x7e0, 5 -#define MASK_WCI_CA_FIRST_PACKET_0_STRIPE 0x0, 0x10, 4 -#define MASK_WCI_CA_FIRST_PACKET_0_DNID 0x0, 0xf, 0 -#define MASK_WCI_CA_FIRST_PACKET_1_RSVD_Z 0xffffffff, 0x80000000, 31 -#define MASK_WCI_CA_FIRST_PACKET_1_ADDR 0x0, 0x7fffffff, 0 -#define MASK_WCI_CA_FREEZE_RSVD_Z 0xffffffff, 0x0, 32 -#define MASK_WCI_CA_FREEZE_VECTOR 0x0, 0xffffffff, 0 -#define MASK_WCI_CA_TIMEOUT_CONFIG_RSVD_Z 0xfc000000, 0x0, 58 -#define MASK_WCI_CA_TIMEOUT_CONFIG_DPHASE_DISABLE 0x2000000, 0x0, 57 -#define MASK_WCI_CA_TIMEOUT_CONFIG_DPHASE_FREEZE 0x1000000, 0x0, 56 -#define MASK_WCI_CA_TIMEOUT_CONFIG_RSVD_Y 0xc00000, 0x0, 54 -#define MASK_WCI_CA_TIMEOUT_CONFIG_DPHASE_DEST_MAG 0x300000, 0x0, 52 -#define MASK_WCI_CA_TIMEOUT_CONFIG_DPHASE_DEST_VAL 0xff000, 0x0, 44 -#define MASK_WCI_CA_TIMEOUT_CONFIG_RSVD_X 0xc00, 0x0, 42 -#define MASK_WCI_CA_TIMEOUT_CONFIG_DPHASE_PASS_MAG 0x300, 0x0, 40 -#define MASK_WCI_CA_TIMEOUT_CONFIG_DPHASE_PASS_VAL 0xff, 0x0, 32 -#define MASK_WCI_CA_TIMEOUT_CONFIG_RSVD_W 0x0, 0xc0000000, 30 -#define MASK_WCI_CA_TIMEOUT_CONFIG_APHASE_DISABLE 0x0, 0x20000000, 29 -#define MASK_WCI_CA_TIMEOUT_CONFIG_APHASE_FREEZE 0x0, 0x10000000, 28 -#define MASK_WCI_CA_TIMEOUT_CONFIG_RSVD_V 0x0, 0xc000000, 26 -#define MASK_WCI_CA_TIMEOUT_CONFIG_APHASE_MAG 0x0, 0x3000000, 24 -#define MASK_WCI_CA_TIMEOUT_CONFIG_APHASE_VAL 0x0, 0xff0000, 16 -#define MASK_WCI_CA_TIMEOUT_CONFIG_RSVD_U 0x0, 0x8000, 15 -#define MASK_WCI_CA_TIMEOUT_CONFIG_REUSE_DISABLE 0x0, 0x4000, 14 -#define MASK_WCI_CA_TIMEOUT_CONFIG_REUSE_FREEZE 0x0, 0x2000, 13 -#define MASK_WCI_CA_TIMEOUT_CONFIG_REUSE_MAG 0x0, 0x1800, 11 -#define MASK_WCI_CA_TIMEOUT_CONFIG_REUSE_VAL 0x0, 0x7ff, 0 -#define MASK_WCI_CA_TIMEOUT_CONFIG_2_RSVD_Z 0xffffffff, 0xfe000000, 25 -#define MASK_WCI_CA_TIMEOUT_CONFIG_2_SFI_TARGID_TIMEOUT_DISABLE 0x0, \ -0x1000000, 24 -#define MASK_WCI_CA_TIMEOUT_CONFIG_2_RSVD_Y 0x0, 0x800000, 23 -#define MASK_WCI_CA_TIMEOUT_CONFIG_2_SFI_TARGID_TIMEOUT_SEL 0x0, 0x700000, 20 -#define MASK_WCI_CA_TIMEOUT_CONFIG_2_RSVD_X 0x0, 0xfc000, 14 -#define MASK_WCI_CA_TIMEOUT_CONFIG_2_LOC_REUSE_MAG 0x0, 0x3000, 12 -#define MASK_WCI_CA_TIMEOUT_CONFIG_2_RSVD_W 0x0, 0x800, 11 -#define MASK_WCI_CA_TIMEOUT_CONFIG_2_LOC_REUSE_VAL 0x0, 0x7ff, 0 -#define MASK_WCI_CCI_ESR_RSVD_Z 0xffffffff, 0xffc00000, 22 -#define MASK_WCI_CCI_ESR_ACC_PARITY 0x0, 0x200000, 21 -#define MASK_WCI_CCI_ESR_ACC_THRESHOLD 0x0, 0x100000, 20 -#define MASK_WCI_CCI_ESR_ACC_SRAM_AE 0x0, 0x80000, 19 -#define MASK_WCI_CCI_ESR_ACC_SRAM_UE 0x0, 0x40000, 18 -#define MASK_WCI_CCI_ESR_ACC_SRAM_CE 0x0, 0x20000, 17 -#define MASK_WCI_CCI_ESR_ACC_CE_COUNT_ZERO 0x0, 0x10000, 16 -#define MASK_WCI_CCI_ESR_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_CCI_ESR_RSVD_Y 0x0, 0x7fc0, 6 -#define MASK_WCI_CCI_ESR_PARITY 0x0, 0x20, 5 -#define MASK_WCI_CCI_ESR_THRESHOLD 0x0, 0x10, 4 -#define MASK_WCI_CCI_ESR_SRAM_AE 0x0, 0x8, 3 -#define MASK_WCI_CCI_ESR_SRAM_UE 0x0, 0x4, 2 -#define MASK_WCI_CCI_ESR_SRAM_CE 0x0, 0x2, 1 -#define MASK_WCI_CCI_ESR_CE_COUNT_ZERO 0x0, 0x1, 0 -#define MASK_WCI_CCI_ESR_MASK_RSVD_Z 0xffffffff, 0xffffffc0, 6 -#define MASK_WCI_CCI_ESR_MASK_PARITY 0x0, 0x20, 5 -#define MASK_WCI_CCI_ESR_MASK_THRESHOLD 0x0, 0x10, 4 -#define MASK_WCI_CCI_ESR_MASK_SRAM_AE 0x0, 0x8, 3 -#define MASK_WCI_CCI_ESR_MASK_SRAM_UE 0x0, 0x4, 2 -#define MASK_WCI_CCI_ESR_MASK_SRAM_CE 0x0, 0x2, 1 -#define MASK_WCI_CCI_ESR_MASK_CE_COUNT_ZERO 0x0, 0x1, 0 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_CCI_ROUTE_MAP0_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_CCI_ROUTE_MAP0_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_CCI_ROUTE_MAP1_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_CCI_ROUTE_MAP1_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_CLUSTER_CONFIG_RSVD_Z 0xffffffff, 0xfffffff8, 3 -#define MASK_WCI_CLUSTER_CONFIG_IN_AN_SSM 0x0, 0x4, 2 -#define MASK_WCI_CLUSTER_CONFIG_BAD_ECC_ON_WRITE_ERROR 0x0, 0x2, 1 -#define MASK_WCI_CLUSTER_CONFIG_ALLOW_MULTIPLE_HOPS 0x0, 0x1, 0 -#define MASK_WCI_CLUSTER_CTR_CTL_RSVD_Z 0xffffffff, 0xfffffe00, 9 -#define MASK_WCI_CLUSTER_CTR_CTL_ENABLE_ALL 0x0, 0x100, 8 -#define MASK_WCI_CLUSTER_CTR_CTL_CNT1_RECEIVED_INTERRUPT 0x0, 0x80, 7 -#define MASK_WCI_CLUSTER_CTR_CTL_CNT1_RECEIVED_ATOMIC 0x0, 0x40, 6 -#define MASK_WCI_CLUSTER_CTR_CTL_CNT1_RECEIVED_CACHEABLE_READ 0x0, 0x20, 5 -#define MASK_WCI_CLUSTER_CTR_CTL_CNT1_RECEIVED_CACHEABLE_WRITE 0x0, 0x10, 4 -#define MASK_WCI_CLUSTER_CTR_CTL_CNT0_RECEIVED_INTERRUPT 0x0, 0x8, 3 -#define MASK_WCI_CLUSTER_CTR_CTL_CNT0_RECEIVED_ATOMIC 0x0, 0x4, 2 -#define MASK_WCI_CLUSTER_CTR_CTL_CNT0_RECEIVED_CACHEABLE_READ 0x0, 0x2, 1 -#define MASK_WCI_CLUSTER_CTR_CTL_CNT0_RECEIVED_CACHEABLE_WRITE 0x0, 0x1, 0 -#define MASK_WCI_CLUSTER_ERROR_COUNT_VALUE 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_CLUSTER_ERROR_STATUS_ARRAY_RSVD_Z 0xffffffff, 0xffffffc0, 6 -#define MASK_WCI_CLUSTER_ERROR_STATUS_ARRAY_DISABLE_FAIL_FAST 0x0, 0x20, 5 -#define MASK_WCI_CLUSTER_ERROR_STATUS_ARRAY_NOT_VALID 0x0, 0x10, 4 -#define MASK_WCI_CLUSTER_ERROR_STATUS_ARRAY_VALUE 0x0, 0xf, 0 -#define MASK_WCI_CLUSTER_MEMBERS_BITS_MASK 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_CLUSTER_SYNC_SYNC_IN_PROGRESS 0x80000000, 0x0, 63 -#define MASK_WCI_CLUSTER_SYNC_RSVD_Z 0x7fffffff, 0x0, 32 -#define MASK_WCI_CLUSTER_SYNC_CAG_BUSY 0x0, 0xffffffff, 0 -#define MASK_WCI_CLUSTER_WRITE_LOCKOUT_MASK 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_CONFIG_RSVD_Z 0xffffe000, 0x0, 45 -#define MASK_WCI_CONFIG_WR_DIR_ON_RINV_MISS 0x1000, 0x0, 44 -#define MASK_WCI_CONFIG_WR_DIR_ON_RWS_MISS 0x800, 0x0, 43 -#define MASK_WCI_CONFIG_SAFARI_COMPLIANT_TARGID 0x400, 0x0, 42 -#define MASK_WCI_CONFIG_RSVD_Y 0x380, 0x0, 39 -#define MASK_WCI_CONFIG_CLUSTER_EARLY_REUSE_EN 0x40, 0x0, 38 -#define MASK_WCI_CONFIG_RESERVED_DEFAULT_0 0x20, 0x0, 37 -#define MASK_WCI_CONFIG_RA_NUMA_BYPASS_EN 0x10, 0x0, 36 -#define MASK_WCI_CONFIG_HA_DISABLE_UNEXP_SNID 0x8, 0x0, 35 -#define MASK_WCI_CONFIG_RA_DISABLE_UNEXP_SNID 0x4, 0x0, 34 -#define MASK_WCI_CONFIG_DC_CPI_SNID_DISABLE 0x2, 0x0, 33 -#define MASK_WCI_CONFIG_DBG_BYTEMASK_EN 0x1, 0x0, 32 -#define MASK_WCI_CONFIG_PARTNER_NODE_ID 0x0, 0xf0000000, 28 -#define MASK_WCI_CONFIG_CLUSTER_MODE 0x0, 0x8000000, 27 -#define MASK_WCI_CONFIG_RSVD_X 0x0, 0x4000000, 26 -#define MASK_WCI_CONFIG_NC_STRIPE_BY_ADDR 0x0, 0x2000000, 25 -#define MASK_WCI_CONFIG_ENABLE_INID 0x0, 0x1000000, 24 -#define MASK_WCI_CONFIG_STRIPE_BITS 0x0, 0xf00000, 20 -#define MASK_WCI_CONFIG_DEV_CONFIG_NODE_ID 0x0, 0xf8000, 15 -#define MASK_WCI_CONFIG_BOX_ID 0x0, 0x7e00, 9 -#define MASK_WCI_CONFIG_DEVICE_ID 0x0, 0x1f0, 4 -#define MASK_WCI_CONFIG_NODE_ID 0x0, 0xf, 0 -#define MASK_WCI_CSR_CONTROL_RSVD_Z 0xffffffff, 0xfffffffe, 1 -#define MASK_WCI_CSR_CONTROL_JTAG_WR_ONLY 0x0, 0x1, 0 -#define MASK_WCI_CSRA_ESR_RSVD_Z 0xffffffff, 0xf8000000, 27 -#define MASK_WCI_CSRA_ESR_ACC_TIMEOUT 0x0, 0x4000000, 26 -#define MASK_WCI_CSRA_ESR_ACC_PULL_TARGID_TIMEOUT 0x0, 0x2000000, 25 -#define MASK_WCI_CSRA_ESR_ACC_PULL_TIMEOUT 0x0, 0x1000000, 24 -#define MASK_WCI_CSRA_ESR_ACC_SRAM_ERROR 0x0, 0x800000, 23 -#define MASK_WCI_CSRA_ESR_ACC_PROTECTION_ERROR 0x0, 0x400000, 22 -#define MASK_WCI_CSRA_ESR_ACC_UNCORRECTABLE_MTAG_ERROR 0x0, 0x200000, 21 -#define MASK_WCI_CSRA_ESR_ACC_UNCORRECTABLE_DATA_ERROR 0x0, 0x100000, 20 -#define MASK_WCI_CSRA_ESR_ACC_CORRECTABLE_MTAG_ERROR 0x0, 0x80000, 19 -#define MASK_WCI_CSRA_ESR_ACC_CORRECTABLE_DATA_ERROR 0x0, 0x40000, 18 -#define MASK_WCI_CSRA_ESR_ACC_MTAG_NOT_GM 0x0, 0x20000, 17 -#define MASK_WCI_CSRA_ESR_ACC_MTAG_MISMATCH 0x0, 0x10000, 16 -#define MASK_WCI_CSRA_ESR_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_CSRA_ESR_RSVD_Y 0x0, 0x7800, 11 -#define MASK_WCI_CSRA_ESR_TIMEOUT 0x0, 0x400, 10 -#define MASK_WCI_CSRA_ESR_PULL_TARGID_TIMEOUT 0x0, 0x200, 9 -#define MASK_WCI_CSRA_ESR_PULL_TIMEOUT 0x0, 0x100, 8 -#define MASK_WCI_CSRA_ESR_SRAM_ERROR 0x0, 0x80, 7 -#define MASK_WCI_CSRA_ESR_PROTECTION_ERROR 0x0, 0x40, 6 -#define MASK_WCI_CSRA_ESR_UNCORRECTABLE_MTAG_ERROR 0x0, 0x20, 5 -#define MASK_WCI_CSRA_ESR_UNCORRECTABLE_DATA_ERROR 0x0, 0x10, 4 -#define MASK_WCI_CSRA_ESR_CORRECTABLE_MTAG_ERROR 0x0, 0x8, 3 -#define MASK_WCI_CSRA_ESR_CORRECTABLE_DATA_ERROR 0x0, 0x4, 2 -#define MASK_WCI_CSRA_ESR_MTAG_NOT_GM 0x0, 0x2, 1 -#define MASK_WCI_CSRA_ESR_MTAG_MISMATCH 0x0, 0x1, 0 -#define MASK_WCI_CSRA_ESR_MASK_RSVD_Z 0xffffffff, 0xfffff800, 11 -#define MASK_WCI_CSRA_ESR_MASK_TIMEOUT 0x0, 0x400, 10 -#define MASK_WCI_CSRA_ESR_MASK_PULL_TARGID_TIMEOUT 0x0, 0x200, 9 -#define MASK_WCI_CSRA_ESR_MASK_PULL_TIMEOUT 0x0, 0x100, 8 -#define MASK_WCI_CSRA_ESR_MASK_SRAM_ERROR 0x0, 0x80, 7 -#define MASK_WCI_CSRA_ESR_MASK_PROTECTION_ERROR 0x0, 0x40, 6 -#define MASK_WCI_CSRA_ESR_MASK_UNCORRECTABLE_MTAG_ERROR 0x0, 0x20, 5 -#define MASK_WCI_CSRA_ESR_MASK_UNCORRECTABLE_DATA_ERROR 0x0, 0x10, 4 -#define MASK_WCI_CSRA_ESR_MASK_CORRECTABLE_MTAG_ERROR 0x0, 0x8, 3 -#define MASK_WCI_CSRA_ESR_MASK_CORRECTABLE_DATA_ERROR 0x0, 0x4, 2 -#define MASK_WCI_CSRA_ESR_MASK_MTAG_NOT_GM 0x0, 0x2, 1 -#define MASK_WCI_CSRA_ESR_MASK_MTAG_MISMATCH 0x0, 0x1, 0 -#define MASK_WCI_CSRA_STATUS_RSVD_Z 0x80000000, 0x0, 63 -#define MASK_WCI_CSRA_STATUS_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_CSRA_STATUS_SCAR 0x4000000, 0x0, 58 -#define MASK_WCI_CSRA_STATUS_ATRANSID 0x3fe0000, 0x0, 49 -#define MASK_WCI_CSRA_STATUS_TARGID_3_TO_0 0x1c000, 0x0, 46 -#define MASK_WCI_CSRA_STATUS_CESR_NUMBER 0x3fc0, 0x0, 38 -#define MASK_WCI_CSRA_STATUS_RW 0x20, 0x0, 37 -#define MASK_WCI_CSRA_STATUS_NC_SLICE 0x1f, 0xe0000000, 29 -#define MASK_WCI_CSRA_STATUS_SF_ADDR_28_TO_5 0x0, 0x1fffffe0, 5 -#define MASK_WCI_CSRA_STATUS_FSM_STATE 0x0, 0x1c, 2 -#define MASK_WCI_CSRA_STATUS_TYPE 0x0, 0x3, 0 -#define MASK_WCI_CSRA_TIMEOUT_CONFIG_RSVD_Z 0xffffffff, 0xffe00000, 21 -#define MASK_WCI_CSRA_TIMEOUT_CONFIG_PULL_TARGID_FAIL_FAST_ENABLE 0x0, \ -0x100000, 20 -#define MASK_WCI_CSRA_TIMEOUT_CONFIG_PULL_FAIL_FAST_ENABLE 0x0, 0x80000, 19 -#define MASK_WCI_CSRA_TIMEOUT_CONFIG_DISABLE 0x0, 0x40000, 18 -#define MASK_WCI_CSRA_TIMEOUT_CONFIG_FREEZE 0x0, 0x20000, 17 -#define MASK_WCI_CSRA_TIMEOUT_CONFIG_MAGNITUDE 0x0, 0x10000, 16 -#define MASK_WCI_CSRA_TIMEOUT_CONFIG_RD_TIMEOUT 0x0, 0xff00, 8 -#define MASK_WCI_CSRA_TIMEOUT_CONFIG_WR_TIMEOUT 0x0, 0xff, 0 -#define MASK_WCI_DC_ESR_RSVD_Z 0xffffffff, 0xfc000000, 26 -#define MASK_WCI_DC_ESR_ACC_DIF_TIMEOUT 0x0, 0x2000000, 25 -#define MASK_WCI_DC_ESR_ACC_DCI_D_ERR_DSTAT 0x0, 0x1000000, 24 -#define MASK_WCI_DC_ESR_ACC_DCO_CE 0x0, 0x800000, 23 -#define MASK_WCI_DC_ESR_ACC_DC_DIF_OVERFLOW 0x0, 0x400000, 22 -#define MASK_WCI_DC_ESR_ACC_DC_LAUNCH_QUEUE_OVERFLOW 0x0, 0x200000, 21 -#define MASK_WCI_DC_ESR_ACC_DCO_MAP_ERROR 0x0, 0x100000, 20 -#define MASK_WCI_DC_ESR_ACC_DCO_DATA_PARITY_ERROR 0x0, 0x80000, 19 -#define MASK_WCI_DC_ESR_ACC_DCI_D_ERR 0x0, 0x40000, 18 -#define MASK_WCI_DC_ESR_ACC_DCI_CPI_INVALID 0x0, 0x20000, 17 -#define MASK_WCI_DC_ESR_ACC_DCI_CPI_SNID_MISMATCH 0x0, 0x10000, 16 -#define MASK_WCI_DC_ESR_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_DC_ESR_RSVD_Y 0x0, 0x7c00, 10 -#define MASK_WCI_DC_ESR_DIF_TIMEOUT 0x0, 0x200, 9 -#define MASK_WCI_DC_ESR_DCI_D_ERR_DSTAT 0x0, 0x100, 8 -#define MASK_WCI_DC_ESR_DCO_CE 0x0, 0x80, 7 -#define MASK_WCI_DC_ESR_DC_DIF_OVERFLOW 0x0, 0x40, 6 -#define MASK_WCI_DC_ESR_DC_LAUNCH_QUEUE_OVERFLOW 0x0, 0x20, 5 -#define MASK_WCI_DC_ESR_DCO_MAP_ERROR 0x0, 0x10, 4 -#define MASK_WCI_DC_ESR_DCO_DATA_PARITY_ERROR 0x0, 0x8, 3 -#define MASK_WCI_DC_ESR_DCI_D_ERR 0x0, 0x4, 2 -#define MASK_WCI_DC_ESR_DCI_CPI_INVALID 0x0, 0x2, 1 -#define MASK_WCI_DC_ESR_DCI_CPI_SNID_MISMATCH 0x0, 0x1, 0 -#define MASK_WCI_DC_ESR_MASK_RSVD_Z 0xffffffff, 0xfffffc00, 10 -#define MASK_WCI_DC_ESR_MASK_DIF_TIMEOUT 0x0, 0x200, 9 -#define MASK_WCI_DC_ESR_MASK_DCI_D_ERR_DSTAT 0x0, 0x100, 8 -#define MASK_WCI_DC_ESR_MASK_DCO_CE 0x0, 0x80, 7 -#define MASK_WCI_DC_ESR_MASK_DC_DIF_OVERFLOW 0x0, 0x40, 6 -#define MASK_WCI_DC_ESR_MASK_DC_LAUNCH_QUEUE_OVERFLOW 0x0, 0x20, 5 -#define MASK_WCI_DC_ESR_MASK_DCO_MAP_ERROR 0x0, 0x10, 4 -#define MASK_WCI_DC_ESR_MASK_DCO_DATA_PARITY_ERROR 0x0, 0x8, 3 -#define MASK_WCI_DC_ESR_MASK_DCI_D_ERR 0x0, 0x4, 2 -#define MASK_WCI_DC_ESR_MASK_DCI_CPI_INVALID 0x0, 0x2, 1 -#define MASK_WCI_DC_ESR_MASK_DCI_CPI_SNID_MISMATCH 0x0, 0x1, 0 -#define MASK_WCI_DCI_STATE_RSVD_Z 0xffffffff, 0xff000000, 24 -#define MASK_WCI_DCI_STATE_DCI_D_ERR_DTARG 0x0, 0x800000, 23 -#define MASK_WCI_DCI_STATE_DCI_D_ERR_DTRANSID 0x0, 0x7fc000, 14 -#define MASK_WCI_DCI_STATE_DCI_CPI_ERR_DTARG 0x0, 0x2000, 13 -#define MASK_WCI_DCI_STATE_DCI_CPI_ERR_DTRANSID 0x0, 0x1ff0, 4 -#define MASK_WCI_DCI_STATE_DCI_CPI_ERR_SOURCE_NID 0x0, 0xf, 0 -#define MASK_WCI_DCO_CE_COUNT_RSVD_Z 0xffffffff, 0xffffff00, 8 -#define MASK_WCI_DCO_CE_COUNT_CE_COUNT 0x0, 0xff, 0 -#define MASK_WCI_DCO_STATE_LINK_0_LQ_OVERFLOW 0x80000000, 0x0, 63 -#define MASK_WCI_DCO_STATE_LINK_1_LQ_OVERFLOW 0x40000000, 0x0, 62 -#define MASK_WCI_DCO_STATE_LINK_2_LQ_OVERFLOW 0x20000000, 0x0, 61 -#define MASK_WCI_DCO_STATE_RSVD_Z 0x18000000, 0x0, 59 -#define MASK_WCI_DCO_STATE_LPBK_LQ_OVERFLOW 0x4000000, 0x0, 58 -#define MASK_WCI_DCO_STATE_CSR_LQ_OVERFLOW 0x2000000, 0x0, 57 -#define MASK_WCI_DCO_STATE_RSVD_Y 0x1f00000, 0x0, 52 -#define MASK_WCI_DCO_STATE_DCO_MAP_ERROR_DTARG 0x80000, 0x0, 51 -#define MASK_WCI_DCO_STATE_DCO_MAP_ERROR_DTRANSID 0x7fc00, 0x0, 42 -#define MASK_WCI_DCO_STATE_MTAG_ECC_ERROR_AID 0x3f8, 0x0, 35 -#define MASK_WCI_DCO_STATE_DATA_ECC_ERROR_AID 0x7, 0xf0000000, 28 -#define MASK_WCI_DCO_STATE_DATA_ECC_UE 0x0, 0x8000000, 27 -#define MASK_WCI_DCO_STATE_MTAG_ECC_UE 0x0, 0x4000000, 26 -#define MASK_WCI_DCO_STATE_MTAG_SYNDROME_0 0x0, 0x3c00000, 22 -#define MASK_WCI_DCO_STATE_MTAG_SYNDROME_1 0x0, 0x3c0000, 18 -#define MASK_WCI_DCO_STATE_DATA_SYNDROME_0 0x0, 0x3fe00, 9 -#define MASK_WCI_DCO_STATE_DATA_SYNDROME_1 0x0, 0x1ff, 0 -#define MASK_WCI_DIF_TIMEOUT_CNTL_RSVD_Z 0xffffffff, 0xfffff000, 12 -#define MASK_WCI_DIF_TIMEOUT_CNTL_TIMEOUT_DISABLE 0x0, 0x800, 11 -#define MASK_WCI_DIF_TIMEOUT_CNTL_TIMEOUT_FREEZE 0x0, 0x400, 10 -#define MASK_WCI_DIF_TIMEOUT_CNTL_TIMEOUT_MAG 0x0, 0x300, 8 -#define MASK_WCI_DIF_TIMEOUT_CNTL_TIMEOUT_VAL 0x0, 0xff, 0 -#define MASK_WCI_DIF_TIMEOUT_COUNT_RSVD_Z 0xffffffff, 0x0, 32 -#define MASK_WCI_DIF_TIMEOUT_COUNT_COUNT 0x0, 0xffffffff, 0 -#define MASK_WCI_DOMAIN_CONFIG_RSVD_Z 0xffffffff, 0xffff0000, 16 -#define MASK_WCI_DOMAIN_CONFIG_DOMAIN_MASK 0x0, 0xffff, 0 -#define MASK_WCI_EMISS_CNTL_ARRAY_RSVD_Z 0xfff80000, 0x0, 51 -#define MASK_WCI_EMISS_CNTL_ARRAY_AUTO_RESET_ACTIVE 0x40000, 0x0, 50 -#define MASK_WCI_EMISS_CNTL_ARRAY_ENABLED 0x20000, 0x0, 49 -#define MASK_WCI_EMISS_CNTL_ARRAY_ADDRESS 0x1ffff, 0xfffff000, 12 -#define MASK_WCI_EMISS_CNTL_ARRAY_NID 0x0, 0xf00, 8 -#define MASK_WCI_EMISS_CNTL_ARRAY_LENGTH 0x0, 0xc0, 6 -#define MASK_WCI_EMISS_CNTL_ARRAY_EVENT0 0x0, 0x38, 3 -#define MASK_WCI_EMISS_CNTL_ARRAY_EVENT1 0x0, 0x7, 0 -#define MASK_WCI_EMISS_DATA_ARRAY_RSVD_Z 0xfffff000, 0x0, 44 -#define MASK_WCI_EMISS_DATA_ARRAY_EVENT0_COUNT 0xffc, 0x0, 34 -#define MASK_WCI_EMISS_DATA_ARRAY_EVENT1_COUNT 0x3, 0xff000000, 24 -#define MASK_WCI_EMISS_DATA_ARRAY_EVENT0_COUNT_ALL 0x0, 0xfff000, 12 -#define MASK_WCI_EMISS_DATA_ARRAY_EVENT1_COUNT_ALL 0x0, 0xfff, 0 -#define MASK_WCI_EMISS_RESET_CTL_RSVD_Z 0xffffffff, 0xffc00000, 22 -#define MASK_WCI_EMISS_RESET_CTL_AUTO_RESET_MASK 0x0, 0x3ff000, 12 -#define MASK_WCI_EMISS_RESET_CTL_COUNT 0x0, 0xfff, 0 -#define MASK_WCI_ERROR_INDUCEMENT_RSVD_Z 0xff000000, 0x0, 56 -#define MASK_WCI_ERROR_INDUCEMENT_INTERNAL_SRAM_VECTOR 0xfe0000, 0x0, 49 -#define MASK_WCI_ERROR_INDUCEMENT_HMQ_P 0x10000, 0x0, 48 -#define MASK_WCI_ERROR_INDUCEMENT_SLQ_P 0x8000, 0x0, 47 -#define MASK_WCI_ERROR_INDUCEMENT_SFQ_P 0x4000, 0x0, 46 -#define MASK_WCI_ERROR_INDUCEMENT_SRAM_ECC_XOR_2_SELECT 0x3f00, 0x0, 40 -#define MASK_WCI_ERROR_INDUCEMENT_SRAM_ECC_XOR_1_SELECT 0xfc, 0x0, 34 -#define MASK_WCI_ERROR_INDUCEMENT_SRAM_P 0x3, 0x0, 32 -#define MASK_WCI_ERROR_INDUCEMENT_MTAG_ECC0_XOR 0x0, 0xf0000000, 28 -#define MASK_WCI_ERROR_INDUCEMENT_MTAG_ECC1_XOR 0x0, 0xf000000, 24 -#define MASK_WCI_ERROR_INDUCEMENT_MTAG0_XOR 0x0, 0xe00000, 21 -#define MASK_WCI_ERROR_INDUCEMENT_MTAG1_XOR 0x0, 0x1c0000, 18 -#define MASK_WCI_ERROR_INDUCEMENT_ECC0_XOR 0x0, 0x3fe00, 9 -#define MASK_WCI_ERROR_INDUCEMENT_ECC1_XOR 0x0, 0x1ff, 0 -#define MASK_WCI_ERROR_PAUSE_TIMER_HOLD_RSVD_Z 0xffffffff, 0xffffff00, 8 -#define MASK_WCI_ERROR_PAUSE_TIMER_HOLD_CA_APHASE 0x0, 0x80, 7 -#define MASK_WCI_ERROR_PAUSE_TIMER_HOLD_CA_DPHASE 0x0, 0x40, 6 -#define MASK_WCI_ERROR_PAUSE_TIMER_HOLD_CA_REUSE 0x0, 0x20, 5 -#define MASK_WCI_ERROR_PAUSE_TIMER_HOLD_RESERVED 0x0, 0x10, 4 -#define MASK_WCI_ERROR_PAUSE_TIMER_HOLD_RA_CLUSTER_PRIMARY 0x0, 0x8, 3 -#define MASK_WCI_ERROR_PAUSE_TIMER_HOLD_RA_SSM_PRIMARY 0x0, 0x4, 2 -#define MASK_WCI_ERROR_PAUSE_TIMER_HOLD_HA_PRIMARY 0x0, 0x2, 1 -#define MASK_WCI_ERROR_PAUSE_TIMER_HOLD_SA_PRIMARY 0x0, 0x1, 0 -#define MASK_WCI_ERROR_SUMMARY_RSVD_Z 0xffffffff, 0xfffff800, 11 -#define MASK_WCI_ERROR_SUMMARY_CCI_ERROR 0x0, 0x400, 10 -#define MASK_WCI_ERROR_SUMMARY_REQUEST_AGENT_ERROR 0x0, 0x200, 9 -#define MASK_WCI_ERROR_SUMMARY_HOME_AGENT_ERROR 0x0, 0x100, 8 -#define MASK_WCI_ERROR_SUMMARY_SLAVE_AGENT_ERROR 0x0, 0x80, 7 -#define MASK_WCI_ERROR_SUMMARY_CLUSTER_AGENT_ERROR 0x0, 0x40, 6 -#define MASK_WCI_ERROR_SUMMARY_CSR_AGENT_ERROR 0x0, 0x20, 5 -#define MASK_WCI_ERROR_SUMMARY_LC_ERROR 0x0, 0x10, 4 -#define MASK_WCI_ERROR_SUMMARY_SFI_ERROR 0x0, 0x8, 3 -#define MASK_WCI_ERROR_SUMMARY_SFQ_ERROR 0x0, 0x4, 2 -#define MASK_WCI_ERROR_SUMMARY_DC_ERROR 0x0, 0x2, 1 -#define MASK_WCI_ERROR_SUMMARY_HLI_ERROR 0x0, 0x1, 0 -#define MASK_WCI_FIRST_ERROR_TIME_STICK_TIME 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_FO_ROUTE_MAP_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_FO_ROUTE_MAP_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_FO_ROUTE_MAP_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_FO_ROUTE_MAP_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_FO_ROUTE_MAP_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_FO_ROUTE_MAP_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_FO_ROUTE_MAP_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_FO_ROUTE_MAP_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_FO_ROUTE_MAP_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_FO_ROUTE_MAP_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_FO_ROUTE_MAP_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_FO_ROUTE_MAP_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_FO_ROUTE_MAP_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_FO_ROUTE_MAP_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_FO_ROUTE_MAP_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_FO_ROUTE_MAP_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_FO_ROUTE_MAP_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_FO_TNID_MAP_RSVD_Z 0xffffffff, 0xfffff000, 12 -#define MASK_WCI_FO_TNID_MAP_LINK2_TNID 0x0, 0xf00, 8 -#define MASK_WCI_FO_TNID_MAP_LINK1_TNID 0x0, 0xf0, 4 -#define MASK_WCI_FO_TNID_MAP_LINK0_TNID 0x0, 0xf, 0 -#define MASK_WCI_GENERATES_CESR_NUMBER_RSVD_Z 0xfffffffe, 0x0, 33 -#define MASK_WCI_GENERATES_CESR_NUMBER_ENABLE 0x1, 0x0, 32 -#define MASK_WCI_GENERATES_CESR_NUMBER_DEVICE_VECTOR 0x0, 0xffffffff, 0 -#define MASK_WCI_GLOBAL_EMISS_COUNTER_RSVD_Z 0xffffffff, 0xff000000, 24 -#define MASK_WCI_GLOBAL_EMISS_COUNTER_COUNT 0x0, 0xffffff, 0 -#define MASK_WCI_GNID_MAP0_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_GNID_MAP0_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_GNID_MAP0_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_GNID_MAP0_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_GNID_MAP0_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_GNID_MAP0_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_GNID_MAP0_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_GNID_MAP0_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_GNID_MAP0_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_GNID_MAP0_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_GNID_MAP0_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_GNID_MAP0_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_GNID_MAP0_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_GNID_MAP0_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_GNID_MAP0_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_GNID_MAP0_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_GNID_MAP0_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_GNID_MAP0_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_GNID_MAP0_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_GNID_MAP0_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_GNID_MAP0_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_GNID_MAP0_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_GNID_MAP0_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_GNID_MAP0_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_GNID_MAP0_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_GNID_MAP0_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_GNID_MAP0_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_GNID_MAP0_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_GNID_MAP0_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_GNID_MAP0_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_GNID_MAP0_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_GNID_MAP0_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_GNID_MAP1_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_GNID_MAP1_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_GNID_MAP1_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_GNID_MAP1_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_GNID_MAP1_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_GNID_MAP1_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_GNID_MAP1_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_GNID_MAP1_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_GNID_MAP1_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_GNID_MAP1_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_GNID_MAP1_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_GNID_MAP1_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_GNID_MAP1_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_GNID_MAP1_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_GNID_MAP1_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_GNID_MAP1_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_GNID_MAP1_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_GNID_MAP1_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_GNID_MAP1_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_GNID_MAP1_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_GNID_MAP1_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_GNID_MAP1_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_GNID_MAP1_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_GNID_MAP1_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_GNID_MAP1_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_GNID_MAP1_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_GNID_MAP1_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_GNID_MAP1_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_GNID_MAP1_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_GNID_MAP1_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_GNID_MAP1_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_GNID_MAP1_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_HA_BUSY_RSVD_Z 0xffffffff, 0xffff0000, 16 -#define MASK_WCI_HA_BUSY_VECTOR 0x0, 0xffff, 0 -#define MASK_WCI_HA_CONFIG_RSVD_Z 0xffffffff, 0xfffffe00, 9 -#define MASK_WCI_HA_CONFIG_SNID_IN_MASK 0x0, 0x100, 8 -#define MASK_WCI_HA_CONFIG_DISABLE_SAME_BOX_OPT 0x0, 0x80, 7 -#define MASK_WCI_HA_CONFIG_MIGRATORY_SHARING_CTRL 0x0, 0x7f, 0 -#define MASK_WCI_HA_ECC_ADDRESS_DATA 0x80000000, 0x0, 63 -#define MASK_WCI_HA_ECC_ADDRESS_UE 0x40000000, 0x0, 62 -#define MASK_WCI_HA_ECC_ADDRESS_RSVD_Z 0x3ffff800, 0x0, 43 -#define MASK_WCI_HA_ECC_ADDRESS_ADDR 0x7ff, 0xfffffff0, 4 -#define MASK_WCI_HA_ECC_ADDRESS_RSVD_Y 0x0, 0xf, 0 -#define MASK_WCI_HA_ERROR_ADDRESS_ESR_REG 0x80000000, 0x0, 63 -#define MASK_WCI_HA_ERROR_ADDRESS_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_HA_ERROR_ADDRESS_RSVD_Z 0x7fff800, 0x0, 43 -#define MASK_WCI_HA_ERROR_ADDRESS_ADDR 0x7ff, 0xfffffff0, 4 -#define MASK_WCI_HA_ERROR_ADDRESS_RSVD_Y 0x0, 0xf, 0 -#define MASK_WCI_HA_ESR_0_RSVD_Z 0xffffffff, 0xe0000000, 29 -#define MASK_WCI_HA_ESR_0_ACC_UNEXPECTED_SNID 0x0, 0x10000000, 28 -#define MASK_WCI_HA_ESR_0_ACC_ADDRESS_NOT_MAPPED_IO 0x0, 0x8000000, 27 -#define MASK_WCI_HA_ESR_0_ACC_DIR_PARITY_ERROR 0x0, 0x4000000, 26 -#define MASK_WCI_HA_ESR_0_ACC_NOT_EXPECTED_COMPL 0x0, 0x2000000, 25 -#define MASK_WCI_HA_ESR_0_ACC_ILLEGAL_SENDER 0x0, 0x1000000, 24 -#define MASK_WCI_HA_ESR_0_ACC_WRONG_CMD 0x0, 0x800000, 23 -#define MASK_WCI_HA_ESR_0_ACC_UNCORRECTABLE_MTAG_ERROR 0x0, 0x400000, 22 -#define MASK_WCI_HA_ESR_0_ACC_UNCORRECTABLE_DATA_ERROR 0x0, 0x200000, 21 -#define MASK_WCI_HA_ESR_0_ACC_CORRECTABLE_MTAG_ERROR 0x0, 0x100000, 20 -#define MASK_WCI_HA_ESR_0_ACC_CORRECTABLE_DATA_ERROR 0x0, 0x80000, 19 -#define MASK_WCI_HA_ESR_0_ACC_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x40000, 18 -#define MASK_WCI_HA_ESR_0_ACC_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x20000, 17 -#define MASK_WCI_HA_ESR_0_ACC_TIMEOUT 0x0, 0x10000, 16 -#define MASK_WCI_HA_ESR_0_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_HA_ESR_0_RSVD_Y 0x0, 0x6000, 13 -#define MASK_WCI_HA_ESR_0_UNEXPECTED_SNID 0x0, 0x1000, 12 -#define MASK_WCI_HA_ESR_0_ADDRESS_NOT_MAPPED_IO 0x0, 0x800, 11 -#define MASK_WCI_HA_ESR_0_DIR_PARITY_ERROR 0x0, 0x400, 10 -#define MASK_WCI_HA_ESR_0_NOT_EXPECTED_COMPL 0x0, 0x200, 9 -#define MASK_WCI_HA_ESR_0_ILLEGAL_SENDER 0x0, 0x100, 8 -#define MASK_WCI_HA_ESR_0_WRONG_CMD 0x0, 0x80, 7 -#define MASK_WCI_HA_ESR_0_UNCORRECTABLE_MTAG_ERROR 0x0, 0x40, 6 -#define MASK_WCI_HA_ESR_0_UNCORRECTABLE_DATA_ERROR 0x0, 0x20, 5 -#define MASK_WCI_HA_ESR_0_CORRECTABLE_MTAG_ERROR 0x0, 0x10, 4 -#define MASK_WCI_HA_ESR_0_CORRECTABLE_DATA_ERROR 0x0, 0x8, 3 -#define MASK_WCI_HA_ESR_0_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x4, 2 -#define MASK_WCI_HA_ESR_0_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x2, 1 -#define MASK_WCI_HA_ESR_0_TIMEOUT 0x0, 0x1, 0 -#define MASK_WCI_HA_ESR_1_RSVD_Z 0xffffffff, 0xffc00000, 22 -#define MASK_WCI_HA_ESR_1_ACC_GNR_ERR 0x0, 0x200000, 21 -#define MASK_WCI_HA_ESR_1_ACC_HW_ERR 0x0, 0x100000, 20 -#define MASK_WCI_HA_ESR_1_ACC_ADDRESS_NOT_MAPPED 0x0, 0x80000, 19 -#define MASK_WCI_HA_ESR_1_ACC_DSTAT_INCONSISTENT 0x0, 0x40000, 18 -#define MASK_WCI_HA_ESR_1_ACC_MTAG_NOT_GM 0x0, 0x20000, 17 -#define MASK_WCI_HA_ESR_1_ACC_UNEXPECTED_MTAG 0x0, 0x10000, 16 -#define MASK_WCI_HA_ESR_1_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_HA_ESR_1_RSVD_Y 0x0, 0x7fc0, 6 -#define MASK_WCI_HA_ESR_1_GNR_ERR 0x0, 0x20, 5 -#define MASK_WCI_HA_ESR_1_HW_ERR 0x0, 0x10, 4 -#define MASK_WCI_HA_ESR_1_ADDRESS_NOT_MAPPED 0x0, 0x8, 3 -#define MASK_WCI_HA_ESR_1_DSTAT_INCONSISTENT 0x0, 0x4, 2 -#define MASK_WCI_HA_ESR_1_MTAG_NOT_GM 0x0, 0x2, 1 -#define MASK_WCI_HA_ESR_1_UNEXPECTED_MTAG 0x0, 0x1, 0 -#define MASK_WCI_HA_ESR_MASK_RSVD_Z 0xffffffff, 0xffc00000, 22 -#define MASK_WCI_HA_ESR_MASK_GNR_ERR 0x0, 0x200000, 21 -#define MASK_WCI_HA_ESR_MASK_HW_ERR 0x0, 0x100000, 20 -#define MASK_WCI_HA_ESR_MASK_ADDRESS_NOT_MAPPED 0x0, 0x80000, 19 -#define MASK_WCI_HA_ESR_MASK_DSTAT_INCONSISTENT 0x0, 0x40000, 18 -#define MASK_WCI_HA_ESR_MASK_MTAG_NOT_GM 0x0, 0x20000, 17 -#define MASK_WCI_HA_ESR_MASK_UNEXPECTED_MTAG 0x0, 0x10000, 16 -#define MASK_WCI_HA_ESR_MASK_RSVD_Y 0x0, 0xe000, 13 -#define MASK_WCI_HA_ESR_MASK_UNEXPECTED_SNID 0x0, 0x1000, 12 -#define MASK_WCI_HA_ESR_MASK_ADDRESS_NOT_MAPPED_IO 0x0, 0x800, 11 -#define MASK_WCI_HA_ESR_MASK_DIR_PARITY_ERROR 0x0, 0x400, 10 -#define MASK_WCI_HA_ESR_MASK_NOT_EXPECTED_COMPL 0x0, 0x200, 9 -#define MASK_WCI_HA_ESR_MASK_ILLEGAL_SENDER 0x0, 0x100, 8 -#define MASK_WCI_HA_ESR_MASK_WRONG_CMD 0x0, 0x80, 7 -#define MASK_WCI_HA_ESR_MASK_UNCORRECTABLE_MTAG_ERROR 0x0, 0x40, 6 -#define MASK_WCI_HA_ESR_MASK_UNCORRECTABLE_DATA_ERROR 0x0, 0x20, 5 -#define MASK_WCI_HA_ESR_MASK_CORRECTABLE_MTAG_ERROR 0x0, 0x10, 4 -#define MASK_WCI_HA_ESR_MASK_CORRECTABLE_DATA_ERROR 0x0, 0x8, 3 -#define MASK_WCI_HA_ESR_MASK_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x4, 2 -#define MASK_WCI_HA_ESR_MASK_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x2, 1 -#define MASK_WCI_HA_ESR_MASK_TIMEOUT 0x0, 0x1, 0 -#define MASK_WCI_HA_FIRST_ERROR_AGENT_ESR_REG 0x80000000, 0x0, 63 -#define MASK_WCI_HA_FIRST_ERROR_AGENT_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_HA_FIRST_ERROR_AGENT_RSVD_Z 0x7ffffff, 0xffffffe0, 5 -#define MASK_WCI_HA_FIRST_ERROR_AGENT_INSTANCE 0x0, 0x1f, 0 -#define MASK_WCI_HA_FIRST_PACKET_0_LO_A 0xfffffff0, 0x0, 36 -#define MASK_WCI_HA_FIRST_PACKET_0_RSVD_Z 0xf, 0xf0000000, 28 -#define MASK_WCI_HA_FIRST_PACKET_0_LO_B 0x0, 0xfffffff, 0 -#define MASK_WCI_HA_FIRST_PACKET_1_ESR_REG 0x80000000, 0x0, 63 -#define MASK_WCI_HA_FIRST_PACKET_1_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_HA_FIRST_PACKET_1_RSVD_Z 0x7ffffff, 0x80000000, 31 -#define MASK_WCI_HA_FIRST_PACKET_1_HI 0x0, 0x7fffffff, 0 -#define MASK_WCI_HA_FREEZE_RSVD_Z 0xffffffff, 0xffff0000, 16 -#define MASK_WCI_HA_FREEZE_VECTOR 0x0, 0xffff, 0 -#define MASK_WCI_HA_HW_ERR_STATUS_RSVD_Z 0xffffffff, 0xfff80000, 19 -#define MASK_WCI_HA_HW_ERR_STATUS_OH_ERROR_CASE_FALL_THROUGH 0x0, 0x40000, 18 -#define MASK_WCI_HA_HW_ERR_STATUS_DIR_FETCHQ_OVFL 0x0, 0x20000, 17 -#define MASK_WCI_HA_HW_ERR_STATUS_DIR_FETCHQ_UNFL 0x0, 0x10000, 16 -#define MASK_WCI_HA_HW_ERR_STATUS_SRQ4_ERRORS_OVFL 0x0, 0x8000, 15 -#define MASK_WCI_HA_HW_ERR_STATUS_SRQ4_ERRORS_UNFL 0x0, 0x4000, 14 -#define MASK_WCI_HA_HW_ERR_STATUS_SRQ3_ERRORS_OVFL 0x0, 0x2000, 13 -#define MASK_WCI_HA_HW_ERR_STATUS_SRQ3_ERRORS_UNFL 0x0, 0x1000, 12 -#define MASK_WCI_HA_HW_ERR_STATUS_SRQ2_ERRORS_OVFL 0x0, 0x800, 11 -#define MASK_WCI_HA_HW_ERR_STATUS_SRQ2_ERRORS_UNFL 0x0, 0x400, 10 -#define MASK_WCI_HA_HW_ERR_STATUS_SRQ1_ERRORS_OVFL 0x0, 0x200, 9 -#define MASK_WCI_HA_HW_ERR_STATUS_SRQ1_ERRORS_UNFL 0x0, 0x100, 8 -#define MASK_WCI_HA_HW_ERR_STATUS_KMAPQ_ERRORS_OVFL 0x0, 0x80, 7 -#define MASK_WCI_HA_HW_ERR_STATUS_KMAPQ_ERRORS_UNFL 0x0, 0x40, 6 -#define MASK_WCI_HA_HW_ERR_STATUS_OHQ_ERRORS_OVFL 0x0, 0x20, 5 -#define MASK_WCI_HA_HW_ERR_STATUS_OHQ_ERRORS_UNFL 0x0, 0x10, 4 -#define MASK_WCI_HA_HW_ERR_STATUS_SHQ_ERRORS_OVFL 0x0, 0x8, 3 -#define MASK_WCI_HA_HW_ERR_STATUS_SHQ_ERRORS_UNFL 0x0, 0x4, 2 -#define MASK_WCI_HA_HW_ERR_STATUS_DHC_ALL_UEXP_RCV_ERROR 0x0, 0x2, 1 -#define MASK_WCI_HA_HW_ERR_STATUS_DHC_ALL_UEXP_SND_ERROR 0x0, 0x1, 0 -#define MASK_WCI_HA_STATUS_2_ARRAY_RSVD_Z 0xfffffffc, 0x0, 34 -#define MASK_WCI_HA_STATUS_2_ARRAY_DIR_VLD 0x2, 0x0, 33 -#define MASK_WCI_HA_STATUS_2_ARRAY_DIR_HIT 0x1, 0x0, 32 -#define MASK_WCI_HA_STATUS_2_ARRAY_OLD_DIR_ENTRY 0x0, 0xfff00000, 20 -#define MASK_WCI_HA_STATUS_2_ARRAY_RSVD_Y 0x0, 0x80000, 19 -#define MASK_WCI_HA_STATUS_2_ARRAY_OLD_MTAG 0x0, 0x70000, 16 -#define MASK_WCI_HA_STATUS_2_ARRAY_DIR_COPT 0x0, 0xc000, 14 -#define MASK_WCI_HA_STATUS_2_ARRAY_DATA_COPT 0x0, 0x3000, 12 -#define MASK_WCI_HA_STATUS_2_ARRAY_RSVD_X 0x0, 0xe00, 9 -#define MASK_WCI_HA_STATUS_2_ARRAY_SAFARI_THREAD 0x0, 0x100, 8 -#define MASK_WCI_HA_STATUS_2_ARRAY_AUXID_THREAD 0x0, 0x80, 7 -#define MASK_WCI_HA_STATUS_2_ARRAY_CMPL_THREAD 0x0, 0x40, 6 -#define MASK_WCI_HA_STATUS_2_ARRAY_DATA_SENT_THREAD 0x0, 0x20, 5 -#define MASK_WCI_HA_STATUS_2_ARRAY_DATA_RCVD_THREAD 0x0, 0x10, 4 -#define MASK_WCI_HA_STATUS_2_ARRAY_DOB_CLRD_THREAD 0x0, 0x8, 3 -#define MASK_WCI_HA_STATUS_2_ARRAY_HDR_SENT_THREAD 0x0, 0x4, 2 -#define MASK_WCI_HA_STATUS_2_ARRAY_CONSTMAP_THREAD 0x0, 0x2, 1 -#define MASK_WCI_HA_STATUS_2_ARRAY_PULL_SEEN_THREAD 0x0, 0x1, 0 -#define MASK_WCI_HA_STATUS_ARRAY_ORIG_ATRANSID 0xff800000, 0x0, 55 -#define MASK_WCI_HA_STATUS_ARRAY_ORIG_RTID 0x7c0000, 0x0, 50 -#define MASK_WCI_HA_STATUS_ARRAY_DISPATCHED_OP 0x3f000, 0x0, 44 -#define MASK_WCI_HA_STATUS_ARRAY_RSVD_Z 0x800, 0x0, 43 -#define MASK_WCI_HA_STATUS_ARRAY_ORIG_ADDR 0x7ff, 0xfffffff0, 4 -#define MASK_WCI_HA_STATUS_ARRAY_ORIG_SNID 0x0, 0xf, 0 -#define MASK_WCI_HA_TIMEOUT_CONFIG_RSVD_Z 0xffffffff, 0xffffc000, 14 -#define MASK_WCI_HA_TIMEOUT_CONFIG_SSM_DISABLE 0x0, 0x2000, 13 -#define MASK_WCI_HA_TIMEOUT_CONFIG_SSM_FREEZE 0x0, 0x1000, 12 -#define MASK_WCI_HA_TIMEOUT_CONFIG_RSVD_Y 0x0, 0xc00, 10 -#define MASK_WCI_HA_TIMEOUT_CONFIG_SSM_MAG 0x0, 0x300, 8 -#define MASK_WCI_HA_TIMEOUT_CONFIG_SSM_VAL 0x0, 0xff, 0 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_HAG_ROUTE_MAP0_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_HAG_ROUTE_MAP0_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_HAG_ROUTE_MAP1_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_HAG_ROUTE_MAP1_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_HLI_ESR_RSVD_Z 0xffffffff, 0xff800000, 23 -#define MASK_WCI_HLI_ESR_ACC_SLQ_PERR 0x0, 0x400000, 22 -#define MASK_WCI_HLI_ESR_ACC_HMQ_PERR 0x0, 0x200000, 21 -#define MASK_WCI_HLI_ESR_ACC_STRANGE_PKT 0x0, 0x100000, 20 -#define MASK_WCI_HLI_ESR_ACC_BQ_UNFL 0x0, 0x80000, 19 -#define MASK_WCI_HLI_ESR_ACC_HMQ_UNFL 0x0, 0x40000, 18 -#define MASK_WCI_HLI_ESR_ACC_HMQ_OVFL 0x0, 0x20000, 17 -#define MASK_WCI_HLI_ESR_ACC_SLQ_OVFL 0x0, 0x10000, 16 -#define MASK_WCI_HLI_ESR_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_HLI_ESR_RSVD_Y 0x0, 0x7f80, 7 -#define MASK_WCI_HLI_ESR_SLQ_PERR 0x0, 0x40, 6 -#define MASK_WCI_HLI_ESR_HMQ_PERR 0x0, 0x20, 5 -#define MASK_WCI_HLI_ESR_STRANGE_PKT 0x0, 0x10, 4 -#define MASK_WCI_HLI_ESR_BQ_UNFL 0x0, 0x8, 3 -#define MASK_WCI_HLI_ESR_HMQ_UNFL 0x0, 0x4, 2 -#define MASK_WCI_HLI_ESR_HMQ_OVFL 0x0, 0x2, 1 -#define MASK_WCI_HLI_ESR_SLQ_OVFL 0x0, 0x1, 0 -#define MASK_WCI_HLI_ESR_MASK_RSVD_Z 0xffffffff, 0xffffff80, 7 -#define MASK_WCI_HLI_ESR_MASK_SLQ_PERR 0x0, 0x40, 6 -#define MASK_WCI_HLI_ESR_MASK_HMQ_PERR 0x0, 0x20, 5 -#define MASK_WCI_HLI_ESR_MASK_STRANGE_PKT 0x0, 0x10, 4 -#define MASK_WCI_HLI_ESR_MASK_BQ_UNFL 0x0, 0x8, 3 -#define MASK_WCI_HLI_ESR_MASK_HMQ_UNFL 0x0, 0x4, 2 -#define MASK_WCI_HLI_ESR_MASK_HMQ_OVFL 0x0, 0x2, 1 -#define MASK_WCI_HLI_ESR_MASK_SLQ_OVFL 0x0, 0x1, 0 -#define MASK_WCI_HLI_STATE_RSVD_Z 0x80000000, 0x0, 63 -#define MASK_WCI_HLI_STATE_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_HLI_STATE_RSVD_Y 0x7ffffff, 0xfe000000, 25 -#define MASK_WCI_HLI_STATE_QUEUE 0x0, 0x1ffff00, 8 -#define MASK_WCI_HLI_STATE_INDEX 0x0, 0xff, 0 -#define MASK_WCI_HLI_STRANGE_PKT_0_LO 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_HLI_STRANGE_PKT_1_RSVD_Z 0xffffffff, 0x80000000, 31 -#define MASK_WCI_HLI_STRANGE_PKT_1_HI 0x0, 0x7fffffff, 0 -#define MASK_WCI_ID_RSVD_Z 0xffffffff, 0x0, 32 -#define MASK_WCI_ID_VERSION 0x0, 0xf0000000, 28 -#define MASK_WCI_ID_PARID 0x0, 0xffff000, 12 -#define MASK_WCI_ID_MANFID 0x0, 0xffe, 1 -#define MASK_WCI_ID_ONE 0x0, 0x1, 0 -#define MASK_WCI_INID2DNID_ARRAY_RSVD_Z 0xffffffff, 0xfffffff0, 4 -#define MASK_WCI_INID2DNID_ARRAY_DNID 0x0, 0xf, 0 -#define MASK_WCI_INT_DEST_BUSY_COUNT_VALUE 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_JNK_ROUTE_MAP0_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_JNK_ROUTE_MAP0_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_JNK_ROUTE_MAP1_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_JNK_ROUTE_MAP1_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_LINK_CTR_CNT1 0xffffffff, 0x0, 32 -#define MASK_WCI_LINK_CTR_CNT0 0x0, 0xffffffff, 0 -#define MASK_WCI_LINK_CTR_CTL_RSVD_Z 0xffffffff, 0x80000000, 31 -#define MASK_WCI_LINK_CTR_CTL_CNT1_SOURCE_SELECT 0x0, 0x60000000, 29 -#define MASK_WCI_LINK_CTR_CTL_CNT1_GNID_TARGET 0x0, 0x1e000000, 25 -#define MASK_WCI_LINK_CTR_CTL_CNT1_SNID_TARGET 0x0, 0x1e00000, 21 -#define MASK_WCI_LINK_CTR_CTL_CNT1_RCVD_ADMIN_PACKET 0x0, 0x100000, 20 -#define MASK_WCI_LINK_CTR_CTL_CNT1_REJECTED_NORMAL_FLIT 0x0, 0x80000, 19 -#define MASK_WCI_LINK_CTR_CTL_CNT1_DATA_RCVD_DATA_PACKET 0x0, 0x40000, 18 -#define MASK_WCI_LINK_CTR_CTL_CNT1_MHOP_RCVD_DATA_PACKET 0x0, 0x20000, 17 -#define MASK_WCI_LINK_CTR_CTL_CNT1_XMITTING_ADMIN_PACKET 0x0, 0x10000, 16 -#define MASK_WCI_LINK_CTR_CTL_RSVD_Y 0x0, 0x8000, 15 -#define MASK_WCI_LINK_CTR_CTL_CNT0_SOURCE_SELECT 0x0, 0x6000, 13 -#define MASK_WCI_LINK_CTR_CTL_CNT0_GNID_TARGET 0x0, 0x1e00, 9 -#define MASK_WCI_LINK_CTR_CTL_CNT0_SNID_TARGET 0x0, 0x1e0, 5 -#define MASK_WCI_LINK_CTR_CTL_CNT0_RCVD_ADMIN_PACKET 0x0, 0x10, 4 -#define MASK_WCI_LINK_CTR_CTL_CNT0_REJECTED_NORMAL_FLIT 0x0, 0x8, 3 -#define MASK_WCI_LINK_CTR_CTL_CNT0_DATA_RCVD_DATA_PACKET 0x0, 0x4, 2 -#define MASK_WCI_LINK_CTR_CTL_CNT0_MHOP_RCVD_DATA_PACKET 0x0, 0x2, 1 -#define MASK_WCI_LINK_CTR_CTL_CNT0_XMITTING_ADMIN_PACKET 0x0, 0x1, 0 -#define MASK_WCI_LINK_ESR_RSVD_Z 0xffffffff, 0xff000000, 24 -#define MASK_WCI_LINK_ESR_ACC_LINK_2_ILLEGAL_GNID 0x0, 0x800000, 23 -#define MASK_WCI_LINK_ESR_ACC_LINK_2_ILLEGAL_LINK 0x0, 0x400000, 22 -#define MASK_WCI_LINK_ESR_RSVD_Y 0x0, 0x200000, 21 -#define MASK_WCI_LINK_ESR_ACC_LINK_1_ILLEGAL_GNID 0x0, 0x100000, 20 -#define MASK_WCI_LINK_ESR_ACC_LINK_1_ILLEGAL_LINK 0x0, 0x80000, 19 -#define MASK_WCI_LINK_ESR_RSVD_X 0x0, 0x40000, 18 -#define MASK_WCI_LINK_ESR_ACC_LINK_0_ILLEGAL_GNID 0x0, 0x20000, 17 -#define MASK_WCI_LINK_ESR_ACC_LINK_0_ILLEGAL_LINK 0x0, 0x10000, 16 -#define MASK_WCI_LINK_ESR_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_LINK_ESR_RSVD_W 0x0, 0x7f00, 8 -#define MASK_WCI_LINK_ESR_LINK_2_ILLEGAL_GNID 0x0, 0x80, 7 -#define MASK_WCI_LINK_ESR_LINK_2_ILLEGAL_LINK 0x0, 0x40, 6 -#define MASK_WCI_LINK_ESR_RSVD_V 0x0, 0x20, 5 -#define MASK_WCI_LINK_ESR_LINK_1_ILLEGAL_GNID 0x0, 0x10, 4 -#define MASK_WCI_LINK_ESR_LINK_1_ILLEGAL_LINK 0x0, 0x8, 3 -#define MASK_WCI_LINK_ESR_RSVD_U 0x0, 0x4, 2 -#define MASK_WCI_LINK_ESR_LINK_0_ILLEGAL_GNID 0x0, 0x2, 1 -#define MASK_WCI_LINK_ESR_LINK_0_ILLEGAL_LINK 0x0, 0x1, 0 -#define MASK_WCI_LINK_ESR_MASK_RSVD_Z 0xffffffff, 0xffffff00, 8 -#define MASK_WCI_LINK_ESR_MASK_LINK_2_ILLEGAL_GNID 0x0, 0x80, 7 -#define MASK_WCI_LINK_ESR_MASK_LINK_2_ILLEGAL_LINK 0x0, 0x40, 6 -#define MASK_WCI_LINK_ESR_MASK_RSVD_Y 0x0, 0x20, 5 -#define MASK_WCI_LINK_ESR_MASK_LINK_1_ILLEGAL_GNID 0x0, 0x10, 4 -#define MASK_WCI_LINK_ESR_MASK_LINK_1_ILLEGAL_LINK 0x0, 0x8, 3 -#define MASK_WCI_LINK_ESR_MASK_RSVD_X 0x0, 0x4, 2 -#define MASK_WCI_LINK_ESR_MASK_LINK_0_ILLEGAL_GNID 0x0, 0x2, 1 -#define MASK_WCI_LINK_ESR_MASK_LINK_0_ILLEGAL_LINK 0x0, 0x1, 0 -#define MASK_WCI_LOCAL_DEVICE_ID_SKIP_RS_VEC 0xffffffff, 0x0, 32 -#define MASK_WCI_LOCAL_DEVICE_ID_SSM_MASK 0x0, 0xffffffff, 0 -#define MASK_WCI_LPBK_CTR_CNT1 0xffffffff, 0x0, 32 -#define MASK_WCI_LPBK_CTR_CNT0 0x0, 0xffffffff, 0 -#define MASK_WCI_LPBK_CTR_CTL_RSVD_Z 0xffffffff, 0xfc000000, 26 -#define MASK_WCI_LPBK_CTR_CTL_CNT1_DATA_GNID_SOURCE_SELECT 0x0, 0x2000000, 25 -#define MASK_WCI_LPBK_CTR_CTL_CNT1_DATA_GNID_TARGET 0x0, 0x1e00000, 21 -#define MASK_WCI_LPBK_CTR_CTL_CNT1_ADDR_LPBK_FULL 0x0, 0x100000, 20 -#define MASK_WCI_LPBK_CTR_CTL_CNT1_DATA_LPBK_FULL 0x0, 0x80000, 19 -#define MASK_WCI_LPBK_CTR_CTL_CNT1_ADDR_LPBK_RCVD_ADDR_1_PACKET 0x0, 0x40000, 18 -#define MASK_WCI_LPBK_CTR_CTL_CNT1_ADDR_LPBK_RCVD_ADDR_2_PACKET 0x0, 0x20000, 17 -#define MASK_WCI_LPBK_CTR_CTL_CNT1_DATA_LPBK_RCVD_DATA_PACKET 0x0, 0x10000, 16 -#define MASK_WCI_LPBK_CTR_CTL_RSVD_Y 0x0, 0xfc00, 10 -#define MASK_WCI_LPBK_CTR_CTL_CNT0_DATA_GNID_SOURCE_SELECT 0x0, 0x200, 9 -#define MASK_WCI_LPBK_CTR_CTL_CNT0_DATA_GNID_TARGET 0x0, 0x1e0, 5 -#define MASK_WCI_LPBK_CTR_CTL_CNT0_ADDR_LPBK_FULL 0x0, 0x10, 4 -#define MASK_WCI_LPBK_CTR_CTL_CNT0_DATA_LPBK_FULL 0x0, 0x8, 3 -#define MASK_WCI_LPBK_CTR_CTL_CNT0_ADDR_LPBK_RCVD_ADDR_1_PACKET 0x0, 0x4, 2 -#define MASK_WCI_LPBK_CTR_CTL_CNT0_ADDR_LPBK_RCVD_ADDR_2_PACKET 0x0, 0x2, 1 -#define MASK_WCI_LPBK_CTR_CTL_CNT0_DATA_LPBK_RCVD_DATA_PACKET 0x0, 0x1, 0 -#define MASK_WCI_MAX_RSVD_Z 0xfffffff8, 0x0, 35 -#define MASK_WCI_MAX_SEL 0x7, 0x0, 32 -#define MASK_WCI_MAX_VALUE 0x0, 0xffffffff, 0 -#define MASK_WCI_MISC_CTR_COUNT1 0xffffffff, 0x0, 32 -#define MASK_WCI_MISC_CTR_COUNT0 0x0, 0xffffffff, 0 -#define MASK_WCI_MISC_CTR_CTL_RSVD_Z 0xffffffff, 0xffe00000, 21 -#define MASK_WCI_MISC_CTR_CTL_DURATION_MODE 0x0, 0x100000, 20 -#define MASK_WCI_MISC_CTR_CTL_CNT1_AGENT_SELECT 0x0, 0xf0000, 16 -#define MASK_WCI_MISC_CTR_CTL_CNT1_EVENT_SELECT 0x0, 0xfc00, 10 -#define MASK_WCI_MISC_CTR_CTL_CNT0_AGENT_SELECT 0x0, 0x3c0, 6 -#define MASK_WCI_MISC_CTR_CTL_CNT0_EVENT_SELECT 0x0, 0x3f, 0 -#define MASK_WCI_MONITOR_PINS_RSVD_Z 0xffff0000, 0x0, 48 -#define MASK_WCI_MONITOR_PINS_MONITOR_PINS 0xffff, 0x0, 32 -#define MASK_WCI_MONITOR_PINS_RSVD_Y 0x0, 0xfffffe00, 9 -#define MASK_WCI_MONITOR_PINS_SIGNAL_SEL 0x0, 0x1f0, 4 -#define MASK_WCI_MONITOR_PINS_MODULE_SEL 0x0, 0xf, 0 -#define MASK_WCI_NC2NID_ARRAY_RSVD_Z 0xffffffff, 0xffffff00, 8 -#define MASK_WCI_NC2NID_ARRAY_NO_STRIPE 0x0, 0x80, 7 -#define MASK_WCI_NC2NID_ARRAY_ENCODE_CLUSTER_ORIGIN_TAG 0x0, 0x40, 6 -#define MASK_WCI_NC2NID_ARRAY_LAUNCH_REMOTE 0x0, 0x20, 5 -#define MASK_WCI_NC2NID_ARRAY_LAUNCH_LOCAL_SRAM 0x0, 0x10, 4 -#define MASK_WCI_NC2NID_ARRAY_DEST_NODE_ID 0x0, 0xf, 0 -#define MASK_WCI_NC_SLICE_CONFIG_ARRAY_CONFIG 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_OS_CLUSTER_DISABLE_RSVD_Z 0xffffffff, 0xfffffff0, 4 -#define MASK_WCI_OS_CLUSTER_DISABLE_CA_CLUSTER_DISABLE 0x0, 0x8, 3 -#define MASK_WCI_OS_CLUSTER_DISABLE_RA_PIQ_DISABLE 0x0, 0x4, 2 -#define MASK_WCI_OS_CLUSTER_DISABLE_RA_NIQ_DISABLE 0x0, 0x2, 1 -#define MASK_WCI_OS_CLUSTER_DISABLE_RA_CIQ_DISABLE 0x0, 0x1, 0 -#define MASK_WCI_PROBE_MEMORY_DONE 0x80000000, 0x0, 63 -#define MASK_WCI_PROBE_MEMORY_IN_PROGRESS 0x40000000, 0x0, 62 -#define MASK_WCI_PROBE_MEMORY_RSVD_Z 0x3fff8000, 0x0, 47 -#define MASK_WCI_PROBE_MEMORY_MTAG 0x7000, 0x0, 44 -#define MASK_WCI_PROBE_MEMORY_RSVD_Y 0x800, 0x0, 43 -#define MASK_WCI_PROBE_MEMORY_ADDRESS 0x7ff, 0xfffffff0, 4 -#define MASK_WCI_PROBE_MEMORY_RSVD_X 0x0, 0xf, 0 -#define MASK_WCI_QLIM_2REQ_PRIORITY_RSVD_Z 0xf0000000, 0x0, 60 -#define MASK_WCI_QLIM_2REQ_PRIORITY_CIQ_NIQ_NUM_SLOTS 0xf000000, 0x0, 56 -#define MASK_WCI_QLIM_2REQ_PRIORITY_PIQ_CIQ_NUM_SLOTS 0xf00000, 0x0, 52 -#define MASK_WCI_QLIM_2REQ_PRIORITY_NIQ_PIQ_NUM_SLOTS 0xf0000, 0x0, 48 -#define MASK_WCI_QLIM_2REQ_PRIORITY_CIQ_NIQ_ARB_SLOTS 0xffff, 0x0, 32 -#define MASK_WCI_QLIM_2REQ_PRIORITY_PIQ_CIQ_ARB_SLOTS 0x0, 0xffff0000, 16 -#define MASK_WCI_QLIM_2REQ_PRIORITY_NIQ_PIQ_ARB_SLOTS 0x0, 0xffff, 0 -#define MASK_WCI_QLIM_3REQ_PRIORITY_RSVD_Z 0xfffffff0, 0x0, 36 -#define MASK_WCI_QLIM_3REQ_PRIORITY_NUM_SLOTS 0xf, 0x0, 32 -#define MASK_WCI_QLIM_3REQ_PRIORITY_ARB_SLOTS 0x0, 0xffffffff, 0 -#define MASK_WCI_QLIM_CAG_TIMER_RSVD_Z 0xffffffff, 0xe0000000, 29 -#define MASK_WCI_QLIM_CAG_TIMER_VALUE 0x0, 0x1fffffff, 0 -#define MASK_WCI_QLIM_CIQ_TIMER_RSVD_Z 0xffffffff, 0xe0000000, 29 -#define MASK_WCI_QLIM_CIQ_TIMER_VALUE 0x0, 0x1fffffff, 0 -#define MASK_WCI_QLIM_CONFIG_CAG_FREEZE 0x80000000, 0x0, 63 -#define MASK_WCI_QLIM_CONFIG_CAG_DISABLE 0x40000000, 0x0, 62 -#define MASK_WCI_QLIM_CONFIG_CAG_RSVD_Z 0x3fe00000, 0x0, 53 -#define MASK_WCI_QLIM_CONFIG_CAG_MAX_DISCARD 0x1fff00, 0x0, 40 -#define MASK_WCI_QLIM_CONFIG_CAG_RSVD_Y 0xc0, 0x0, 38 -#define MASK_WCI_QLIM_CONFIG_CAG_NUM2DISCARD 0x3f, 0xf0000000, 28 -#define MASK_WCI_QLIM_CONFIG_CAG_RSVD_X 0x0, 0xffe0000, 17 -#define MASK_WCI_QLIM_CONFIG_CAG_TMIN_MAG 0x0, 0x1fff0, 4 -#define MASK_WCI_QLIM_CONFIG_CAG_RSVD_W 0x0, 0x8, 3 -#define MASK_WCI_QLIM_CONFIG_CAG_HWMARK_EXP 0x0, 0x7, 0 -#define MASK_WCI_QLIM_CONFIG_CIQ_FREEZE 0x80000000, 0x0, 63 -#define MASK_WCI_QLIM_CONFIG_CIQ_DISABLE 0x40000000, 0x0, 62 -#define MASK_WCI_QLIM_CONFIG_CIQ_RSVD_Z 0x30000000, 0x0, 60 -#define MASK_WCI_QLIM_CONFIG_CIQ_DISCARD_CNT_TIMER_EN 0x8000000, 0x0, 59 -#define MASK_WCI_QLIM_CONFIG_CIQ_DISCARD_CNT_TIMER_MAG 0x7000000, 0x0, 56 -#define MASK_WCI_QLIM_CONFIG_CIQ_DISCARD_CNT_TIMER_VAL 0xe00000, 0x0, 53 -#define MASK_WCI_QLIM_CONFIG_CIQ_MAX_DISCARD 0x1fff00, 0x0, 40 -#define MASK_WCI_QLIM_CONFIG_CIQ_RSVD_Y 0xc0, 0x0, 38 -#define MASK_WCI_QLIM_CONFIG_CIQ_NUM2DISCARD 0x3f, 0xf0000000, 28 -#define MASK_WCI_QLIM_CONFIG_CIQ_RSVD_X 0x0, 0xf000000, 24 -#define MASK_WCI_QLIM_CONFIG_CIQ_DECAY 0x0, 0xf00000, 20 -#define MASK_WCI_QLIM_CONFIG_CIQ_RSVD_W 0x0, 0xe0000, 17 -#define MASK_WCI_QLIM_CONFIG_CIQ_TMIN_MAG 0x0, 0x1fff0, 4 -#define MASK_WCI_QLIM_CONFIG_CIQ_RSVD_V 0x0, 0x8, 3 -#define MASK_WCI_QLIM_CONFIG_CIQ_HWMARK_EXP 0x0, 0x7, 0 -#define MASK_WCI_QLIM_CONFIG_NIQ_FREEZE 0x80000000, 0x0, 63 -#define MASK_WCI_QLIM_CONFIG_NIQ_DISABLE 0x40000000, 0x0, 62 -#define MASK_WCI_QLIM_CONFIG_NIQ_RSVD_Z 0x30000000, 0x0, 60 -#define MASK_WCI_QLIM_CONFIG_NIQ_DISCARD_CNT_TIMER_EN 0x8000000, 0x0, 59 -#define MASK_WCI_QLIM_CONFIG_NIQ_DISCARD_CNT_TIMER_MAG 0x7000000, 0x0, 56 -#define MASK_WCI_QLIM_CONFIG_NIQ_DISCARD_CNT_TIMER_VAL 0xe00000, 0x0, 53 -#define MASK_WCI_QLIM_CONFIG_NIQ_MAX_DISCARD 0x1fff00, 0x0, 40 -#define MASK_WCI_QLIM_CONFIG_NIQ_RSVD_Y 0xc0, 0x0, 38 -#define MASK_WCI_QLIM_CONFIG_NIQ_NUM2DISCARD 0x3f, 0xf0000000, 28 -#define MASK_WCI_QLIM_CONFIG_NIQ_RSVD_X 0x0, 0xf000000, 24 -#define MASK_WCI_QLIM_CONFIG_NIQ_DECAY 0x0, 0xf00000, 20 -#define MASK_WCI_QLIM_CONFIG_NIQ_RSVD_W 0x0, 0xe0000, 17 -#define MASK_WCI_QLIM_CONFIG_NIQ_TMIN_MAG 0x0, 0x1fff0, 4 -#define MASK_WCI_QLIM_CONFIG_NIQ_RSVD_V 0x0, 0x8, 3 -#define MASK_WCI_QLIM_CONFIG_NIQ_HWMARK_EXP 0x0, 0x7, 0 -#define MASK_WCI_QLIM_CONFIG_PIQ_FREEZE 0x80000000, 0x0, 63 -#define MASK_WCI_QLIM_CONFIG_PIQ_DISABLE 0x40000000, 0x0, 62 -#define MASK_WCI_QLIM_CONFIG_PIQ_RSVD_Z 0x30000000, 0x0, 60 -#define MASK_WCI_QLIM_CONFIG_PIQ_DISCARD_CNT_TIMER_EN 0x8000000, 0x0, 59 -#define MASK_WCI_QLIM_CONFIG_PIQ_DISCARD_CNT_TIMER_MAG 0x7000000, 0x0, 56 -#define MASK_WCI_QLIM_CONFIG_PIQ_DISCARD_CNT_TIMER_VAL 0xe00000, 0x0, 53 -#define MASK_WCI_QLIM_CONFIG_PIQ_MAX_DISCARD 0x1fff00, 0x0, 40 -#define MASK_WCI_QLIM_CONFIG_PIQ_RSVD_Y 0xc0, 0x0, 38 -#define MASK_WCI_QLIM_CONFIG_PIQ_NUM2DISCARD 0x3f, 0xf0000000, 28 -#define MASK_WCI_QLIM_CONFIG_PIQ_RSVD_X 0x0, 0xf000000, 24 -#define MASK_WCI_QLIM_CONFIG_PIQ_DECAY 0x0, 0xf00000, 20 -#define MASK_WCI_QLIM_CONFIG_PIQ_RSVD_W 0x0, 0xe0000, 17 -#define MASK_WCI_QLIM_CONFIG_PIQ_TMIN_MAG 0x0, 0x1fff0, 4 -#define MASK_WCI_QLIM_CONFIG_PIQ_RSVD_V 0x0, 0x8, 3 -#define MASK_WCI_QLIM_CONFIG_PIQ_HWMARK_EXP 0x0, 0x7, 0 -#define MASK_WCI_QLIM_NIQ_TIMER_RSVD_Z 0xffffffff, 0xe0000000, 29 -#define MASK_WCI_QLIM_NIQ_TIMER_VALUE 0x0, 0x1fffffff, 0 -#define MASK_WCI_QLIM_PIQ_TIMER_RSVD_Z 0xffffffff, 0xe0000000, 29 -#define MASK_WCI_QLIM_PIQ_TIMER_VALUE 0x0, 0x1fffffff, 0 -#define MASK_WCI_QLIM_SORT_CIQ_RSVD_Z 0xffffffff, 0x0, 32 -#define MASK_WCI_QLIM_SORT_CIQ_DEV_ID_VEC 0x0, 0xffffffff, 0 -#define MASK_WCI_QLIM_SORT_NIQ_RSVD_Z 0xffffffff, 0x0, 32 -#define MASK_WCI_QLIM_SORT_NIQ_DEV_ID_VEC 0x0, 0xffffffff, 0 -#define MASK_WCI_QLIM_SORT_PIQ_RSVD_Z 0xffffffff, 0x0, 32 -#define MASK_WCI_QLIM_SORT_PIQ_DEV_ID_VEC 0x0, 0xffffffff, 0 -#define MASK_WCI_RA_BUSY_REQUEST_SYNCH 0xffffffff, 0x0, 32 -#define MASK_WCI_RA_BUSY_VECTOR 0x0, 0xffffffff, 0 -#define MASK_WCI_RA_ECC_ADDRESS_DATA 0x80000000, 0x0, 63 -#define MASK_WCI_RA_ECC_ADDRESS_UE 0x40000000, 0x0, 62 -#define MASK_WCI_RA_ECC_ADDRESS_ATRANSID 0x3fe00000, 0x0, 53 -#define MASK_WCI_RA_ECC_ADDRESS_TRANSACTION_TYPE 0x1f8000, 0x0, 47 -#define MASK_WCI_RA_ECC_ADDRESS_RSVD_Z 0x7800, 0x0, 43 -#define MASK_WCI_RA_ECC_ADDRESS_ADDR 0x7ff, 0xfffffff0, 4 -#define MASK_WCI_RA_ECC_ADDRESS_RSVD_Y 0x0, 0xf, 0 -#define MASK_WCI_RA_ERROR_TRANSACTION_0_ESR_REG 0x80000000, 0x0, 63 -#define MASK_WCI_RA_ERROR_TRANSACTION_0_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_RA_ERROR_TRANSACTION_0_RSVD_Z 0x7000000, 0x0, 56 -#define MASK_WCI_RA_ERROR_TRANSACTION_0_CESR_INDEX 0xff0000, 0x0, 48 -#define MASK_WCI_RA_ERROR_TRANSACTION_0_ATRANSID 0xff80, 0x0, 39 -#define MASK_WCI_RA_ERROR_TRANSACTION_0_ADDR 0x7f, 0xffffffff, 0 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_FSM_STATE 0xfe000000, 0x0, 57 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_RSVD_Z 0x1ffffff, 0x0, 32 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_RTID 0x0, 0xf0000000, 28 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_RSVD_Y 0x0, 0x8000000, 27 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_DH_ERRORS 0x0, 0x7f00000, 20 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_ERROR_CODE 0x0, 0xf0000, 16 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_RCV_CNTR 0x0, 0xc000, 14 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_SND_CNTR 0x0, 0x3000, 12 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_TMOT_ERR 0x0, 0x800, 11 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_RH_ERR 0x0, 0x400, 10 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_TRANSACTION_TYPE 0x0, 0x3f0, 4 -#define MASK_WCI_RA_ERROR_TRANSACTION_1_RSVD_X 0x0, 0xf, 0 -#define MASK_WCI_RA_ESR_0_RSVD_Z 0xffffffff, 0x80000000, 31 -#define MASK_WCI_RA_ESR_0_ACC_SSM_TIMEOUT 0x0, 0x40000000, 30 -#define MASK_WCI_RA_ESR_0_ACC_WRONG_REPLY 0x0, 0x20000000, 29 -#define MASK_WCI_RA_ESR_0_ACC_ILLEGAL_SENDER 0x0, 0x10000000, 28 -#define MASK_WCI_RA_ESR_0_ACC_NOT_EXPECTED_REPLY 0x0, 0x8000000, 27 -#define MASK_WCI_RA_ESR_0_ACC_QLIMIT_TIMEOUT 0x0, 0x4000000, 26 -#define MASK_WCI_RA_ESR_0_ACC_UNEXPECTED_SNID 0x0, 0x2000000, 25 -#define MASK_WCI_RA_ESR_0_ACC_WRONG_SAFARI_COMMAND 0x0, 0x1000000, 24 -#define MASK_WCI_RA_ESR_0_ACC_NON_BLOCK_TRANS 0x0, 0x800000, 23 -#define MASK_WCI_RA_ESR_0_ACC_CESR_ERROR_WRONG 0x0, 0x400000, 22 -#define MASK_WCI_RA_ESR_0_ACC_CLUSTER_LOCAL_TIMEOUT 0x0, 0x200000, 21 -#define MASK_WCI_RA_ESR_0_ACC_CLUSTER_REMOTE_TIMEOUT 0x0, 0x100000, 20 -#define MASK_WCI_RA_ESR_0_ACC_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x80000, 19 -#define MASK_WCI_RA_ESR_0_ACC_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x40000, 18 -#define MASK_WCI_RA_ESR_0_ACC_DSTAT_INCONSISTENT 0x0, 0x20000, 17 -#define MASK_WCI_RA_ESR_0_ACC_MTAG_NOT_GM 0x0, 0x10000, 16 -#define MASK_WCI_RA_ESR_0_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_RA_ESR_0_SSM_TIMEOUT 0x0, 0x4000, 14 -#define MASK_WCI_RA_ESR_0_WRONG_REPLY 0x0, 0x2000, 13 -#define MASK_WCI_RA_ESR_0_ILLEGAL_SENDER 0x0, 0x1000, 12 -#define MASK_WCI_RA_ESR_0_NOT_EXPECTED_REPLY 0x0, 0x800, 11 -#define MASK_WCI_RA_ESR_0_QLIMIT_TIMEOUT 0x0, 0x400, 10 -#define MASK_WCI_RA_ESR_0_UNEXPECTED_SNID 0x0, 0x200, 9 -#define MASK_WCI_RA_ESR_0_WRONG_SAFARI_COMMAND 0x0, 0x100, 8 -#define MASK_WCI_RA_ESR_0_NON_BLOCK_TRANS 0x0, 0x80, 7 -#define MASK_WCI_RA_ESR_0_CESR_ERROR_WRONG 0x0, 0x40, 6 -#define MASK_WCI_RA_ESR_0_CLUSTER_LOCAL_TIMEOUT 0x0, 0x20, 5 -#define MASK_WCI_RA_ESR_0_CLUSTER_REMOTE_TIMEOUT 0x0, 0x10, 4 -#define MASK_WCI_RA_ESR_0_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x8, 3 -#define MASK_WCI_RA_ESR_0_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x4, 2 -#define MASK_WCI_RA_ESR_0_DSTAT_INCONSISTENT 0x0, 0x2, 1 -#define MASK_WCI_RA_ESR_0_MTAG_NOT_GM 0x0, 0x1, 0 -#define MASK_WCI_RA_ESR_1_RSVD_Z 0xffffffff, 0x80000000, 31 -#define MASK_WCI_RA_ESR_1_ACC_WRITE_LOCKOUT 0x0, 0x40000000, 30 -#define MASK_WCI_RA_ESR_1_ACC_UNEXPECTED_MTAG 0x0, 0x20000000, 29 -#define MASK_WCI_RA_ESR_1_ACC_ADDRESS_NOT_MAPPED 0x0, 0x10000000, 28 -#define MASK_WCI_RA_ESR_1_ACC_ILLEGAL_HOME_NODE 0x0, 0x8000000, 27 -#define MASK_WCI_RA_ESR_1_ACC_LPA2GA_ECC_ERROR 0x0, 0x4000000, 26 -#define MASK_WCI_RA_ESR_1_ACC_LPA2GA_VIOLATION 0x0, 0x2000000, 25 -#define MASK_WCI_RA_ESR_1_ACC_UNEXPECTED_SEND_ACK 0x0, 0x1000000, 24 -#define MASK_WCI_RA_ESR_1_ACC_UNEXPECTED_RECEIVE_ACK 0x0, 0x800000, 23 -#define MASK_WCI_RA_ESR_1_ACC_INVALID_REPLY_PATTERN 0x0, 0x400000, 22 -#define MASK_WCI_RA_ESR_1_ACC_HW_PROTOCOL_ERROR 0x0, 0x200000, 21 -#define MASK_WCI_RA_ESR_1_ACC_HW_FIFO_OVFL_UNFL 0x0, 0x100000, 20 -#define MASK_WCI_RA_ESR_1_ACC_CORRECTABLE_MTAG_ERROR 0x0, 0x80000, 19 -#define MASK_WCI_RA_ESR_1_ACC_CORRECTABLE_DATA_ERROR 0x0, 0x40000, 18 -#define MASK_WCI_RA_ESR_1_ACC_UNCORRECTABLE_MTAG_ERROR 0x0, 0x20000, 17 -#define MASK_WCI_RA_ESR_1_ACC_UNCORRECTABLE_DATA_ERROR 0x0, 0x10000, 16 -#define MASK_WCI_RA_ESR_1_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_RA_ESR_1_WRITE_LOCKOUT 0x0, 0x4000, 14 -#define MASK_WCI_RA_ESR_1_UNEXPECTED_MTAG 0x0, 0x2000, 13 -#define MASK_WCI_RA_ESR_1_ADDRESS_NOT_MAPPED 0x0, 0x1000, 12 -#define MASK_WCI_RA_ESR_1_ILLEGAL_HOME_NODE 0x0, 0x800, 11 -#define MASK_WCI_RA_ESR_1_LPA2GA_ECC_ERROR 0x0, 0x400, 10 -#define MASK_WCI_RA_ESR_1_LPA2GA_VIOLATION 0x0, 0x200, 9 -#define MASK_WCI_RA_ESR_1_UNEXPECTED_SEND_ACK 0x0, 0x100, 8 -#define MASK_WCI_RA_ESR_1_UNEXPECTED_RECEIVE_ACK 0x0, 0x80, 7 -#define MASK_WCI_RA_ESR_1_INVALID_REPLY_PATTERN 0x0, 0x40, 6 -#define MASK_WCI_RA_ESR_1_HW_PROTOCOL_ERROR 0x0, 0x20, 5 -#define MASK_WCI_RA_ESR_1_HW_FIFO_OVFL_UNFL 0x0, 0x10, 4 -#define MASK_WCI_RA_ESR_1_CORRECTABLE_MTAG_ERROR 0x0, 0x8, 3 -#define MASK_WCI_RA_ESR_1_CORRECTABLE_DATA_ERROR 0x0, 0x4, 2 -#define MASK_WCI_RA_ESR_1_UNCORRECTABLE_MTAG_ERROR 0x0, 0x2, 1 -#define MASK_WCI_RA_ESR_1_UNCORRECTABLE_DATA_ERROR 0x0, 0x1, 0 -#define MASK_WCI_RA_ESR_MASK_RSVD_Z 0xffffffff, 0x80000000, 31 -#define MASK_WCI_RA_ESR_MASK_WRITE_LOCKOUT 0x0, 0x40000000, 30 -#define MASK_WCI_RA_ESR_MASK_UNEXPECTED_MTAG 0x0, 0x20000000, 29 -#define MASK_WCI_RA_ESR_MASK_ADDRESS_NOT_MAPPED 0x0, 0x10000000, 28 -#define MASK_WCI_RA_ESR_MASK_ILLEGAL_HOME_NODE 0x0, 0x8000000, 27 -#define MASK_WCI_RA_ESR_MASK_LPA2GA_ECC_ERROR 0x0, 0x4000000, 26 -#define MASK_WCI_RA_ESR_MASK_LPA2GA_VIOLATION 0x0, 0x2000000, 25 -#define MASK_WCI_RA_ESR_MASK_UNEXPECTED_SEND_ACK 0x0, 0x1000000, 24 -#define MASK_WCI_RA_ESR_MASK_UNEXPECTED_RECEIVE_ACK 0x0, 0x800000, 23 -#define MASK_WCI_RA_ESR_MASK_INVALID_REPLY_PATTERN 0x0, 0x400000, 22 -#define MASK_WCI_RA_ESR_MASK_HW_PROTOCOL_ERROR 0x0, 0x200000, 21 -#define MASK_WCI_RA_ESR_MASK_HW_FIFO_OVFL_UNFL 0x0, 0x100000, 20 -#define MASK_WCI_RA_ESR_MASK_CORRECTABLE_MTAG_ERROR 0x0, 0x80000, 19 -#define MASK_WCI_RA_ESR_MASK_CORRECTABLE_DATA_ERROR 0x0, 0x40000, 18 -#define MASK_WCI_RA_ESR_MASK_UNCORRECTABLE_MTAG_ERROR 0x0, 0x20000, 17 -#define MASK_WCI_RA_ESR_MASK_UNCORRECTABLE_DATA_ERROR 0x0, 0x10000, 16 -#define MASK_WCI_RA_ESR_MASK_RSVD_Y 0x0, 0x8000, 15 -#define MASK_WCI_RA_ESR_MASK_SSM_TIMEOUT 0x0, 0x4000, 14 -#define MASK_WCI_RA_ESR_MASK_WRONG_REPLY 0x0, 0x2000, 13 -#define MASK_WCI_RA_ESR_MASK_ILLEGAL_SENDER 0x0, 0x1000, 12 -#define MASK_WCI_RA_ESR_MASK_NOT_EXPECTED_REPLY 0x0, 0x800, 11 -#define MASK_WCI_RA_ESR_MASK_QLIMIT_TIMEOUT 0x0, 0x400, 10 -#define MASK_WCI_RA_ESR_MASK_UNEXPECTED_SNID 0x0, 0x200, 9 -#define MASK_WCI_RA_ESR_MASK_WRONG_SAFARI_COMMAND 0x0, 0x100, 8 -#define MASK_WCI_RA_ESR_MASK_NON_BLOCK_TRANS 0x0, 0x80, 7 -#define MASK_WCI_RA_ESR_MASK_CESR_ERROR_WRONG 0x0, 0x40, 6 -#define MASK_WCI_RA_ESR_MASK_CLUSTER_LOCAL_TIMEOUT 0x0, 0x20, 5 -#define MASK_WCI_RA_ESR_MASK_CLUSTER_REMOTE_TIMEOUT 0x0, 0x10, 4 -#define MASK_WCI_RA_ESR_MASK_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x8, 3 -#define MASK_WCI_RA_ESR_MASK_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x4, 2 -#define MASK_WCI_RA_ESR_MASK_DSTAT_INCONSISTENT 0x0, 0x2, 1 -#define MASK_WCI_RA_ESR_MASK_MTAG_NOT_GM 0x0, 0x1, 0 -#define MASK_WCI_RA_FIRST_ERROR_AGENT_ESR_REG 0x80000000, 0x0, 63 -#define MASK_WCI_RA_FIRST_ERROR_AGENT_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_RA_FIRST_ERROR_AGENT_RSVD_Z 0x7ffffff, 0xffffffe0, 5 -#define MASK_WCI_RA_FIRST_ERROR_AGENT_INSTANCE 0x0, 0x1f, 0 -#define MASK_WCI_RA_FIRST_PACKET_0_LO 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_RA_FIRST_PACKET_1_ESR_REG 0x80000000, 0x0, 63 -#define MASK_WCI_RA_FIRST_PACKET_1_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_RA_FIRST_PACKET_1_SFQ_INPUT 0x6000000, 0x0, 57 -#define MASK_WCI_RA_FIRST_PACKET_1_TRANSACTION_TYPE 0x1f80000, 0x0, 51 -#define MASK_WCI_RA_FIRST_PACKET_1_RSVD_Z 0x7ffff, 0x80000000, 31 -#define MASK_WCI_RA_FIRST_PACKET_1_HI 0x0, 0x7fffffff, 0 -#define MASK_WCI_RA_FREEZE_RSVD_Z 0xffffffff, 0x0, 32 -#define MASK_WCI_RA_FREEZE_VECTOR 0x0, 0xffffffff, 0 -#define MASK_WCI_RA_STATUS_2_ARRAY_TFLG_ECC 0x80000000, 0x0, 63 -#define MASK_WCI_RA_STATUS_2_ARRAY_REPLIES_RCVD_VLD 0x40000000, 0x0, 62 -#define MASK_WCI_RA_STATUS_2_ARRAY_STRIPE 0x20000000, 0x0, 61 -#define MASK_WCI_RA_STATUS_2_ARRAY_RH_SM 0x18000000, 0x0, 59 -#define MASK_WCI_RA_STATUS_2_ARRAY_RCVD_MTAG 0x7000000, 0x0, 56 -#define MASK_WCI_RA_STATUS_2_ARRAY_CESR_INDEX 0xff0000, 0x0, 48 -#define MASK_WCI_RA_STATUS_2_ARRAY_NTRANSID 0xff80, 0x0, 39 -#define MASK_WCI_RA_STATUS_2_ARRAY_DTARG 0x40, 0x0, 38 -#define MASK_WCI_RA_STATUS_2_ARRAY_SAW_S_ACK 0x20, 0x0, 37 -#define MASK_WCI_RA_STATUS_2_ARRAY_SAW_H_D 0x10, 0x0, 36 -#define MASK_WCI_RA_STATUS_2_ARRAY_SAW_S_D 0x8, 0x0, 35 -#define MASK_WCI_RA_STATUS_2_ARRAY_SAW_H_PULL 0x4, 0x0, 34 -#define MASK_WCI_RA_STATUS_2_ARRAY_SAW_H_PULL_M 0x2, 0x0, 33 -#define MASK_WCI_RA_STATUS_2_ARRAY_SAW_H_PULL_I 0x1, 0x0, 32 -#define MASK_WCI_RA_STATUS_2_ARRAY_REPLIES_RCVD 0x0, 0xffff0000, 16 -#define MASK_WCI_RA_STATUS_2_ARRAY_RCV_CNTR 0x0, 0xc000, 14 -#define MASK_WCI_RA_STATUS_2_ARRAY_SND_CNTR 0x0, 0x3000, 12 -#define MASK_WCI_RA_STATUS_2_ARRAY_SAW_H_NACK 0x0, 0x800, 11 -#define MASK_WCI_RA_STATUS_2_ARRAY_SAW_H_ERR 0x0, 0x400, 10 -#define MASK_WCI_RA_STATUS_2_ARRAY_TRANSACTION_TYPE 0x0, 0x3f0, 4 -#define MASK_WCI_RA_STATUS_2_ARRAY_HNID 0x0, 0xf, 0 -#define MASK_WCI_RA_STATUS_ARRAY_FSM_STATE 0xfe000000, 0x0, 57 -#define MASK_WCI_RA_STATUS_ARRAY_DTARGID 0x1ff0000, 0x0, 48 -#define MASK_WCI_RA_STATUS_ARRAY_ATRANSID 0xff80, 0x0, 39 -#define MASK_WCI_RA_STATUS_ARRAY_ADDR 0x7f, 0xffffffff, 0 -#define MASK_WCI_RA_TIMEOUT_CONFIG_RSVD_Z 0xfffffc00, 0x0, 42 -#define MASK_WCI_RA_TIMEOUT_CONFIG_CLUS_DISABLE 0x200, 0x0, 41 -#define MASK_WCI_RA_TIMEOUT_CONFIG_CLUS_FREEZE 0x100, 0x0, 40 -#define MASK_WCI_RA_TIMEOUT_CONFIG_RSVD_Y 0xc0, 0x0, 38 -#define MASK_WCI_RA_TIMEOUT_CONFIG_CLUS_APHASE_MAG 0x30, 0x0, 36 -#define MASK_WCI_RA_TIMEOUT_CONFIG_RSVD_X 0xc, 0x0, 34 -#define MASK_WCI_RA_TIMEOUT_CONFIG_CLUS_APHASE_VAL 0x3, 0xfc000000, 26 -#define MASK_WCI_RA_TIMEOUT_CONFIG_CLUS_DPHASE_MAG 0x0, 0x3000000, 24 -#define MASK_WCI_RA_TIMEOUT_CONFIG_CLUS_DPHASE_VAL 0x0, 0xff0000, 16 -#define MASK_WCI_RA_TIMEOUT_CONFIG_RSVD_W 0x0, 0xc000, 14 -#define MASK_WCI_RA_TIMEOUT_CONFIG_SSM_DISABLE 0x0, 0x2000, 13 -#define MASK_WCI_RA_TIMEOUT_CONFIG_SSM_FREEZE 0x0, 0x1000, 12 -#define MASK_WCI_RA_TIMEOUT_CONFIG_RSVD_V 0x0, 0xc00, 10 -#define MASK_WCI_RA_TIMEOUT_CONFIG_SSM_MAG 0x0, 0x300, 8 -#define MASK_WCI_RA_TIMEOUT_CONFIG_SSM_VAL 0x0, 0xff, 0 -#define MASK_WCI_RA_WRITE_LOCKOUT_STATUS_RSVD_Z 0xffffffff, 0xfffffc00, 10 -#define MASK_WCI_RA_WRITE_LOCKOUT_STATUS_LINK_STRIPE 0x0, 0x300, 8 -#define MASK_WCI_RA_WRITE_LOCKOUT_STATUS_NC_SLICE 0x0, 0xff, 0 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_RAG_ROUTE_MAP0_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_RAG_ROUTE_MAP0_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_RAG_ROUTE_MAP1_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_RAG_ROUTE_MAP1_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_RESET_CONFIG_RSVD_Z 0xffffffff, 0xfffffffe, 1 -#define MASK_WCI_RESET_CONFIG_AGENT_RESET_E 0x0, 0x1, 0 -#define MASK_WCI_RESET_STATUS_RSVD_Z 0xffffffff, 0xfffffff8, 3 -#define MASK_WCI_RESET_STATUS_POR 0x0, 0x4, 2 -#define MASK_WCI_RESET_STATUS_NODE_RESET 0x0, 0x2, 1 -#define MASK_WCI_RESET_STATUS_AGENT_RESET 0x0, 0x1, 0 -#define MASK_WCI_SA_BUSY_RSVD_Z 0xffffffff, 0xffffff00, 8 -#define MASK_WCI_SA_BUSY_VECTOR 0x0, 0xff, 0 -#define MASK_WCI_SA_ECC_ADDRESS_DATA 0x80000000, 0x0, 63 -#define MASK_WCI_SA_ECC_ADDRESS_UE 0x40000000, 0x0, 62 -#define MASK_WCI_SA_ECC_ADDRESS_RSVD_Z 0x3ffff800, 0x0, 43 -#define MASK_WCI_SA_ECC_ADDRESS_ADDR 0x7ff, 0xffffffe0, 5 -#define MASK_WCI_SA_ECC_ADDRESS_RSVD_Y 0x0, 0x1f, 0 -#define MASK_WCI_SA_ESR_0_RSVD_Z 0xffffffff, 0x80000000, 31 -#define MASK_WCI_SA_ESR_0_ACC_HW_ERR 0x0, 0x40000000, 30 -#define MASK_WCI_SA_ESR_0_ACC_ADDRESS_NOT_OWNED 0x0, 0x20000000, 29 -#define MASK_WCI_SA_ESR_0_ACC_ADDRESS_NOT_MAPPED 0x0, 0x10000000, 28 -#define MASK_WCI_SA_ESR_0_ACC_GA2LPA_ECC_ERROR 0x0, 0x8000000, 27 -#define MASK_WCI_SA_ESR_0_ACC_RIP_MULTI_HIT 0x0, 0x4000000, 26 -#define MASK_WCI_SA_ESR_0_ACC_ILLEGAL_SENDER 0x0, 0x2000000, 25 -#define MASK_WCI_SA_ESR_0_ACC_WRONG_DEMAND 0x0, 0x1000000, 24 -#define MASK_WCI_SA_ESR_0_ACC_UNCORRECTABLE_MTAG_ERROR 0x0, 0x800000, 23 -#define MASK_WCI_SA_ESR_0_ACC_UNCORRECTABLE_DATA_ERROR 0x0, 0x400000, 22 -#define MASK_WCI_SA_ESR_0_ACC_CORRECTABLE_MTAG_ERROR 0x0, 0x200000, 21 -#define MASK_WCI_SA_ESR_0_ACC_CORRECTABLE_DATA_ERROR 0x0, 0x100000, 20 -#define MASK_WCI_SA_ESR_0_ACC_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x80000, 19 -#define MASK_WCI_SA_ESR_0_ACC_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x40000, 18 -#define MASK_WCI_SA_ESR_0_ACC_UNEXPECTED_MTAG 0x0, 0x20000, 17 -#define MASK_WCI_SA_ESR_0_ACC_TIMEOUT 0x0, 0x10000, 16 -#define MASK_WCI_SA_ESR_0_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_SA_ESR_0_HW_ERR 0x0, 0x4000, 14 -#define MASK_WCI_SA_ESR_0_ADDRESS_NOT_OWNED 0x0, 0x2000, 13 -#define MASK_WCI_SA_ESR_0_ADDRESS_NOT_MAPPED 0x0, 0x1000, 12 -#define MASK_WCI_SA_ESR_0_GA2LPA_ECC_ERROR 0x0, 0x800, 11 -#define MASK_WCI_SA_ESR_0_RIP_MULTI_HIT 0x0, 0x400, 10 -#define MASK_WCI_SA_ESR_0_ILLEGAL_SENDER 0x0, 0x200, 9 -#define MASK_WCI_SA_ESR_0_WRONG_DEMAND 0x0, 0x100, 8 -#define MASK_WCI_SA_ESR_0_UNCORRECTABLE_MTAG_ERROR 0x0, 0x80, 7 -#define MASK_WCI_SA_ESR_0_UNCORRECTABLE_DATA_ERROR 0x0, 0x40, 6 -#define MASK_WCI_SA_ESR_0_CORRECTABLE_MTAG_ERROR 0x0, 0x20, 5 -#define MASK_WCI_SA_ESR_0_CORRECTABLE_DATA_ERROR 0x0, 0x10, 4 -#define MASK_WCI_SA_ESR_0_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x8, 3 -#define MASK_WCI_SA_ESR_0_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x4, 2 -#define MASK_WCI_SA_ESR_0_UNEXPECTED_MTAG 0x0, 0x2, 1 -#define MASK_WCI_SA_ESR_0_TIMEOUT 0x0, 0x1, 0 -#define MASK_WCI_SA_ESR_MASK_RSVD_Z 0xffffffff, 0xffff8000, 15 -#define MASK_WCI_SA_ESR_MASK_HW_ERR 0x0, 0x4000, 14 -#define MASK_WCI_SA_ESR_MASK_ADDRESS_NOT_OWNED 0x0, 0x2000, 13 -#define MASK_WCI_SA_ESR_MASK_ADDRESS_NOT_MAPPED 0x0, 0x1000, 12 -#define MASK_WCI_SA_ESR_MASK_GA2LPA_ECC_ERROR 0x0, 0x800, 11 -#define MASK_WCI_SA_ESR_MASK_RIP_MULTI_HIT 0x0, 0x400, 10 -#define MASK_WCI_SA_ESR_MASK_ILLEGAL_SENDER 0x0, 0x200, 9 -#define MASK_WCI_SA_ESR_MASK_WRONG_DEMAND 0x0, 0x100, 8 -#define MASK_WCI_SA_ESR_MASK_UNCORRECTABLE_MTAG_ERROR 0x0, 0x80, 7 -#define MASK_WCI_SA_ESR_MASK_UNCORRECTABLE_DATA_ERROR 0x0, 0x40, 6 -#define MASK_WCI_SA_ESR_MASK_CORRECTABLE_MTAG_ERROR 0x0, 0x20, 5 -#define MASK_WCI_SA_ESR_MASK_CORRECTABLE_DATA_ERROR 0x0, 0x10, 4 -#define MASK_WCI_SA_ESR_MASK_MTAG_MISMATCH_WITHIN_HCL 0x0, 0x8, 3 -#define MASK_WCI_SA_ESR_MASK_MTAG_MISMATCH_BETWEEN_HCLS 0x0, 0x4, 2 -#define MASK_WCI_SA_ESR_MASK_UNEXPECTED_MTAG 0x0, 0x2, 1 -#define MASK_WCI_SA_ESR_MASK_TIMEOUT 0x0, 0x1, 0 -#define MASK_WCI_SA_FIRST_ERROR_AGENT_ESR_REG 0x80000000, 0x0, 63 -#define MASK_WCI_SA_FIRST_ERROR_AGENT_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_SA_FIRST_ERROR_AGENT_RSVD_Z 0x7ffffff, 0xfffffff8, 3 -#define MASK_WCI_SA_FIRST_ERROR_AGENT_INSTANCE 0x0, 0x7, 0 -#define MASK_WCI_SA_FIRST_PACKET_0_RSVD_Z 0xfe000000, 0x0, 57 -#define MASK_WCI_SA_FIRST_PACKET_0_NTRANSID 0x1ff0000, 0x0, 48 -#define MASK_WCI_SA_FIRST_PACKET_0_RSVD_Y 0xc000, 0x0, 46 -#define MASK_WCI_SA_FIRST_PACKET_0_CMR 0x2000, 0x0, 45 -#define MASK_WCI_SA_FIRST_PACKET_0_OTRANSID 0x1ff0, 0x0, 36 -#define MASK_WCI_SA_FIRST_PACKET_0_RSVD_X 0xc, 0x0, 34 -#define MASK_WCI_SA_FIRST_PACKET_0_RNID 0x3, 0xc0000000, 30 -#define MASK_WCI_SA_FIRST_PACKET_0_R2E 0x0, 0x3c000000, 26 -#define MASK_WCI_SA_FIRST_PACKET_0_EMISS 0x0, 0x2000000, 25 -#define MASK_WCI_SA_FIRST_PACKET_0_RSVD_W 0x0, 0x1000000, 24 -#define MASK_WCI_SA_FIRST_PACKET_0_HTID 0x0, 0xf00000, 20 -#define MASK_WCI_SA_FIRST_PACKET_0_RTID 0x0, 0xf8000, 15 -#define MASK_WCI_SA_FIRST_PACKET_0_SNID 0x0, 0x7800, 11 -#define MASK_WCI_SA_FIRST_PACKET_0_MSGOP 0x0, 0x780, 7 -#define MASK_WCI_SA_FIRST_PACKET_0_HTYP 0x0, 0x60, 5 -#define MASK_WCI_SA_FIRST_PACKET_0_STRIPE 0x0, 0x10, 4 -#define MASK_WCI_SA_FIRST_PACKET_0_DNID 0x0, 0xf, 0 -#define MASK_WCI_SA_FIRST_PACKET_1_ESR_REG 0x80000000, 0x0, 63 -#define MASK_WCI_SA_FIRST_PACKET_1_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_SA_FIRST_PACKET_1_A_ENTRY 0x4000000, 0x0, 58 -#define MASK_WCI_SA_FIRST_PACKET_1_S_ENTRY 0x2000000, 0x0, 57 -#define MASK_WCI_SA_FIRST_PACKET_1_RSVD_Z 0x1fff800, 0x0, 43 -#define MASK_WCI_SA_FIRST_PACKET_1_GA 0x7ff, 0xffffffe0, 5 -#define MASK_WCI_SA_FIRST_PACKET_1_RSVD_Y 0x0, 0x1f, 0 -#define MASK_WCI_SA_FREEZE_RSVD_Z 0xffffffff, 0xffffff00, 8 -#define MASK_WCI_SA_FREEZE_VECTOR 0x0, 0xff, 0 -#define MASK_WCI_SA_HW_ERR_STATE_RSVD_Z 0xffffffff, 0xffffff00, 8 -#define MASK_WCI_SA_HW_ERR_STATE_SH_QUEUE_OVERFLOW 0x0, 0x80, 7 -#define MASK_WCI_SA_HW_ERR_STATE_SH_WRONG_STID 0x0, 0x40, 6 -#define MASK_WCI_SA_HW_ERR_STATE_SH_UNEXPECTED_SNOOP 0x0, 0x20, 5 -#define MASK_WCI_SA_HW_ERR_STATE_OH_QUEUE_OVERFLOW 0x0, 0x10, 4 -#define MASK_WCI_SA_HW_ERR_STATE_OH_WRONG_STID 0x0, 0x8, 3 -#define MASK_WCI_SA_HW_ERR_STATE_OH_UNEXPECTED_ORDERED 0x0, 0x4, 2 -#define MASK_WCI_SA_HW_ERR_STATE_UNEXPECTED_SEND_ACK 0x0, 0x2, 1 -#define MASK_WCI_SA_HW_ERR_STATE_UNEXPECTED_RECEIVE_ACK 0x0, 0x1, 0 -#define MASK_WCI_SA_STATUS_2_ARRAY_RSVD_Z 0xffffffff, 0xfffff800, 11 -#define MASK_WCI_SA_STATUS_2_ARRAY_SEND_DONE 0x0, 0x400, 10 -#define MASK_WCI_SA_STATUS_2_ARRAY_PH_DONE 0x0, 0x200, 9 -#define MASK_WCI_SA_STATUS_2_ARRAY_GOT_2ND_SNOOP 0x0, 0x100, 8 -#define MASK_WCI_SA_STATUS_2_ARRAY_GOT_1ST_SNOOP 0x0, 0x80, 7 -#define MASK_WCI_SA_STATUS_2_ARRAY_GOT_2ND_ORD 0x0, 0x40, 6 -#define MASK_WCI_SA_STATUS_2_ARRAY_GOT_1ST_ORD 0x0, 0x20, 5 -#define MASK_WCI_SA_STATUS_2_ARRAY_SF_3_DONE 0x0, 0x10, 4 -#define MASK_WCI_SA_STATUS_2_ARRAY_SF_2_DONE 0x0, 0x8, 3 -#define MASK_WCI_SA_STATUS_2_ARRAY_DSH_DONE 0x0, 0x4, 2 -#define MASK_WCI_SA_STATUS_2_ARRAY_DRH_DONE 0x0, 0x2, 1 -#define MASK_WCI_SA_STATUS_2_ARRAY_REQ_DONE 0x0, 0x1, 0 -#define MASK_WCI_SA_STATUS_3_ARRAY_RSVD_Z 0xffffffff, 0xffffe000, 13 -#define MASK_WCI_SA_STATUS_3_ARRAY_NTRANSID 0x0, 0x1ff0, 4 -#define MASK_WCI_SA_STATUS_3_ARRAY_SNID 0x0, 0xf, 0 -#define MASK_WCI_SA_STATUS_4_ARRAY_RSVD_Z 0xfffffffe, 0x0, 33 -#define MASK_WCI_SA_STATUS_4_ARRAY_OTRANSID 0x1, 0xff000000, 24 -#define MASK_WCI_SA_STATUS_4_ARRAY_RNID 0x0, 0xf00000, 20 -#define MASK_WCI_SA_STATUS_4_ARRAY_REPLIES_2_EXP 0x0, 0xf0000, 16 -#define MASK_WCI_SA_STATUS_4_ARRAY_HTID 0x0, 0xf000, 12 -#define MASK_WCI_SA_STATUS_4_ARRAY_RSVD_Y 0x0, 0xe00, 9 -#define MASK_WCI_SA_STATUS_4_ARRAY_RTID 0x0, 0x1f0, 4 -#define MASK_WCI_SA_STATUS_4_ARRAY_RSVD_X 0x0, 0xc, 2 -#define MASK_WCI_SA_STATUS_4_ARRAY_EMISS 0x0, 0x2, 1 -#define MASK_WCI_SA_STATUS_4_ARRAY_STRIPE 0x0, 0x1, 0 -#define MASK_WCI_SA_STATUS_5_ARRAY_RSVD_Z 0xfffff800, 0x0, 43 -#define MASK_WCI_SA_STATUS_5_ARRAY_ORIGINAL_GA 0x7ff, 0xffffe000, 13 -#define MASK_WCI_SA_STATUS_5_ARRAY_RSVD_Y 0x0, 0x1ffe, 1 -#define MASK_WCI_SA_STATUS_5_ARRAY_CMR 0x0, 0x1, 0 -#define MASK_WCI_SA_STATUS_6_ARRAY_RSVD_Z 0xfffff800, 0x0, 43 -#define MASK_WCI_SA_STATUS_6_ARRAY_SAFARI_ADDR_42 0x400, 0x0, 42 -#define MASK_WCI_SA_STATUS_6_ARRAY_SAFARI_ADDR_41_38 0x3c0, 0x0, 38 -#define MASK_WCI_SA_STATUS_6_ARRAY_SAFARI_ADDR_37 0x20, 0x0, 37 -#define MASK_WCI_SA_STATUS_6_ARRAY_SAFARI_ADDR_36_5 0x1f, 0xffffffe0, 5 -#define MASK_WCI_SA_STATUS_6_ARRAY_RSVD_Y 0x0, 0x1f, 0 -#define MASK_WCI_SA_STATUS_ARRAY_RSVD_Z 0xffffffff, 0xffe00000, 21 -#define MASK_WCI_SA_STATUS_ARRAY_RECEIVE_COUNT 0x0, 0x180000, 19 -#define MASK_WCI_SA_STATUS_ARRAY_SEND_COUNT 0x0, 0x70000, 16 -#define MASK_WCI_SA_STATUS_ARRAY_OWNED 0x0, 0x8000, 15 -#define MASK_WCI_SA_STATUS_ARRAY_FIRST_MTAG 0x0, 0x7000, 12 -#define MASK_WCI_SA_STATUS_ARRAY_ATRANSID_3_0 0x0, 0xf00, 8 -#define MASK_WCI_SA_STATUS_ARRAY_RSVD_Y 0x0, 0xc0, 6 -#define MASK_WCI_SA_STATUS_ARRAY_GA2LPA_STATUS 0x0, 0x30, 4 -#define MASK_WCI_SA_STATUS_ARRAY_MSGOP 0x0, 0xf, 0 -#define MASK_WCI_SA_TIMEOUT_CONFIG_RSVD_Z 0xffffffff, 0xffffc000, 14 -#define MASK_WCI_SA_TIMEOUT_CONFIG_SSM_DISABLE 0x0, 0x2000, 13 -#define MASK_WCI_SA_TIMEOUT_CONFIG_SSM_FREEZE 0x0, 0x1000, 12 -#define MASK_WCI_SA_TIMEOUT_CONFIG_RSVD_Y 0x0, 0xc00, 10 -#define MASK_WCI_SA_TIMEOUT_CONFIG_SSM_MAG 0x0, 0x300, 8 -#define MASK_WCI_SA_TIMEOUT_CONFIG_SSM_VAL 0x0, 0xff, 0 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_SAG_ROUTE_MAP0_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_SAG_ROUTE_MAP0_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_SAG_ROUTE_MAP1_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_SAG_ROUTE_MAP1_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_SC_CLUSTER_DISABLE_RSVD_Z 0xffffffff, 0xfffffff0, 4 -#define MASK_WCI_SC_CLUSTER_DISABLE_CA_CLUSTER_DISABLE 0x0, 0x8, 3 -#define MASK_WCI_SC_CLUSTER_DISABLE_RA_PIQ_DISABLE 0x0, 0x4, 2 -#define MASK_WCI_SC_CLUSTER_DISABLE_RA_NIQ_DISABLE 0x0, 0x2, 1 -#define MASK_WCI_SC_CLUSTER_DISABLE_RA_CIQ_DISABLE 0x0, 0x1, 0 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_SEC_FO_ROUTE_MAP_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_SEC_FO_ROUTE_MAP_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_SFI_ANALYZER_VALID 0x80000000, 0x0, 63 -#define MASK_WCI_SFI_ANALYZER_IN_USE 0x40000000, 0x0, 62 -#define MASK_WCI_SFI_ANALYZER_SHARED 0x20000000, 0x0, 61 -#define MASK_WCI_SFI_ANALYZER_OWNED 0x10000000, 0x0, 60 -#define MASK_WCI_SFI_ANALYZER_MAPPED 0x8000000, 0x0, 59 -#define MASK_WCI_SFI_ANALYZER_OVERFLOW 0x7e00000, 0x0, 53 -#define MASK_WCI_SFI_ANALYZER_ADDRESS 0x1fffff, 0xffffc000, 14 -#define MASK_WCI_SFI_ANALYZER_MASK 0x0, 0x3c00, 10 -#define MASK_WCI_SFI_ANALYZER_COMMAND 0x0, 0x200, 9 -#define MASK_WCI_SFI_ANALYZER_ATRANSID 0x0, 0x1ff, 0 -#define MASK_WCI_SFI_CTR0_MASK_RSVD_Z 0xfc000000, 0x0, 58 -#define MASK_WCI_SFI_CTR0_MASK_MASK 0x3ff0000, 0x0, 48 -#define MASK_WCI_SFI_CTR0_MASK_ATRANSID 0xff80, 0x0, 39 -#define MASK_WCI_SFI_CTR0_MASK_ADDRESS 0x7f, 0xffffffff, 0 -#define MASK_WCI_SFI_CTR0_MATCH_RSVD_Z 0xfc000000, 0x0, 58 -#define MASK_WCI_SFI_CTR0_MATCH_MASK 0x3ff0000, 0x0, 48 -#define MASK_WCI_SFI_CTR0_MATCH_ATRANSID 0xff80, 0x0, 39 -#define MASK_WCI_SFI_CTR0_MATCH_ADDRESS 0x7f, 0xffffffff, 0 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RSVD_Z 0xffffffff, 0xfff80000, 19 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RTS 0x0, 0x40000, 18 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RTO 0x0, 0x20000, 17 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RS 0x0, 0x10000, 16 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_WS 0x0, 0x8000, 15 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RTSR 0x0, 0x4000, 14 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RTOR 0x0, 0x2000, 13 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RSR 0x0, 0x1000, 12 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_WB 0x0, 0x800, 11 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RTSM 0x0, 0x400, 10 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_INTERRUPT 0x0, 0x200, 9 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_R_RTS 0x0, 0x100, 8 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_R_RTO 0x0, 0x80, 7 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_R_RS 0x0, 0x40, 6 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_R_WS 0x0, 0x20, 5 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_R_WB 0x0, 0x10, 4 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RBIO 0x0, 0x8, 3 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_RIO 0x0, 0x4, 2 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_WBIO 0x0, 0x2, 1 -#define MASK_WCI_SFI_CTR0_MATCH_TRANSACTION_WIO 0x0, 0x1, 0 -#define MASK_WCI_SFI_CTR1_MASK_RSVD_Z 0xfc000000, 0x0, 58 -#define MASK_WCI_SFI_CTR1_MASK_MASK 0x3ff0000, 0x0, 48 -#define MASK_WCI_SFI_CTR1_MASK_ATRANSID 0xff80, 0x0, 39 -#define MASK_WCI_SFI_CTR1_MASK_ADDRESS 0x7f, 0xffffffff, 0 -#define MASK_WCI_SFI_CTR1_MATCH_RSVD_Z 0xfc000000, 0x0, 58 -#define MASK_WCI_SFI_CTR1_MATCH_MASK 0x3ff0000, 0x0, 48 -#define MASK_WCI_SFI_CTR1_MATCH_ATRANSID 0xff80, 0x0, 39 -#define MASK_WCI_SFI_CTR1_MATCH_ADDRESS 0x7f, 0xffffffff, 0 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RSVD_Z 0xffffffff, 0xfff80000, 19 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RTS 0x0, 0x40000, 18 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RTO 0x0, 0x20000, 17 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RS 0x0, 0x10000, 16 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_WS 0x0, 0x8000, 15 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RTSR 0x0, 0x4000, 14 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RTOR 0x0, 0x2000, 13 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RSR 0x0, 0x1000, 12 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_WB 0x0, 0x800, 11 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RTSM 0x0, 0x400, 10 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_INTERRUPT 0x0, 0x200, 9 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_R_RTS 0x0, 0x100, 8 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_R_RTO 0x0, 0x80, 7 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_R_RS 0x0, 0x40, 6 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_R_WS 0x0, 0x20, 5 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_R_WB 0x0, 0x10, 4 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RBIO 0x0, 0x8, 3 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_RIO 0x0, 0x4, 2 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_WBIO 0x0, 0x2, 1 -#define MASK_WCI_SFI_CTR1_MATCH_TRANSACTION_WIO 0x0, 0x1, 0 -#define MASK_WCI_SFI_ESR_RSVD_Z 0xffffffff, 0xfc000000, 26 -#define MASK_WCI_SFI_ESR_ACC_TARGID_TIMEOUT 0x0, 0x2000000, 25 -#define MASK_WCI_SFI_ESR_ACC_NC2NID_MISCONFIG 0x0, 0x1000000, 24 -#define MASK_WCI_SFI_ESR_ACC_ADDR_PTY 0x0, 0x800000, 23 -#define MASK_WCI_SFI_ESR_ACC_INCOMING_PREREQ_CONFLICT 0x0, 0x400000, 22 -#define MASK_WCI_SFI_ESR_ACC_MODCAM_CLR_SET_CONFLICT 0x0, 0x200000, 21 -#define MASK_WCI_SFI_ESR_ACC_MODCAM_MULTI_HIT 0x0, 0x100000, 20 -#define MASK_WCI_SFI_ESR_ACC_MODCAM_SET_SET 0x0, 0x80000, 19 -#define MASK_WCI_SFI_ESR_ACC_UNEXPECTED_INCOMING 0x0, 0x40000, 18 -#define MASK_WCI_SFI_ESR_ACC_UNEXPECTED_TARGARBGNT 0x0, 0x20000, 17 -#define MASK_WCI_SFI_ESR_ACC_TRANSID_UNALLOC_RELEASED 0x0, 0x10000, 16 -#define MASK_WCI_SFI_ESR_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_SFI_ESR_RSVD_Y 0x0, 0x7c00, 10 -#define MASK_WCI_SFI_ESR_TARGID_TIMEOUT 0x0, 0x200, 9 -#define MASK_WCI_SFI_ESR_NC2NID_MISCONFIG 0x0, 0x100, 8 -#define MASK_WCI_SFI_ESR_ADDR_PTY 0x0, 0x80, 7 -#define MASK_WCI_SFI_ESR_INCOMING_PREREQ_CONFLICT 0x0, 0x40, 6 -#define MASK_WCI_SFI_ESR_MODCAM_CLR_SET_CONFLICT 0x0, 0x20, 5 -#define MASK_WCI_SFI_ESR_MODCAM_MULTI_HIT 0x0, 0x10, 4 -#define MASK_WCI_SFI_ESR_MODCAM_SET_SET 0x0, 0x8, 3 -#define MASK_WCI_SFI_ESR_UNEXPECTED_INCOMING 0x0, 0x4, 2 -#define MASK_WCI_SFI_ESR_UNEXPECTED_TARGARBGNT 0x0, 0x2, 1 -#define MASK_WCI_SFI_ESR_TRANSID_UNALLOC_RELEASED 0x0, 0x1, 0 -#define MASK_WCI_SFI_ESR_MASK_RSVD_Z 0xffffffff, 0xfffffc00, 10 -#define MASK_WCI_SFI_ESR_MASK_TARGID_TIMEOUT 0x0, 0x200, 9 -#define MASK_WCI_SFI_ESR_MASK_NC2NID_MISCONFIG 0x0, 0x100, 8 -#define MASK_WCI_SFI_ESR_MASK_ADDR_PTY 0x0, 0x80, 7 -#define MASK_WCI_SFI_ESR_MASK_INCOMING_PREREQ_CONFLICT 0x0, 0x40, 6 -#define MASK_WCI_SFI_ESR_MASK_MODCAM_CLR_SET_CONFLICT 0x0, 0x20, 5 -#define MASK_WCI_SFI_ESR_MASK_MODCAM_MULTI_HIT 0x0, 0x10, 4 -#define MASK_WCI_SFI_ESR_MASK_MODCAM_SET_SET 0x0, 0x8, 3 -#define MASK_WCI_SFI_ESR_MASK_UNEXPECTED_INCOMING 0x0, 0x4, 2 -#define MASK_WCI_SFI_ESR_MASK_UNEXPECTED_TARGARBGNT 0x0, 0x2, 1 -#define MASK_WCI_SFI_ESR_MASK_TRANSID_UNALLOC_RELEASED 0x0, 0x1, 0 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_SFI_ROUTE_MAP0_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_SFI_ROUTE_MAP0_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_Z 0xffff8000, 0x0, 47 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE15_TLINK 0x6000, 0x0, 45 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_Y 0x1000, 0x0, 44 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE14_TLINK 0xc00, 0x0, 42 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_X 0x200, 0x0, 41 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE13_TLINK 0x180, 0x0, 39 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_W 0x40, 0x0, 38 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE12_TLINK 0x30, 0x0, 36 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_V 0x8, 0x0, 35 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE11_TLINK 0x6, 0x0, 33 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_U 0x1, 0x0, 32 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE10_TLINK 0x0, 0xc0000000, 30 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_T 0x0, 0x20000000, 29 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE9_TLINK 0x0, 0x18000000, 27 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_S 0x0, 0x4000000, 26 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE8_TLINK 0x0, 0x3000000, 24 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_R 0x0, 0x800000, 23 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE7_TLINK 0x0, 0x600000, 21 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_Q 0x0, 0x100000, 20 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE6_TLINK 0x0, 0xc0000, 18 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_P 0x0, 0x20000, 17 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE5_TLINK 0x0, 0x18000, 15 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_O 0x0, 0x4000, 14 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE4_TLINK 0x0, 0x3000, 12 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_N 0x0, 0x800, 11 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE3_TLINK 0x0, 0x600, 9 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_M 0x0, 0x100, 8 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE2_TLINK 0x0, 0xc0, 6 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_L 0x0, 0x20, 5 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE1_TLINK 0x0, 0x18, 3 -#define MASK_WCI_SFI_ROUTE_MAP1_RSVD_K 0x0, 0x4, 2 -#define MASK_WCI_SFI_ROUTE_MAP1_NODE0_TLINK 0x0, 0x3, 0 -#define MASK_WCI_SFI_STATE_RSVD_Z 0x80000000, 0x0, 63 -#define MASK_WCI_SFI_STATE_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_SFI_STATE_RSVD_Y 0x7fe0000, 0x0, 49 -#define MASK_WCI_SFI_STATE_WCI_ISSUED 0x10000, 0x0, 48 -#define MASK_WCI_SFI_STATE_AGENT_ID 0xfe00, 0x0, 41 -#define MASK_WCI_SFI_STATE_MODCAM_INDEX 0x1e0, 0x0, 37 -#define MASK_WCI_SFI_STATE_MODCAM_ADDR 0x1f, 0xffffffc0, 6 -#define MASK_WCI_SFI_STATE_SF_CMD 0x0, 0x30, 4 -#define MASK_WCI_SFI_STATE_SF_MASK_3_TO_0 0x0, 0xf, 0 -#define MASK_WCI_SFI_STATE1_RSVD_Z 0x80000000, 0x0, 63 -#define MASK_WCI_SFI_STATE1_ESR_INDEX 0x78000000, 0x0, 59 -#define MASK_WCI_SFI_STATE1_RSVD_Y 0x7f80000, 0x0, 51 -#define MASK_WCI_SFI_STATE1_UNALLOC_RELEASE_AGENTS 0x7c000, 0x0, 46 -#define MASK_WCI_SFI_STATE1_UNALLOC_TARGIDS_RELEASED 0x3fff, 0x80000000, 31 -#define MASK_WCI_SFI_STATE1_UNALLOC_ATRANSIDS_RELEASED 0x0, 0x7fff0000, 16 -#define MASK_WCI_SFI_STATE1_NC2NID_INDEX 0x0, 0xff00, 8 -#define MASK_WCI_SFI_STATE1_NC2NID_DATA 0x0, 0xff, 0 -#define MASK_WCI_SFI_TRANSID_ALLOC_RSVD_Z 0xffffffff, 0x80000000, 31 -#define MASK_WCI_SFI_TRANSID_ALLOC_TARGID_AVAILABLE 0x0, 0x7fff0000, 16 -#define MASK_WCI_SFI_TRANSID_ALLOC_ATRANSID_AVAILABLE 0x0, 0xfffe, 1 -#define MASK_WCI_SFI_TRANSID_ALLOC_RSVD_Y 0x0, 0x1, 0 -#define MASK_WCI_SFQ_ESR_RSVD_Z 0xffffffff, 0xfffc0000, 18 -#define MASK_WCI_SFQ_ESR_ACC_SFQ_PERR 0x0, 0x20000, 17 -#define MASK_WCI_SFQ_ESR_ACC_SFQ_OVFL 0x0, 0x10000, 16 -#define MASK_WCI_SFQ_ESR_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_SFQ_ESR_RSVD_Y 0x0, 0x7ffc, 2 -#define MASK_WCI_SFQ_ESR_SFQ_PERR 0x0, 0x2, 1 -#define MASK_WCI_SFQ_ESR_SFQ_OVFL 0x0, 0x1, 0 -#define MASK_WCI_SFQ_ESR_MASK_RSVD_Z 0xffffffff, 0xfffffffc, 2 -#define MASK_WCI_SFQ_ESR_MASK_SFQ_PERR 0x0, 0x2, 1 -#define MASK_WCI_SFQ_ESR_MASK_SFQ_OVFL 0x0, 0x1, 0 -#define MASK_WCI_SFQ_STATE_RSVD_Z 0xffffffff, 0xfffffe00, 9 -#define MASK_WCI_SFQ_STATE_INDEX 0x0, 0x1ff, 0 -#define MASK_WCI_SHADOW_ADDR_SET_AGENT_RESET 0x80000000, 0x0, 63 -#define MASK_WCI_SHADOW_ADDR_PULL_STOP 0x40000000, 0x0, 62 -#define MASK_WCI_SHADOW_ADDR_DATA_STOP 0x20000000, 0x0, 61 -#define MASK_WCI_SHADOW_ADDR_SHADOW_RSVD 0x10000000, 0x0, 60 -#define MASK_WCI_SHADOW_ADDR_RSVD_Z 0xffc0000, 0x0, 50 -#define MASK_WCI_SHADOW_ADDR_SHADOW_VALID 0x20000, 0x0, 49 -#define MASK_WCI_SHADOW_ADDR_SHADOW_TIMEOUT 0x10000, 0x0, 48 -#define MASK_WCI_SHADOW_ADDR_SHADOW_ADDR_NOT_VLD 0x8000, 0x0, 47 -#define MASK_WCI_SHADOW_ADDR_SHADOW_SRAM_ERROR 0x4000, 0x0, 46 -#define MASK_WCI_SHADOW_ADDR_SHADOW_SRAM 0x2000, 0x0, 45 -#define MASK_WCI_SHADOW_ADDR_SHADOW_WRITE 0x1000, 0x0, 44 -#define MASK_WCI_SHADOW_ADDR_RSVD_Y 0xfff, 0xe0000000, 29 -#define MASK_WCI_SHADOW_ADDR_SHADOW_ADDR 0x0, 0x1fffffe0, 5 -#define MASK_WCI_SHADOW_ADDR_RSVD_X 0x0, 0x1f, 0 -#define MASK_WCI_SHADOW_DATA_SHADOW_DATA 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_SRAM_ARRAY_ERROR 0x80000000, 0x0, 63 -#define MASK_WCI_SRAM_ARRAY_DATA 0x7fffffff, 0xffffffff, 0 -#define MASK_WCI_SRAM_CE_COUNT_RSVD_Z 0xffffffff, 0xffffff00, 8 -#define MASK_WCI_SRAM_CE_COUNT_CE_COUNT 0x0, 0xff, 0 -#define MASK_WCI_SRAM_CONFIG_RSVD_Z 0xffffffff, 0xfff80000, 19 -#define MASK_WCI_SRAM_CONFIG_ERROR_THRESHOLD 0x0, 0x7c000, 14 -#define MASK_WCI_SRAM_CONFIG_ECC_WRITEBACK_DISABLE 0x0, 0x2000, 13 -#define MASK_WCI_SRAM_CONFIG_ECC_DISABLE 0x0, 0x1000, 12 -#define MASK_WCI_SRAM_CONFIG_PARITY_DISABLE 0x0, 0x800, 11 -#define MASK_WCI_SRAM_CONFIG_USE_GA2LPA 0x0, 0x400, 10 -#define MASK_WCI_SRAM_CONFIG_USE_DIRECTORY 0x0, 0x200, 9 -#define MASK_WCI_SRAM_CONFIG_DIR_STRIPE 0x0, 0x180, 7 -#define MASK_WCI_SRAM_CONFIG_RSVD_Y 0x0, 0x60, 5 -#define MASK_WCI_SRAM_CONFIG_SRAM_SIZE 0x0, 0x1c, 2 -#define MASK_WCI_SRAM_CONFIG_SRAM_SIZE_PINS 0x0, 0x3, 0 -#define MASK_WCI_SRAM_ECC_ADDRESS_RSVD_Z 0xfffffffe, 0x0, 33 -#define MASK_WCI_SRAM_ECC_ADDRESS_CE 0x1, 0x0, 32 -#define MASK_WCI_SRAM_ECC_ADDRESS_ADDR_ERROR 0x0, 0x80000000, 31 -#define MASK_WCI_SRAM_ECC_ADDRESS_SYNDROME 0x0, 0x7f000000, 24 -#define MASK_WCI_SRAM_ECC_ADDRESS_ADDRESS 0x0, 0xffffff, 0 -#define MASK_WCI_SRAM_STATUS_RSVD_Z 0xffffffff, 0xfff00000, 20 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_19 0x0, 0x80000, 19 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_18 0x0, 0x40000, 18 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_17 0x0, 0x20000, 17 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_16 0x0, 0x10000, 16 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_15 0x0, 0x8000, 15 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_14 0x0, 0x4000, 14 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_13 0x0, 0x2000, 13 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_12 0x0, 0x1000, 12 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_11 0x0, 0x800, 11 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_10 0x0, 0x400, 10 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_9 0x0, 0x200, 9 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_8 0x0, 0x100, 8 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_7 0x0, 0x80, 7 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_6 0x0, 0x40, 6 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_5 0x0, 0x20, 5 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_4 0x0, 0x10, 4 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_3 0x0, 0x8, 3 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_2 0x0, 0x4, 2 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_1 0x0, 0x2, 1 -#define MASK_WCI_SRAM_STATUS_STICKY_ERROR_0 0x0, 0x1, 0 -#define MASK_WCI_STICK_COUNT 0xffffffff, 0xffffffff, 0 -#define MASK_WCI_STICK_RATE_RESET 0x80000000, 0x0, 63 -#define MASK_WCI_STICK_RATE_CYCLE_LIMIT_INTEGER 0x7fff0000, 0x0, 48 -#define MASK_WCI_STICK_RATE_CYCLE_LIMIT_FRACTION 0xffff, 0xffffffff, 0 -#define MASK_WCI_SW_CONFIG_MAX_ERRORS 0xffffff00, 0x0, 40 -#define MASK_WCI_SW_CONFIG_RSVD_Z 0xff, 0xfffe0000, 17 -#define MASK_WCI_SW_CONFIG_ERROR_PAUSE_SHUTDOWN_EN 0x0, 0x10000, 16 -#define MASK_WCI_SW_CONFIG_PARTNER_GNID 0x0, 0xf000, 12 -#define MASK_WCI_SW_CONFIG_GNID 0x0, 0xf00, 8 -#define MASK_WCI_SW_CONFIG_FAILOVER_EN 0x0, 0x80, 7 -#define MASK_WCI_SW_CONFIG_DROP_ILLEGAL_GNID 0x0, 0x40, 6 -#define MASK_WCI_SW_CONFIG_SYNC_BUFFER_SAFETY_LEVEL 0x0, 0x30, 4 -#define MASK_WCI_SW_CONFIG_MASK_ORIGINATE_BROADCAST 0x0, 0x8, 3 -#define MASK_WCI_SW_CONFIG_XMIT_ARB_POLICY 0x0, 0x6, 1 -#define MASK_WCI_SW_CONFIG_ENABLE_DX_SHORTCUT 0x0, 0x1, 0 -#define MASK_WCI_SW_ESR_RSVD_Z 0xffffffff, 0xf0000000, 28 -#define MASK_WCI_SW_ESR_ACC_LINK_2_FAILOVER 0x0, 0x8000000, 27 -#define MASK_WCI_SW_ESR_ACC_LINK_1_FAILOVER 0x0, 0x4000000, 26 -#define MASK_WCI_SW_ESR_ACC_LINK_0_FAILOVER 0x0, 0x2000000, 25 -#define MASK_WCI_SW_ESR_RSVD_Y 0x0, 0x1800000, 23 -#define MASK_WCI_SW_ESR_ACC_LINK_2_AUTO_SHUT 0x0, 0x400000, 22 -#define MASK_WCI_SW_ESR_ACC_LINK_1_AUTO_SHUT 0x0, 0x200000, 21 -#define MASK_WCI_SW_ESR_ACC_LINK_0_AUTO_SHUT 0x0, 0x100000, 20 -#define MASK_WCI_SW_ESR_ACC_ADDR_LPBK_ILLEGAL_GNID 0x0, 0x80000, 19 -#define MASK_WCI_SW_ESR_ACC_ERROR_PAUSE_BROADCAST 0x0, 0x40000, 18 -#define MASK_WCI_SW_ESR_ACC_ADDR_LPBK_FIFO_OVF 0x0, 0x20000, 17 -#define MASK_WCI_SW_ESR_ACC_DATA_LPBK_FIFO_OVF 0x0, 0x10000, 16 -#define MASK_WCI_SW_ESR_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_SW_ESR_RSVD_X 0x0, 0x7000, 12 -#define MASK_WCI_SW_ESR_LINK_2_FAILOVER 0x0, 0x800, 11 -#define MASK_WCI_SW_ESR_LINK_1_FAILOVER 0x0, 0x400, 10 -#define MASK_WCI_SW_ESR_LINK_0_FAILOVER 0x0, 0x200, 9 -#define MASK_WCI_SW_ESR_RSVD_W 0x0, 0x180, 7 -#define MASK_WCI_SW_ESR_LINK_2_AUTO_SHUT 0x0, 0x40, 6 -#define MASK_WCI_SW_ESR_LINK_1_AUTO_SHUT 0x0, 0x20, 5 -#define MASK_WCI_SW_ESR_LINK_0_AUTO_SHUT 0x0, 0x10, 4 -#define MASK_WCI_SW_ESR_ADDR_LPBK_ILLEGAL_GNID 0x0, 0x8, 3 -#define MASK_WCI_SW_ESR_ERROR_PAUSE_BROADCAST 0x0, 0x4, 2 -#define MASK_WCI_SW_ESR_ADDR_LPBK_FIFO_OVF 0x0, 0x2, 1 -#define MASK_WCI_SW_ESR_DATA_LPBK_FIFO_OVF 0x0, 0x1, 0 -#define MASK_WCI_SW_ESR_A_RSVD_Z 0xffffffff, 0xfffc0000, 18 -#define MASK_WCI_SW_ESR_A_ACC_FO_B_FIFO_OVF 0x0, 0x20000, 17 -#define MASK_WCI_SW_ESR_A_ACC_FO_A_FIFO_OVF 0x0, 0x10000, 16 -#define MASK_WCI_SW_ESR_A_FIRST_ERROR 0x0, 0x8000, 15 -#define MASK_WCI_SW_ESR_A_RSVD_Y 0x0, 0x7ffc, 2 -#define MASK_WCI_SW_ESR_A_FO_B_FIFO_OVF 0x0, 0x2, 1 -#define MASK_WCI_SW_ESR_A_FO_A_FIFO_OVF 0x0, 0x1, 0 -#define MASK_WCI_SW_ESR_A_MASK_RSVD_Z 0xffffffff, 0xfffffffc, 2 -#define MASK_WCI_SW_ESR_A_MASK_FO_B_FIFO_OVF 0x0, 0x2, 1 -#define MASK_WCI_SW_ESR_A_MASK_FO_A_FIFO_OVF 0x0, 0x1, 0 -#define MASK_WCI_SW_ESR_MASK_RSVD_Z 0xffffffff, 0xfffff000, 12 -#define MASK_WCI_SW_ESR_MASK_LINK_2_FAILOVER 0x0, 0x800, 11 -#define MASK_WCI_SW_ESR_MASK_LINK_1_FAILOVER 0x0, 0x400, 10 -#define MASK_WCI_SW_ESR_MASK_LINK_0_FAILOVER 0x0, 0x200, 9 -#define MASK_WCI_SW_ESR_MASK_RSVD_Y 0x0, 0x180, 7 -#define MASK_WCI_SW_ESR_MASK_LINK_2_AUTO_SHUT 0x0, 0x40, 6 -#define MASK_WCI_SW_ESR_MASK_LINK_1_AUTO_SHUT 0x0, 0x20, 5 -#define MASK_WCI_SW_ESR_MASK_LINK_0_AUTO_SHUT 0x0, 0x10, 4 -#define MASK_WCI_SW_ESR_MASK_ADDR_LPBK_ILLEGAL_GNID 0x0, 0x8, 3 -#define MASK_WCI_SW_ESR_MASK_ERROR_PAUSE_BROADCAST 0x0, 0x4, 2 -#define MASK_WCI_SW_ESR_MASK_ADDR_LPBK_FIFO_OVF 0x0, 0x2, 1 -#define MASK_WCI_SW_ESR_MASK_DATA_LPBK_FIFO_OVF 0x0, 0x1, 0 -#define MASK_WCI_SW_LINK_CONTROL_RSVD_Z 0xff800000, 0x0, 55 -#define MASK_WCI_SW_LINK_CONTROL_REXMIT_FREEZE 0x400000, 0x0, 54 -#define MASK_WCI_SW_LINK_CONTROL_REXMIT_MAG 0x300000, 0x0, 52 -#define MASK_WCI_SW_LINK_CONTROL_REXMIT_VAL 0xff000, 0x0, 44 -#define MASK_WCI_SW_LINK_CONTROL_ERROR_INDUCEMENT 0xc00, 0x0, 42 -#define MASK_WCI_SW_LINK_CONTROL_XMIT_TIMEOUT 0x3fc, 0x0, 34 -#define MASK_WCI_SW_LINK_CONTROL_USR_DATA_2 0x3, 0x0, 32 -#define MASK_WCI_SW_LINK_CONTROL_USR_DATA_1 0x0, 0xffff0000, 16 -#define MASK_WCI_SW_LINK_CONTROL_RSVD_Y 0x0, 0xe000, 13 -#define MASK_WCI_SW_LINK_CONTROL_XMIT_ENABLE 0x0, 0x1000, 12 -#define MASK_WCI_SW_LINK_CONTROL_USTAT_SRC 0x0, 0xc00, 10 -#define MASK_WCI_SW_LINK_CONTROL_IN_DOMAIN 0x0, 0x200, 9 -#define MASK_WCI_SW_LINK_CONTROL_PAROLI_TCK_ENABLE 0x0, 0x100, 8 -#define MASK_WCI_SW_LINK_CONTROL_LASER_ENABLE 0x0, 0x80, 7 -#define MASK_WCI_SW_LINK_CONTROL_RSVD_X 0x0, 0x40, 6 -#define MASK_WCI_SW_LINK_CONTROL_REXMIT_SHUTDOWN_EN 0x0, 0x20, 5 -#define MASK_WCI_SW_LINK_CONTROL_NEAR_END_SHUTDOWN_LOCK 0x0, 0x10, 4 -#define MASK_WCI_SW_LINK_CONTROL_FAILOVER_EN 0x0, 0x8, 3 -#define MASK_WCI_SW_LINK_CONTROL_AUTO_SHUT_EN 0x0, 0x4, 2 -#define MASK_WCI_SW_LINK_CONTROL_LINK_STATE 0x0, 0x3, 0 -#define MASK_WCI_SW_LINK_ERROR_COUNT_ERROR_COUNT 0xffffff00, 0x0, 40 -#define MASK_WCI_SW_LINK_ERROR_COUNT_RSVD_Z 0xff, 0xffffffff, 0 -#define MASK_WCI_SW_LINK_REXMIT_RSVD_Z 0xffffffff, 0x0, 32 -#define MASK_WCI_SW_LINK_REXMIT_REXMIT_COUNT 0x0, 0xffffffff, 0 -#define MASK_WCI_SW_LINK_STATUS_RSVD_Z 0xff800000, 0x0, 55 -#define MASK_WCI_SW_LINK_STATUS_PAROLI_PRESENT 0x400000, 0x0, 54 -#define MASK_WCI_SW_LINK_STATUS_BAD_GNID 0x3c0000, 0x0, 50 -#define MASK_WCI_SW_LINK_STATUS_FAREND_USTAT_2 0x30000, 0x0, 48 -#define MASK_WCI_SW_LINK_STATUS_FAREND_USTAT_1 0xffff, 0x0, 32 -#define MASK_WCI_SW_LINK_STATUS_USTAT_1 0x0, 0xffff0000, 16 -#define MASK_WCI_SW_LINK_STATUS_SHUTDOWN_CAUSE 0x0, 0xc000, 14 -#define MASK_WCI_SW_LINK_STATUS_GOT_FO_PKT 0x0, 0x2000, 13 -#define MASK_WCI_SW_LINK_STATUS_MULTIPLE_LINK_FAILOVER 0x0, 0x1000, 12 -#define MASK_WCI_SW_LINK_STATUS_FAILOVER_CAUSE 0x0, 0x800, 11 -#define MASK_WCI_SW_LINK_STATUS_LINK_IDLE 0x0, 0x400, 10 -#define MASK_WCI_SW_LINK_STATUS_SYNC_LOCKED 0x0, 0x200, 9 -#define MASK_WCI_SW_LINK_STATUS_OPTICAL_SIGNAL_DETECT 0x0, 0x100, 8 -#define MASK_WCI_SW_LINK_STATUS_RESET_PENDING 0x0, 0x80, 7 -#define MASK_WCI_SW_LINK_STATUS_FRAMING_ERROR 0x0, 0x40, 6 -#define MASK_WCI_SW_LINK_STATUS_CLOCKING_ERROR 0x0, 0x20, 5 -#define MASK_WCI_SW_LINK_STATUS_END_STATUS 0x0, 0x18, 3 -#define MASK_WCI_SW_LINK_STATUS_CRC_ERROR 0x0, 0x4, 2 -#define MASK_WCI_SW_LINK_STATUS_RSVD_Y 0x0, 0x2, 1 -#define MASK_WCI_SW_LINK_STATUS_PACKETS_DISCARDED 0x0, 0x1, 0 -#define MASK_WCI_SW_STATUS_RSVD_Z 0xffffffff, 0xfffffe00, 9 -#define MASK_WCI_SW_STATUS_ADDR_LPBK_ILLEGAL_GNID 0x0, 0x1e0, 5 -#define MASK_WCI_SW_STATUS_ERROR_PAUSE_BROADCAST_STATUS 0x0, 0x1c, 2 -#define MASK_WCI_SW_STATUS_ORIGINATE 0x0, 0x2, 1 -#define MASK_WCI_SW_STATUS_LOCAL_SOURCE 0x0, 0x1, 0 -#define MASK_WCI_UE_DIRECTION_RSVD_Z 0xffffff80, 0x0, 39 -#define MASK_WCI_UE_DIRECTION_OUTBOUND_ERROR_DETECTED 0x40, 0x0, 38 -#define MASK_WCI_UE_DIRECTION_UE_INBOUND 0x20, 0x0, 37 -#define MASK_WCI_UE_DIRECTION_UE_OUTBOUND 0x10, 0x0, 36 -#define MASK_WCI_UE_DIRECTION_UE_AGENT 0xf, 0x0, 32 -#define MASK_WCI_UE_DIRECTION_UE_STICK 0x0, 0xffffffff, 0 - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WCI_MASKS_H */ diff --git a/usr/src/uts/sun4u/sys/wci_offsets.h b/usr/src/uts/sun4u/sys/wci_offsets.h deleted file mode 100644 index f6bf2936c6..0000000000 --- a/usr/src/uts/sun4u/sys/wci_offsets.h +++ /dev/null @@ -1,299 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - * Automatically Generated file based on CSR definitions - * - */ - -/* - * This file automatically generated from - * wci_defs.csr - * 11/27/2000 17:21:38 - * Using ./csr_filter.pl by pcw - */ - -/* **DO NOT EDIT THIS FILE** */ -/* - * File ../../../design/wci/include/wci_offsets.h * - */ - -#ifndef _SYS_WCI_OFFSETS_H -#define _SYS_WCI_OFFSETS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Include any headers you depend on. - */ - - - -#define ADDR_WCI_SRAM_ARRAY 0x00000000000 -#define ENTRIES_WCI_SRAM_ARRAY 0x1000000 -#define STRIDE_WCI_SRAM_ARRAY 0x20 -#define ADDR_WCI_SHADOW_ADDR 0x00000000000 -#define ADDR_WCI_SHADOW_DATA 0x00000000020 -#define ADDR_WCI_CONFIG 0x00000000040 -#define ADDR_WCI_DOMAIN_CONFIG 0x00000000060 -#define ADDR_WCI_LOCAL_DEVICE_ID 0x00000000080 -#define ADDR_WCI_RESET_CONFIG 0x000000000a0 -#define ADDR_WCI_RESET_STATUS 0x000000000c0 -#define ADDR_WCI_ID 0x000000000e0 -#define ADDR_WCI_BOARD2CNID_CONTROL 0x00000000100 -#define ADDR_WCI_CSR_CONTROL 0x00000000120 -#define ADDR_WCI_ERROR_SUMMARY 0x00000000160 -#define ADDR_WCI_ERROR_PAUSE_TIMER_HOLD 0x00000000180 -#define ADDR_WCI_FIRST_ERROR_TIME 0x000000001a0 -#define ADDR_WCI_CSRA_ESR 0x000000001c0 -#define ADDR_WCI_CSRA_ESR_MASK 0x000000001e0 -#define ADDR_WCI_CSRA_STATUS 0x00000000200 -#define ADDR_WCI_CSRA_TIMEOUT_CONFIG 0x00000000220 -#define ADDR_WCI_DC_ESR 0x00000000240 -#define ADDR_WCI_DC_ESR_MASK 0x00000000260 -#define ADDR_WCI_DCO_STATE 0x00000000280 -#define ADDR_WCI_DCO_CE_COUNT 0x000000002a0 -#define ADDR_WCI_DCI_STATE 0x000000002c0 -#define ADDR_WCI_HLI_STRANGE_PKT_1 0x000000002e0 -#define ADDR_WCI_HLI_STRANGE_PKT_0 0x00000000300 -#define ADDR_WCI_HLI_ESR 0x00000000320 -#define ADDR_WCI_HLI_ESR_MASK 0x00000000340 -#define ADDR_WCI_HLI_STATE 0x00000000360 -#define ADDR_WCI_SFQ_ESR 0x00000000380 -#define ADDR_WCI_SFQ_ESR_MASK 0x000000003a0 -#define ADDR_WCI_SFQ_STATE 0x000000003c0 -#define ADDR_WCI_ERROR_INDUCEMENT 0x000000003e0 -#define ADDR_WCI_UE_DIRECTION 0x00000000400 -#define ADDR_WCI_GENERATES_CESR_NUMBER 0x00000000420 -#define ADDR_WCI_DIF_TIMEOUT_CNTL 0x00000000440 -#define ADDR_WCI_DIF_TIMEOUT_COUNT 0x00000000460 -#define ADDR_WCI_MAX 0x00000000480 -#define ADDR_WCI_JNK_ROUTE_MAP0 0x00000002000 -#define ADDR_WCI_JNK_ROUTE_MAP1 0x00000002020 -#define ADDR_WCI_STICK_RATE 0x00000004000 -#define ADDR_WCI_STICK 0x00000004020 -#define ADDR_WCI_MISC_CTR 0x00000006000 -#define ADDR_WCI_MISC_CTR_CTL 0x00000006020 -#define ADDR_WCI_MONITOR_PINS 0x00000006040 -#define ADDR_WCI_SRAM_CONFIG 0x00000010000 -#define ADDR_WCI_CLUSTER_MEMBERS_BITS 0x00000010080 -#define ENTRIES_WCI_CLUSTER_MEMBERS_BITS 0x4 -#define STRIDE_WCI_CLUSTER_MEMBERS_BITS 0x20 -#define ADDR_WCI_NC_SLICE_CONFIG_ARRAY 0x00000010200 -#define ENTRIES_WCI_NC_SLICE_CONFIG_ARRAY 0x8 -#define STRIDE_WCI_NC_SLICE_CONFIG_ARRAY 0x20 -#define ADDR_WCI_CLUSTER_CTR_CTL 0x00000010300 -#define ADDR_WCI_SRAM_STATUS 0x00000010320 -#define ADDR_WCI_SRAM_CE_COUNT 0x00000010340 -#define ADDR_WCI_SRAM_ECC_ADDRESS 0x00000010360 -#define ADDR_WCI_CCI_ESR 0x00000010380 -#define ADDR_WCI_CCI_ESR_MASK 0x000000103a0 -#define ADDR_WCI_CCI_ROUTE_MAP0 0x000000103c0 -#define ADDR_WCI_CCI_ROUTE_MAP1 0x000000103e0 -#define ADDR_WCI_CLUSTER_WRITE_LOCKOUT 0x00000010480 -#define ENTRIES_WCI_CLUSTER_WRITE_LOCKOUT 0x4 -#define STRIDE_WCI_CLUSTER_WRITE_LOCKOUT 0x20 -#define ADDR_WCI_CLUSTER_CONFIG 0x00000020000 -#define ADDR_WCI_CA_FREEZE 0x00000020020 -#define ADDR_WCI_CA_BUSY 0x00000020040 -#define ADDR_WCI_CA_FIRST_PACKET_0 0x00000020060 -#define ADDR_WCI_CA_FIRST_PACKET_1 0x00000020080 -#define ADDR_WCI_CA_ECC_ADDRESS 0x000000200a0 -#define ADDR_WCI_CA_ERROR_TRANSACTION 0x000000200c0 -#define ADDR_WCI_CA_TIMEOUT_CONFIG 0x000000200e0 -#define ADDR_WCI_CA_CONFIG 0x00000020100 -#define ADDR_WCI_CA_ESR_0 0x00000020120 -#define ADDR_WCI_CA_ESR_1 0x00000020140 -#define ADDR_WCI_CA_ESR_MASK 0x00000020160 -#define ADDR_WCI_CLUSTER_SYNC 0x00000020180 -#define ADDR_WCI_CA_TIMEOUT_CONFIG_2 0x000000201a0 -#define ADDR_WCI_CA_ERROR_TRANSACTION_2 0x000000201c0 -#define ADDR_WCI_QLIM_CONFIG_CAG 0x000000201e0 -#define ADDR_WCI_QLIM_CAG_TIMER 0x00000020200 -#define ADDR_WCI_BOARD2CNID_ARRAY 0x00000030000 -#define ENTRIES_WCI_BOARD2CNID_ARRAY 0x38 -#define STRIDE_WCI_BOARD2CNID_ARRAY 0x20 -#define ADDR_WCI_INID2DNID_ARRAY 0x00000030800 -#define ENTRIES_WCI_INID2DNID_ARRAY 0x40 -#define STRIDE_WCI_INID2DNID_ARRAY 0x20 -#define ADDR_WCI_RA_FREEZE 0x00000031000 -#define ADDR_WCI_RA_BUSY 0x00000031020 -#define ADDR_WCI_RA_FIRST_ERROR_AGENT 0x00000031040 -#define ADDR_WCI_RA_FIRST_PACKET_0 0x00000031060 -#define ADDR_WCI_RA_FIRST_PACKET_1 0x00000031080 -#define ADDR_WCI_RA_ECC_ADDRESS 0x000000310a0 -#define ADDR_WCI_RA_ERROR_TRANSACTION_0 0x000000310c0 -#define ADDR_WCI_RA_ERROR_TRANSACTION_1 0x000000310e0 -#define ADDR_WCI_RA_TIMEOUT_CONFIG 0x00000031100 -#define ADDR_WCI_RA_ESR_0 0x00000031120 -#define ADDR_WCI_RA_ESR_1 0x00000031140 -#define ADDR_WCI_RA_ESR_MASK 0x00000031160 -#define ADDR_WCI_RA_STATUS_ARRAY 0x00000031400 -#define ENTRIES_WCI_RA_STATUS_ARRAY 0x20 -#define STRIDE_WCI_RA_STATUS_ARRAY 0x20 -#define ADDR_WCI_RA_STATUS_2_ARRAY 0x00000031800 -#define ENTRIES_WCI_RA_STATUS_2_ARRAY 0x20 -#define STRIDE_WCI_RA_STATUS_2_ARRAY 0x20 -#define ADDR_WCI_RA_WRITE_LOCKOUT_STATUS 0x00000031c00 -#define ADDR_WCI_RAG_ROUTE_MAP0 0x00000031c20 -#define ADDR_WCI_RAG_ROUTE_MAP1 0x00000031c40 -#define ADDR_WCI_CLUSTER_ERROR_STATUS_ARRAY 0x00000032000 -#define ENTRIES_WCI_CLUSTER_ERROR_STATUS_ARRAY 0x100 -#define STRIDE_WCI_CLUSTER_ERROR_STATUS_ARRAY 0x20 -#define ADDR_WCI_CLUSTER_ERROR_COUNT 0x00000034000 -#define ADDR_WCI_INT_DEST_BUSY_COUNT 0x00000034020 -#define ADDR_WCI_QLIM_3REQ_PRIORITY 0x00000034040 -#define ADDR_WCI_QLIM_2REQ_PRIORITY 0x00000034060 -#define ADDR_WCI_QLIM_CONFIG_PIQ 0x00000034080 -#define ADDR_WCI_QLIM_CONFIG_NIQ 0x000000340a0 -#define ADDR_WCI_QLIM_CONFIG_CIQ 0x000000340c0 -#define ADDR_WCI_QLIM_PIQ_TIMER 0x000000340e0 -#define ADDR_WCI_QLIM_NIQ_TIMER 0x00000034100 -#define ADDR_WCI_QLIM_CIQ_TIMER 0x00000034120 -#define ADDR_WCI_OS_CLUSTER_DISABLE 0x00000034140 -#define ADDR_WCI_SC_CLUSTER_DISABLE 0x00000034160 -#define ADDR_WCI_HA_FREEZE 0x00000040000 -#define ADDR_WCI_HA_BUSY 0x00000040020 -#define ADDR_WCI_HA_FIRST_ERROR_AGENT 0x00000040040 -#define ADDR_WCI_HA_FIRST_PACKET_0 0x00000040060 -#define ADDR_WCI_HA_FIRST_PACKET_1 0x00000040080 -#define ADDR_WCI_HA_ECC_ADDRESS 0x000000400a0 -#define ADDR_WCI_HA_ERROR_ADDRESS 0x000000400c0 -#define ADDR_WCI_HA_TIMEOUT_CONFIG 0x000000400e0 -#define ADDR_WCI_HA_ESR_0 0x00000040100 -#define ADDR_WCI_HA_ESR_1 0x00000040120 -#define ADDR_WCI_HA_HW_ERR_STATUS 0x00000040140 -#define ADDR_WCI_HA_ESR_MASK 0x00000040160 -#define ADDR_WCI_PROBE_MEMORY 0x00000040180 -#define ADDR_WCI_HA_STATUS_ARRAY 0x00000040200 -#define ENTRIES_WCI_HA_STATUS_ARRAY 0x10 -#define STRIDE_WCI_HA_STATUS_ARRAY 0x20 -#define ADDR_WCI_HA_STATUS_2_ARRAY 0x00000040400 -#define ENTRIES_WCI_HA_STATUS_2_ARRAY 0x10 -#define STRIDE_WCI_HA_STATUS_2_ARRAY 0x20 -#define ADDR_WCI_HA_CONFIG 0x00000040600 -#define ADDR_WCI_HAG_ROUTE_MAP0 0x00000040620 -#define ADDR_WCI_HAG_ROUTE_MAP1 0x00000040640 -#define ADDR_WCI_EMISS_CNTL_ARRAY 0x00000042000 -#define ENTRIES_WCI_EMISS_CNTL_ARRAY 0x10 -#define STRIDE_WCI_EMISS_CNTL_ARRAY 0x20 -#define ADDR_WCI_EMISS_DATA_ARRAY 0x00000042200 -#define ENTRIES_WCI_EMISS_DATA_ARRAY 0x10 -#define STRIDE_WCI_EMISS_DATA_ARRAY 0x20 -#define ADDR_WCI_EMISS_RESET_CTL 0x00000042400 -#define ADDR_WCI_GLOBAL_EMISS_COUNTER 0x00000042420 -#define ADDR_WCI_SA_FREEZE 0x00000050000 -#define ADDR_WCI_SA_BUSY 0x00000050020 -#define ADDR_WCI_SA_FIRST_ERROR_AGENT 0x00000050040 -#define ADDR_WCI_SA_FIRST_PACKET_0 0x00000050060 -#define ADDR_WCI_SA_FIRST_PACKET_1 0x00000050080 -#define ADDR_WCI_SA_ECC_ADDRESS 0x000000500a0 -#define ADDR_WCI_SA_TIMEOUT_CONFIG 0x000000500c0 -#define ADDR_WCI_SA_ESR_0 0x000000500e0 -#define ADDR_WCI_SA_HW_ERR_STATE 0x00000050100 -#define ADDR_WCI_SA_ESR_MASK 0x00000050120 -#define ADDR_WCI_SA_STATUS_ARRAY 0x00000050200 -#define ENTRIES_WCI_SA_STATUS_ARRAY 0x8 -#define STRIDE_WCI_SA_STATUS_ARRAY 0x20 -#define ADDR_WCI_SA_STATUS_2_ARRAY 0x00000050300 -#define ENTRIES_WCI_SA_STATUS_2_ARRAY 0x8 -#define STRIDE_WCI_SA_STATUS_2_ARRAY 0x20 -#define ADDR_WCI_SA_STATUS_3_ARRAY 0x00000050400 -#define ENTRIES_WCI_SA_STATUS_3_ARRAY 0x8 -#define STRIDE_WCI_SA_STATUS_3_ARRAY 0x20 -#define ADDR_WCI_SA_STATUS_4_ARRAY 0x00000050500 -#define ENTRIES_WCI_SA_STATUS_4_ARRAY 0x8 -#define STRIDE_WCI_SA_STATUS_4_ARRAY 0x20 -#define ADDR_WCI_SA_STATUS_5_ARRAY 0x00000050600 -#define ENTRIES_WCI_SA_STATUS_5_ARRAY 0x8 -#define STRIDE_WCI_SA_STATUS_5_ARRAY 0x20 -#define ADDR_WCI_SA_STATUS_6_ARRAY 0x00000050700 -#define ENTRIES_WCI_SA_STATUS_6_ARRAY 0x8 -#define STRIDE_WCI_SA_STATUS_6_ARRAY 0x20 -#define ADDR_WCI_SAG_ROUTE_MAP0 0x00000050800 -#define ADDR_WCI_SAG_ROUTE_MAP1 0x00000050820 -#define ADDR_WCI_NC2NID_ARRAY 0x00000060000 -#define ENTRIES_WCI_NC2NID_ARRAY 0x100 -#define STRIDE_WCI_NC2NID_ARRAY 0x20 -#define ADDR_WCI_SFI_TRANSID_ALLOC 0x00000062000 -#define ADDR_WCI_SFI_ESR 0x00000062020 -#define ADDR_WCI_SFI_ESR_MASK 0x00000062040 -#define ADDR_WCI_SFI_STATE 0x00000062060 -#define ADDR_WCI_SFI_STATE1 0x00000062080 -#define ADDR_WCI_SFI_CTR1_MASK 0x00000064000 -#define ADDR_WCI_SFI_CTR1_MATCH_TRANSACTION 0x00000064020 -#define ADDR_WCI_SFI_CTR1_MATCH 0x00000064040 -#define ADDR_WCI_SFI_CTR0_MASK 0x00000064060 -#define ADDR_WCI_SFI_CTR0_MATCH_TRANSACTION 0x00000064080 -#define ADDR_WCI_SFI_CTR0_MATCH 0x000000640a0 -#define ADDR_WCI_SFI_ANALYZER 0x000000640c0 -#define ADDR_WCI_SFI_ROUTE_MAP0 0x000000640e0 -#define ADDR_WCI_SFI_ROUTE_MAP1 0x00000064100 -#define ADDR_WCI_QLIM_SORT_PIQ 0x00000064120 -#define ADDR_WCI_QLIM_SORT_NIQ 0x00000064140 -#define ADDR_WCI_QLIM_SORT_CIQ 0x00000064160 -#define ADDR_WCI_LINK_ESR 0x00000070000 -#define ADDR_WCI_LINK_ESR_MASK 0x00000070100 -#define ADDR_WCI_SW_ESR 0x00000070120 -#define ADDR_WCI_SW_ESR_MASK 0x00000070140 -#define ADDR_WCI_SW_LINK_CONTROL 0x00000070200 -#define ENTRIES_WCI_SW_LINK_CONTROL 0x3 -#define STRIDE_WCI_SW_LINK_CONTROL 0x20 -#define ADDR_WCI_SW_LINK_ERROR_COUNT 0x00000070300 -#define ENTRIES_WCI_SW_LINK_ERROR_COUNT 0x3 -#define STRIDE_WCI_SW_LINK_ERROR_COUNT 0x20 -#define ADDR_WCI_SW_LINK_STATUS 0x00000070400 -#define ENTRIES_WCI_SW_LINK_STATUS 0x3 -#define STRIDE_WCI_SW_LINK_STATUS 0x20 -#define ADDR_WCI_SW_CONFIG 0x00000070500 -#define ADDR_WCI_SW_STATUS 0x00000070520 -#define ADDR_WCI_LINK_CTR_CTL 0x00000070600 -#define ENTRIES_WCI_LINK_CTR_CTL 0x3 -#define STRIDE_WCI_LINK_CTR_CTL 0x20 -#define ADDR_WCI_LPBK_CTR_CTL 0x00000070700 -#define ADDR_WCI_LINK_CTR 0x00000070800 -#define ENTRIES_WCI_LINK_CTR 0x3 -#define STRIDE_WCI_LINK_CTR 0x20 -#define ADDR_WCI_LPBK_CTR 0x00000070900 -#define ADDR_WCI_SW_ESR_A 0x00000070920 -#define ADDR_WCI_SW_ESR_A_MASK 0x00000070940 -#define ADDR_WCI_GNID_MAP0 0x00000070960 -#define ADDR_WCI_GNID_MAP1 0x00000070980 -#define ADDR_WCI_FO_ROUTE_MAP 0x000000709a0 -#define ADDR_WCI_SEC_FO_ROUTE_MAP 0x000000709c0 -#define ADDR_WCI_FO_TNID_MAP 0x000000709e0 -#define ADDR_WCI_SW_LINK_REXMIT 0x00000070b00 -#define ENTRIES_WCI_SW_LINK_REXMIT 0x3 -#define STRIDE_WCI_SW_LINK_REXMIT 0x20 -#define ADDR_WCI_DNID2GNID 0x00000070c00 - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WCI_OFFSETS_H */ diff --git a/usr/src/uts/sun4u/sys/wci_regs.h b/usr/src/uts/sun4u/sys/wci_regs.h deleted file mode 100644 index e8ce40ae80..0000000000 --- a/usr/src/uts/sun4u/sys/wci_regs.h +++ /dev/null @@ -1,6920 +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 2001,2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_WCI_REGS_H -#define _SYS_WCI_REGS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_KERNEL) && !defined(_ASM) - -/* - * wci_sram_array - */ -typedef union { - struct wci_sram_array { - uint64_t error : 1; /* 63 */ - uint64_t data : 63; /* 62:0 */ - } bit; - uint64_t val; -} wci_sram_array_u; - -#define wci_sram_array_error \ - bit.error -#define wci_sram_array_data \ - bit.data - - -/* - * wci_shadow_addr - */ -typedef union { - struct wci_shadow_addr { - uint64_t set_agent_reset : 1; /* 63 */ - uint64_t pull_stop : 1; /* 62 */ - uint64_t data_stop : 1; /* 61 */ - uint64_t shadow_rsvd : 1; /* 60 */ - uint64_t rsvd_z : 10; /* 59:50 */ - uint64_t shadow_valid : 1; /* 49 */ - uint64_t shadow_timeout : 1; /* 48 */ - uint64_t shadow_addr_not_vld : 1; /* 47 */ - uint64_t shadow_sram_error : 1; /* 46 */ - uint64_t shadow_sram : 1; /* 45 */ - uint64_t shadow_write : 1; /* 44 */ - uint64_t rsvd_y : 15; /* 43:29 */ - uint64_t shadow_addr : 24; /* 28:5 */ - uint64_t rsvd_x : 5; /* 4:0 */ - } bit; - uint64_t val; -} wci_shadow_addr_u; - -#define wci_shadow_addr_set_agent_reset \ - bit.set_agent_reset -#define wci_shadow_addr_pull_stop \ - bit.pull_stop -#define wci_shadow_addr_data_stop \ - bit.data_stop -#define wci_shadow_addr_shadow_rsvd \ - bit.shadow_rsvd -#define wci_shadow_addr_shadow_valid \ - bit.shadow_valid -#define wci_shadow_addr_shadow_timeout \ - bit.shadow_timeout -#define wci_shadow_addr_shadow_addr_not_vld \ - bit.shadow_addr_not_vld -#define wci_shadow_addr_shadow_sram_error \ - bit.shadow_sram_error -#define wci_shadow_addr_shadow_sram \ - bit.shadow_sram -#define wci_shadow_addr_shadow_write \ - bit.shadow_write -#define wci_shadow_addr_shadow_addr \ - bit.shadow_addr - - -/* - * wci_shadow_data - */ -typedef union { - struct wci_shadow_data { - uint64_t shadow_data : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_shadow_data_u; - -#define wci_shadow_data_shadow_data \ - bit.shadow_data - - -/* - * wci_config - */ -typedef union { - struct wci_config { - uint64_t rsvd_z : 19; /* 63:45 */ - uint64_t wr_dir_on_rinv_miss : 1; /* 44 */ - uint64_t wr_dir_on_rws_miss : 1; /* 43 */ - uint64_t safari_compliant_targid : 1; /* 42 */ - uint64_t rsvd_y : 3; /* 41:39 */ - uint64_t cluster_early_reuse_en : 1; /* 38 */ - uint64_t reserved_default_0 : 1; /* 37 */ - uint64_t ra_numa_bypass_en : 1; /* 36 */ - uint64_t ha_disable_unexp_snid : 1; /* 35 */ - uint64_t ra_disable_unexp_snid : 1; /* 34 */ - uint64_t dc_cpi_snid_disable : 1; /* 33 */ - uint64_t dbg_bytemask_en : 1; /* 32 */ - uint64_t partner_node_id : 4; /* 31:28 */ - uint64_t cluster_mode : 1; /* 27 */ - uint64_t rsvd_x : 1; /* 26 */ - uint64_t nc_stripe_by_addr : 1; /* 25 */ - uint64_t enable_inid : 1; /* 24 */ - uint64_t stripe_bits : 4; /* 23:20 */ - uint64_t dev_config_node_id : 5; /* 19:15 */ - uint64_t box_id : 6; /* 14:9 */ - uint64_t device_id : 5; /* 8:4 */ - uint64_t node_id : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_config_u; - -#define wci_config_wr_dir_on_rinv_miss \ - bit.wr_dir_on_rinv_miss -#define wci_config_wr_dir_on_rws_miss \ - bit.wr_dir_on_rws_miss -#define wci_config_safari_compliant_targid \ - bit.safari_compliant_targid -#define wci_config_cluster_early_reuse_en \ - bit.cluster_early_reuse_en -#define wci_config_reserved_default_0 \ - bit.reserved_default_0 -#define wci_config_ra_numa_bypass_en \ - bit.ra_numa_bypass_en -#define wci_config_ha_disable_unexp_snid \ - bit.ha_disable_unexp_snid -#define wci_config_ra_disable_unexp_snid \ - bit.ra_disable_unexp_snid -#define wci_config_dc_cpi_snid_disable \ - bit.dc_cpi_snid_disable -#define wci_config_dbg_bytemask_en \ - bit.dbg_bytemask_en -#define wci_config_partner_node_id \ - bit.partner_node_id -#define wci_config_cluster_mode \ - bit.cluster_mode -#define wci_config_nc_stripe_by_addr \ - bit.nc_stripe_by_addr -#define wci_config_enable_inid \ - bit.enable_inid -#define wci_config_stripe_bits \ - bit.stripe_bits -#define wci_config_dev_config_node_id \ - bit.dev_config_node_id -#define wci_config_box_id \ - bit.box_id -#define wci_config_device_id \ - bit.device_id -#define wci_config_node_id \ - bit.node_id - - -/* - * wci_domain_config - */ -typedef union { - struct wci_domain_config { - uint64_t rsvd_z : 48; /* 63:16 */ - uint64_t domain_mask : 16; /* 15:0 */ - } bit; - uint64_t val; -} wci_domain_config_u; - -#define wci_domain_config_domain_mask \ - bit.domain_mask - - -/* - * wci_local_device_id - */ -typedef union { - struct wci_local_device_id { - uint64_t skip_rs_vec : 32; /* 63:32 */ - uint64_t ssm_mask : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_local_device_id_u; - -#define wci_local_device_id_skip_rs_vec \ - bit.skip_rs_vec -#define wci_local_device_id_ssm_mask \ - bit.ssm_mask - - -/* - * wci_reset_config - */ -typedef union { - struct wci_reset_config { - uint64_t rsvd_z : 63; /* 63:1 */ - uint64_t agent_reset_e : 1; /* 0 */ - } bit; - uint64_t val; -} wci_reset_config_u; - -#define wci_reset_config_agent_reset_e \ - bit.agent_reset_e - - -/* - * wci_reset_status - */ -typedef union { - struct wci_reset_status { - uint64_t rsvd_z : 61; /* 63:3 */ - uint64_t por : 1; /* 2 */ - uint64_t node_reset : 1; /* 1 */ - uint64_t agent_reset : 1; /* 0 */ - } bit; - uint64_t val; -} wci_reset_status_u; - -#define wci_reset_status_por \ - bit.por -#define wci_reset_status_node_reset \ - bit.node_reset -#define wci_reset_status_agent_reset \ - bit.agent_reset - - -/* - * wci_id - */ -typedef union { - struct wci_id { - uint64_t rsvd_z : 32; /* 63:32 */ - uint64_t version : 4; /* 31:28 */ - uint64_t parid : 16; /* 27:12 */ - uint64_t manfid : 11; /* 11:1 */ - uint64_t one : 1; /* 0 */ - } bit; - uint64_t val; -} wci_id_u; - -#define wci_id_version \ - bit.version -#define wci_id_parid \ - bit.parid -#define wci_id_manfid \ - bit.manfid -#define wci_id_one \ - bit.one - - -/* - * wci_board2cnid_control - */ -typedef union { - struct wci_board2cnid_control { - uint64_t rsvd_z : 63; /* 63:1 */ - uint64_t board2cnid_enable : 1; /* 0 */ - } bit; - uint64_t val; -} wci_board2cnid_control_u; - -#define wci_board2cnid_control_board2cnid_enable \ - bit.board2cnid_enable - - -/* - * wci_csr_control - */ -typedef union { - struct wci_csr_control { - uint64_t rsvd_z : 63; /* 63:1 */ - uint64_t jtag_wr_only : 1; /* 0 */ - } bit; - uint64_t val; -} wci_csr_control_u; - -#define wci_csr_control_jtag_wr_only \ - bit.jtag_wr_only - - -/* - * wci_error_summary - */ -typedef union { - struct wci_error_summary { - uint64_t rsvd_z : 53; /* 63:11 */ - uint64_t cci_error : 1; /* 10 */ - uint64_t request_agent_error : 1; /* 9 */ - uint64_t home_agent_error : 1; /* 8 */ - uint64_t slave_agent_error : 1; /* 7 */ - uint64_t cluster_agent_error : 1; /* 6 */ - uint64_t csr_agent_error : 1; /* 5 */ - uint64_t lc_error : 1; /* 4 */ - uint64_t sfi_error : 1; /* 3 */ - uint64_t sfq_error : 1; /* 2 */ - uint64_t dc_error : 1; /* 1 */ - uint64_t hli_error : 1; /* 0 */ - } bit; - uint64_t val; -} wci_error_summary_u; - -#define wci_error_summary_cci_error \ - bit.cci_error -#define wci_error_summary_request_agent_error \ - bit.request_agent_error -#define wci_error_summary_home_agent_error \ - bit.home_agent_error -#define wci_error_summary_slave_agent_error \ - bit.slave_agent_error -#define wci_error_summary_cluster_agent_error \ - bit.cluster_agent_error -#define wci_error_summary_csr_agent_error \ - bit.csr_agent_error -#define wci_error_summary_lc_error \ - bit.lc_error -#define wci_error_summary_sfi_error \ - bit.sfi_error -#define wci_error_summary_sfq_error \ - bit.sfq_error -#define wci_error_summary_dc_error \ - bit.dc_error -#define wci_error_summary_hli_error \ - bit.hli_error - - -/* - * wci_error_pause_timer_hold - */ -typedef union { - struct wci_error_pause_timer_hold { - uint64_t rsvd_z : 56; /* 63:8 */ - uint64_t ca_aphase : 1; /* 7 */ - uint64_t ca_dphase : 1; /* 6 */ - uint64_t ca_reuse : 1; /* 5 */ - uint64_t reserved : 1; /* 4 */ - uint64_t ra_cluster_primary : 1; /* 3 */ - uint64_t ra_ssm_primary : 1; /* 2 */ - uint64_t ha_primary : 1; /* 1 */ - uint64_t sa_primary : 1; /* 0 */ - } bit; - uint64_t val; -} wci_error_pause_timer_hold_u; - -#define wci_error_pause_timer_hold_ca_aphase \ - bit.ca_aphase -#define wci_error_pause_timer_hold_ca_dphase \ - bit.ca_dphase -#define wci_error_pause_timer_hold_ca_reuse \ - bit.ca_reuse -#define wci_error_pause_timer_hold_reserved \ - bit.reserved -#define wci_error_pause_timer_hold_ra_cluster_primary \ - bit.ra_cluster_primary -#define wci_error_pause_timer_hold_ra_ssm_primary \ - bit.ra_ssm_primary -#define wci_error_pause_timer_hold_ha_primary \ - bit.ha_primary -#define wci_error_pause_timer_hold_sa_primary \ - bit.sa_primary - - -/* - * wci_first_error_time - */ -typedef union { - struct wci_first_error_time { - uint64_t stick_time : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_first_error_time_u; - -#define wci_first_error_time_stick_time \ - bit.stick_time - - -/* - * wci_csra_esr - */ -typedef union { - struct wci_csra_esr { - uint64_t rsvd_z : 37; /* 63:27 */ - uint64_t acc_timeout : 1; /* 26 */ - uint64_t acc_pull_targid_timeout : 1; /* 25 */ - uint64_t acc_pull_timeout : 1; /* 24 */ - uint64_t acc_sram_error : 1; /* 23 */ - uint64_t acc_protection_error : 1; /* 22 */ - uint64_t acc_uncorrectable_mtag_error : 1; /* 21 */ - uint64_t acc_uncorrectable_data_error : 1; /* 20 */ - uint64_t acc_correctable_mtag_error : 1; /* 19 */ - uint64_t acc_correctable_data_error : 1; /* 18 */ - uint64_t acc_mtag_not_gm : 1; /* 17 */ - uint64_t acc_mtag_mismatch : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 4; /* 14:11 */ - uint64_t timeout : 1; /* 10 */ - uint64_t pull_targid_timeout : 1; /* 9 */ - uint64_t pull_timeout : 1; /* 8 */ - uint64_t sram_error : 1; /* 7 */ - uint64_t protection_error : 1; /* 6 */ - uint64_t uncorrectable_mtag_error : 1; /* 5 */ - uint64_t uncorrectable_data_error : 1; /* 4 */ - uint64_t correctable_mtag_error : 1; /* 3 */ - uint64_t correctable_data_error : 1; /* 2 */ - uint64_t mtag_not_gm : 1; /* 1 */ - uint64_t mtag_mismatch : 1; /* 0 */ - } bit; - uint64_t val; -} wci_csra_esr_u; - -#define wci_csra_esr_acc_timeout \ - bit.acc_timeout -#define wci_csra_esr_acc_pull_targid_timeout \ - bit.acc_pull_targid_timeout -#define wci_csra_esr_acc_pull_timeout \ - bit.acc_pull_timeout -#define wci_csra_esr_acc_sram_error \ - bit.acc_sram_error -#define wci_csra_esr_acc_protection_error \ - bit.acc_protection_error -#define wci_csra_esr_acc_uncorrectable_mtag_error \ - bit.acc_uncorrectable_mtag_error -#define wci_csra_esr_acc_uncorrectable_data_error \ - bit.acc_uncorrectable_data_error -#define wci_csra_esr_acc_correctable_mtag_error \ - bit.acc_correctable_mtag_error -#define wci_csra_esr_acc_correctable_data_error \ - bit.acc_correctable_data_error -#define wci_csra_esr_acc_mtag_not_gm \ - bit.acc_mtag_not_gm -#define wci_csra_esr_acc_mtag_mismatch \ - bit.acc_mtag_mismatch -#define wci_csra_esr_first_error \ - bit.first_error -#define wci_csra_esr_timeout \ - bit.timeout -#define wci_csra_esr_pull_targid_timeout \ - bit.pull_targid_timeout -#define wci_csra_esr_pull_timeout \ - bit.pull_timeout -#define wci_csra_esr_sram_error \ - bit.sram_error -#define wci_csra_esr_protection_error \ - bit.protection_error -#define wci_csra_esr_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_csra_esr_uncorrectable_data_error \ - bit.uncorrectable_data_error -#define wci_csra_esr_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_csra_esr_correctable_data_error \ - bit.correctable_data_error -#define wci_csra_esr_mtag_not_gm \ - bit.mtag_not_gm -#define wci_csra_esr_mtag_mismatch \ - bit.mtag_mismatch - - -/* - * wci_csra_esr_mask - */ -typedef union { - struct wci_csra_esr_mask { - uint64_t rsvd_z : 53; /* 63:11 */ - uint64_t timeout : 1; /* 10 */ - uint64_t pull_targid_timeout : 1; /* 9 */ - uint64_t pull_timeout : 1; /* 8 */ - uint64_t sram_error : 1; /* 7 */ - uint64_t protection_error : 1; /* 6 */ - uint64_t uncorrectable_mtag_error : 1; /* 5 */ - uint64_t uncorrectable_data_error : 1; /* 4 */ - uint64_t correctable_mtag_error : 1; /* 3 */ - uint64_t correctable_data_error : 1; /* 2 */ - uint64_t mtag_not_gm : 1; /* 1 */ - uint64_t mtag_mismatch : 1; /* 0 */ - } bit; - uint64_t val; -} wci_csra_esr_mask_u; - -#define wci_csra_esr_mask_timeout \ - bit.timeout -#define wci_csra_esr_mask_pull_targid_timeout \ - bit.pull_targid_timeout -#define wci_csra_esr_mask_pull_timeout \ - bit.pull_timeout -#define wci_csra_esr_mask_sram_error \ - bit.sram_error -#define wci_csra_esr_mask_protection_error \ - bit.protection_error -#define wci_csra_esr_mask_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_csra_esr_mask_uncorrectable_data_error \ - bit.uncorrectable_data_error -#define wci_csra_esr_mask_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_csra_esr_mask_correctable_data_error \ - bit.correctable_data_error -#define wci_csra_esr_mask_mtag_not_gm \ - bit.mtag_not_gm -#define wci_csra_esr_mask_mtag_mismatch \ - bit.mtag_mismatch - - -/* - * wci_csra_status - */ -typedef union { - struct wci_csra_status { - uint64_t rsvd_z : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t scar : 1; /* 58 */ - uint64_t atransid : 9; /* 57:49 */ - uint64_t targid_3_to_0 : 3; /* 48:46 */ - uint64_t cesr_number : 8; /* 45:38 */ - uint64_t rw : 1; /* 37 */ - uint64_t nc_slice : 8; /* 36:29 */ - uint64_t sf_addr_28_to_5 : 24; /* 28:5 */ - uint64_t fsm_state : 3; /* 4:2 */ - uint64_t type : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_csra_status_u; - -#define wci_csra_status_esr_index \ - bit.esr_index -#define wci_csra_status_scar \ - bit.scar -#define wci_csra_status_atransid \ - bit.atransid -#define wci_csra_status_targid_3_to_0 \ - bit.targid_3_to_0 -#define wci_csra_status_cesr_number \ - bit.cesr_number -#define wci_csra_status_rw \ - bit.rw -#define wci_csra_status_nc_slice \ - bit.nc_slice -#define wci_csra_status_sf_addr_28_to_5 \ - bit.sf_addr_28_to_5 -#define wci_csra_status_fsm_state \ - bit.fsm_state -#define wci_csra_status_type \ - bit.type - - -/* - * wci_csra_timeout_config - */ -typedef union { - struct wci_csra_timeout_config { - uint64_t rsvd_z : 43; /* 63:21 */ - uint64_t pull_targid_fail_fast_enable : 1; /* 20 */ - uint64_t pull_fail_fast_enable : 1; /* 19 */ - uint64_t disable : 1; /* 18 */ - uint64_t freeze : 1; /* 17 */ - uint64_t magnitude : 1; /* 16 */ - uint64_t rd_timeout : 8; /* 15:8 */ - uint64_t wr_timeout : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_csra_timeout_config_u; - -#define wci_csra_timeout_config_pull_targid_fail_fast_enable \ - bit.pull_targid_fail_fast_enable -#define wci_csra_timeout_config_pull_fail_fast_enable \ - bit.pull_fail_fast_enable -#define wci_csra_timeout_config_disable \ - bit.disable -#define wci_csra_timeout_config_freeze \ - bit.freeze -#define wci_csra_timeout_config_magnitude \ - bit.magnitude -#define wci_csra_timeout_config_rd_timeout \ - bit.rd_timeout -#define wci_csra_timeout_config_wr_timeout \ - bit.wr_timeout - - -/* - * wci_dc_esr - */ -typedef union { - struct wci_dc_esr { - uint64_t rsvd_z : 38; /* 63:26 */ - uint64_t acc_dif_timeout : 1; /* 25 */ - uint64_t acc_dci_d_err_dstat : 1; /* 24 */ - uint64_t acc_dco_ce : 1; /* 23 */ - uint64_t acc_dc_dif_overflow : 1; /* 22 */ - uint64_t acc_dc_launch_queue_overflow : 1; /* 21 */ - uint64_t acc_dco_map_error : 1; /* 20 */ - uint64_t acc_dco_data_parity_error : 1; /* 19 */ - uint64_t acc_dci_d_err : 1; /* 18 */ - uint64_t acc_dci_cpi_invalid : 1; /* 17 */ - uint64_t acc_dci_cpi_snid_mismatch : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 5; /* 14:10 */ - uint64_t dif_timeout : 1; /* 9 */ - uint64_t dci_d_err_dstat : 1; /* 8 */ - uint64_t dco_ce : 1; /* 7 */ - uint64_t dc_dif_overflow : 1; /* 6 */ - uint64_t dc_launch_queue_overflow : 1; /* 5 */ - uint64_t dco_map_error : 1; /* 4 */ - uint64_t dco_data_parity_error : 1; /* 3 */ - uint64_t dci_d_err : 1; /* 2 */ - uint64_t dci_cpi_invalid : 1; /* 1 */ - uint64_t dci_cpi_snid_mismatch : 1; /* 0 */ - } bit; - uint64_t val; -} wci_dc_esr_u; - -#define wci_dc_esr_acc_dif_timeout \ - bit.acc_dif_timeout -#define wci_dc_esr_acc_dci_d_err_dstat \ - bit.acc_dci_d_err_dstat -#define wci_dc_esr_acc_dco_ce \ - bit.acc_dco_ce -#define wci_dc_esr_acc_dc_dif_overflow \ - bit.acc_dc_dif_overflow -#define wci_dc_esr_acc_dc_launch_queue_overflow \ - bit.acc_dc_launch_queue_overflow -#define wci_dc_esr_acc_dco_map_error \ - bit.acc_dco_map_error -#define wci_dc_esr_acc_dco_data_parity_error \ - bit.acc_dco_data_parity_error -#define wci_dc_esr_acc_dci_d_err \ - bit.acc_dci_d_err -#define wci_dc_esr_acc_dci_cpi_invalid \ - bit.acc_dci_cpi_invalid -#define wci_dc_esr_acc_dci_cpi_snid_mismatch \ - bit.acc_dci_cpi_snid_mismatch -#define wci_dc_esr_first_error \ - bit.first_error -#define wci_dc_esr_dif_timeout \ - bit.dif_timeout -#define wci_dc_esr_dci_d_err_dstat \ - bit.dci_d_err_dstat -#define wci_dc_esr_dco_ce \ - bit.dco_ce -#define wci_dc_esr_dc_dif_overflow \ - bit.dc_dif_overflow -#define wci_dc_esr_dc_launch_queue_overflow \ - bit.dc_launch_queue_overflow -#define wci_dc_esr_dco_map_error \ - bit.dco_map_error -#define wci_dc_esr_dco_data_parity_error \ - bit.dco_data_parity_error -#define wci_dc_esr_dci_d_err \ - bit.dci_d_err -#define wci_dc_esr_dci_cpi_invalid \ - bit.dci_cpi_invalid -#define wci_dc_esr_dci_cpi_snid_mismatch \ - bit.dci_cpi_snid_mismatch - - -/* - * wci_dc_esr_mask - */ -typedef union { - struct wci_dc_esr_mask { - uint64_t rsvd_z : 54; /* 63:10 */ - uint64_t dif_timeout : 1; /* 9 */ - uint64_t dci_d_err_dstat : 1; /* 8 */ - uint64_t dco_ce : 1; /* 7 */ - uint64_t dc_dif_overflow : 1; /* 6 */ - uint64_t dc_launch_queue_overflow : 1; /* 5 */ - uint64_t dco_map_error : 1; /* 4 */ - uint64_t dco_data_parity_error : 1; /* 3 */ - uint64_t dci_d_err : 1; /* 2 */ - uint64_t dci_cpi_invalid : 1; /* 1 */ - uint64_t dci_cpi_snid_mismatch : 1; /* 0 */ - } bit; - uint64_t val; -} wci_dc_esr_mask_u; - -#define wci_dc_esr_mask_dif_timeout \ - bit.dif_timeout -#define wci_dc_esr_mask_dci_d_err_dstat \ - bit.dci_d_err_dstat -#define wci_dc_esr_mask_dco_ce \ - bit.dco_ce -#define wci_dc_esr_mask_dc_dif_overflow \ - bit.dc_dif_overflow -#define wci_dc_esr_mask_dc_launch_queue_overflow \ - bit.dc_launch_queue_overflow -#define wci_dc_esr_mask_dco_map_error \ - bit.dco_map_error -#define wci_dc_esr_mask_dco_data_parity_error \ - bit.dco_data_parity_error -#define wci_dc_esr_mask_dci_d_err \ - bit.dci_d_err -#define wci_dc_esr_mask_dci_cpi_invalid \ - bit.dci_cpi_invalid -#define wci_dc_esr_mask_dci_cpi_snid_mismatch \ - bit.dci_cpi_snid_mismatch - - -/* - * wci_dco_state - */ -typedef union { - struct wci_dco_state { - uint64_t link_0_lq_overflow : 1; /* 63 */ - uint64_t link_1_lq_overflow : 1; /* 62 */ - uint64_t link_2_lq_overflow : 1; /* 61 */ - uint64_t rsvd_z : 2; /* 60:59 */ - uint64_t lpbk_lq_overflow : 1; /* 58 */ - uint64_t csr_lq_overflow : 1; /* 57 */ - uint64_t rsvd_y : 5; /* 56:52 */ - uint64_t dco_map_error_dtarg : 1; /* 51 */ - uint64_t dco_map_error_dtransid : 9; /* 50:42 */ - uint64_t mtag_ecc_error_aid : 7; /* 41:35 */ - uint64_t data_ecc_error_aid : 7; /* 34:28 */ - uint64_t data_ecc_ue : 1; /* 27 */ - uint64_t mtag_ecc_ue : 1; /* 26 */ - uint64_t mtag_syndrome_0 : 4; /* 25:22 */ - uint64_t mtag_syndrome_1 : 4; /* 21:18 */ - uint64_t data_syndrome_0 : 9; /* 17:9 */ - uint64_t data_syndrome_1 : 9; /* 8:0 */ - } bit; - uint64_t val; -} wci_dco_state_u; - -#define wci_dco_state_link_0_lq_overflow \ - bit.link_0_lq_overflow -#define wci_dco_state_link_1_lq_overflow \ - bit.link_1_lq_overflow -#define wci_dco_state_link_2_lq_overflow \ - bit.link_2_lq_overflow -#define wci_dco_state_lpbk_lq_overflow \ - bit.lpbk_lq_overflow -#define wci_dco_state_csr_lq_overflow \ - bit.csr_lq_overflow -#define wci_dco_state_dco_map_error_dtarg \ - bit.dco_map_error_dtarg -#define wci_dco_state_dco_map_error_dtransid \ - bit.dco_map_error_dtransid -#define wci_dco_state_mtag_ecc_error_aid \ - bit.mtag_ecc_error_aid -#define wci_dco_state_data_ecc_error_aid \ - bit.data_ecc_error_aid -#define wci_dco_state_data_ecc_ue \ - bit.data_ecc_ue -#define wci_dco_state_mtag_ecc_ue \ - bit.mtag_ecc_ue -#define wci_dco_state_mtag_syndrome_0 \ - bit.mtag_syndrome_0 -#define wci_dco_state_mtag_syndrome_1 \ - bit.mtag_syndrome_1 -#define wci_dco_state_data_syndrome_0 \ - bit.data_syndrome_0 -#define wci_dco_state_data_syndrome_1 \ - bit.data_syndrome_1 - - -/* - * wci_dco_ce_count - */ -typedef union { - struct wci_dco_ce_count { - uint64_t rsvd_z : 56; /* 63:8 */ - uint64_t ce_count : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_dco_ce_count_u; - -#define wci_dco_ce_count_ce_count \ - bit.ce_count - - -/* - * wci_dci_state - */ -typedef union { - struct wci_dci_state { - uint64_t rsvd_z : 40; /* 63:24 */ - uint64_t dci_d_err_dtarg : 1; /* 23 */ - uint64_t dci_d_err_dtransid : 9; /* 22:14 */ - uint64_t dci_cpi_err_dtarg : 1; /* 13 */ - uint64_t dci_cpi_err_dtransid : 9; /* 12:4 */ - uint64_t dci_cpi_err_source_nid : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_dci_state_u; - -#define wci_dci_state_dci_d_err_dtarg \ - bit.dci_d_err_dtarg -#define wci_dci_state_dci_d_err_dtransid \ - bit.dci_d_err_dtransid -#define wci_dci_state_dci_cpi_err_dtarg \ - bit.dci_cpi_err_dtarg -#define wci_dci_state_dci_cpi_err_dtransid \ - bit.dci_cpi_err_dtransid -#define wci_dci_state_dci_cpi_err_source_nid \ - bit.dci_cpi_err_source_nid - - -/* - * wci_hli_strange_pkt_1 - */ -typedef union { - struct wci_hli_strange_pkt_1 { - uint64_t rsvd_z : 33; /* 63:31 */ - uint64_t hi : 31; /* 30:0 */ - } bit; - uint64_t val; -} wci_hli_strange_pkt_1_u; - -#define wci_hli_strange_pkt_1_hi \ - bit.hi - - -/* - * wci_hli_strange_pkt_0 - */ -typedef union { - struct wci_hli_strange_pkt_0 { - uint64_t lo : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_hli_strange_pkt_0_u; - -#define wci_hli_strange_pkt_0_lo \ - bit.lo - - -/* - * wci_hli_esr - */ -typedef union { - struct wci_hli_esr { - uint64_t rsvd_z : 41; /* 63:23 */ - uint64_t acc_slq_perr : 1; /* 22 */ - uint64_t acc_hmq_perr : 1; /* 21 */ - uint64_t acc_strange_pkt : 1; /* 20 */ - uint64_t acc_bq_unfl : 1; /* 19 */ - uint64_t acc_hmq_unfl : 1; /* 18 */ - uint64_t acc_hmq_ovfl : 1; /* 17 */ - uint64_t acc_slq_ovfl : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 8; /* 14:7 */ - uint64_t slq_perr : 1; /* 6 */ - uint64_t hmq_perr : 1; /* 5 */ - uint64_t strange_pkt : 1; /* 4 */ - uint64_t bq_unfl : 1; /* 3 */ - uint64_t hmq_unfl : 1; /* 2 */ - uint64_t hmq_ovfl : 1; /* 1 */ - uint64_t slq_ovfl : 1; /* 0 */ - } bit; - uint64_t val; -} wci_hli_esr_u; - -#define wci_hli_esr_acc_slq_perr \ - bit.acc_slq_perr -#define wci_hli_esr_acc_hmq_perr \ - bit.acc_hmq_perr -#define wci_hli_esr_acc_strange_pkt \ - bit.acc_strange_pkt -#define wci_hli_esr_acc_bq_unfl \ - bit.acc_bq_unfl -#define wci_hli_esr_acc_hmq_unfl \ - bit.acc_hmq_unfl -#define wci_hli_esr_acc_hmq_ovfl \ - bit.acc_hmq_ovfl -#define wci_hli_esr_acc_slq_ovfl \ - bit.acc_slq_ovfl -#define wci_hli_esr_first_error \ - bit.first_error -#define wci_hli_esr_slq_perr \ - bit.slq_perr -#define wci_hli_esr_hmq_perr \ - bit.hmq_perr -#define wci_hli_esr_strange_pkt \ - bit.strange_pkt -#define wci_hli_esr_bq_unfl \ - bit.bq_unfl -#define wci_hli_esr_hmq_unfl \ - bit.hmq_unfl -#define wci_hli_esr_hmq_ovfl \ - bit.hmq_ovfl -#define wci_hli_esr_slq_ovfl \ - bit.slq_ovfl - - -/* - * wci_hli_esr_mask - */ -typedef union { - struct wci_hli_esr_mask { - uint64_t rsvd_z : 57; /* 63:7 */ - uint64_t slq_perr : 1; /* 6 */ - uint64_t hmq_perr : 1; /* 5 */ - uint64_t strange_pkt : 1; /* 4 */ - uint64_t bq_unfl : 1; /* 3 */ - uint64_t hmq_unfl : 1; /* 2 */ - uint64_t hmq_ovfl : 1; /* 1 */ - uint64_t slq_ovfl : 1; /* 0 */ - } bit; - uint64_t val; -} wci_hli_esr_mask_u; - -#define wci_hli_esr_mask_slq_perr \ - bit.slq_perr -#define wci_hli_esr_mask_hmq_perr \ - bit.hmq_perr -#define wci_hli_esr_mask_strange_pkt \ - bit.strange_pkt -#define wci_hli_esr_mask_bq_unfl \ - bit.bq_unfl -#define wci_hli_esr_mask_hmq_unfl \ - bit.hmq_unfl -#define wci_hli_esr_mask_hmq_ovfl \ - bit.hmq_ovfl -#define wci_hli_esr_mask_slq_ovfl \ - bit.slq_ovfl - - -/* - * wci_hli_state - */ -typedef union { - struct wci_hli_state { - uint64_t rsvd_z : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t rsvd_y : 34; /* 58:25 */ - uint64_t queue : 17; /* 24:8 */ - uint64_t index : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_hli_state_u; - -#define wci_hli_state_esr_index \ - bit.esr_index -#define wci_hli_state_queue \ - bit.queue -#define wci_hli_state_index \ - bit.index - - -/* - * wci_sfq_esr - */ -typedef union { - struct wci_sfq_esr { - uint64_t rsvd_z : 46; /* 63:18 */ - uint64_t acc_sfq_perr : 1; /* 17 */ - uint64_t acc_sfq_ovfl : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 13; /* 14:2 */ - uint64_t sfq_perr : 1; /* 1 */ - uint64_t sfq_ovfl : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sfq_esr_u; - -#define wci_sfq_esr_acc_sfq_perr \ - bit.acc_sfq_perr -#define wci_sfq_esr_acc_sfq_ovfl \ - bit.acc_sfq_ovfl -#define wci_sfq_esr_first_error \ - bit.first_error -#define wci_sfq_esr_sfq_perr \ - bit.sfq_perr -#define wci_sfq_esr_sfq_ovfl \ - bit.sfq_ovfl - - -/* - * wci_sfq_esr_mask - */ -typedef union { - struct wci_sfq_esr_mask { - uint64_t rsvd_z : 62; /* 63:2 */ - uint64_t sfq_perr : 1; /* 1 */ - uint64_t sfq_ovfl : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sfq_esr_mask_u; - -#define wci_sfq_esr_mask_sfq_perr \ - bit.sfq_perr -#define wci_sfq_esr_mask_sfq_ovfl \ - bit.sfq_ovfl - - -/* - * wci_sfq_state - */ -typedef union { - struct wci_sfq_state { - uint64_t rsvd_z : 55; /* 63:9 */ - uint64_t index : 9; /* 8:0 */ - } bit; - uint64_t val; -} wci_sfq_state_u; - -#define wci_sfq_state_index \ - bit.index - - -/* - * wci_error_inducement - */ -typedef union { - struct wci_error_inducement { - uint64_t rsvd_z : 8; /* 63:56 */ - uint64_t internal_sram_vector : 7; /* 55:49 */ - uint64_t hmq_p : 1; /* 48 */ - uint64_t slq_p : 1; /* 47 */ - uint64_t sfq_p : 1; /* 46 */ - uint64_t sram_ecc_xor_2_select : 6; /* 45:40 */ - uint64_t sram_ecc_xor_1_select : 6; /* 39:34 */ - uint64_t sram_p : 2; /* 33:32 */ - uint64_t mtag_ecc0_xor : 4; /* 31:28 */ - uint64_t mtag_ecc1_xor : 4; /* 27:24 */ - uint64_t mtag0_xor : 3; /* 23:21 */ - uint64_t mtag1_xor : 3; /* 20:18 */ - uint64_t ecc0_xor : 9; /* 17:9 */ - uint64_t ecc1_xor : 9; /* 8:0 */ - } bit; - uint64_t val; -} wci_error_inducement_u; - -#define wci_error_inducement_internal_sram_vector \ - bit.internal_sram_vector -#define wci_error_inducement_hmq_p \ - bit.hmq_p -#define wci_error_inducement_slq_p \ - bit.slq_p -#define wci_error_inducement_sfq_p \ - bit.sfq_p -#define wci_error_inducement_sram_ecc_xor_2_select \ - bit.sram_ecc_xor_2_select -#define wci_error_inducement_sram_ecc_xor_1_select \ - bit.sram_ecc_xor_1_select -#define wci_error_inducement_sram_p \ - bit.sram_p -#define wci_error_inducement_mtag_ecc0_xor \ - bit.mtag_ecc0_xor -#define wci_error_inducement_mtag_ecc1_xor \ - bit.mtag_ecc1_xor -#define wci_error_inducement_mtag0_xor \ - bit.mtag0_xor -#define wci_error_inducement_mtag1_xor \ - bit.mtag1_xor -#define wci_error_inducement_ecc0_xor \ - bit.ecc0_xor -#define wci_error_inducement_ecc1_xor \ - bit.ecc1_xor - - -/* - * wci_ue_direction - */ -typedef union { - struct wci_ue_direction { - uint64_t rsvd_z : 25; /* 63:39 */ - uint64_t outbound_error_detected : 1; /* 38 */ - uint64_t ue_inbound : 1; /* 37 */ - uint64_t ue_outbound : 1; /* 36 */ - uint64_t ue_agent : 4; /* 35:32 */ - uint64_t ue_stick : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_ue_direction_u; - -#define wci_ue_direction_outbound_error_detected \ - bit.outbound_error_detected -#define wci_ue_direction_ue_inbound \ - bit.ue_inbound -#define wci_ue_direction_ue_outbound \ - bit.ue_outbound -#define wci_ue_direction_ue_agent \ - bit.ue_agent -#define wci_ue_direction_ue_stick \ - bit.ue_stick - - -/* - * wci_generates_cesr_number - */ -typedef union { - struct wci_generates_cesr_number { - uint64_t rsvd_z : 31; /* 63:33 */ - uint64_t enable : 1; /* 32 */ - uint64_t device_vector : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_generates_cesr_number_u; - -#define wci_generates_cesr_number_enable \ - bit.enable -#define wci_generates_cesr_number_device_vector \ - bit.device_vector - - -/* - * wci_dif_timeout_cntl - */ -typedef union { - struct wci_dif_timeout_cntl { - uint64_t rsvd_z : 52; /* 63:12 */ - uint64_t timeout_disable : 1; /* 11 */ - uint64_t timeout_freeze : 1; /* 10 */ - uint64_t timeout_mag : 2; /* 9:8 */ - uint64_t timeout_val : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_dif_timeout_cntl_u; - -#define wci_dif_timeout_cntl_timeout_disable \ - bit.timeout_disable -#define wci_dif_timeout_cntl_timeout_freeze \ - bit.timeout_freeze -#define wci_dif_timeout_cntl_timeout_mag \ - bit.timeout_mag -#define wci_dif_timeout_cntl_timeout_val \ - bit.timeout_val - - -/* - * wci_dif_timeout_count - */ -typedef union { - struct wci_dif_timeout_count { - uint64_t rsvd_z : 32; /* 63:32 */ - uint64_t count : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_dif_timeout_count_u; - -#define wci_dif_timeout_count_count \ - bit.count - - -/* - * wci_max - */ -typedef union { - struct wci_max { - uint64_t rsvd_z : 29; /* 63:35 */ - uint64_t sel : 3; /* 34:32 */ - uint64_t value : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_max_u; - -#define wci_max_sel \ - bit.sel -#define wci_max_value \ - bit.value - - -/* - * wci_jnk_route_map0 - */ -typedef union { - struct wci_jnk_route_map0 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_jnk_route_map0_u; - -#define wci_jnk_route_map0_node15_tlink \ - bit.node15_tlink -#define wci_jnk_route_map0_node14_tlink \ - bit.node14_tlink -#define wci_jnk_route_map0_node13_tlink \ - bit.node13_tlink -#define wci_jnk_route_map0_node12_tlink \ - bit.node12_tlink -#define wci_jnk_route_map0_node11_tlink \ - bit.node11_tlink -#define wci_jnk_route_map0_node10_tlink \ - bit.node10_tlink -#define wci_jnk_route_map0_node9_tlink \ - bit.node9_tlink -#define wci_jnk_route_map0_node8_tlink \ - bit.node8_tlink -#define wci_jnk_route_map0_node7_tlink \ - bit.node7_tlink -#define wci_jnk_route_map0_node6_tlink \ - bit.node6_tlink -#define wci_jnk_route_map0_node5_tlink \ - bit.node5_tlink -#define wci_jnk_route_map0_node4_tlink \ - bit.node4_tlink -#define wci_jnk_route_map0_node3_tlink \ - bit.node3_tlink -#define wci_jnk_route_map0_node2_tlink \ - bit.node2_tlink -#define wci_jnk_route_map0_node1_tlink \ - bit.node1_tlink -#define wci_jnk_route_map0_node0_tlink \ - bit.node0_tlink - - -/* - * wci_jnk_route_map1 - */ -typedef union { - struct wci_jnk_route_map1 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_jnk_route_map1_u; - -#define wci_jnk_route_map1_node15_tlink \ - bit.node15_tlink -#define wci_jnk_route_map1_node14_tlink \ - bit.node14_tlink -#define wci_jnk_route_map1_node13_tlink \ - bit.node13_tlink -#define wci_jnk_route_map1_node12_tlink \ - bit.node12_tlink -#define wci_jnk_route_map1_node11_tlink \ - bit.node11_tlink -#define wci_jnk_route_map1_node10_tlink \ - bit.node10_tlink -#define wci_jnk_route_map1_node9_tlink \ - bit.node9_tlink -#define wci_jnk_route_map1_node8_tlink \ - bit.node8_tlink -#define wci_jnk_route_map1_node7_tlink \ - bit.node7_tlink -#define wci_jnk_route_map1_node6_tlink \ - bit.node6_tlink -#define wci_jnk_route_map1_node5_tlink \ - bit.node5_tlink -#define wci_jnk_route_map1_node4_tlink \ - bit.node4_tlink -#define wci_jnk_route_map1_node3_tlink \ - bit.node3_tlink -#define wci_jnk_route_map1_node2_tlink \ - bit.node2_tlink -#define wci_jnk_route_map1_node1_tlink \ - bit.node1_tlink -#define wci_jnk_route_map1_node0_tlink \ - bit.node0_tlink - - -/* - * wci_stick_rate - */ -typedef union { - struct wci_stick_rate { - uint64_t reset : 1; /* 63 */ - uint64_t cycle_limit_integer : 15; /* 62:48 */ - uint64_t cycle_limit_fraction : 48; /* 47:0 */ - } bit; - uint64_t val; -} wci_stick_rate_u; - -#define wci_stick_rate_reset \ - bit.reset -#define wci_stick_rate_cycle_limit_integer \ - bit.cycle_limit_integer -#define wci_stick_rate_cycle_limit_fraction \ - bit.cycle_limit_fraction - - -/* - * wci_stick - */ -typedef union { - struct wci_stick { - uint64_t count : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_stick_u; - -#define wci_stick_count \ - bit.count - - -/* - * wci_misc_ctr - */ -typedef union { - struct wci_misc_ctr { - uint64_t count1 : 32; /* 63:32 */ - uint64_t count0 : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_misc_ctr_u; - -#define wci_misc_ctr_count1 \ - bit.count1 -#define wci_misc_ctr_count0 \ - bit.count0 - - -/* - * wci_misc_ctr_ctl - */ -typedef union { - struct wci_misc_ctr_ctl { - uint64_t rsvd_z : 43; /* 63:21 */ - uint64_t duration_mode : 1; /* 20 */ - uint64_t cnt1_agent_select : 4; /* 19:16 */ - uint64_t cnt1_event_select : 6; /* 15:10 */ - uint64_t cnt0_agent_select : 4; /* 9:6 */ - uint64_t cnt0_event_select : 6; /* 5:0 */ - } bit; - uint64_t val; -} wci_misc_ctr_ctl_u; - -#define wci_misc_ctr_ctl_duration_mode \ - bit.duration_mode -#define wci_misc_ctr_ctl_cnt1_agent_select \ - bit.cnt1_agent_select -#define wci_misc_ctr_ctl_cnt1_event_select \ - bit.cnt1_event_select -#define wci_misc_ctr_ctl_cnt0_agent_select \ - bit.cnt0_agent_select -#define wci_misc_ctr_ctl_cnt0_event_select \ - bit.cnt0_event_select - - -/* - * wci_monitor_pins - */ -typedef union { - struct wci_monitor_pins { - uint64_t rsvd_z : 16; /* 63:48 */ - uint64_t monitor_pins : 16; /* 47:32 */ - uint64_t rsvd_y : 23; /* 31:9 */ - uint64_t signal_sel : 5; /* 8:4 */ - uint64_t module_sel : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_monitor_pins_u; - -#define wci_monitor_pins_monitor_pins \ - bit.monitor_pins -#define wci_monitor_pins_signal_sel \ - bit.signal_sel -#define wci_monitor_pins_module_sel \ - bit.module_sel - - -/* - * wci_sram_config - */ -typedef union { - struct wci_sram_config { - uint64_t rsvd_z : 45; /* 63:19 */ - uint64_t error_threshold : 5; /* 18:14 */ - uint64_t ecc_writeback_disable : 1; /* 13 */ - uint64_t ecc_disable : 1; /* 12 */ - uint64_t parity_disable : 1; /* 11 */ - uint64_t use_ga2lpa : 1; /* 10 */ - uint64_t use_directory : 1; /* 9 */ - uint64_t dir_stripe : 2; /* 8:7 */ - uint64_t rsvd_y : 2; /* 6:5 */ - uint64_t sram_size : 3; /* 4:2 */ - uint64_t sram_size_pins : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_sram_config_u; - -#define wci_sram_config_error_threshold \ - bit.error_threshold -#define wci_sram_config_ecc_writeback_disable \ - bit.ecc_writeback_disable -#define wci_sram_config_ecc_disable \ - bit.ecc_disable -#define wci_sram_config_parity_disable \ - bit.parity_disable -#define wci_sram_config_use_ga2lpa \ - bit.use_ga2lpa -#define wci_sram_config_use_directory \ - bit.use_directory -#define wci_sram_config_dir_stripe \ - bit.dir_stripe -#define wci_sram_config_sram_size \ - bit.sram_size -#define wci_sram_config_sram_size_pins \ - bit.sram_size_pins - - -/* - * wci_cluster_members_bits - */ -typedef union { - struct wci_cluster_members_bits { - uint64_t mask : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_cluster_members_bits_u; - -#define wci_cluster_members_bits_mask \ - bit.mask - - -/* - * wci_nc_slice_config_array - */ -typedef union { - struct wci_nc_slice_config_array { - uint64_t config : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_nc_slice_config_array_u; - -#define wci_nc_slice_config_array_config \ - bit.config - - -/* - * wci_cluster_ctr_ctl - */ -typedef union { - struct wci_cluster_ctr_ctl { - uint64_t rsvd_z : 55; /* 63:9 */ - uint64_t enable_all : 1; /* 8 */ - uint64_t cnt1_received_interrupt : 1; /* 7 */ - uint64_t cnt1_received_atomic : 1; /* 6 */ - uint64_t cnt1_received_cacheable_read : 1; /* 5 */ - uint64_t cnt1_received_cacheable_write : 1; /* 4 */ - uint64_t cnt0_received_interrupt : 1; /* 3 */ - uint64_t cnt0_received_atomic : 1; /* 2 */ - uint64_t cnt0_received_cacheable_read : 1; /* 1 */ - uint64_t cnt0_received_cacheable_write : 1; /* 0 */ - } bit; - uint64_t val; -} wci_cluster_ctr_ctl_u; - -#define wci_cluster_ctr_ctl_enable_all \ - bit.enable_all -#define wci_cluster_ctr_ctl_cnt1_received_interrupt \ - bit.cnt1_received_interrupt -#define wci_cluster_ctr_ctl_cnt1_received_atomic \ - bit.cnt1_received_atomic -#define wci_cluster_ctr_ctl_cnt1_received_cacheable_read \ - bit.cnt1_received_cacheable_read -#define wci_cluster_ctr_ctl_cnt1_received_cacheable_write \ - bit.cnt1_received_cacheable_write -#define wci_cluster_ctr_ctl_cnt0_received_interrupt \ - bit.cnt0_received_interrupt -#define wci_cluster_ctr_ctl_cnt0_received_atomic \ - bit.cnt0_received_atomic -#define wci_cluster_ctr_ctl_cnt0_received_cacheable_read \ - bit.cnt0_received_cacheable_read -#define wci_cluster_ctr_ctl_cnt0_received_cacheable_write \ - bit.cnt0_received_cacheable_write - - -/* - * wci_sram_status - */ -typedef union { - struct wci_sram_status { - uint64_t rsvd_z : 44; /* 63:20 */ - uint64_t sticky_error_19 : 1; /* 19 */ - uint64_t sticky_error_18 : 1; /* 18 */ - uint64_t sticky_error_17 : 1; /* 17 */ - uint64_t sticky_error_16 : 1; /* 16 */ - uint64_t sticky_error_15 : 1; /* 15 */ - uint64_t sticky_error_14 : 1; /* 14 */ - uint64_t sticky_error_13 : 1; /* 13 */ - uint64_t sticky_error_12 : 1; /* 12 */ - uint64_t sticky_error_11 : 1; /* 11 */ - uint64_t sticky_error_10 : 1; /* 10 */ - uint64_t sticky_error_9 : 1; /* 9 */ - uint64_t sticky_error_8 : 1; /* 8 */ - uint64_t sticky_error_7 : 1; /* 7 */ - uint64_t sticky_error_6 : 1; /* 6 */ - uint64_t sticky_error_5 : 1; /* 5 */ - uint64_t sticky_error_4 : 1; /* 4 */ - uint64_t sticky_error_3 : 1; /* 3 */ - uint64_t sticky_error_2 : 1; /* 2 */ - uint64_t sticky_error_1 : 1; /* 1 */ - uint64_t sticky_error_0 : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sram_status_u; - -#define wci_sram_status_sticky_error_19 \ - bit.sticky_error_19 -#define wci_sram_status_sticky_error_18 \ - bit.sticky_error_18 -#define wci_sram_status_sticky_error_17 \ - bit.sticky_error_17 -#define wci_sram_status_sticky_error_16 \ - bit.sticky_error_16 -#define wci_sram_status_sticky_error_15 \ - bit.sticky_error_15 -#define wci_sram_status_sticky_error_14 \ - bit.sticky_error_14 -#define wci_sram_status_sticky_error_13 \ - bit.sticky_error_13 -#define wci_sram_status_sticky_error_12 \ - bit.sticky_error_12 -#define wci_sram_status_sticky_error_11 \ - bit.sticky_error_11 -#define wci_sram_status_sticky_error_10 \ - bit.sticky_error_10 -#define wci_sram_status_sticky_error_9 \ - bit.sticky_error_9 -#define wci_sram_status_sticky_error_8 \ - bit.sticky_error_8 -#define wci_sram_status_sticky_error_7 \ - bit.sticky_error_7 -#define wci_sram_status_sticky_error_6 \ - bit.sticky_error_6 -#define wci_sram_status_sticky_error_5 \ - bit.sticky_error_5 -#define wci_sram_status_sticky_error_4 \ - bit.sticky_error_4 -#define wci_sram_status_sticky_error_3 \ - bit.sticky_error_3 -#define wci_sram_status_sticky_error_2 \ - bit.sticky_error_2 -#define wci_sram_status_sticky_error_1 \ - bit.sticky_error_1 -#define wci_sram_status_sticky_error_0 \ - bit.sticky_error_0 - - -/* - * wci_sram_ce_count - */ -typedef union { - struct wci_sram_ce_count { - uint64_t rsvd_z : 56; /* 63:8 */ - uint64_t ce_count : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_sram_ce_count_u; - -#define wci_sram_ce_count_ce_count \ - bit.ce_count - - -/* - * wci_sram_ecc_address - */ -typedef union { - struct wci_sram_ecc_address { - uint64_t rsvd_z : 31; /* 63:33 */ - uint64_t ce : 1; /* 32 */ - uint64_t addr_error : 1; /* 31 */ - uint64_t syndrome : 7; /* 30:24 */ - uint64_t address : 24; /* 23:0 */ - } bit; - uint64_t val; -} wci_sram_ecc_address_u; - -#define wci_sram_ecc_address_ce \ - bit.ce -#define wci_sram_ecc_address_addr_error \ - bit.addr_error -#define wci_sram_ecc_address_syndrome \ - bit.syndrome -#define wci_sram_ecc_address_address \ - bit.address - - -/* - * wci_cci_esr - */ -typedef union { - struct wci_cci_esr { - uint64_t rsvd_z : 42; /* 63:22 */ - uint64_t acc_parity : 1; /* 21 */ - uint64_t acc_threshold : 1; /* 20 */ - uint64_t acc_sram_ae : 1; /* 19 */ - uint64_t acc_sram_ue : 1; /* 18 */ - uint64_t acc_sram_ce : 1; /* 17 */ - uint64_t acc_ce_count_zero : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 9; /* 14:6 */ - uint64_t parity : 1; /* 5 */ - uint64_t threshold : 1; /* 4 */ - uint64_t sram_ae : 1; /* 3 */ - uint64_t sram_ue : 1; /* 2 */ - uint64_t sram_ce : 1; /* 1 */ - uint64_t ce_count_zero : 1; /* 0 */ - } bit; - uint64_t val; -} wci_cci_esr_u; - -#define wci_cci_esr_acc_parity \ - bit.acc_parity -#define wci_cci_esr_acc_threshold \ - bit.acc_threshold -#define wci_cci_esr_acc_sram_ae \ - bit.acc_sram_ae -#define wci_cci_esr_acc_sram_ue \ - bit.acc_sram_ue -#define wci_cci_esr_acc_sram_ce \ - bit.acc_sram_ce -#define wci_cci_esr_acc_ce_count_zero \ - bit.acc_ce_count_zero -#define wci_cci_esr_first_error \ - bit.first_error -#define wci_cci_esr_parity \ - bit.parity -#define wci_cci_esr_threshold \ - bit.threshold -#define wci_cci_esr_sram_ae \ - bit.sram_ae -#define wci_cci_esr_sram_ue \ - bit.sram_ue -#define wci_cci_esr_sram_ce \ - bit.sram_ce -#define wci_cci_esr_ce_count_zero \ - bit.ce_count_zero - - -/* - * wci_cci_esr_mask - */ -typedef union { - struct wci_cci_esr_mask { - uint64_t rsvd_z : 58; /* 63:6 */ - uint64_t parity : 1; /* 5 */ - uint64_t threshold : 1; /* 4 */ - uint64_t sram_ae : 1; /* 3 */ - uint64_t sram_ue : 1; /* 2 */ - uint64_t sram_ce : 1; /* 1 */ - uint64_t ce_count_zero : 1; /* 0 */ - } bit; - uint64_t val; -} wci_cci_esr_mask_u; - -#define wci_cci_esr_mask_parity \ - bit.parity -#define wci_cci_esr_mask_threshold \ - bit.threshold -#define wci_cci_esr_mask_sram_ae \ - bit.sram_ae -#define wci_cci_esr_mask_sram_ue \ - bit.sram_ue -#define wci_cci_esr_mask_sram_ce \ - bit.sram_ce -#define wci_cci_esr_mask_ce_count_zero \ - bit.ce_count_zero - - -/* - * wci_cci_route_map0 - */ -typedef union { - struct wci_cci_route_map0 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_cci_route_map0_u; - -#define wci_cci_route_map0_node15_tlink \ - bit.node15_tlink -#define wci_cci_route_map0_node14_tlink \ - bit.node14_tlink -#define wci_cci_route_map0_node13_tlink \ - bit.node13_tlink -#define wci_cci_route_map0_node12_tlink \ - bit.node12_tlink -#define wci_cci_route_map0_node11_tlink \ - bit.node11_tlink -#define wci_cci_route_map0_node10_tlink \ - bit.node10_tlink -#define wci_cci_route_map0_node9_tlink \ - bit.node9_tlink -#define wci_cci_route_map0_node8_tlink \ - bit.node8_tlink -#define wci_cci_route_map0_node7_tlink \ - bit.node7_tlink -#define wci_cci_route_map0_node6_tlink \ - bit.node6_tlink -#define wci_cci_route_map0_node5_tlink \ - bit.node5_tlink -#define wci_cci_route_map0_node4_tlink \ - bit.node4_tlink -#define wci_cci_route_map0_node3_tlink \ - bit.node3_tlink -#define wci_cci_route_map0_node2_tlink \ - bit.node2_tlink -#define wci_cci_route_map0_node1_tlink \ - bit.node1_tlink -#define wci_cci_route_map0_node0_tlink \ - bit.node0_tlink - - -/* - * wci_cci_route_map1 - */ -typedef union { - struct wci_cci_route_map1 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_cci_route_map1_u; - -#define wci_cci_route_map1_node15_tlink \ - bit.node15_tlink -#define wci_cci_route_map1_node14_tlink \ - bit.node14_tlink -#define wci_cci_route_map1_node13_tlink \ - bit.node13_tlink -#define wci_cci_route_map1_node12_tlink \ - bit.node12_tlink -#define wci_cci_route_map1_node11_tlink \ - bit.node11_tlink -#define wci_cci_route_map1_node10_tlink \ - bit.node10_tlink -#define wci_cci_route_map1_node9_tlink \ - bit.node9_tlink -#define wci_cci_route_map1_node8_tlink \ - bit.node8_tlink -#define wci_cci_route_map1_node7_tlink \ - bit.node7_tlink -#define wci_cci_route_map1_node6_tlink \ - bit.node6_tlink -#define wci_cci_route_map1_node5_tlink \ - bit.node5_tlink -#define wci_cci_route_map1_node4_tlink \ - bit.node4_tlink -#define wci_cci_route_map1_node3_tlink \ - bit.node3_tlink -#define wci_cci_route_map1_node2_tlink \ - bit.node2_tlink -#define wci_cci_route_map1_node1_tlink \ - bit.node1_tlink -#define wci_cci_route_map1_node0_tlink \ - bit.node0_tlink - - -/* - * wci_cluster_write_lockout - */ -typedef union { - struct wci_cluster_write_lockout { - uint64_t mask : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_cluster_write_lockout_u; - -#define wci_cluster_write_lockout_mask \ - bit.mask - - -/* - * wci_cluster_config - */ -typedef union { - struct wci_cluster_config { - uint64_t rsvd_z : 61; /* 63:3 */ - uint64_t in_an_ssm : 1; /* 2 */ - uint64_t bad_ecc_on_write_error : 1; /* 1 */ - uint64_t allow_multiple_hops : 1; /* 0 */ - } bit; - uint64_t val; -} wci_cluster_config_u; - -#define wci_cluster_config_in_an_ssm \ - bit.in_an_ssm -#define wci_cluster_config_bad_ecc_on_write_error \ - bit.bad_ecc_on_write_error -#define wci_cluster_config_allow_multiple_hops \ - bit.allow_multiple_hops - - -/* - * wci_ca_freeze - */ -typedef union { - struct wci_ca_freeze { - uint64_t rsvd_z : 32; /* 63:32 */ - uint64_t vector : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_ca_freeze_u; - -#define wci_ca_freeze_vector \ - bit.vector - - -/* - * wci_ca_busy - */ -typedef union { - struct wci_ca_busy { - uint64_t rsvd_z : 32; /* 63:32 */ - uint64_t vector : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_ca_busy_u; - -#define wci_ca_busy_vector \ - bit.vector - - -/* - * wci_ca_first_packet_0 - */ -typedef union { - struct wci_ca_first_packet_0 { - uint64_t addr : 6; /* 63:58 */ - uint64_t rsvd_z : 13; /* 57:45 */ - uint64_t rtransid : 9; /* 44:36 */ - uint64_t scnid : 8; /* 35:28 */ - uint64_t rsvd_y : 8; /* 27:20 */ - uint64_t rtid : 5; /* 19:15 */ - uint64_t snid : 4; /* 14:11 */ - uint64_t opcode : 6; /* 10:5 */ - uint64_t stripe : 1; /* 4 */ - uint64_t dnid : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_ca_first_packet_0_u; - -#define wci_ca_first_packet_0_addr \ - bit.addr -#define wci_ca_first_packet_0_rtransid \ - bit.rtransid -#define wci_ca_first_packet_0_scnid \ - bit.scnid -#define wci_ca_first_packet_0_rtid \ - bit.rtid -#define wci_ca_first_packet_0_snid \ - bit.snid -#define wci_ca_first_packet_0_opcode \ - bit.opcode -#define wci_ca_first_packet_0_stripe \ - bit.stripe -#define wci_ca_first_packet_0_dnid \ - bit.dnid - - -/* - * wci_ca_first_packet_1 - */ -typedef union { - struct wci_ca_first_packet_1 { - uint64_t rsvd_z : 33; /* 63:31 */ - uint64_t addr : 31; /* 30:0 */ - } bit; - uint64_t val; -} wci_ca_first_packet_1_u; - -#define wci_ca_first_packet_1_addr \ - bit.addr - - -/* - * wci_ca_ecc_address - */ -typedef union { - struct wci_ca_ecc_address { - uint64_t data : 1; /* 63 */ - uint64_t ue : 1; /* 62 */ - uint64_t passthru : 1; /* 61 */ - uint64_t rsvd_z : 24; /* 60:37 */ - uint64_t addr : 37; /* 36:0 */ - } bit; - uint64_t val; -} wci_ca_ecc_address_u; - -#define wci_ca_ecc_address_data \ - bit.data -#define wci_ca_ecc_address_ue \ - bit.ue -#define wci_ca_ecc_address_passthru \ - bit.passthru -#define wci_ca_ecc_address_addr \ - bit.addr - - -/* - * wci_ca_error_transaction - */ -typedef union { - struct wci_ca_error_transaction { - uint64_t status : 4; /* 63:60 */ - uint64_t esr_reg : 1; /* 59 */ - uint64_t esr_index : 4; /* 58:55 */ - uint64_t ctid : 5; /* 54:50 */ - uint64_t targid : 9; /* 49:41 */ - uint64_t second_atransid : 4; /* 40:37 */ - uint64_t first_atransid : 4; /* 36:33 */ - uint64_t cmd_grant_1 : 1; /* 32 */ - uint64_t cmd_grant_2 : 1; /* 31 */ - uint64_t reissue_pending_1 : 1; /* 30 */ - uint64_t reissue_pending_2 : 1; /* 29 */ - uint64_t transid_released : 1; /* 28 */ - uint64_t const_grant : 1; /* 27 */ - uint64_t map_grant : 1; /* 26 */ - uint64_t map_queued : 1; /* 25 */ - uint64_t reuse_timeout : 1; /* 24 */ - uint64_t data_timeout : 1; /* 23 */ - uint64_t aphase_timeout : 1; /* 22 */ - uint64_t pkt_sent : 1; /* 21 */ - uint64_t pkt_queued : 1; /* 20 */ - uint64_t cpi_inval : 1; /* 19 */ - uint64_t cpi_queued : 1; /* 18 */ - uint64_t cpi_err : 1; /* 17 */ - uint64_t cpi_rcv2 : 1; /* 16 */ - uint64_t cpi_rcv1 : 1; /* 15 */ - uint64_t dc_atom_err : 1; /* 14 */ - uint64_t dc_snd2 : 1; /* 13 */ - uint64_t dc_rcv2 : 1; /* 12 */ - uint64_t dc_err1 : 1; /* 11 */ - uint64_t pull_late : 1; /* 10 */ - uint64_t pull_timeout : 1; /* 9 */ - uint64_t pull_cleared : 1; /* 8 */ - uint64_t pull_err : 1; /* 7 */ - uint64_t pull_ok : 1; /* 6 */ - uint64_t snoop_late : 1; /* 5 */ - uint64_t snoop2 : 2; /* 4:3 */ - uint64_t snoop1 : 3; /* 2:0 */ - } bit; - uint64_t val; -} wci_ca_error_transaction_u; - -#define wci_ca_error_transaction_status \ - bit.status -#define wci_ca_error_transaction_esr_reg \ - bit.esr_reg -#define wci_ca_error_transaction_esr_index \ - bit.esr_index -#define wci_ca_error_transaction_ctid \ - bit.ctid -#define wci_ca_error_transaction_targid \ - bit.targid -#define wci_ca_error_transaction_second_atransid \ - bit.second_atransid -#define wci_ca_error_transaction_first_atransid \ - bit.first_atransid -#define wci_ca_error_transaction_cmd_grant_1 \ - bit.cmd_grant_1 -#define wci_ca_error_transaction_cmd_grant_2 \ - bit.cmd_grant_2 -#define wci_ca_error_transaction_reissue_pending_1 \ - bit.reissue_pending_1 -#define wci_ca_error_transaction_reissue_pending_2 \ - bit.reissue_pending_2 -#define wci_ca_error_transaction_transid_released \ - bit.transid_released -#define wci_ca_error_transaction_const_grant \ - bit.const_grant -#define wci_ca_error_transaction_map_grant \ - bit.map_grant -#define wci_ca_error_transaction_map_queued \ - bit.map_queued -#define wci_ca_error_transaction_reuse_timeout \ - bit.reuse_timeout -#define wci_ca_error_transaction_data_timeout \ - bit.data_timeout -#define wci_ca_error_transaction_aphase_timeout \ - bit.aphase_timeout -#define wci_ca_error_transaction_pkt_sent \ - bit.pkt_sent -#define wci_ca_error_transaction_pkt_queued \ - bit.pkt_queued -#define wci_ca_error_transaction_cpi_inval \ - bit.cpi_inval -#define wci_ca_error_transaction_cpi_queued \ - bit.cpi_queued -#define wci_ca_error_transaction_cpi_err \ - bit.cpi_err -#define wci_ca_error_transaction_cpi_rcv2 \ - bit.cpi_rcv2 -#define wci_ca_error_transaction_cpi_rcv1 \ - bit.cpi_rcv1 -#define wci_ca_error_transaction_dc_atom_err \ - bit.dc_atom_err -#define wci_ca_error_transaction_dc_snd2 \ - bit.dc_snd2 -#define wci_ca_error_transaction_dc_rcv2 \ - bit.dc_rcv2 -#define wci_ca_error_transaction_dc_err1 \ - bit.dc_err1 -#define wci_ca_error_transaction_pull_late \ - bit.pull_late -#define wci_ca_error_transaction_pull_timeout \ - bit.pull_timeout -#define wci_ca_error_transaction_pull_cleared \ - bit.pull_cleared -#define wci_ca_error_transaction_pull_err \ - bit.pull_err -#define wci_ca_error_transaction_pull_ok \ - bit.pull_ok -#define wci_ca_error_transaction_snoop_late \ - bit.snoop_late -#define wci_ca_error_transaction_snoop2 \ - bit.snoop2 -#define wci_ca_error_transaction_snoop1 \ - bit.snoop1 - - -/* - * wci_ca_timeout_config - */ -typedef union { - struct wci_ca_timeout_config { - uint64_t rsvd_z : 6; /* 63:58 */ - uint64_t dphase_disable : 1; /* 57 */ - uint64_t dphase_freeze : 1; /* 56 */ - uint64_t rsvd_y : 2; /* 55:54 */ - uint64_t dphase_dest_mag : 2; /* 53:52 */ - uint64_t dphase_dest_val : 8; /* 51:44 */ - uint64_t rsvd_x : 2; /* 43:42 */ - uint64_t dphase_pass_mag : 2; /* 41:40 */ - uint64_t dphase_pass_val : 8; /* 39:32 */ - uint64_t rsvd_w : 2; /* 31:30 */ - uint64_t aphase_disable : 1; /* 29 */ - uint64_t aphase_freeze : 1; /* 28 */ - uint64_t rsvd_v : 2; /* 27:26 */ - uint64_t aphase_mag : 2; /* 25:24 */ - uint64_t aphase_val : 8; /* 23:16 */ - uint64_t rsvd_u : 1; /* 15 */ - uint64_t reuse_disable : 1; /* 14 */ - uint64_t reuse_freeze : 1; /* 13 */ - uint64_t reuse_mag : 2; /* 12:11 */ - uint64_t reuse_val : 11; /* 10:0 */ - } bit; - uint64_t val; -} wci_ca_timeout_config_u; - -#define wci_ca_timeout_config_dphase_disable \ - bit.dphase_disable -#define wci_ca_timeout_config_dphase_freeze \ - bit.dphase_freeze -#define wci_ca_timeout_config_dphase_dest_mag \ - bit.dphase_dest_mag -#define wci_ca_timeout_config_dphase_dest_val \ - bit.dphase_dest_val -#define wci_ca_timeout_config_dphase_pass_mag \ - bit.dphase_pass_mag -#define wci_ca_timeout_config_dphase_pass_val \ - bit.dphase_pass_val -#define wci_ca_timeout_config_aphase_disable \ - bit.aphase_disable -#define wci_ca_timeout_config_aphase_freeze \ - bit.aphase_freeze -#define wci_ca_timeout_config_aphase_mag \ - bit.aphase_mag -#define wci_ca_timeout_config_aphase_val \ - bit.aphase_val -#define wci_ca_timeout_config_reuse_disable \ - bit.reuse_disable -#define wci_ca_timeout_config_reuse_freeze \ - bit.reuse_freeze -#define wci_ca_timeout_config_reuse_mag \ - bit.reuse_mag -#define wci_ca_timeout_config_reuse_val \ - bit.reuse_val - - -/* - * wci_ca_config - */ -typedef union { - struct wci_ca_config { - uint64_t rsvd_z : 58; /* 63:6 */ - uint64_t cluster_disable : 1; /* 5 */ - uint64_t reuse_timeout_limit : 5; /* 4:0 */ - } bit; - uint64_t val; -} wci_ca_config_u; - -#define wci_ca_config_cluster_disable \ - bit.cluster_disable -#define wci_ca_config_reuse_timeout_limit \ - bit.reuse_timeout_limit - - -/* - * wci_ca_esr_0 - */ -typedef union { - struct wci_ca_esr_0 { - uint64_t rsvd_z : 33; /* 63:31 */ - uint64_t acc_unexpect_cpi_ack : 1; /* 30 */ - uint64_t acc_unexpect_dc_ack : 1; /* 29 */ - uint64_t acc_unexpect_pull : 1; /* 28 */ - uint64_t acc_unexpect_reissue : 1; /* 27 */ - uint64_t acc_atomic_map_mismatch : 1; /* 26 */ - uint64_t acc_unmapped : 1; /* 25 */ - uint64_t acc_uncorrectable_mtag_error : 1; /* 24 */ - uint64_t acc_uncorrectable_data_error : 1; /* 23 */ - uint64_t acc_correctable_mtag_error : 1; /* 22 */ - uint64_t acc_correctable_data_error : 1; /* 21 */ - uint64_t acc_dstat_inconsistent : 1; /* 20 */ - uint64_t acc_mtag_mismatch_within_hcl : 1; /* 19 */ - uint64_t acc_mtag_mismatch_between_hcls : 1; /* 18 */ - uint64_t acc_remote_timeout : 1; /* 17 */ - uint64_t acc_local_timeout : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t unexpect_cpi_ack : 1; /* 14 */ - uint64_t unexpect_dc_ack : 1; /* 13 */ - uint64_t unexpect_pull : 1; /* 12 */ - uint64_t unexpect_reissue : 1; /* 11 */ - uint64_t atomic_map_mismatch : 1; /* 10 */ - uint64_t unmapped : 1; /* 9 */ - uint64_t uncorrectable_mtag_error : 1; /* 8 */ - uint64_t uncorrectable_data_error : 1; /* 7 */ - uint64_t correctable_mtag_error : 1; /* 6 */ - uint64_t correctable_data_error : 1; /* 5 */ - uint64_t dstat_inconsistent : 1; /* 4 */ - uint64_t mtag_mismatch_within_hcl : 1; /* 3 */ - uint64_t mtag_mismatch_between_hcls : 1; /* 2 */ - uint64_t remote_timeout : 1; /* 1 */ - uint64_t local_timeout : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ca_esr_0_u; - -#define wci_ca_esr_0_acc_unexpect_cpi_ack \ - bit.acc_unexpect_cpi_ack -#define wci_ca_esr_0_acc_unexpect_dc_ack \ - bit.acc_unexpect_dc_ack -#define wci_ca_esr_0_acc_unexpect_pull \ - bit.acc_unexpect_pull -#define wci_ca_esr_0_acc_unexpect_reissue \ - bit.acc_unexpect_reissue -#define wci_ca_esr_0_acc_atomic_map_mismatch \ - bit.acc_atomic_map_mismatch -#define wci_ca_esr_0_acc_unmapped \ - bit.acc_unmapped -#define wci_ca_esr_0_acc_uncorrectable_mtag_error \ - bit.acc_uncorrectable_mtag_error -#define wci_ca_esr_0_acc_uncorrectable_data_error \ - bit.acc_uncorrectable_data_error -#define wci_ca_esr_0_acc_correctable_mtag_error \ - bit.acc_correctable_mtag_error -#define wci_ca_esr_0_acc_correctable_data_error \ - bit.acc_correctable_data_error -#define wci_ca_esr_0_acc_dstat_inconsistent \ - bit.acc_dstat_inconsistent -#define wci_ca_esr_0_acc_mtag_mismatch_within_hcl \ - bit.acc_mtag_mismatch_within_hcl -#define wci_ca_esr_0_acc_mtag_mismatch_between_hcls \ - bit.acc_mtag_mismatch_between_hcls -#define wci_ca_esr_0_acc_remote_timeout \ - bit.acc_remote_timeout -#define wci_ca_esr_0_acc_local_timeout \ - bit.acc_local_timeout -#define wci_ca_esr_0_first_error \ - bit.first_error -#define wci_ca_esr_0_unexpect_cpi_ack \ - bit.unexpect_cpi_ack -#define wci_ca_esr_0_unexpect_dc_ack \ - bit.unexpect_dc_ack -#define wci_ca_esr_0_unexpect_pull \ - bit.unexpect_pull -#define wci_ca_esr_0_unexpect_reissue \ - bit.unexpect_reissue -#define wci_ca_esr_0_atomic_map_mismatch \ - bit.atomic_map_mismatch -#define wci_ca_esr_0_unmapped \ - bit.unmapped -#define wci_ca_esr_0_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_ca_esr_0_uncorrectable_data_error \ - bit.uncorrectable_data_error -#define wci_ca_esr_0_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_ca_esr_0_correctable_data_error \ - bit.correctable_data_error -#define wci_ca_esr_0_dstat_inconsistent \ - bit.dstat_inconsistent -#define wci_ca_esr_0_mtag_mismatch_within_hcl \ - bit.mtag_mismatch_within_hcl -#define wci_ca_esr_0_mtag_mismatch_between_hcls \ - bit.mtag_mismatch_between_hcls -#define wci_ca_esr_0_remote_timeout \ - bit.remote_timeout -#define wci_ca_esr_0_local_timeout \ - bit.local_timeout - - -/* - * wci_ca_esr_1 - */ -typedef union { - struct wci_ca_esr_1 { - uint64_t rsvd_z : 43; /* 63:21 */ - uint64_t acc_qlimit_timeout : 1; /* 20 */ - uint64_t acc_internal_error : 1; /* 19 */ - uint64_t acc_cmmu_ecc_error : 1; /* 18 */ - uint64_t acc_wrong_cmd : 1; /* 17 */ - uint64_t acc_data_phase_timeout : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 10; /* 14:5 */ - uint64_t qlimit_timeout : 1; /* 4 */ - uint64_t internal_error : 1; /* 3 */ - uint64_t cmmu_ecc_error : 1; /* 2 */ - uint64_t wrong_cmd : 1; /* 1 */ - uint64_t data_phase_timeout : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ca_esr_1_u; - -#define wci_ca_esr_1_acc_qlimit_timeout \ - bit.acc_qlimit_timeout -#define wci_ca_esr_1_acc_internal_error \ - bit.acc_internal_error -#define wci_ca_esr_1_acc_cmmu_ecc_error \ - bit.acc_cmmu_ecc_error -#define wci_ca_esr_1_acc_wrong_cmd \ - bit.acc_wrong_cmd -#define wci_ca_esr_1_acc_data_phase_timeout \ - bit.acc_data_phase_timeout -#define wci_ca_esr_1_first_error \ - bit.first_error -#define wci_ca_esr_1_qlimit_timeout \ - bit.qlimit_timeout -#define wci_ca_esr_1_internal_error \ - bit.internal_error -#define wci_ca_esr_1_cmmu_ecc_error \ - bit.cmmu_ecc_error -#define wci_ca_esr_1_wrong_cmd \ - bit.wrong_cmd -#define wci_ca_esr_1_data_phase_timeout \ - bit.data_phase_timeout - - -/* - * wci_ca_esr_mask - */ -typedef union { - struct wci_ca_esr_mask { - uint64_t rsvd_z : 43; /* 63:21 */ - uint64_t qlimit_timeout : 1; /* 20 */ - uint64_t internal_error : 1; /* 19 */ - uint64_t cmmu_ecc_error : 1; /* 18 */ - uint64_t wrong_cmd : 1; /* 17 */ - uint64_t data_phase_timeout : 1; /* 16 */ - uint64_t rsvd_y : 1; /* 15 */ - uint64_t unexpect_cpi_ack : 1; /* 14 */ - uint64_t unexpect_dc_ack : 1; /* 13 */ - uint64_t unexpect_pull : 1; /* 12 */ - uint64_t unexpect_reissue : 1; /* 11 */ - uint64_t atomic_map_mismatch : 1; /* 10 */ - uint64_t unmapped : 1; /* 9 */ - uint64_t uncorrectable_mtag_error : 1; /* 8 */ - uint64_t uncorrectable_data_error : 1; /* 7 */ - uint64_t correctable_mtag_error : 1; /* 6 */ - uint64_t correctable_data_error : 1; /* 5 */ - uint64_t dstat_inconsistent : 1; /* 4 */ - uint64_t mtag_mismatch_within_hcl : 1; /* 3 */ - uint64_t mtag_mismatch_between_hcls : 1; /* 2 */ - uint64_t remote_timeout : 1; /* 1 */ - uint64_t local_timeout : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ca_esr_mask_u; - -#define wci_ca_esr_mask_qlimit_timeout \ - bit.qlimit_timeout -#define wci_ca_esr_mask_internal_error \ - bit.internal_error -#define wci_ca_esr_mask_cmmu_ecc_error \ - bit.cmmu_ecc_error -#define wci_ca_esr_mask_wrong_cmd \ - bit.wrong_cmd -#define wci_ca_esr_mask_data_phase_timeout \ - bit.data_phase_timeout -#define wci_ca_esr_mask_unexpect_cpi_ack \ - bit.unexpect_cpi_ack -#define wci_ca_esr_mask_unexpect_dc_ack \ - bit.unexpect_dc_ack -#define wci_ca_esr_mask_unexpect_pull \ - bit.unexpect_pull -#define wci_ca_esr_mask_unexpect_reissue \ - bit.unexpect_reissue -#define wci_ca_esr_mask_atomic_map_mismatch \ - bit.atomic_map_mismatch -#define wci_ca_esr_mask_unmapped \ - bit.unmapped -#define wci_ca_esr_mask_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_ca_esr_mask_uncorrectable_data_error \ - bit.uncorrectable_data_error -#define wci_ca_esr_mask_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_ca_esr_mask_correctable_data_error \ - bit.correctable_data_error -#define wci_ca_esr_mask_dstat_inconsistent \ - bit.dstat_inconsistent -#define wci_ca_esr_mask_mtag_mismatch_within_hcl \ - bit.mtag_mismatch_within_hcl -#define wci_ca_esr_mask_mtag_mismatch_between_hcls \ - bit.mtag_mismatch_between_hcls -#define wci_ca_esr_mask_remote_timeout \ - bit.remote_timeout -#define wci_ca_esr_mask_local_timeout \ - bit.local_timeout - - -/* - * wci_cluster_sync - */ -typedef union { - struct wci_cluster_sync { - uint64_t sync_in_progress : 1; /* 63 */ - uint64_t rsvd_z : 31; /* 62:32 */ - uint64_t cag_busy : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_cluster_sync_u; - -#define wci_cluster_sync_sync_in_progress \ - bit.sync_in_progress -#define wci_cluster_sync_cag_busy \ - bit.cag_busy - - -/* - * wci_ca_timeout_config_2 - */ -typedef union { - struct wci_ca_timeout_config_2 { - uint64_t rsvd_z : 39; /* 63:25 */ - uint64_t sfi_targid_timeout_disable : 1; /* 24 */ - uint64_t rsvd_y : 1; /* 23 */ - uint64_t sfi_targid_timeout_sel : 3; /* 22:20 */ - uint64_t rsvd_x : 6; /* 19:14 */ - uint64_t loc_reuse_mag : 2; /* 13:12 */ - uint64_t rsvd_w : 1; /* 11 */ - uint64_t loc_reuse_val : 11; /* 10:0 */ - } bit; - uint64_t val; -} wci_ca_timeout_config_2_u; - -#define wci_ca_timeout_config_2_sfi_targid_timeout_disable \ - bit.sfi_targid_timeout_disable -#define wci_ca_timeout_config_2_sfi_targid_timeout_sel \ - bit.sfi_targid_timeout_sel -#define wci_ca_timeout_config_2_loc_reuse_mag \ - bit.loc_reuse_mag -#define wci_ca_timeout_config_2_loc_reuse_val \ - bit.loc_reuse_val - - -/* - * wci_ca_error_transaction_2 - */ -typedef union { - struct wci_ca_error_transaction_2 { - uint64_t rsvd_z : 60; /* 63:4 */ - uint64_t snoop2_late_reissue : 1; /* 3 */ - uint64_t dc_rcv2_barrier : 1; /* 2 */ - uint64_t cpi_barrier : 1; /* 1 */ - uint64_t cpi_rcv2_barrier : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ca_error_transaction_2_u; - -#define wci_ca_error_transaction_2_snoop2_late_reissue \ - bit.snoop2_late_reissue -#define wci_ca_error_transaction_2_dc_rcv2_barrier \ - bit.dc_rcv2_barrier -#define wci_ca_error_transaction_2_cpi_barrier \ - bit.cpi_barrier -#define wci_ca_error_transaction_2_cpi_rcv2_barrier \ - bit.cpi_rcv2_barrier - - -/* - * wci_qlim_config_cag - */ -typedef union { - struct wci_qlim_config_cag { - uint64_t freeze : 1; /* 63 */ - uint64_t disable : 1; /* 62 */ - uint64_t rsvd_z : 9; /* 61:53 */ - uint64_t max_discard : 13; /* 52:40 */ - uint64_t rsvd_y : 2; /* 39:38 */ - uint64_t num2discard : 10; /* 37:28 */ - uint64_t rsvd_x : 11; /* 27:17 */ - uint64_t tmin_mag : 13; /* 16:4 */ - uint64_t rsvd_w : 1; /* 3 */ - uint64_t hwmark_exp : 3; /* 2:0 */ - } bit; - uint64_t val; -} wci_qlim_config_cag_u; - -#define wci_qlim_config_cag_freeze \ - bit.freeze -#define wci_qlim_config_cag_disable \ - bit.disable -#define wci_qlim_config_cag_max_discard \ - bit.max_discard -#define wci_qlim_config_cag_num2discard \ - bit.num2discard -#define wci_qlim_config_cag_tmin_mag \ - bit.tmin_mag -#define wci_qlim_config_cag_hwmark_exp \ - bit.hwmark_exp - - -/* - * wci_qlim_cag_timer - */ -typedef union { - struct wci_qlim_cag_timer { - uint64_t rsvd_z : 35; /* 63:29 */ - uint64_t value : 29; /* 28:0 */ - } bit; - uint64_t val; -} wci_qlim_cag_timer_u; - -#define wci_qlim_cag_timer_value \ - bit.value - - -/* - * wci_board2cnid_array - */ -typedef union { - struct wci_board2cnid_array { - uint64_t rsvd_z : 56; /* 63:8 */ - uint64_t data : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_board2cnid_array_u; - -#define wci_board2cnid_array_data \ - bit.data - - -/* - * wci_inid2dnid_array - */ -typedef union { - struct wci_inid2dnid_array { - uint64_t rsvd_z : 60; /* 63:4 */ - uint64_t dnid : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_inid2dnid_array_u; - -#define wci_inid2dnid_array_dnid \ - bit.dnid - - -/* - * wci_ra_freeze - */ -typedef union { - struct wci_ra_freeze { - uint64_t rsvd_z : 32; /* 63:32 */ - uint64_t vector : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_ra_freeze_u; - -#define wci_ra_freeze_vector \ - bit.vector - - -/* - * wci_ra_busy - */ -typedef union { - struct wci_ra_busy { - uint64_t request_synch : 32; /* 63:32 */ - uint64_t vector : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_ra_busy_u; - -#define wci_ra_busy_request_synch \ - bit.request_synch -#define wci_ra_busy_vector \ - bit.vector - - -/* - * wci_ra_first_error_agent - */ -typedef union { - struct wci_ra_first_error_agent { - uint64_t esr_reg : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t rsvd_z : 54; /* 58:5 */ - uint64_t instance : 5; /* 4:0 */ - } bit; - uint64_t val; -} wci_ra_first_error_agent_u; - -#define wci_ra_first_error_agent_esr_reg \ - bit.esr_reg -#define wci_ra_first_error_agent_esr_index \ - bit.esr_index -#define wci_ra_first_error_agent_instance \ - bit.instance - - -/* - * wci_ra_first_packet_0 - */ -typedef union { - struct wci_ra_first_packet_0 { - uint64_t lo : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_ra_first_packet_0_u; - -#define wci_ra_first_packet_0_lo \ - bit.lo - - -/* - * wci_ra_first_packet_1 - */ -typedef union { - struct wci_ra_first_packet_1 { - uint64_t esr_reg : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t sfq_input : 2; /* 58:57 */ - uint64_t transaction_type : 6; /* 56:51 */ - uint64_t rsvd_z : 20; /* 50:31 */ - uint64_t hi : 31; /* 30:0 */ - } bit; - uint64_t val; -} wci_ra_first_packet_1_u; - -#define wci_ra_first_packet_1_esr_reg \ - bit.esr_reg -#define wci_ra_first_packet_1_esr_index \ - bit.esr_index -#define wci_ra_first_packet_1_sfq_input \ - bit.sfq_input -#define wci_ra_first_packet_1_transaction_type \ - bit.transaction_type -#define wci_ra_first_packet_1_hi \ - bit.hi - - -/* - * wci_ra_ecc_address - */ -typedef union { - struct wci_ra_ecc_address { - uint64_t data : 1; /* 63 */ - uint64_t ue : 1; /* 62 */ - uint64_t atransid : 9; /* 61:53 */ - uint64_t transaction_type : 6; /* 52:47 */ - uint64_t rsvd_z : 4; /* 46:43 */ - uint64_t addr : 39; /* 42:4 */ - uint64_t rsvd_y : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_ra_ecc_address_u; - -#define wci_ra_ecc_address_data \ - bit.data -#define wci_ra_ecc_address_ue \ - bit.ue -#define wci_ra_ecc_address_atransid \ - bit.atransid -#define wci_ra_ecc_address_transaction_type \ - bit.transaction_type -#define wci_ra_ecc_address_addr \ - bit.addr - - -/* - * wci_ra_error_transaction_0 - */ -typedef union { - struct wci_ra_error_transaction_0 { - uint64_t esr_reg : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t rsvd_z : 3; /* 58:56 */ - uint64_t cesr_index : 8; /* 55:48 */ - uint64_t atransid : 9; /* 47:39 */ - uint64_t addr : 39; /* 38:0 */ - } bit; - uint64_t val; -} wci_ra_error_transaction_0_u; - -#define wci_ra_error_transaction_0_esr_reg \ - bit.esr_reg -#define wci_ra_error_transaction_0_esr_index \ - bit.esr_index -#define wci_ra_error_transaction_0_cesr_index \ - bit.cesr_index -#define wci_ra_error_transaction_0_atransid \ - bit.atransid -#define wci_ra_error_transaction_0_addr \ - bit.addr - - -/* - * wci_ra_error_transaction_1 - */ -typedef union { - struct wci_ra_error_transaction_1 { - uint64_t fsm_state : 7; /* 63:57 */ - uint64_t rsvd_z : 25; /* 56:32 */ - uint64_t rtid : 4; /* 31:28 */ - uint64_t rsvd_y : 1; /* 27 */ - uint64_t dh_errors : 7; /* 26:20 */ - uint64_t error_code : 4; /* 19:16 */ - uint64_t rcv_cntr : 2; /* 15:14 */ - uint64_t snd_cntr : 2; /* 13:12 */ - uint64_t tmot_err : 1; /* 11 */ - uint64_t rh_err : 1; /* 10 */ - uint64_t transaction_type : 6; /* 9:4 */ - uint64_t rsvd_x : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_ra_error_transaction_1_u; - -#define wci_ra_error_transaction_1_fsm_state \ - bit.fsm_state -#define wci_ra_error_transaction_1_rtid \ - bit.rtid -#define wci_ra_error_transaction_1_dh_errors \ - bit.dh_errors -#define wci_ra_error_transaction_1_error_code \ - bit.error_code -#define wci_ra_error_transaction_1_rcv_cntr \ - bit.rcv_cntr -#define wci_ra_error_transaction_1_snd_cntr \ - bit.snd_cntr -#define wci_ra_error_transaction_1_tmot_err \ - bit.tmot_err -#define wci_ra_error_transaction_1_rh_err \ - bit.rh_err -#define wci_ra_error_transaction_1_transaction_type \ - bit.transaction_type - - -/* - * wci_ra_timeout_config - */ -typedef union { - struct wci_ra_timeout_config { - uint64_t rsvd_z : 22; /* 63:42 */ - uint64_t clus_disable : 1; /* 41 */ - uint64_t clus_freeze : 1; /* 40 */ - uint64_t rsvd_y : 2; /* 39:38 */ - uint64_t clus_aphase_mag : 2; /* 37:36 */ - uint64_t rsvd_x : 2; /* 35:34 */ - uint64_t clus_aphase_val : 8; /* 33:26 */ - uint64_t clus_dphase_mag : 2; /* 25:24 */ - uint64_t clus_dphase_val : 8; /* 23:16 */ - uint64_t rsvd_w : 2; /* 15:14 */ - uint64_t ssm_disable : 1; /* 13 */ - uint64_t ssm_freeze : 1; /* 12 */ - uint64_t rsvd_v : 2; /* 11:10 */ - uint64_t ssm_mag : 2; /* 9:8 */ - uint64_t ssm_val : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_ra_timeout_config_u; - -#define wci_ra_timeout_config_clus_disable \ - bit.clus_disable -#define wci_ra_timeout_config_clus_freeze \ - bit.clus_freeze -#define wci_ra_timeout_config_clus_aphase_mag \ - bit.clus_aphase_mag -#define wci_ra_timeout_config_clus_aphase_val \ - bit.clus_aphase_val -#define wci_ra_timeout_config_clus_dphase_mag \ - bit.clus_dphase_mag -#define wci_ra_timeout_config_clus_dphase_val \ - bit.clus_dphase_val -#define wci_ra_timeout_config_ssm_disable \ - bit.ssm_disable -#define wci_ra_timeout_config_ssm_freeze \ - bit.ssm_freeze -#define wci_ra_timeout_config_ssm_mag \ - bit.ssm_mag -#define wci_ra_timeout_config_ssm_val \ - bit.ssm_val - - -/* - * wci_ra_esr_0 - */ -typedef union { - struct wci_ra_esr_0 { - uint64_t rsvd_z : 33; /* 63:31 */ - uint64_t acc_ssm_timeout : 1; /* 30 */ - uint64_t acc_wrong_reply : 1; /* 29 */ - uint64_t acc_illegal_sender : 1; /* 28 */ - uint64_t acc_not_expected_reply : 1; /* 27 */ - uint64_t acc_qlimit_timeout : 1; /* 26 */ - uint64_t acc_unexpected_snid : 1; /* 25 */ - uint64_t acc_wrong_safari_command : 1; /* 24 */ - uint64_t acc_non_block_trans : 1; /* 23 */ - uint64_t acc_cesr_error_wrong : 1; /* 22 */ - uint64_t acc_cluster_local_timeout : 1; /* 21 */ - uint64_t acc_cluster_remote_timeout : 1; /* 20 */ - uint64_t acc_mtag_mismatch_between_hcls : 1; /* 19 */ - uint64_t acc_mtag_mismatch_within_hcl : 1; /* 18 */ - uint64_t acc_dstat_inconsistent : 1; /* 17 */ - uint64_t acc_mtag_not_gm : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t ssm_timeout : 1; /* 14 */ - uint64_t wrong_reply : 1; /* 13 */ - uint64_t illegal_sender : 1; /* 12 */ - uint64_t not_expected_reply : 1; /* 11 */ - uint64_t qlimit_timeout : 1; /* 10 */ - uint64_t unexpected_snid : 1; /* 9 */ - uint64_t wrong_safari_command : 1; /* 8 */ - uint64_t non_block_trans : 1; /* 7 */ - uint64_t cesr_error_wrong : 1; /* 6 */ - uint64_t cluster_local_timeout : 1; /* 5 */ - uint64_t cluster_remote_timeout : 1; /* 4 */ - uint64_t mtag_mismatch_between_hcls : 1; /* 3 */ - uint64_t mtag_mismatch_within_hcl : 1; /* 2 */ - uint64_t dstat_inconsistent : 1; /* 1 */ - uint64_t mtag_not_gm : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ra_esr_0_u; - -#define wci_ra_esr_0_acc_ssm_timeout \ - bit.acc_ssm_timeout -#define wci_ra_esr_0_acc_wrong_reply \ - bit.acc_wrong_reply -#define wci_ra_esr_0_acc_illegal_sender \ - bit.acc_illegal_sender -#define wci_ra_esr_0_acc_not_expected_reply \ - bit.acc_not_expected_reply -#define wci_ra_esr_0_acc_qlimit_timeout \ - bit.acc_qlimit_timeout -#define wci_ra_esr_0_acc_unexpected_snid \ - bit.acc_unexpected_snid -#define wci_ra_esr_0_acc_wrong_safari_command \ - bit.acc_wrong_safari_command -#define wci_ra_esr_0_acc_non_block_trans \ - bit.acc_non_block_trans -#define wci_ra_esr_0_acc_cesr_error_wrong \ - bit.acc_cesr_error_wrong -#define wci_ra_esr_0_acc_cluster_local_timeout \ - bit.acc_cluster_local_timeout -#define wci_ra_esr_0_acc_cluster_remote_timeout \ - bit.acc_cluster_remote_timeout -#define wci_ra_esr_0_acc_mtag_mismatch_between_hcls \ - bit.acc_mtag_mismatch_between_hcls -#define wci_ra_esr_0_acc_mtag_mismatch_within_hcl \ - bit.acc_mtag_mismatch_within_hcl -#define wci_ra_esr_0_acc_dstat_inconsistent \ - bit.acc_dstat_inconsistent -#define wci_ra_esr_0_acc_mtag_not_gm \ - bit.acc_mtag_not_gm -#define wci_ra_esr_0_first_error \ - bit.first_error -#define wci_ra_esr_0_ssm_timeout \ - bit.ssm_timeout -#define wci_ra_esr_0_wrong_reply \ - bit.wrong_reply -#define wci_ra_esr_0_illegal_sender \ - bit.illegal_sender -#define wci_ra_esr_0_not_expected_reply \ - bit.not_expected_reply -#define wci_ra_esr_0_qlimit_timeout \ - bit.qlimit_timeout -#define wci_ra_esr_0_unexpected_snid \ - bit.unexpected_snid -#define wci_ra_esr_0_wrong_safari_command \ - bit.wrong_safari_command -#define wci_ra_esr_0_non_block_trans \ - bit.non_block_trans -#define wci_ra_esr_0_cesr_error_wrong \ - bit.cesr_error_wrong -#define wci_ra_esr_0_cluster_local_timeout \ - bit.cluster_local_timeout -#define wci_ra_esr_0_cluster_remote_timeout \ - bit.cluster_remote_timeout -#define wci_ra_esr_0_mtag_mismatch_between_hcls \ - bit.mtag_mismatch_between_hcls -#define wci_ra_esr_0_mtag_mismatch_within_hcl \ - bit.mtag_mismatch_within_hcl -#define wci_ra_esr_0_dstat_inconsistent \ - bit.dstat_inconsistent -#define wci_ra_esr_0_mtag_not_gm \ - bit.mtag_not_gm - - -/* - * wci_ra_esr_1 - */ -typedef union { - struct wci_ra_esr_1 { - uint64_t rsvd_z : 33; /* 63:31 */ - uint64_t acc_write_lockout : 1; /* 30 */ - uint64_t acc_unexpected_mtag : 1; /* 29 */ - uint64_t acc_address_not_mapped : 1; /* 28 */ - uint64_t acc_illegal_home_node : 1; /* 27 */ - uint64_t acc_lpa2ga_ecc_error : 1; /* 26 */ - uint64_t acc_lpa2ga_violation : 1; /* 25 */ - uint64_t acc_unexpected_send_ack : 1; /* 24 */ - uint64_t acc_unexpected_receive_ack : 1; /* 23 */ - uint64_t acc_invalid_reply_pattern : 1; /* 22 */ - uint64_t acc_hw_protocol_error : 1; /* 21 */ - uint64_t acc_hw_fifo_ovfl_unfl : 1; /* 20 */ - uint64_t acc_correctable_mtag_error : 1; /* 19 */ - uint64_t acc_correctable_data_error : 1; /* 18 */ - uint64_t acc_uncorrectable_mtag_error : 1; /* 17 */ - uint64_t acc_uncorrectable_data_error : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t write_lockout : 1; /* 14 */ - uint64_t unexpected_mtag : 1; /* 13 */ - uint64_t address_not_mapped : 1; /* 12 */ - uint64_t illegal_home_node : 1; /* 11 */ - uint64_t lpa2ga_ecc_error : 1; /* 10 */ - uint64_t lpa2ga_violation : 1; /* 9 */ - uint64_t unexpected_send_ack : 1; /* 8 */ - uint64_t unexpected_receive_ack : 1; /* 7 */ - uint64_t invalid_reply_pattern : 1; /* 6 */ - uint64_t hw_protocol_error : 1; /* 5 */ - uint64_t hw_fifo_ovfl_unfl : 1; /* 4 */ - uint64_t correctable_mtag_error : 1; /* 3 */ - uint64_t correctable_data_error : 1; /* 2 */ - uint64_t uncorrectable_mtag_error : 1; /* 1 */ - uint64_t uncorrectable_data_error : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ra_esr_1_u; - -#define wci_ra_esr_1_acc_write_lockout \ - bit.acc_write_lockout -#define wci_ra_esr_1_acc_unexpected_mtag \ - bit.acc_unexpected_mtag -#define wci_ra_esr_1_acc_address_not_mapped \ - bit.acc_address_not_mapped -#define wci_ra_esr_1_acc_illegal_home_node \ - bit.acc_illegal_home_node -#define wci_ra_esr_1_acc_lpa2ga_ecc_error \ - bit.acc_lpa2ga_ecc_error -#define wci_ra_esr_1_acc_lpa2ga_violation \ - bit.acc_lpa2ga_violation -#define wci_ra_esr_1_acc_unexpected_send_ack \ - bit.acc_unexpected_send_ack -#define wci_ra_esr_1_acc_unexpected_receive_ack \ - bit.acc_unexpected_receive_ack -#define wci_ra_esr_1_acc_invalid_reply_pattern \ - bit.acc_invalid_reply_pattern -#define wci_ra_esr_1_acc_hw_protocol_error \ - bit.acc_hw_protocol_error -#define wci_ra_esr_1_acc_hw_fifo_ovfl_unfl \ - bit.acc_hw_fifo_ovfl_unfl -#define wci_ra_esr_1_acc_correctable_mtag_error \ - bit.acc_correctable_mtag_error -#define wci_ra_esr_1_acc_correctable_data_error \ - bit.acc_correctable_data_error -#define wci_ra_esr_1_acc_uncorrectable_mtag_error \ - bit.acc_uncorrectable_mtag_error -#define wci_ra_esr_1_acc_uncorrectable_data_error \ - bit.acc_uncorrectable_data_error -#define wci_ra_esr_1_first_error \ - bit.first_error -#define wci_ra_esr_1_write_lockout \ - bit.write_lockout -#define wci_ra_esr_1_unexpected_mtag \ - bit.unexpected_mtag -#define wci_ra_esr_1_address_not_mapped \ - bit.address_not_mapped -#define wci_ra_esr_1_illegal_home_node \ - bit.illegal_home_node -#define wci_ra_esr_1_lpa2ga_ecc_error \ - bit.lpa2ga_ecc_error -#define wci_ra_esr_1_lpa2ga_violation \ - bit.lpa2ga_violation -#define wci_ra_esr_1_unexpected_send_ack \ - bit.unexpected_send_ack -#define wci_ra_esr_1_unexpected_receive_ack \ - bit.unexpected_receive_ack -#define wci_ra_esr_1_invalid_reply_pattern \ - bit.invalid_reply_pattern -#define wci_ra_esr_1_hw_protocol_error \ - bit.hw_protocol_error -#define wci_ra_esr_1_hw_fifo_ovfl_unfl \ - bit.hw_fifo_ovfl_unfl -#define wci_ra_esr_1_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_ra_esr_1_correctable_data_error \ - bit.correctable_data_error -#define wci_ra_esr_1_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_ra_esr_1_uncorrectable_data_error \ - bit.uncorrectable_data_error - - -/* - * wci_ra_esr_mask - */ -typedef union { - struct wci_ra_esr_mask { - uint64_t rsvd_z : 33; /* 63:31 */ - uint64_t write_lockout : 1; /* 30 */ - uint64_t unexpected_mtag : 1; /* 29 */ - uint64_t address_not_mapped : 1; /* 28 */ - uint64_t illegal_home_node : 1; /* 27 */ - uint64_t lpa2ga_ecc_error : 1; /* 26 */ - uint64_t lpa2ga_violation : 1; /* 25 */ - uint64_t unexpected_send_ack : 1; /* 24 */ - uint64_t unexpected_receive_ack : 1; /* 23 */ - uint64_t invalid_reply_pattern : 1; /* 22 */ - uint64_t hw_protocol_error : 1; /* 21 */ - uint64_t hw_fifo_ovfl_unfl : 1; /* 20 */ - uint64_t correctable_mtag_error : 1; /* 19 */ - uint64_t correctable_data_error : 1; /* 18 */ - uint64_t uncorrectable_mtag_error : 1; /* 17 */ - uint64_t uncorrectable_data_error : 1; /* 16 */ - uint64_t rsvd_y : 1; /* 15 */ - uint64_t ssm_timeout : 1; /* 14 */ - uint64_t wrong_reply : 1; /* 13 */ - uint64_t illegal_sender : 1; /* 12 */ - uint64_t not_expected_reply : 1; /* 11 */ - uint64_t qlimit_timeout : 1; /* 10 */ - uint64_t unexpected_snid : 1; /* 9 */ - uint64_t wrong_safari_command : 1; /* 8 */ - uint64_t non_block_trans : 1; /* 7 */ - uint64_t cesr_error_wrong : 1; /* 6 */ - uint64_t cluster_local_timeout : 1; /* 5 */ - uint64_t cluster_remote_timeout : 1; /* 4 */ - uint64_t mtag_mismatch_between_hcls : 1; /* 3 */ - uint64_t mtag_mismatch_within_hcl : 1; /* 2 */ - uint64_t dstat_inconsistent : 1; /* 1 */ - uint64_t mtag_not_gm : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ra_esr_mask_u; - -#define wci_ra_esr_mask_write_lockout \ - bit.write_lockout -#define wci_ra_esr_mask_unexpected_mtag \ - bit.unexpected_mtag -#define wci_ra_esr_mask_address_not_mapped \ - bit.address_not_mapped -#define wci_ra_esr_mask_illegal_home_node \ - bit.illegal_home_node -#define wci_ra_esr_mask_lpa2ga_ecc_error \ - bit.lpa2ga_ecc_error -#define wci_ra_esr_mask_lpa2ga_violation \ - bit.lpa2ga_violation -#define wci_ra_esr_mask_unexpected_send_ack \ - bit.unexpected_send_ack -#define wci_ra_esr_mask_unexpected_receive_ack \ - bit.unexpected_receive_ack -#define wci_ra_esr_mask_invalid_reply_pattern \ - bit.invalid_reply_pattern -#define wci_ra_esr_mask_hw_protocol_error \ - bit.hw_protocol_error -#define wci_ra_esr_mask_hw_fifo_ovfl_unfl \ - bit.hw_fifo_ovfl_unfl -#define wci_ra_esr_mask_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_ra_esr_mask_correctable_data_error \ - bit.correctable_data_error -#define wci_ra_esr_mask_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_ra_esr_mask_uncorrectable_data_error \ - bit.uncorrectable_data_error -#define wci_ra_esr_mask_ssm_timeout \ - bit.ssm_timeout -#define wci_ra_esr_mask_wrong_reply \ - bit.wrong_reply -#define wci_ra_esr_mask_illegal_sender \ - bit.illegal_sender -#define wci_ra_esr_mask_not_expected_reply \ - bit.not_expected_reply -#define wci_ra_esr_mask_qlimit_timeout \ - bit.qlimit_timeout -#define wci_ra_esr_mask_unexpected_snid \ - bit.unexpected_snid -#define wci_ra_esr_mask_wrong_safari_command \ - bit.wrong_safari_command -#define wci_ra_esr_mask_non_block_trans \ - bit.non_block_trans -#define wci_ra_esr_mask_cesr_error_wrong \ - bit.cesr_error_wrong -#define wci_ra_esr_mask_cluster_local_timeout \ - bit.cluster_local_timeout -#define wci_ra_esr_mask_cluster_remote_timeout \ - bit.cluster_remote_timeout -#define wci_ra_esr_mask_mtag_mismatch_between_hcls \ - bit.mtag_mismatch_between_hcls -#define wci_ra_esr_mask_mtag_mismatch_within_hcl \ - bit.mtag_mismatch_within_hcl -#define wci_ra_esr_mask_dstat_inconsistent \ - bit.dstat_inconsistent -#define wci_ra_esr_mask_mtag_not_gm \ - bit.mtag_not_gm - - -/* - * wci_ra_status_array - */ -typedef union { - struct wci_ra_status_array { - uint64_t fsm_state : 7; /* 63:57 */ - uint64_t dtargid : 9; /* 56:48 */ - uint64_t atransid : 9; /* 47:39 */ - uint64_t addr : 39; /* 38:0 */ - } bit; - uint64_t val; -} wci_ra_status_array_u; - -#define wci_ra_status_array_fsm_state \ - bit.fsm_state -#define wci_ra_status_array_dtargid \ - bit.dtargid -#define wci_ra_status_array_atransid \ - bit.atransid -#define wci_ra_status_array_addr \ - bit.addr - - -/* - * wci_ra_status_2_array - */ -typedef union { - struct wci_ra_status_2_array { - uint64_t tflg_ecc : 1; /* 63 */ - uint64_t replies_rcvd_vld : 1; /* 62 */ - uint64_t stripe : 1; /* 61 */ - uint64_t rh_sm : 2; /* 60:59 */ - uint64_t rcvd_mtag : 3; /* 58:56 */ - uint64_t cesr_index : 8; /* 55:48 */ - uint64_t ntransid : 9; /* 47:39 */ - uint64_t dtarg : 1; /* 38 */ - uint64_t saw_s_ack : 1; /* 37 */ - uint64_t saw_h_d : 1; /* 36 */ - uint64_t saw_s_d : 1; /* 35 */ - uint64_t saw_h_pull : 1; /* 34 */ - uint64_t saw_h_pull_m : 1; /* 33 */ - uint64_t saw_h_pull_i : 1; /* 32 */ - uint64_t replies_rcvd : 16; /* 31:16 */ - uint64_t rcv_cntr : 2; /* 15:14 */ - uint64_t snd_cntr : 2; /* 13:12 */ - uint64_t saw_h_nack : 1; /* 11 */ - uint64_t saw_h_err : 1; /* 10 */ - uint64_t transaction_type : 6; /* 9:4 */ - uint64_t hnid : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_ra_status_2_array_u; - -#define wci_ra_status_2_array_tflg_ecc \ - bit.tflg_ecc -#define wci_ra_status_2_array_replies_rcvd_vld \ - bit.replies_rcvd_vld -#define wci_ra_status_2_array_stripe \ - bit.stripe -#define wci_ra_status_2_array_rh_sm \ - bit.rh_sm -#define wci_ra_status_2_array_rcvd_mtag \ - bit.rcvd_mtag -#define wci_ra_status_2_array_cesr_index \ - bit.cesr_index -#define wci_ra_status_2_array_ntransid \ - bit.ntransid -#define wci_ra_status_2_array_dtarg \ - bit.dtarg -#define wci_ra_status_2_array_saw_s_ack \ - bit.saw_s_ack -#define wci_ra_status_2_array_saw_h_d \ - bit.saw_h_d -#define wci_ra_status_2_array_saw_s_d \ - bit.saw_s_d -#define wci_ra_status_2_array_saw_h_pull \ - bit.saw_h_pull -#define wci_ra_status_2_array_saw_h_pull_m \ - bit.saw_h_pull_m -#define wci_ra_status_2_array_saw_h_pull_i \ - bit.saw_h_pull_i -#define wci_ra_status_2_array_replies_rcvd \ - bit.replies_rcvd -#define wci_ra_status_2_array_rcv_cntr \ - bit.rcv_cntr -#define wci_ra_status_2_array_snd_cntr \ - bit.snd_cntr -#define wci_ra_status_2_array_saw_h_nack \ - bit.saw_h_nack -#define wci_ra_status_2_array_saw_h_err \ - bit.saw_h_err -#define wci_ra_status_2_array_transaction_type \ - bit.transaction_type -#define wci_ra_status_2_array_hnid \ - bit.hnid - - -/* - * wci_ra_write_lockout_status - */ -typedef union { - struct wci_ra_write_lockout_status { - uint64_t rsvd_z : 54; /* 63:10 */ - uint64_t link_stripe : 2; /* 9:8 */ - uint64_t nc_slice : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_ra_write_lockout_status_u; - -#define wci_ra_write_lockout_status_link_stripe \ - bit.link_stripe -#define wci_ra_write_lockout_status_nc_slice \ - bit.nc_slice - - -/* - * wci_rag_route_map0 - */ -typedef union { - struct wci_rag_route_map0 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_rag_route_map0_u; - -#define wci_rag_route_map0_node15_tlink \ - bit.node15_tlink -#define wci_rag_route_map0_node14_tlink \ - bit.node14_tlink -#define wci_rag_route_map0_node13_tlink \ - bit.node13_tlink -#define wci_rag_route_map0_node12_tlink \ - bit.node12_tlink -#define wci_rag_route_map0_node11_tlink \ - bit.node11_tlink -#define wci_rag_route_map0_node10_tlink \ - bit.node10_tlink -#define wci_rag_route_map0_node9_tlink \ - bit.node9_tlink -#define wci_rag_route_map0_node8_tlink \ - bit.node8_tlink -#define wci_rag_route_map0_node7_tlink \ - bit.node7_tlink -#define wci_rag_route_map0_node6_tlink \ - bit.node6_tlink -#define wci_rag_route_map0_node5_tlink \ - bit.node5_tlink -#define wci_rag_route_map0_node4_tlink \ - bit.node4_tlink -#define wci_rag_route_map0_node3_tlink \ - bit.node3_tlink -#define wci_rag_route_map0_node2_tlink \ - bit.node2_tlink -#define wci_rag_route_map0_node1_tlink \ - bit.node1_tlink -#define wci_rag_route_map0_node0_tlink \ - bit.node0_tlink - - -/* - * wci_rag_route_map1 - */ -typedef union { - struct wci_rag_route_map1 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_rag_route_map1_u; - -#define wci_rag_route_map1_node15_tlink \ - bit.node15_tlink -#define wci_rag_route_map1_node14_tlink \ - bit.node14_tlink -#define wci_rag_route_map1_node13_tlink \ - bit.node13_tlink -#define wci_rag_route_map1_node12_tlink \ - bit.node12_tlink -#define wci_rag_route_map1_node11_tlink \ - bit.node11_tlink -#define wci_rag_route_map1_node10_tlink \ - bit.node10_tlink -#define wci_rag_route_map1_node9_tlink \ - bit.node9_tlink -#define wci_rag_route_map1_node8_tlink \ - bit.node8_tlink -#define wci_rag_route_map1_node7_tlink \ - bit.node7_tlink -#define wci_rag_route_map1_node6_tlink \ - bit.node6_tlink -#define wci_rag_route_map1_node5_tlink \ - bit.node5_tlink -#define wci_rag_route_map1_node4_tlink \ - bit.node4_tlink -#define wci_rag_route_map1_node3_tlink \ - bit.node3_tlink -#define wci_rag_route_map1_node2_tlink \ - bit.node2_tlink -#define wci_rag_route_map1_node1_tlink \ - bit.node1_tlink -#define wci_rag_route_map1_node0_tlink \ - bit.node0_tlink - - -/* - * wci_cluster_error_status_array - */ -typedef union { - struct wci_cluster_error_status_array { - uint64_t rsvd_z : 58; /* 63:6 */ - uint64_t disable_fail_fast : 1; /* 5 */ - uint64_t not_valid : 1; /* 4 */ - uint64_t value : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_cluster_error_status_array_u; - -#define wci_cluster_error_status_array_disable_fail_fast \ - bit.disable_fail_fast -#define wci_cluster_error_status_array_not_valid \ - bit.not_valid -#define wci_cluster_error_status_array_value \ - bit.value - - -/* - * wci_cluster_error_count - */ -typedef union { - struct wci_cluster_error_count { - uint64_t value : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_cluster_error_count_u; - -#define wci_cluster_error_count_value \ - bit.value - - -/* - * wci_int_dest_busy_count - */ -typedef union { - struct wci_int_dest_busy_count { - uint64_t value : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_int_dest_busy_count_u; - -#define wci_int_dest_busy_count_value \ - bit.value - - -/* - * wci_qlim_3req_priority - */ -typedef union { - struct wci_qlim_3req_priority { - uint64_t rsvd_z : 28; /* 63:36 */ - uint64_t num_slots : 4; /* 35:32 */ - uint64_t arb_slots : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_qlim_3req_priority_u; - -#define wci_qlim_3req_priority_num_slots \ - bit.num_slots -#define wci_qlim_3req_priority_arb_slots \ - bit.arb_slots - - -/* - * wci_qlim_2req_priority - */ -typedef union { - struct wci_qlim_2req_priority { - uint64_t rsvd_z : 4; /* 63:60 */ - uint64_t ciq_niq_num_slots : 4; /* 59:56 */ - uint64_t piq_ciq_num_slots : 4; /* 55:52 */ - uint64_t niq_piq_num_slots : 4; /* 51:48 */ - uint64_t ciq_niq_arb_slots : 16; /* 47:32 */ - uint64_t piq_ciq_arb_slots : 16; /* 31:16 */ - uint64_t niq_piq_arb_slots : 16; /* 15:0 */ - } bit; - uint64_t val; -} wci_qlim_2req_priority_u; - -#define wci_qlim_2req_priority_ciq_niq_num_slots \ - bit.ciq_niq_num_slots -#define wci_qlim_2req_priority_piq_ciq_num_slots \ - bit.piq_ciq_num_slots -#define wci_qlim_2req_priority_niq_piq_num_slots \ - bit.niq_piq_num_slots -#define wci_qlim_2req_priority_ciq_niq_arb_slots \ - bit.ciq_niq_arb_slots -#define wci_qlim_2req_priority_piq_ciq_arb_slots \ - bit.piq_ciq_arb_slots -#define wci_qlim_2req_priority_niq_piq_arb_slots \ - bit.niq_piq_arb_slots - - -/* - * wci_qlim_config_piq - */ -typedef union { - struct wci_qlim_config_piq { - uint64_t freeze : 1; /* 63 */ - uint64_t disable : 1; /* 62 */ - uint64_t rsvd_z : 2; /* 61:60 */ - uint64_t discard_cnt_timer_en : 1; /* 59 */ - uint64_t discard_cnt_timer_mag : 3; /* 58:56 */ - uint64_t discard_cnt_timer_val : 3; /* 55:53 */ - uint64_t max_discard : 13; /* 52:40 */ - uint64_t rsvd_y : 2; /* 39:38 */ - uint64_t num2discard : 10; /* 37:28 */ - uint64_t rsvd_x : 4; /* 27:24 */ - uint64_t decay : 4; /* 23:20 */ - uint64_t rsvd_w : 3; /* 19:17 */ - uint64_t tmin_mag : 13; /* 16:4 */ - uint64_t rsvd_v : 1; /* 3 */ - uint64_t hwmark_exp : 3; /* 2:0 */ - } bit; - uint64_t val; -} wci_qlim_config_piq_u; - -#define wci_qlim_config_piq_freeze \ - bit.freeze -#define wci_qlim_config_piq_disable \ - bit.disable -#define wci_qlim_config_piq_discard_cnt_timer_en \ - bit.discard_cnt_timer_en -#define wci_qlim_config_piq_discard_cnt_timer_mag \ - bit.discard_cnt_timer_mag -#define wci_qlim_config_piq_discard_cnt_timer_val \ - bit.discard_cnt_timer_val -#define wci_qlim_config_piq_max_discard \ - bit.max_discard -#define wci_qlim_config_piq_num2discard \ - bit.num2discard -#define wci_qlim_config_piq_decay \ - bit.decay -#define wci_qlim_config_piq_tmin_mag \ - bit.tmin_mag -#define wci_qlim_config_piq_hwmark_exp \ - bit.hwmark_exp - - -/* - * wci_qlim_config_niq - */ -typedef union { - struct wci_qlim_config_niq { - uint64_t freeze : 1; /* 63 */ - uint64_t disable : 1; /* 62 */ - uint64_t rsvd_z : 2; /* 61:60 */ - uint64_t discard_cnt_timer_en : 1; /* 59 */ - uint64_t discard_cnt_timer_mag : 3; /* 58:56 */ - uint64_t discard_cnt_timer_val : 3; /* 55:53 */ - uint64_t max_discard : 13; /* 52:40 */ - uint64_t rsvd_y : 2; /* 39:38 */ - uint64_t num2discard : 10; /* 37:28 */ - uint64_t rsvd_x : 4; /* 27:24 */ - uint64_t decay : 4; /* 23:20 */ - uint64_t rsvd_w : 3; /* 19:17 */ - uint64_t tmin_mag : 13; /* 16:4 */ - uint64_t rsvd_v : 1; /* 3 */ - uint64_t hwmark_exp : 3; /* 2:0 */ - } bit; - uint64_t val; -} wci_qlim_config_niq_u; - -#define wci_qlim_config_niq_freeze \ - bit.freeze -#define wci_qlim_config_niq_disable \ - bit.disable -#define wci_qlim_config_niq_discard_cnt_timer_en \ - bit.discard_cnt_timer_en -#define wci_qlim_config_niq_discard_cnt_timer_mag \ - bit.discard_cnt_timer_mag -#define wci_qlim_config_niq_discard_cnt_timer_val \ - bit.discard_cnt_timer_val -#define wci_qlim_config_niq_max_discard \ - bit.max_discard -#define wci_qlim_config_niq_num2discard \ - bit.num2discard -#define wci_qlim_config_niq_decay \ - bit.decay -#define wci_qlim_config_niq_tmin_mag \ - bit.tmin_mag -#define wci_qlim_config_niq_hwmark_exp \ - bit.hwmark_exp - - -/* - * wci_qlim_config_ciq - */ -typedef union { - struct wci_qlim_config_ciq { - uint64_t freeze : 1; /* 63 */ - uint64_t disable : 1; /* 62 */ - uint64_t rsvd_z : 2; /* 61:60 */ - uint64_t discard_cnt_timer_en : 1; /* 59 */ - uint64_t discard_cnt_timer_mag : 3; /* 58:56 */ - uint64_t discard_cnt_timer_val : 3; /* 55:53 */ - uint64_t max_discard : 13; /* 52:40 */ - uint64_t rsvd_y : 2; /* 39:38 */ - uint64_t num2discard : 10; /* 37:28 */ - uint64_t rsvd_x : 4; /* 27:24 */ - uint64_t decay : 4; /* 23:20 */ - uint64_t rsvd_w : 3; /* 19:17 */ - uint64_t tmin_mag : 13; /* 16:4 */ - uint64_t rsvd_v : 1; /* 3 */ - uint64_t hwmark_exp : 3; /* 2:0 */ - } bit; - uint64_t val; -} wci_qlim_config_ciq_u; - -#define wci_qlim_config_ciq_freeze \ - bit.freeze -#define wci_qlim_config_ciq_disable \ - bit.disable -#define wci_qlim_config_ciq_discard_cnt_timer_en \ - bit.discard_cnt_timer_en -#define wci_qlim_config_ciq_discard_cnt_timer_mag \ - bit.discard_cnt_timer_mag -#define wci_qlim_config_ciq_discard_cnt_timer_val \ - bit.discard_cnt_timer_val -#define wci_qlim_config_ciq_max_discard \ - bit.max_discard -#define wci_qlim_config_ciq_num2discard \ - bit.num2discard -#define wci_qlim_config_ciq_decay \ - bit.decay -#define wci_qlim_config_ciq_tmin_mag \ - bit.tmin_mag -#define wci_qlim_config_ciq_hwmark_exp \ - bit.hwmark_exp - - -/* - * wci_qlim_piq_timer - */ -typedef union { - struct wci_qlim_piq_timer { - uint64_t rsvd_z : 35; /* 63:29 */ - uint64_t value : 29; /* 28:0 */ - } bit; - uint64_t val; -} wci_qlim_piq_timer_u; - -#define wci_qlim_piq_timer_value \ - bit.value - - -/* - * wci_qlim_niq_timer - */ -typedef union { - struct wci_qlim_niq_timer { - uint64_t rsvd_z : 35; /* 63:29 */ - uint64_t value : 29; /* 28:0 */ - } bit; - uint64_t val; -} wci_qlim_niq_timer_u; - -#define wci_qlim_niq_timer_value \ - bit.value - - -/* - * wci_qlim_ciq_timer - */ -typedef union { - struct wci_qlim_ciq_timer { - uint64_t rsvd_z : 35; /* 63:29 */ - uint64_t value : 29; /* 28:0 */ - } bit; - uint64_t val; -} wci_qlim_ciq_timer_u; - -#define wci_qlim_ciq_timer_value \ - bit.value - - -/* - * wci_os_cluster_disable - */ -typedef union { - struct wci_os_cluster_disable { - uint64_t rsvd_z : 60; /* 63:4 */ - uint64_t ca_cluster_disable : 1; /* 3 */ - uint64_t ra_piq_disable : 1; /* 2 */ - uint64_t ra_niq_disable : 1; /* 1 */ - uint64_t ra_ciq_disable : 1; /* 0 */ - } bit; - uint64_t val; -} wci_os_cluster_disable_u; - -#define wci_os_cluster_disable_ca_cluster_disable \ - bit.ca_cluster_disable -#define wci_os_cluster_disable_ra_piq_disable \ - bit.ra_piq_disable -#define wci_os_cluster_disable_ra_niq_disable \ - bit.ra_niq_disable -#define wci_os_cluster_disable_ra_ciq_disable \ - bit.ra_ciq_disable - - -/* - * wci_sc_cluster_disable - */ -typedef union { - struct wci_sc_cluster_disable { - uint64_t rsvd_z : 60; /* 63:4 */ - uint64_t ca_cluster_disable : 1; /* 3 */ - uint64_t ra_piq_disable : 1; /* 2 */ - uint64_t ra_niq_disable : 1; /* 1 */ - uint64_t ra_ciq_disable : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sc_cluster_disable_u; - -#define wci_sc_cluster_disable_ca_cluster_disable \ - bit.ca_cluster_disable -#define wci_sc_cluster_disable_ra_piq_disable \ - bit.ra_piq_disable -#define wci_sc_cluster_disable_ra_niq_disable \ - bit.ra_niq_disable -#define wci_sc_cluster_disable_ra_ciq_disable \ - bit.ra_ciq_disable - - -/* - * wci_ha_freeze - */ -typedef union { - struct wci_ha_freeze { - uint64_t rsvd_z : 48; /* 63:16 */ - uint64_t vector : 16; /* 15:0 */ - } bit; - uint64_t val; -} wci_ha_freeze_u; - -#define wci_ha_freeze_vector \ - bit.vector - - -/* - * wci_ha_busy - */ -typedef union { - struct wci_ha_busy { - uint64_t rsvd_z : 48; /* 63:16 */ - uint64_t vector : 16; /* 15:0 */ - } bit; - uint64_t val; -} wci_ha_busy_u; - -#define wci_ha_busy_vector \ - bit.vector - - -/* - * wci_ha_first_error_agent - */ -typedef union { - struct wci_ha_first_error_agent { - uint64_t esr_reg : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t rsvd_z : 54; /* 58:5 */ - uint64_t instance : 5; /* 4:0 */ - } bit; - uint64_t val; -} wci_ha_first_error_agent_u; - -#define wci_ha_first_error_agent_esr_reg \ - bit.esr_reg -#define wci_ha_first_error_agent_esr_index \ - bit.esr_index -#define wci_ha_first_error_agent_instance \ - bit.instance - - -/* - * wci_ha_first_packet_0 - */ -typedef union { - struct wci_ha_first_packet_0 { - uint64_t lo_a : 28; /* 63:36 */ - uint64_t rsvd_z : 8; /* 35:28 */ - uint64_t lo_b : 28; /* 27:0 */ - } bit; - uint64_t val; -} wci_ha_first_packet_0_u; - -#define wci_ha_first_packet_0_lo_a \ - bit.lo_a -#define wci_ha_first_packet_0_lo_b \ - bit.lo_b - - -/* - * wci_ha_first_packet_1 - */ -typedef union { - struct wci_ha_first_packet_1 { - uint64_t esr_reg : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t rsvd_z : 28; /* 58:31 */ - uint64_t hi : 31; /* 30:0 */ - } bit; - uint64_t val; -} wci_ha_first_packet_1_u; - -#define wci_ha_first_packet_1_esr_reg \ - bit.esr_reg -#define wci_ha_first_packet_1_esr_index \ - bit.esr_index -#define wci_ha_first_packet_1_hi \ - bit.hi - - -/* - * wci_ha_ecc_address - */ -typedef union { - struct wci_ha_ecc_address { - uint64_t data : 1; /* 63 */ - uint64_t ue : 1; /* 62 */ - uint64_t rsvd_z : 19; /* 61:43 */ - uint64_t addr : 39; /* 42:4 */ - uint64_t rsvd_y : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_ha_ecc_address_u; - -#define wci_ha_ecc_address_data \ - bit.data -#define wci_ha_ecc_address_ue \ - bit.ue -#define wci_ha_ecc_address_addr \ - bit.addr - - -/* - * wci_ha_error_address - */ -typedef union { - struct wci_ha_error_address { - uint64_t esr_reg : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t rsvd_z : 16; /* 58:43 */ - uint64_t addr : 39; /* 42:4 */ - uint64_t rsvd_y : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_ha_error_address_u; - -#define wci_ha_error_address_esr_reg \ - bit.esr_reg -#define wci_ha_error_address_esr_index \ - bit.esr_index -#define wci_ha_error_address_addr \ - bit.addr - - -/* - * wci_ha_timeout_config - */ -typedef union { - struct wci_ha_timeout_config { - uint64_t rsvd_z : 50; /* 63:14 */ - uint64_t ssm_disable : 1; /* 13 */ - uint64_t ssm_freeze : 1; /* 12 */ - uint64_t rsvd_y : 2; /* 11:10 */ - uint64_t ssm_mag : 2; /* 9:8 */ - uint64_t ssm_val : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_ha_timeout_config_u; - -#define wci_ha_timeout_config_ssm_disable \ - bit.ssm_disable -#define wci_ha_timeout_config_ssm_freeze \ - bit.ssm_freeze -#define wci_ha_timeout_config_ssm_mag \ - bit.ssm_mag -#define wci_ha_timeout_config_ssm_val \ - bit.ssm_val - - -/* - * wci_ha_esr_0 - */ -typedef union { - struct wci_ha_esr_0 { - uint64_t rsvd_z : 35; /* 63:29 */ - uint64_t acc_unexpected_snid : 1; /* 28 */ - uint64_t acc_address_not_mapped_io : 1; /* 27 */ - uint64_t acc_dir_parity_error : 1; /* 26 */ - uint64_t acc_not_expected_compl : 1; /* 25 */ - uint64_t acc_illegal_sender : 1; /* 24 */ - uint64_t acc_wrong_cmd : 1; /* 23 */ - uint64_t acc_uncorrectable_mtag_error : 1; /* 22 */ - uint64_t acc_uncorrectable_data_error : 1; /* 21 */ - uint64_t acc_correctable_mtag_error : 1; /* 20 */ - uint64_t acc_correctable_data_error : 1; /* 19 */ - uint64_t acc_mtag_mismatch_within_hcl : 1; /* 18 */ - uint64_t acc_mtag_mismatch_between_hcls : 1; /* 17 */ - uint64_t acc_timeout : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 2; /* 14:13 */ - uint64_t unexpected_snid : 1; /* 12 */ - uint64_t address_not_mapped_io : 1; /* 11 */ - uint64_t dir_parity_error : 1; /* 10 */ - uint64_t not_expected_compl : 1; /* 9 */ - uint64_t illegal_sender : 1; /* 8 */ - uint64_t wrong_cmd : 1; /* 7 */ - uint64_t uncorrectable_mtag_error : 1; /* 6 */ - uint64_t uncorrectable_data_error : 1; /* 5 */ - uint64_t correctable_mtag_error : 1; /* 4 */ - uint64_t correctable_data_error : 1; /* 3 */ - uint64_t mtag_mismatch_within_hcl : 1; /* 2 */ - uint64_t mtag_mismatch_between_hcls : 1; /* 1 */ - uint64_t timeout : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ha_esr_0_u; - -#define wci_ha_esr_0_acc_unexpected_snid \ - bit.acc_unexpected_snid -#define wci_ha_esr_0_acc_address_not_mapped_io \ - bit.acc_address_not_mapped_io -#define wci_ha_esr_0_acc_dir_parity_error \ - bit.acc_dir_parity_error -#define wci_ha_esr_0_acc_not_expected_compl \ - bit.acc_not_expected_compl -#define wci_ha_esr_0_acc_illegal_sender \ - bit.acc_illegal_sender -#define wci_ha_esr_0_acc_wrong_cmd \ - bit.acc_wrong_cmd -#define wci_ha_esr_0_acc_uncorrectable_mtag_error \ - bit.acc_uncorrectable_mtag_error -#define wci_ha_esr_0_acc_uncorrectable_data_error \ - bit.acc_uncorrectable_data_error -#define wci_ha_esr_0_acc_correctable_mtag_error \ - bit.acc_correctable_mtag_error -#define wci_ha_esr_0_acc_correctable_data_error \ - bit.acc_correctable_data_error -#define wci_ha_esr_0_acc_mtag_mismatch_within_hcl \ - bit.acc_mtag_mismatch_within_hcl -#define wci_ha_esr_0_acc_mtag_mismatch_between_hcls \ - bit.acc_mtag_mismatch_between_hcls -#define wci_ha_esr_0_acc_timeout \ - bit.acc_timeout -#define wci_ha_esr_0_first_error \ - bit.first_error -#define wci_ha_esr_0_unexpected_snid \ - bit.unexpected_snid -#define wci_ha_esr_0_address_not_mapped_io \ - bit.address_not_mapped_io -#define wci_ha_esr_0_dir_parity_error \ - bit.dir_parity_error -#define wci_ha_esr_0_not_expected_compl \ - bit.not_expected_compl -#define wci_ha_esr_0_illegal_sender \ - bit.illegal_sender -#define wci_ha_esr_0_wrong_cmd \ - bit.wrong_cmd -#define wci_ha_esr_0_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_ha_esr_0_uncorrectable_data_error \ - bit.uncorrectable_data_error -#define wci_ha_esr_0_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_ha_esr_0_correctable_data_error \ - bit.correctable_data_error -#define wci_ha_esr_0_mtag_mismatch_within_hcl \ - bit.mtag_mismatch_within_hcl -#define wci_ha_esr_0_mtag_mismatch_between_hcls \ - bit.mtag_mismatch_between_hcls -#define wci_ha_esr_0_timeout \ - bit.timeout - - -/* - * wci_ha_esr_1 - */ -typedef union { - struct wci_ha_esr_1 { - uint64_t rsvd_z : 42; /* 63:22 */ - uint64_t acc_gnr_err : 1; /* 21 */ - uint64_t acc_hw_err : 1; /* 20 */ - uint64_t acc_address_not_mapped : 1; /* 19 */ - uint64_t acc_dstat_inconsistent : 1; /* 18 */ - uint64_t acc_mtag_not_gm : 1; /* 17 */ - uint64_t acc_unexpected_mtag : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 9; /* 14:6 */ - uint64_t gnr_err : 1; /* 5 */ - uint64_t hw_err : 1; /* 4 */ - uint64_t address_not_mapped : 1; /* 3 */ - uint64_t dstat_inconsistent : 1; /* 2 */ - uint64_t mtag_not_gm : 1; /* 1 */ - uint64_t unexpected_mtag : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ha_esr_1_u; - -#define wci_ha_esr_1_acc_gnr_err \ - bit.acc_gnr_err -#define wci_ha_esr_1_acc_hw_err \ - bit.acc_hw_err -#define wci_ha_esr_1_acc_address_not_mapped \ - bit.acc_address_not_mapped -#define wci_ha_esr_1_acc_dstat_inconsistent \ - bit.acc_dstat_inconsistent -#define wci_ha_esr_1_acc_mtag_not_gm \ - bit.acc_mtag_not_gm -#define wci_ha_esr_1_acc_unexpected_mtag \ - bit.acc_unexpected_mtag -#define wci_ha_esr_1_first_error \ - bit.first_error -#define wci_ha_esr_1_gnr_err \ - bit.gnr_err -#define wci_ha_esr_1_hw_err \ - bit.hw_err -#define wci_ha_esr_1_address_not_mapped \ - bit.address_not_mapped -#define wci_ha_esr_1_dstat_inconsistent \ - bit.dstat_inconsistent -#define wci_ha_esr_1_mtag_not_gm \ - bit.mtag_not_gm -#define wci_ha_esr_1_unexpected_mtag \ - bit.unexpected_mtag - - -/* - * wci_ha_hw_err_status - */ -typedef union { - struct wci_ha_hw_err_status { - uint64_t rsvd_z : 45; /* 63:19 */ - uint64_t oh_error_case_fall_through : 1; /* 18 */ - uint64_t dir_fetchq_ovfl : 1; /* 17 */ - uint64_t dir_fetchq_unfl : 1; /* 16 */ - uint64_t srq4_errors_ovfl : 1; /* 15 */ - uint64_t srq4_errors_unfl : 1; /* 14 */ - uint64_t srq3_errors_ovfl : 1; /* 13 */ - uint64_t srq3_errors_unfl : 1; /* 12 */ - uint64_t srq2_errors_ovfl : 1; /* 11 */ - uint64_t srq2_errors_unfl : 1; /* 10 */ - uint64_t srq1_errors_ovfl : 1; /* 9 */ - uint64_t srq1_errors_unfl : 1; /* 8 */ - uint64_t kmapq_errors_ovfl : 1; /* 7 */ - uint64_t kmapq_errors_unfl : 1; /* 6 */ - uint64_t ohq_errors_ovfl : 1; /* 5 */ - uint64_t ohq_errors_unfl : 1; /* 4 */ - uint64_t shq_errors_ovfl : 1; /* 3 */ - uint64_t shq_errors_unfl : 1; /* 2 */ - uint64_t dhc_all_uexp_rcv_error : 1; /* 1 */ - uint64_t dhc_all_uexp_snd_error : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ha_hw_err_status_u; - -#define wci_ha_hw_err_status_oh_error_case_fall_through \ - bit.oh_error_case_fall_through -#define wci_ha_hw_err_status_dir_fetchq_ovfl \ - bit.dir_fetchq_ovfl -#define wci_ha_hw_err_status_dir_fetchq_unfl \ - bit.dir_fetchq_unfl -#define wci_ha_hw_err_status_srq4_errors_ovfl \ - bit.srq4_errors_ovfl -#define wci_ha_hw_err_status_srq4_errors_unfl \ - bit.srq4_errors_unfl -#define wci_ha_hw_err_status_srq3_errors_ovfl \ - bit.srq3_errors_ovfl -#define wci_ha_hw_err_status_srq3_errors_unfl \ - bit.srq3_errors_unfl -#define wci_ha_hw_err_status_srq2_errors_ovfl \ - bit.srq2_errors_ovfl -#define wci_ha_hw_err_status_srq2_errors_unfl \ - bit.srq2_errors_unfl -#define wci_ha_hw_err_status_srq1_errors_ovfl \ - bit.srq1_errors_ovfl -#define wci_ha_hw_err_status_srq1_errors_unfl \ - bit.srq1_errors_unfl -#define wci_ha_hw_err_status_kmapq_errors_ovfl \ - bit.kmapq_errors_ovfl -#define wci_ha_hw_err_status_kmapq_errors_unfl \ - bit.kmapq_errors_unfl -#define wci_ha_hw_err_status_ohq_errors_ovfl \ - bit.ohq_errors_ovfl -#define wci_ha_hw_err_status_ohq_errors_unfl \ - bit.ohq_errors_unfl -#define wci_ha_hw_err_status_shq_errors_ovfl \ - bit.shq_errors_ovfl -#define wci_ha_hw_err_status_shq_errors_unfl \ - bit.shq_errors_unfl -#define wci_ha_hw_err_status_dhc_all_uexp_rcv_error \ - bit.dhc_all_uexp_rcv_error -#define wci_ha_hw_err_status_dhc_all_uexp_snd_error \ - bit.dhc_all_uexp_snd_error - - -/* - * wci_ha_esr_mask - */ -typedef union { - struct wci_ha_esr_mask { - uint64_t rsvd_z : 42; /* 63:22 */ - uint64_t gnr_err : 1; /* 21 */ - uint64_t hw_err : 1; /* 20 */ - uint64_t address_not_mapped : 1; /* 19 */ - uint64_t dstat_inconsistent : 1; /* 18 */ - uint64_t mtag_not_gm : 1; /* 17 */ - uint64_t unexpected_mtag : 1; /* 16 */ - uint64_t rsvd_y : 3; /* 15:13 */ - uint64_t unexpected_snid : 1; /* 12 */ - uint64_t address_not_mapped_io : 1; /* 11 */ - uint64_t dir_parity_error : 1; /* 10 */ - uint64_t not_expected_compl : 1; /* 9 */ - uint64_t illegal_sender : 1; /* 8 */ - uint64_t wrong_cmd : 1; /* 7 */ - uint64_t uncorrectable_mtag_error : 1; /* 6 */ - uint64_t uncorrectable_data_error : 1; /* 5 */ - uint64_t correctable_mtag_error : 1; /* 4 */ - uint64_t correctable_data_error : 1; /* 3 */ - uint64_t mtag_mismatch_within_hcl : 1; /* 2 */ - uint64_t mtag_mismatch_between_hcls : 1; /* 1 */ - uint64_t timeout : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ha_esr_mask_u; - -#define wci_ha_esr_mask_gnr_err \ - bit.gnr_err -#define wci_ha_esr_mask_hw_err \ - bit.hw_err -#define wci_ha_esr_mask_address_not_mapped \ - bit.address_not_mapped -#define wci_ha_esr_mask_dstat_inconsistent \ - bit.dstat_inconsistent -#define wci_ha_esr_mask_mtag_not_gm \ - bit.mtag_not_gm -#define wci_ha_esr_mask_unexpected_mtag \ - bit.unexpected_mtag -#define wci_ha_esr_mask_unexpected_snid \ - bit.unexpected_snid -#define wci_ha_esr_mask_address_not_mapped_io \ - bit.address_not_mapped_io -#define wci_ha_esr_mask_dir_parity_error \ - bit.dir_parity_error -#define wci_ha_esr_mask_not_expected_compl \ - bit.not_expected_compl -#define wci_ha_esr_mask_illegal_sender \ - bit.illegal_sender -#define wci_ha_esr_mask_wrong_cmd \ - bit.wrong_cmd -#define wci_ha_esr_mask_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_ha_esr_mask_uncorrectable_data_error \ - bit.uncorrectable_data_error -#define wci_ha_esr_mask_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_ha_esr_mask_correctable_data_error \ - bit.correctable_data_error -#define wci_ha_esr_mask_mtag_mismatch_within_hcl \ - bit.mtag_mismatch_within_hcl -#define wci_ha_esr_mask_mtag_mismatch_between_hcls \ - bit.mtag_mismatch_between_hcls -#define wci_ha_esr_mask_timeout \ - bit.timeout - - -/* - * wci_probe_memory - */ -typedef union { - struct wci_probe_memory { - uint64_t done : 1; /* 63 */ - uint64_t in_progress : 1; /* 62 */ - uint64_t rsvd_z : 15; /* 61:47 */ - uint64_t mtag : 3; /* 46:44 */ - uint64_t rsvd_y : 1; /* 43 */ - uint64_t address : 39; /* 42:4 */ - uint64_t rsvd_x : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_probe_memory_u; - -#define wci_probe_memory_done \ - bit.done -#define wci_probe_memory_in_progress \ - bit.in_progress -#define wci_probe_memory_mtag \ - bit.mtag -#define wci_probe_memory_address \ - bit.address - - -/* - * wci_ha_status_array - */ -typedef union { - struct wci_ha_status_array { - uint64_t orig_atransid : 9; /* 63:55 */ - uint64_t orig_rtid : 5; /* 54:50 */ - uint64_t dispatched_op : 6; /* 49:44 */ - uint64_t rsvd_z : 1; /* 43 */ - uint64_t orig_addr : 39; /* 42:4 */ - uint64_t orig_snid : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_ha_status_array_u; - -#define wci_ha_status_array_orig_atransid \ - bit.orig_atransid -#define wci_ha_status_array_orig_rtid \ - bit.orig_rtid -#define wci_ha_status_array_dispatched_op \ - bit.dispatched_op -#define wci_ha_status_array_orig_addr \ - bit.orig_addr -#define wci_ha_status_array_orig_snid \ - bit.orig_snid - - -/* - * wci_ha_status_2_array - */ -typedef union { - struct wci_ha_status_2_array { - uint64_t rsvd_z : 30; /* 63:34 */ - uint64_t dir_vld : 1; /* 33 */ - uint64_t dir_hit : 1; /* 32 */ - uint64_t old_dir_entry : 12; /* 31:20 */ - uint64_t rsvd_y : 1; /* 19 */ - uint64_t old_mtag : 3; /* 18:16 */ - uint64_t dir_copt : 2; /* 15:14 */ - uint64_t data_copt : 2; /* 13:12 */ - uint64_t rsvd_x : 3; /* 11:9 */ - uint64_t safari_thread : 1; /* 8 */ - uint64_t auxid_thread : 1; /* 7 */ - uint64_t cmpl_thread : 1; /* 6 */ - uint64_t data_sent_thread : 1; /* 5 */ - uint64_t data_rcvd_thread : 1; /* 4 */ - uint64_t dob_clrd_thread : 1; /* 3 */ - uint64_t hdr_sent_thread : 1; /* 2 */ - uint64_t constmap_thread : 1; /* 1 */ - uint64_t pull_seen_thread : 1; /* 0 */ - } bit; - uint64_t val; -} wci_ha_status_2_array_u; - -#define wci_ha_status_2_array_dir_vld \ - bit.dir_vld -#define wci_ha_status_2_array_dir_hit \ - bit.dir_hit -#define wci_ha_status_2_array_old_dir_entry \ - bit.old_dir_entry -#define wci_ha_status_2_array_old_mtag \ - bit.old_mtag -#define wci_ha_status_2_array_dir_copt \ - bit.dir_copt -#define wci_ha_status_2_array_data_copt \ - bit.data_copt -#define wci_ha_status_2_array_safari_thread \ - bit.safari_thread -#define wci_ha_status_2_array_auxid_thread \ - bit.auxid_thread -#define wci_ha_status_2_array_cmpl_thread \ - bit.cmpl_thread -#define wci_ha_status_2_array_data_sent_thread \ - bit.data_sent_thread -#define wci_ha_status_2_array_data_rcvd_thread \ - bit.data_rcvd_thread -#define wci_ha_status_2_array_dob_clrd_thread \ - bit.dob_clrd_thread -#define wci_ha_status_2_array_hdr_sent_thread \ - bit.hdr_sent_thread -#define wci_ha_status_2_array_constmap_thread \ - bit.constmap_thread -#define wci_ha_status_2_array_pull_seen_thread \ - bit.pull_seen_thread - - -/* - * wci_ha_config - */ -typedef union { - struct wci_ha_config { - uint64_t rsvd_z : 55; /* 63:9 */ - uint64_t snid_in_mask : 1; /* 8 */ - uint64_t disable_same_box_opt : 1; /* 7 */ - uint64_t migratory_sharing_ctrl : 7; /* 6:0 */ - } bit; - uint64_t val; -} wci_ha_config_u; - -#define wci_ha_config_snid_in_mask \ - bit.snid_in_mask -#define wci_ha_config_disable_same_box_opt \ - bit.disable_same_box_opt -#define wci_ha_config_migratory_sharing_ctrl \ - bit.migratory_sharing_ctrl - - -/* - * wci_hag_route_map0 - */ -typedef union { - struct wci_hag_route_map0 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_hag_route_map0_u; - -#define wci_hag_route_map0_node15_tlink \ - bit.node15_tlink -#define wci_hag_route_map0_node14_tlink \ - bit.node14_tlink -#define wci_hag_route_map0_node13_tlink \ - bit.node13_tlink -#define wci_hag_route_map0_node12_tlink \ - bit.node12_tlink -#define wci_hag_route_map0_node11_tlink \ - bit.node11_tlink -#define wci_hag_route_map0_node10_tlink \ - bit.node10_tlink -#define wci_hag_route_map0_node9_tlink \ - bit.node9_tlink -#define wci_hag_route_map0_node8_tlink \ - bit.node8_tlink -#define wci_hag_route_map0_node7_tlink \ - bit.node7_tlink -#define wci_hag_route_map0_node6_tlink \ - bit.node6_tlink -#define wci_hag_route_map0_node5_tlink \ - bit.node5_tlink -#define wci_hag_route_map0_node4_tlink \ - bit.node4_tlink -#define wci_hag_route_map0_node3_tlink \ - bit.node3_tlink -#define wci_hag_route_map0_node2_tlink \ - bit.node2_tlink -#define wci_hag_route_map0_node1_tlink \ - bit.node1_tlink -#define wci_hag_route_map0_node0_tlink \ - bit.node0_tlink - - -/* - * wci_hag_route_map1 - */ -typedef union { - struct wci_hag_route_map1 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_hag_route_map1_u; - -#define wci_hag_route_map1_node15_tlink \ - bit.node15_tlink -#define wci_hag_route_map1_node14_tlink \ - bit.node14_tlink -#define wci_hag_route_map1_node13_tlink \ - bit.node13_tlink -#define wci_hag_route_map1_node12_tlink \ - bit.node12_tlink -#define wci_hag_route_map1_node11_tlink \ - bit.node11_tlink -#define wci_hag_route_map1_node10_tlink \ - bit.node10_tlink -#define wci_hag_route_map1_node9_tlink \ - bit.node9_tlink -#define wci_hag_route_map1_node8_tlink \ - bit.node8_tlink -#define wci_hag_route_map1_node7_tlink \ - bit.node7_tlink -#define wci_hag_route_map1_node6_tlink \ - bit.node6_tlink -#define wci_hag_route_map1_node5_tlink \ - bit.node5_tlink -#define wci_hag_route_map1_node4_tlink \ - bit.node4_tlink -#define wci_hag_route_map1_node3_tlink \ - bit.node3_tlink -#define wci_hag_route_map1_node2_tlink \ - bit.node2_tlink -#define wci_hag_route_map1_node1_tlink \ - bit.node1_tlink -#define wci_hag_route_map1_node0_tlink \ - bit.node0_tlink - - -/* - * wci_emiss_cntl_array - */ -typedef union { - struct wci_emiss_cntl_array { - uint64_t rsvd_z : 13; /* 63:51 */ - uint64_t auto_reset_active : 1; /* 50 */ - uint64_t enabled : 1; /* 49 */ - uint64_t address : 37; /* 48:12 */ - uint64_t nid : 4; /* 11:8 */ - uint64_t length : 2; /* 7:6 */ - uint64_t event0 : 3; /* 5:3 */ - uint64_t event1 : 3; /* 2:0 */ - } bit; - uint64_t val; -} wci_emiss_cntl_array_u; - -#define wci_emiss_cntl_array_auto_reset_active \ - bit.auto_reset_active -#define wci_emiss_cntl_array_enabled \ - bit.enabled -#define wci_emiss_cntl_array_address \ - bit.address -#define wci_emiss_cntl_array_nid \ - bit.nid -#define wci_emiss_cntl_array_length \ - bit.length -#define wci_emiss_cntl_array_event0 \ - bit.event0 -#define wci_emiss_cntl_array_event1 \ - bit.event1 - - -/* - * wci_emiss_data_array - */ -typedef union { - struct wci_emiss_data_array { - uint64_t rsvd_z : 20; /* 63:44 */ - uint64_t event0_count : 10; /* 43:34 */ - uint64_t event1_count : 10; /* 33:24 */ - uint64_t event0_count_all : 12; /* 23:12 */ - uint64_t event1_count_all : 12; /* 11:0 */ - } bit; - uint64_t val; -} wci_emiss_data_array_u; - -#define wci_emiss_data_array_event0_count \ - bit.event0_count -#define wci_emiss_data_array_event1_count \ - bit.event1_count -#define wci_emiss_data_array_event0_count_all \ - bit.event0_count_all -#define wci_emiss_data_array_event1_count_all \ - bit.event1_count_all - - -/* - * wci_emiss_reset_ctl - */ -typedef union { - struct wci_emiss_reset_ctl { - uint64_t rsvd_z : 42; /* 63:22 */ - uint64_t auto_reset_mask : 10; /* 21:12 */ - uint64_t count : 12; /* 11:0 */ - } bit; - uint64_t val; -} wci_emiss_reset_ctl_u; - -#define wci_emiss_reset_ctl_auto_reset_mask \ - bit.auto_reset_mask -#define wci_emiss_reset_ctl_count \ - bit.count - - -/* - * wci_global_emiss_counter - */ -typedef union { - struct wci_global_emiss_counter { - uint64_t rsvd_z : 40; /* 63:24 */ - uint64_t count : 24; /* 23:0 */ - } bit; - uint64_t val; -} wci_global_emiss_counter_u; - -#define wci_global_emiss_counter_count \ - bit.count - - -/* - * wci_sa_freeze - */ -typedef union { - struct wci_sa_freeze { - uint64_t rsvd_z : 56; /* 63:8 */ - uint64_t vector : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_sa_freeze_u; - -#define wci_sa_freeze_vector \ - bit.vector - - -/* - * wci_sa_busy - */ -typedef union { - struct wci_sa_busy { - uint64_t rsvd_z : 56; /* 63:8 */ - uint64_t vector : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_sa_busy_u; - -#define wci_sa_busy_vector \ - bit.vector - - -/* - * wci_sa_first_error_agent - */ -typedef union { - struct wci_sa_first_error_agent { - uint64_t esr_reg : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t rsvd_z : 56; /* 58:3 */ - uint64_t instance : 3; /* 2:0 */ - } bit; - uint64_t val; -} wci_sa_first_error_agent_u; - -#define wci_sa_first_error_agent_esr_reg \ - bit.esr_reg -#define wci_sa_first_error_agent_esr_index \ - bit.esr_index -#define wci_sa_first_error_agent_instance \ - bit.instance - - -/* - * wci_sa_first_packet_0 - */ -typedef union { - struct wci_sa_first_packet_0 { - uint64_t rsvd_z : 7; /* 63:57 */ - uint64_t ntransid : 9; /* 56:48 */ - uint64_t rsvd_y : 2; /* 47:46 */ - uint64_t cmr : 1; /* 45 */ - uint64_t otransid : 9; /* 44:36 */ - uint64_t rsvd_x : 2; /* 35:34 */ - uint64_t rnid : 4; /* 33:30 */ - uint64_t r2e : 4; /* 29:26 */ - uint64_t emiss : 1; /* 25 */ - uint64_t rsvd_w : 1; /* 24 */ - uint64_t htid : 4; /* 23:20 */ - uint64_t rtid : 5; /* 19:15 */ - uint64_t snid : 4; /* 14:11 */ - uint64_t msgop : 4; /* 10:7 */ - uint64_t htyp : 2; /* 6:5 */ - uint64_t stripe : 1; /* 4 */ - uint64_t dnid : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_sa_first_packet_0_u; - -#define wci_sa_first_packet_0_ntransid \ - bit.ntransid -#define wci_sa_first_packet_0_cmr \ - bit.cmr -#define wci_sa_first_packet_0_otransid \ - bit.otransid -#define wci_sa_first_packet_0_rnid \ - bit.rnid -#define wci_sa_first_packet_0_r2e \ - bit.r2e -#define wci_sa_first_packet_0_emiss \ - bit.emiss -#define wci_sa_first_packet_0_htid \ - bit.htid -#define wci_sa_first_packet_0_rtid \ - bit.rtid -#define wci_sa_first_packet_0_snid \ - bit.snid -#define wci_sa_first_packet_0_msgop \ - bit.msgop -#define wci_sa_first_packet_0_htyp \ - bit.htyp -#define wci_sa_first_packet_0_stripe \ - bit.stripe -#define wci_sa_first_packet_0_dnid \ - bit.dnid - - -/* - * wci_sa_first_packet_1 - */ -typedef union { - struct wci_sa_first_packet_1 { - uint64_t esr_reg : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t a_entry : 1; /* 58 */ - uint64_t s_entry : 1; /* 57 */ - uint64_t rsvd_z : 14; /* 56:43 */ - uint64_t ga : 38; /* 42:5 */ - uint64_t rsvd_y : 5; /* 4:0 */ - } bit; - uint64_t val; -} wci_sa_first_packet_1_u; - -#define wci_sa_first_packet_1_esr_reg \ - bit.esr_reg -#define wci_sa_first_packet_1_esr_index \ - bit.esr_index -#define wci_sa_first_packet_1_a_entry \ - bit.a_entry -#define wci_sa_first_packet_1_s_entry \ - bit.s_entry -#define wci_sa_first_packet_1_ga \ - bit.ga - - -/* - * wci_sa_ecc_address - */ -typedef union { - struct wci_sa_ecc_address { - uint64_t data : 1; /* 63 */ - uint64_t ue : 1; /* 62 */ - uint64_t rsvd_z : 19; /* 61:43 */ - uint64_t addr : 38; /* 42:5 */ - uint64_t rsvd_y : 5; /* 4:0 */ - } bit; - uint64_t val; -} wci_sa_ecc_address_u; - -#define wci_sa_ecc_address_data \ - bit.data -#define wci_sa_ecc_address_ue \ - bit.ue -#define wci_sa_ecc_address_addr \ - bit.addr - - -/* - * wci_sa_timeout_config - */ -typedef union { - struct wci_sa_timeout_config { - uint64_t rsvd_z : 50; /* 63:14 */ - uint64_t ssm_disable : 1; /* 13 */ - uint64_t ssm_freeze : 1; /* 12 */ - uint64_t rsvd_y : 2; /* 11:10 */ - uint64_t ssm_mag : 2; /* 9:8 */ - uint64_t ssm_val : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_sa_timeout_config_u; - -#define wci_sa_timeout_config_ssm_disable \ - bit.ssm_disable -#define wci_sa_timeout_config_ssm_freeze \ - bit.ssm_freeze -#define wci_sa_timeout_config_ssm_mag \ - bit.ssm_mag -#define wci_sa_timeout_config_ssm_val \ - bit.ssm_val - - -/* - * wci_sa_esr_0 - */ -typedef union { - struct wci_sa_esr_0 { - uint64_t rsvd_z : 33; /* 63:31 */ - uint64_t acc_hw_err : 1; /* 30 */ - uint64_t acc_address_not_owned : 1; /* 29 */ - uint64_t acc_address_not_mapped : 1; /* 28 */ - uint64_t acc_ga2lpa_ecc_error : 1; /* 27 */ - uint64_t acc_rip_multi_hit : 1; /* 26 */ - uint64_t acc_illegal_sender : 1; /* 25 */ - uint64_t acc_wrong_demand : 1; /* 24 */ - uint64_t acc_uncorrectable_mtag_error : 1; /* 23 */ - uint64_t acc_uncorrectable_data_error : 1; /* 22 */ - uint64_t acc_correctable_mtag_error : 1; /* 21 */ - uint64_t acc_correctable_data_error : 1; /* 20 */ - uint64_t acc_mtag_mismatch_within_hcl : 1; /* 19 */ - uint64_t acc_mtag_mismatch_between_hcls : 1; /* 18 */ - uint64_t acc_unexpected_mtag : 1; /* 17 */ - uint64_t acc_timeout : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t hw_err : 1; /* 14 */ - uint64_t address_not_owned : 1; /* 13 */ - uint64_t address_not_mapped : 1; /* 12 */ - uint64_t ga2lpa_ecc_error : 1; /* 11 */ - uint64_t rip_multi_hit : 1; /* 10 */ - uint64_t illegal_sender : 1; /* 9 */ - uint64_t wrong_demand : 1; /* 8 */ - uint64_t uncorrectable_mtag_error : 1; /* 7 */ - uint64_t uncorrectable_data_error : 1; /* 6 */ - uint64_t correctable_mtag_error : 1; /* 5 */ - uint64_t correctable_data_error : 1; /* 4 */ - uint64_t mtag_mismatch_within_hcl : 1; /* 3 */ - uint64_t mtag_mismatch_between_hcls : 1; /* 2 */ - uint64_t unexpected_mtag : 1; /* 1 */ - uint64_t timeout : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sa_esr_0_u; - -#define wci_sa_esr_0_acc_hw_err \ - bit.acc_hw_err -#define wci_sa_esr_0_acc_address_not_owned \ - bit.acc_address_not_owned -#define wci_sa_esr_0_acc_address_not_mapped \ - bit.acc_address_not_mapped -#define wci_sa_esr_0_acc_ga2lpa_ecc_error \ - bit.acc_ga2lpa_ecc_error -#define wci_sa_esr_0_acc_rip_multi_hit \ - bit.acc_rip_multi_hit -#define wci_sa_esr_0_acc_illegal_sender \ - bit.acc_illegal_sender -#define wci_sa_esr_0_acc_wrong_demand \ - bit.acc_wrong_demand -#define wci_sa_esr_0_acc_uncorrectable_mtag_error \ - bit.acc_uncorrectable_mtag_error -#define wci_sa_esr_0_acc_uncorrectable_data_error \ - bit.acc_uncorrectable_data_error -#define wci_sa_esr_0_acc_correctable_mtag_error \ - bit.acc_correctable_mtag_error -#define wci_sa_esr_0_acc_correctable_data_error \ - bit.acc_correctable_data_error -#define wci_sa_esr_0_acc_mtag_mismatch_within_hcl \ - bit.acc_mtag_mismatch_within_hcl -#define wci_sa_esr_0_acc_mtag_mismatch_between_hcls \ - bit.acc_mtag_mismatch_between_hcls -#define wci_sa_esr_0_acc_unexpected_mtag \ - bit.acc_unexpected_mtag -#define wci_sa_esr_0_acc_timeout \ - bit.acc_timeout -#define wci_sa_esr_0_first_error \ - bit.first_error -#define wci_sa_esr_0_hw_err \ - bit.hw_err -#define wci_sa_esr_0_address_not_owned \ - bit.address_not_owned -#define wci_sa_esr_0_address_not_mapped \ - bit.address_not_mapped -#define wci_sa_esr_0_ga2lpa_ecc_error \ - bit.ga2lpa_ecc_error -#define wci_sa_esr_0_rip_multi_hit \ - bit.rip_multi_hit -#define wci_sa_esr_0_illegal_sender \ - bit.illegal_sender -#define wci_sa_esr_0_wrong_demand \ - bit.wrong_demand -#define wci_sa_esr_0_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_sa_esr_0_uncorrectable_data_error \ - bit.uncorrectable_data_error -#define wci_sa_esr_0_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_sa_esr_0_correctable_data_error \ - bit.correctable_data_error -#define wci_sa_esr_0_mtag_mismatch_within_hcl \ - bit.mtag_mismatch_within_hcl -#define wci_sa_esr_0_mtag_mismatch_between_hcls \ - bit.mtag_mismatch_between_hcls -#define wci_sa_esr_0_unexpected_mtag \ - bit.unexpected_mtag -#define wci_sa_esr_0_timeout \ - bit.timeout - - -/* - * wci_sa_hw_err_state - */ -typedef union { - struct wci_sa_hw_err_state { - uint64_t rsvd_z : 56; /* 63:8 */ - uint64_t sh_queue_overflow : 1; /* 7 */ - uint64_t sh_wrong_stid : 1; /* 6 */ - uint64_t sh_unexpected_snoop : 1; /* 5 */ - uint64_t oh_queue_overflow : 1; /* 4 */ - uint64_t oh_wrong_stid : 1; /* 3 */ - uint64_t oh_unexpected_ordered : 1; /* 2 */ - uint64_t unexpected_send_ack : 1; /* 1 */ - uint64_t unexpected_receive_ack : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sa_hw_err_state_u; - -#define wci_sa_hw_err_state_sh_queue_overflow \ - bit.sh_queue_overflow -#define wci_sa_hw_err_state_sh_wrong_stid \ - bit.sh_wrong_stid -#define wci_sa_hw_err_state_sh_unexpected_snoop \ - bit.sh_unexpected_snoop -#define wci_sa_hw_err_state_oh_queue_overflow \ - bit.oh_queue_overflow -#define wci_sa_hw_err_state_oh_wrong_stid \ - bit.oh_wrong_stid -#define wci_sa_hw_err_state_oh_unexpected_ordered \ - bit.oh_unexpected_ordered -#define wci_sa_hw_err_state_unexpected_send_ack \ - bit.unexpected_send_ack -#define wci_sa_hw_err_state_unexpected_receive_ack \ - bit.unexpected_receive_ack - - -/* - * wci_sa_esr_mask - */ -typedef union { - struct wci_sa_esr_mask { - uint64_t rsvd_z : 49; /* 63:15 */ - uint64_t hw_err : 1; /* 14 */ - uint64_t address_not_owned : 1; /* 13 */ - uint64_t address_not_mapped : 1; /* 12 */ - uint64_t ga2lpa_ecc_error : 1; /* 11 */ - uint64_t rip_multi_hit : 1; /* 10 */ - uint64_t illegal_sender : 1; /* 9 */ - uint64_t wrong_demand : 1; /* 8 */ - uint64_t uncorrectable_mtag_error : 1; /* 7 */ - uint64_t uncorrectable_data_error : 1; /* 6 */ - uint64_t correctable_mtag_error : 1; /* 5 */ - uint64_t correctable_data_error : 1; /* 4 */ - uint64_t mtag_mismatch_within_hcl : 1; /* 3 */ - uint64_t mtag_mismatch_between_hcls : 1; /* 2 */ - uint64_t unexpected_mtag : 1; /* 1 */ - uint64_t timeout : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sa_esr_mask_u; - -#define wci_sa_esr_mask_hw_err \ - bit.hw_err -#define wci_sa_esr_mask_address_not_owned \ - bit.address_not_owned -#define wci_sa_esr_mask_address_not_mapped \ - bit.address_not_mapped -#define wci_sa_esr_mask_ga2lpa_ecc_error \ - bit.ga2lpa_ecc_error -#define wci_sa_esr_mask_rip_multi_hit \ - bit.rip_multi_hit -#define wci_sa_esr_mask_illegal_sender \ - bit.illegal_sender -#define wci_sa_esr_mask_wrong_demand \ - bit.wrong_demand -#define wci_sa_esr_mask_uncorrectable_mtag_error \ - bit.uncorrectable_mtag_error -#define wci_sa_esr_mask_uncorrectable_data_error \ - bit.uncorrectable_data_error -#define wci_sa_esr_mask_correctable_mtag_error \ - bit.correctable_mtag_error -#define wci_sa_esr_mask_correctable_data_error \ - bit.correctable_data_error -#define wci_sa_esr_mask_mtag_mismatch_within_hcl \ - bit.mtag_mismatch_within_hcl -#define wci_sa_esr_mask_mtag_mismatch_between_hcls \ - bit.mtag_mismatch_between_hcls -#define wci_sa_esr_mask_unexpected_mtag \ - bit.unexpected_mtag -#define wci_sa_esr_mask_timeout \ - bit.timeout - - -/* - * wci_sa_status_array - */ -typedef union { - struct wci_sa_status_array { - uint64_t rsvd_z : 43; /* 63:21 */ - uint64_t receive_count : 2; /* 20:19 */ - uint64_t send_count : 3; /* 18:16 */ - uint64_t owned : 1; /* 15 */ - uint64_t first_mtag : 3; /* 14:12 */ - uint64_t atransid_3_0 : 4; /* 11:8 */ - uint64_t rsvd_y : 2; /* 7:6 */ - uint64_t ga2lpa_status : 2; /* 5:4 */ - uint64_t msgop : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_sa_status_array_u; - -#define wci_sa_status_array_receive_count \ - bit.receive_count -#define wci_sa_status_array_send_count \ - bit.send_count -#define wci_sa_status_array_owned \ - bit.owned -#define wci_sa_status_array_first_mtag \ - bit.first_mtag -#define wci_sa_status_array_atransid_3_0 \ - bit.atransid_3_0 -#define wci_sa_status_array_ga2lpa_status \ - bit.ga2lpa_status -#define wci_sa_status_array_msgop \ - bit.msgop - - -/* - * wci_sa_status_2_array - */ -typedef union { - struct wci_sa_status_2_array { - uint64_t rsvd_z : 53; /* 63:11 */ - uint64_t send_done : 1; /* 10 */ - uint64_t ph_done : 1; /* 9 */ - uint64_t got_2nd_snoop : 1; /* 8 */ - uint64_t got_1st_snoop : 1; /* 7 */ - uint64_t got_2nd_ord : 1; /* 6 */ - uint64_t got_1st_ord : 1; /* 5 */ - uint64_t sf_3_done : 1; /* 4 */ - uint64_t sf_2_done : 1; /* 3 */ - uint64_t dsh_done : 1; /* 2 */ - uint64_t drh_done : 1; /* 1 */ - uint64_t req_done : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sa_status_2_array_u; - -#define wci_sa_status_2_array_send_done \ - bit.send_done -#define wci_sa_status_2_array_ph_done \ - bit.ph_done -#define wci_sa_status_2_array_got_2nd_snoop \ - bit.got_2nd_snoop -#define wci_sa_status_2_array_got_1st_snoop \ - bit.got_1st_snoop -#define wci_sa_status_2_array_got_2nd_ord \ - bit.got_2nd_ord -#define wci_sa_status_2_array_got_1st_ord \ - bit.got_1st_ord -#define wci_sa_status_2_array_sf_3_done \ - bit.sf_3_done -#define wci_sa_status_2_array_sf_2_done \ - bit.sf_2_done -#define wci_sa_status_2_array_dsh_done \ - bit.dsh_done -#define wci_sa_status_2_array_drh_done \ - bit.drh_done -#define wci_sa_status_2_array_req_done \ - bit.req_done - - -/* - * wci_sa_status_3_array - */ -typedef union { - struct wci_sa_status_3_array { - uint64_t rsvd_z : 51; /* 63:13 */ - uint64_t ntransid : 9; /* 12:4 */ - uint64_t snid : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_sa_status_3_array_u; - -#define wci_sa_status_3_array_ntransid \ - bit.ntransid -#define wci_sa_status_3_array_snid \ - bit.snid - - -/* - * wci_sa_status_4_array - */ -typedef union { - struct wci_sa_status_4_array { - uint64_t rsvd_z : 31; /* 63:33 */ - uint64_t otransid : 9; /* 32:24 */ - uint64_t rnid : 4; /* 23:20 */ - uint64_t replies_2_exp : 4; /* 19:16 */ - uint64_t htid : 4; /* 15:12 */ - uint64_t rsvd_y : 3; /* 11:9 */ - uint64_t rtid : 5; /* 8:4 */ - uint64_t rsvd_x : 2; /* 3:2 */ - uint64_t emiss : 1; /* 1 */ - uint64_t stripe : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sa_status_4_array_u; - -#define wci_sa_status_4_array_otransid \ - bit.otransid -#define wci_sa_status_4_array_rnid \ - bit.rnid -#define wci_sa_status_4_array_replies_2_exp \ - bit.replies_2_exp -#define wci_sa_status_4_array_htid \ - bit.htid -#define wci_sa_status_4_array_rtid \ - bit.rtid -#define wci_sa_status_4_array_emiss \ - bit.emiss -#define wci_sa_status_4_array_stripe \ - bit.stripe - - -/* - * wci_sa_status_5_array - */ -typedef union { - struct wci_sa_status_5_array { - uint64_t rsvd_z : 21; /* 63:43 */ - uint64_t original_ga : 30; /* 42:13 */ - uint64_t rsvd_y : 12; /* 12:1 */ - uint64_t cmr : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sa_status_5_array_u; - -#define wci_sa_status_5_array_original_ga \ - bit.original_ga -#define wci_sa_status_5_array_cmr \ - bit.cmr - - -/* - * wci_sa_status_6_array - */ -typedef union { - struct wci_sa_status_6_array { - uint64_t rsvd_z : 21; /* 63:43 */ - uint64_t safari_addr_42 : 1; /* 42 */ - uint64_t safari_addr_41_38 : 4; /* 41:38 */ - uint64_t safari_addr_37 : 1; /* 37 */ - uint64_t safari_addr_36_5 : 32; /* 36:5 */ - uint64_t rsvd_y : 5; /* 4:0 */ - } bit; - uint64_t val; -} wci_sa_status_6_array_u; - -#define wci_sa_status_6_array_safari_addr_42 \ - bit.safari_addr_42 -#define wci_sa_status_6_array_safari_addr_41_38 \ - bit.safari_addr_41_38 -#define wci_sa_status_6_array_safari_addr_37 \ - bit.safari_addr_37 -#define wci_sa_status_6_array_safari_addr_36_5 \ - bit.safari_addr_36_5 - - -/* - * wci_sag_route_map0 - */ -typedef union { - struct wci_sag_route_map0 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_sag_route_map0_u; - -#define wci_sag_route_map0_node15_tlink \ - bit.node15_tlink -#define wci_sag_route_map0_node14_tlink \ - bit.node14_tlink -#define wci_sag_route_map0_node13_tlink \ - bit.node13_tlink -#define wci_sag_route_map0_node12_tlink \ - bit.node12_tlink -#define wci_sag_route_map0_node11_tlink \ - bit.node11_tlink -#define wci_sag_route_map0_node10_tlink \ - bit.node10_tlink -#define wci_sag_route_map0_node9_tlink \ - bit.node9_tlink -#define wci_sag_route_map0_node8_tlink \ - bit.node8_tlink -#define wci_sag_route_map0_node7_tlink \ - bit.node7_tlink -#define wci_sag_route_map0_node6_tlink \ - bit.node6_tlink -#define wci_sag_route_map0_node5_tlink \ - bit.node5_tlink -#define wci_sag_route_map0_node4_tlink \ - bit.node4_tlink -#define wci_sag_route_map0_node3_tlink \ - bit.node3_tlink -#define wci_sag_route_map0_node2_tlink \ - bit.node2_tlink -#define wci_sag_route_map0_node1_tlink \ - bit.node1_tlink -#define wci_sag_route_map0_node0_tlink \ - bit.node0_tlink - - -/* - * wci_sag_route_map1 - */ -typedef union { - struct wci_sag_route_map1 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_sag_route_map1_u; - -#define wci_sag_route_map1_node15_tlink \ - bit.node15_tlink -#define wci_sag_route_map1_node14_tlink \ - bit.node14_tlink -#define wci_sag_route_map1_node13_tlink \ - bit.node13_tlink -#define wci_sag_route_map1_node12_tlink \ - bit.node12_tlink -#define wci_sag_route_map1_node11_tlink \ - bit.node11_tlink -#define wci_sag_route_map1_node10_tlink \ - bit.node10_tlink -#define wci_sag_route_map1_node9_tlink \ - bit.node9_tlink -#define wci_sag_route_map1_node8_tlink \ - bit.node8_tlink -#define wci_sag_route_map1_node7_tlink \ - bit.node7_tlink -#define wci_sag_route_map1_node6_tlink \ - bit.node6_tlink -#define wci_sag_route_map1_node5_tlink \ - bit.node5_tlink -#define wci_sag_route_map1_node4_tlink \ - bit.node4_tlink -#define wci_sag_route_map1_node3_tlink \ - bit.node3_tlink -#define wci_sag_route_map1_node2_tlink \ - bit.node2_tlink -#define wci_sag_route_map1_node1_tlink \ - bit.node1_tlink -#define wci_sag_route_map1_node0_tlink \ - bit.node0_tlink - - -/* - * wci_nc2nid_array - */ -typedef union { - struct wci_nc2nid_array { - uint64_t rsvd_z : 56; /* 63:8 */ - uint64_t no_stripe : 1; /* 7 */ - uint64_t encode_cluster_origin_tag : 1; /* 6 */ - uint64_t launch_remote : 1; /* 5 */ - uint64_t launch_local_sram : 1; /* 4 */ - uint64_t dest_node_id : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_nc2nid_array_u; - -#define wci_nc2nid_array_no_stripe \ - bit.no_stripe -#define wci_nc2nid_array_encode_cluster_origin_tag \ - bit.encode_cluster_origin_tag -#define wci_nc2nid_array_launch_remote \ - bit.launch_remote -#define wci_nc2nid_array_launch_local_sram \ - bit.launch_local_sram -#define wci_nc2nid_array_dest_node_id \ - bit.dest_node_id - - -/* - * wci_sfi_transid_alloc - */ -typedef union { - struct wci_sfi_transid_alloc { - uint64_t rsvd_z : 33; /* 63:31 */ - uint64_t targid_available : 15; /* 30:16 */ - uint64_t atransid_available : 15; /* 15:1 */ - uint64_t rsvd_y : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sfi_transid_alloc_u; - -#define wci_sfi_transid_alloc_targid_available \ - bit.targid_available -#define wci_sfi_transid_alloc_atransid_available \ - bit.atransid_available - - -/* - * wci_sfi_esr - */ -typedef union { - struct wci_sfi_esr { - uint64_t rsvd_z : 38; /* 63:26 */ - uint64_t acc_targid_timeout : 1; /* 25 */ - uint64_t acc_nc2nid_misconfig : 1; /* 24 */ - uint64_t acc_addr_pty : 1; /* 23 */ - uint64_t acc_incoming_prereq_conflict : 1; /* 22 */ - uint64_t acc_modcam_clr_set_conflict : 1; /* 21 */ - uint64_t acc_modcam_multi_hit : 1; /* 20 */ - uint64_t acc_modcam_set_set : 1; /* 19 */ - uint64_t acc_unexpected_incoming : 1; /* 18 */ - uint64_t acc_unexpected_targarbgnt : 1; /* 17 */ - uint64_t acc_transid_unalloc_released : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 5; /* 14:10 */ - uint64_t targid_timeout : 1; /* 9 */ - uint64_t nc2nid_misconfig : 1; /* 8 */ - uint64_t addr_pty : 1; /* 7 */ - uint64_t incoming_prereq_conflict : 1; /* 6 */ - uint64_t modcam_clr_set_conflict : 1; /* 5 */ - uint64_t modcam_multi_hit : 1; /* 4 */ - uint64_t modcam_set_set : 1; /* 3 */ - uint64_t unexpected_incoming : 1; /* 2 */ - uint64_t unexpected_targarbgnt : 1; /* 1 */ - uint64_t transid_unalloc_released : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sfi_esr_u; - -#define wci_sfi_esr_acc_targid_timeout \ - bit.acc_targid_timeout -#define wci_sfi_esr_acc_nc2nid_misconfig \ - bit.acc_nc2nid_misconfig -#define wci_sfi_esr_acc_addr_pty \ - bit.acc_addr_pty -#define wci_sfi_esr_acc_incoming_prereq_conflict \ - bit.acc_incoming_prereq_conflict -#define wci_sfi_esr_acc_modcam_clr_set_conflict \ - bit.acc_modcam_clr_set_conflict -#define wci_sfi_esr_acc_modcam_multi_hit \ - bit.acc_modcam_multi_hit -#define wci_sfi_esr_acc_modcam_set_set \ - bit.acc_modcam_set_set -#define wci_sfi_esr_acc_unexpected_incoming \ - bit.acc_unexpected_incoming -#define wci_sfi_esr_acc_unexpected_targarbgnt \ - bit.acc_unexpected_targarbgnt -#define wci_sfi_esr_acc_transid_unalloc_released \ - bit.acc_transid_unalloc_released -#define wci_sfi_esr_first_error \ - bit.first_error -#define wci_sfi_esr_targid_timeout \ - bit.targid_timeout -#define wci_sfi_esr_nc2nid_misconfig \ - bit.nc2nid_misconfig -#define wci_sfi_esr_addr_pty \ - bit.addr_pty -#define wci_sfi_esr_incoming_prereq_conflict \ - bit.incoming_prereq_conflict -#define wci_sfi_esr_modcam_clr_set_conflict \ - bit.modcam_clr_set_conflict -#define wci_sfi_esr_modcam_multi_hit \ - bit.modcam_multi_hit -#define wci_sfi_esr_modcam_set_set \ - bit.modcam_set_set -#define wci_sfi_esr_unexpected_incoming \ - bit.unexpected_incoming -#define wci_sfi_esr_unexpected_targarbgnt \ - bit.unexpected_targarbgnt -#define wci_sfi_esr_transid_unalloc_released \ - bit.transid_unalloc_released - - -/* - * wci_sfi_esr_mask - */ -typedef union { - struct wci_sfi_esr_mask { - uint64_t rsvd_z : 54; /* 63:10 */ - uint64_t targid_timeout : 1; /* 9 */ - uint64_t nc2nid_misconfig : 1; /* 8 */ - uint64_t addr_pty : 1; /* 7 */ - uint64_t incoming_prereq_conflict : 1; /* 6 */ - uint64_t modcam_clr_set_conflict : 1; /* 5 */ - uint64_t modcam_multi_hit : 1; /* 4 */ - uint64_t modcam_set_set : 1; /* 3 */ - uint64_t unexpected_incoming : 1; /* 2 */ - uint64_t unexpected_targarbgnt : 1; /* 1 */ - uint64_t transid_unalloc_released : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sfi_esr_mask_u; - -#define wci_sfi_esr_mask_targid_timeout \ - bit.targid_timeout -#define wci_sfi_esr_mask_nc2nid_misconfig \ - bit.nc2nid_misconfig -#define wci_sfi_esr_mask_addr_pty \ - bit.addr_pty -#define wci_sfi_esr_mask_incoming_prereq_conflict \ - bit.incoming_prereq_conflict -#define wci_sfi_esr_mask_modcam_clr_set_conflict \ - bit.modcam_clr_set_conflict -#define wci_sfi_esr_mask_modcam_multi_hit \ - bit.modcam_multi_hit -#define wci_sfi_esr_mask_modcam_set_set \ - bit.modcam_set_set -#define wci_sfi_esr_mask_unexpected_incoming \ - bit.unexpected_incoming -#define wci_sfi_esr_mask_unexpected_targarbgnt \ - bit.unexpected_targarbgnt -#define wci_sfi_esr_mask_transid_unalloc_released \ - bit.transid_unalloc_released - - -/* - * wci_sfi_state - */ -typedef union { - struct wci_sfi_state { - uint64_t rsvd_z : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t rsvd_y : 10; /* 58:49 */ - uint64_t wci_issued : 1; /* 48 */ - uint64_t agent_id : 7; /* 47:41 */ - uint64_t modcam_index : 4; /* 40:37 */ - uint64_t modcam_addr : 31; /* 36:6 */ - uint64_t sf_cmd : 2; /* 5:4 */ - uint64_t sf_mask_3_to_0 : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_sfi_state_u; - -#define wci_sfi_state_esr_index \ - bit.esr_index -#define wci_sfi_state_wci_issued \ - bit.wci_issued -#define wci_sfi_state_agent_id \ - bit.agent_id -#define wci_sfi_state_modcam_index \ - bit.modcam_index -#define wci_sfi_state_modcam_addr \ - bit.modcam_addr -#define wci_sfi_state_sf_cmd \ - bit.sf_cmd -#define wci_sfi_state_sf_mask_3_to_0 \ - bit.sf_mask_3_to_0 - - -/* - * wci_sfi_state1 - */ -typedef union { - struct wci_sfi_state1 { - uint64_t rsvd_z : 1; /* 63 */ - uint64_t esr_index : 4; /* 62:59 */ - uint64_t rsvd_y : 8; /* 58:51 */ - uint64_t unalloc_release_agents : 5; /* 50:46 */ - uint64_t unalloc_targids_released : 15; /* 45:31 */ - uint64_t unalloc_atransids_released : 15; /* 30:16 */ - uint64_t nc2nid_index : 8; /* 15:8 */ - uint64_t nc2nid_data : 8; /* 7:0 */ - } bit; - uint64_t val; -} wci_sfi_state1_u; - -#define wci_sfi_state1_esr_index \ - bit.esr_index -#define wci_sfi_state1_unalloc_release_agents \ - bit.unalloc_release_agents -#define wci_sfi_state1_unalloc_targids_released \ - bit.unalloc_targids_released -#define wci_sfi_state1_unalloc_atransids_released \ - bit.unalloc_atransids_released -#define wci_sfi_state1_nc2nid_index \ - bit.nc2nid_index -#define wci_sfi_state1_nc2nid_data \ - bit.nc2nid_data - - -/* - * wci_sfi_ctr1_mask - */ -typedef union { - struct wci_sfi_ctr1_mask { - uint64_t rsvd_z : 6; /* 63:58 */ - uint64_t mask : 10; /* 57:48 */ - uint64_t atransid : 9; /* 47:39 */ - uint64_t address : 39; /* 38:0 */ - } bit; - uint64_t val; -} wci_sfi_ctr1_mask_u; - -#define wci_sfi_ctr1_mask_mask \ - bit.mask -#define wci_sfi_ctr1_mask_atransid \ - bit.atransid -#define wci_sfi_ctr1_mask_address \ - bit.address - - -/* - * wci_sfi_ctr1_match_transaction - */ -typedef union { - struct wci_sfi_ctr1_match_transaction { - uint64_t rsvd_z : 45; /* 63:19 */ - uint64_t rts : 1; /* 18 */ - uint64_t rto : 1; /* 17 */ - uint64_t rs : 1; /* 16 */ - uint64_t ws : 1; /* 15 */ - uint64_t rtsr : 1; /* 14 */ - uint64_t rtor : 1; /* 13 */ - uint64_t rsr : 1; /* 12 */ - uint64_t wb : 1; /* 11 */ - uint64_t rtsm : 1; /* 10 */ - uint64_t interrupt : 1; /* 9 */ - uint64_t r_rts : 1; /* 8 */ - uint64_t r_rto : 1; /* 7 */ - uint64_t r_rs : 1; /* 6 */ - uint64_t r_ws : 1; /* 5 */ - uint64_t r_wb : 1; /* 4 */ - uint64_t rbio : 1; /* 3 */ - uint64_t rio : 1; /* 2 */ - uint64_t wbio : 1; /* 1 */ - uint64_t wio : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sfi_ctr1_match_transaction_u; - -#define wci_sfi_ctr1_match_transaction_rts \ - bit.rts -#define wci_sfi_ctr1_match_transaction_rto \ - bit.rto -#define wci_sfi_ctr1_match_transaction_rs \ - bit.rs -#define wci_sfi_ctr1_match_transaction_ws \ - bit.ws -#define wci_sfi_ctr1_match_transaction_rtsr \ - bit.rtsr -#define wci_sfi_ctr1_match_transaction_rtor \ - bit.rtor -#define wci_sfi_ctr1_match_transaction_rsr \ - bit.rsr -#define wci_sfi_ctr1_match_transaction_wb \ - bit.wb -#define wci_sfi_ctr1_match_transaction_rtsm \ - bit.rtsm -#define wci_sfi_ctr1_match_transaction_interrupt \ - bit.interrupt -#define wci_sfi_ctr1_match_transaction_r_rts \ - bit.r_rts -#define wci_sfi_ctr1_match_transaction_r_rto \ - bit.r_rto -#define wci_sfi_ctr1_match_transaction_r_rs \ - bit.r_rs -#define wci_sfi_ctr1_match_transaction_r_ws \ - bit.r_ws -#define wci_sfi_ctr1_match_transaction_r_wb \ - bit.r_wb -#define wci_sfi_ctr1_match_transaction_rbio \ - bit.rbio -#define wci_sfi_ctr1_match_transaction_rio \ - bit.rio -#define wci_sfi_ctr1_match_transaction_wbio \ - bit.wbio -#define wci_sfi_ctr1_match_transaction_wio \ - bit.wio - - -/* - * wci_sfi_ctr1_match - */ -typedef union { - struct wci_sfi_ctr1_match { - uint64_t rsvd_z : 6; /* 63:58 */ - uint64_t mask : 10; /* 57:48 */ - uint64_t atransid : 9; /* 47:39 */ - uint64_t address : 39; /* 38:0 */ - } bit; - uint64_t val; -} wci_sfi_ctr1_match_u; - -#define wci_sfi_ctr1_match_mask \ - bit.mask -#define wci_sfi_ctr1_match_atransid \ - bit.atransid -#define wci_sfi_ctr1_match_address \ - bit.address - - -/* - * wci_sfi_ctr0_mask - */ -typedef union { - struct wci_sfi_ctr0_mask { - uint64_t rsvd_z : 6; /* 63:58 */ - uint64_t mask : 10; /* 57:48 */ - uint64_t atransid : 9; /* 47:39 */ - uint64_t address : 39; /* 38:0 */ - } bit; - uint64_t val; -} wci_sfi_ctr0_mask_u; - -#define wci_sfi_ctr0_mask_mask \ - bit.mask -#define wci_sfi_ctr0_mask_atransid \ - bit.atransid -#define wci_sfi_ctr0_mask_address \ - bit.address - - -/* - * wci_sfi_ctr0_match_transaction - */ -typedef union { - struct wci_sfi_ctr0_match_transaction { - uint64_t rsvd_z : 45; /* 63:19 */ - uint64_t rts : 1; /* 18 */ - uint64_t rto : 1; /* 17 */ - uint64_t rs : 1; /* 16 */ - uint64_t ws : 1; /* 15 */ - uint64_t rtsr : 1; /* 14 */ - uint64_t rtor : 1; /* 13 */ - uint64_t rsr : 1; /* 12 */ - uint64_t wb : 1; /* 11 */ - uint64_t rtsm : 1; /* 10 */ - uint64_t interrupt : 1; /* 9 */ - uint64_t r_rts : 1; /* 8 */ - uint64_t r_rto : 1; /* 7 */ - uint64_t r_rs : 1; /* 6 */ - uint64_t r_ws : 1; /* 5 */ - uint64_t r_wb : 1; /* 4 */ - uint64_t rbio : 1; /* 3 */ - uint64_t rio : 1; /* 2 */ - uint64_t wbio : 1; /* 1 */ - uint64_t wio : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sfi_ctr0_match_transaction_u; - -#define wci_sfi_ctr0_match_transaction_rts \ - bit.rts -#define wci_sfi_ctr0_match_transaction_rto \ - bit.rto -#define wci_sfi_ctr0_match_transaction_rs \ - bit.rs -#define wci_sfi_ctr0_match_transaction_ws \ - bit.ws -#define wci_sfi_ctr0_match_transaction_rtsr \ - bit.rtsr -#define wci_sfi_ctr0_match_transaction_rtor \ - bit.rtor -#define wci_sfi_ctr0_match_transaction_rsr \ - bit.rsr -#define wci_sfi_ctr0_match_transaction_wb \ - bit.wb -#define wci_sfi_ctr0_match_transaction_rtsm \ - bit.rtsm -#define wci_sfi_ctr0_match_transaction_interrupt \ - bit.interrupt -#define wci_sfi_ctr0_match_transaction_r_rts \ - bit.r_rts -#define wci_sfi_ctr0_match_transaction_r_rto \ - bit.r_rto -#define wci_sfi_ctr0_match_transaction_r_rs \ - bit.r_rs -#define wci_sfi_ctr0_match_transaction_r_ws \ - bit.r_ws -#define wci_sfi_ctr0_match_transaction_r_wb \ - bit.r_wb -#define wci_sfi_ctr0_match_transaction_rbio \ - bit.rbio -#define wci_sfi_ctr0_match_transaction_rio \ - bit.rio -#define wci_sfi_ctr0_match_transaction_wbio \ - bit.wbio -#define wci_sfi_ctr0_match_transaction_wio \ - bit.wio - - -/* - * wci_sfi_ctr0_match - */ -typedef union { - struct wci_sfi_ctr0_match { - uint64_t rsvd_z : 6; /* 63:58 */ - uint64_t mask : 10; /* 57:48 */ - uint64_t atransid : 9; /* 47:39 */ - uint64_t address : 39; /* 38:0 */ - } bit; - uint64_t val; -} wci_sfi_ctr0_match_u; - -#define wci_sfi_ctr0_match_mask \ - bit.mask -#define wci_sfi_ctr0_match_atransid \ - bit.atransid -#define wci_sfi_ctr0_match_address \ - bit.address - - -/* - * wci_sfi_analyzer - */ -typedef union { - struct wci_sfi_analyzer { - uint64_t valid : 1; /* 63 */ - uint64_t in_use : 1; /* 62 */ - uint64_t shared : 1; /* 61 */ - uint64_t owned : 1; /* 60 */ - uint64_t mapped : 1; /* 59 */ - uint64_t overflow : 6; /* 58:53 */ - uint64_t address : 39; /* 52:14 */ - uint64_t mask : 4; /* 13:10 */ - uint64_t command : 1; /* 9 */ - uint64_t atransid : 9; /* 8:0 */ - } bit; - uint64_t val; -} wci_sfi_analyzer_u; - -#define wci_sfi_analyzer_valid \ - bit.valid -#define wci_sfi_analyzer_in_use \ - bit.in_use -#define wci_sfi_analyzer_shared \ - bit.shared -#define wci_sfi_analyzer_owned \ - bit.owned -#define wci_sfi_analyzer_mapped \ - bit.mapped -#define wci_sfi_analyzer_overflow \ - bit.overflow -#define wci_sfi_analyzer_address \ - bit.address -#define wci_sfi_analyzer_mask \ - bit.mask -#define wci_sfi_analyzer_command \ - bit.command -#define wci_sfi_analyzer_atransid \ - bit.atransid - - -/* - * wci_sfi_route_map0 - */ -typedef union { - struct wci_sfi_route_map0 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_sfi_route_map0_u; - -#define wci_sfi_route_map0_node15_tlink \ - bit.node15_tlink -#define wci_sfi_route_map0_node14_tlink \ - bit.node14_tlink -#define wci_sfi_route_map0_node13_tlink \ - bit.node13_tlink -#define wci_sfi_route_map0_node12_tlink \ - bit.node12_tlink -#define wci_sfi_route_map0_node11_tlink \ - bit.node11_tlink -#define wci_sfi_route_map0_node10_tlink \ - bit.node10_tlink -#define wci_sfi_route_map0_node9_tlink \ - bit.node9_tlink -#define wci_sfi_route_map0_node8_tlink \ - bit.node8_tlink -#define wci_sfi_route_map0_node7_tlink \ - bit.node7_tlink -#define wci_sfi_route_map0_node6_tlink \ - bit.node6_tlink -#define wci_sfi_route_map0_node5_tlink \ - bit.node5_tlink -#define wci_sfi_route_map0_node4_tlink \ - bit.node4_tlink -#define wci_sfi_route_map0_node3_tlink \ - bit.node3_tlink -#define wci_sfi_route_map0_node2_tlink \ - bit.node2_tlink -#define wci_sfi_route_map0_node1_tlink \ - bit.node1_tlink -#define wci_sfi_route_map0_node0_tlink \ - bit.node0_tlink - - -/* - * wci_sfi_route_map1 - */ -typedef union { - struct wci_sfi_route_map1 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_sfi_route_map1_u; - -#define wci_sfi_route_map1_node15_tlink \ - bit.node15_tlink -#define wci_sfi_route_map1_node14_tlink \ - bit.node14_tlink -#define wci_sfi_route_map1_node13_tlink \ - bit.node13_tlink -#define wci_sfi_route_map1_node12_tlink \ - bit.node12_tlink -#define wci_sfi_route_map1_node11_tlink \ - bit.node11_tlink -#define wci_sfi_route_map1_node10_tlink \ - bit.node10_tlink -#define wci_sfi_route_map1_node9_tlink \ - bit.node9_tlink -#define wci_sfi_route_map1_node8_tlink \ - bit.node8_tlink -#define wci_sfi_route_map1_node7_tlink \ - bit.node7_tlink -#define wci_sfi_route_map1_node6_tlink \ - bit.node6_tlink -#define wci_sfi_route_map1_node5_tlink \ - bit.node5_tlink -#define wci_sfi_route_map1_node4_tlink \ - bit.node4_tlink -#define wci_sfi_route_map1_node3_tlink \ - bit.node3_tlink -#define wci_sfi_route_map1_node2_tlink \ - bit.node2_tlink -#define wci_sfi_route_map1_node1_tlink \ - bit.node1_tlink -#define wci_sfi_route_map1_node0_tlink \ - bit.node0_tlink - - -/* - * wci_qlim_sort_piq - */ -typedef union { - struct wci_qlim_sort_piq { - uint64_t rsvd_z : 32; /* 63:32 */ - uint64_t dev_id_vec : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_qlim_sort_piq_u; - -#define wci_qlim_sort_piq_dev_id_vec \ - bit.dev_id_vec - - -/* - * wci_qlim_sort_niq - */ -typedef union { - struct wci_qlim_sort_niq { - uint64_t rsvd_z : 32; /* 63:32 */ - uint64_t dev_id_vec : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_qlim_sort_niq_u; - -#define wci_qlim_sort_niq_dev_id_vec \ - bit.dev_id_vec - - -/* - * wci_qlim_sort_ciq - */ -typedef union { - struct wci_qlim_sort_ciq { - uint64_t rsvd_z : 32; /* 63:32 */ - uint64_t dev_id_vec : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_qlim_sort_ciq_u; - -#define wci_qlim_sort_ciq_dev_id_vec \ - bit.dev_id_vec - - -/* - * wci_link_esr - */ -typedef union { - struct wci_link_esr { - uint64_t rsvd_z : 40; /* 63:24 */ - uint64_t acc_link_2_illegal_gnid : 1; /* 23 */ - uint64_t acc_link_2_illegal_link : 1; /* 22 */ - uint64_t rsvd_y : 1; /* 21 */ - uint64_t acc_link_1_illegal_gnid : 1; /* 20 */ - uint64_t acc_link_1_illegal_link : 1; /* 19 */ - uint64_t rsvd_x : 1; /* 18 */ - uint64_t acc_link_0_illegal_gnid : 1; /* 17 */ - uint64_t acc_link_0_illegal_link : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_w : 7; /* 14:8 */ - uint64_t link_2_illegal_gnid : 1; /* 7 */ - uint64_t link_2_illegal_link : 1; /* 6 */ - uint64_t rsvd_v : 1; /* 5 */ - uint64_t link_1_illegal_gnid : 1; /* 4 */ - uint64_t link_1_illegal_link : 1; /* 3 */ - uint64_t rsvd_u : 1; /* 2 */ - uint64_t link_0_illegal_gnid : 1; /* 1 */ - uint64_t link_0_illegal_link : 1; /* 0 */ - } bit; - uint64_t val; -} wci_link_esr_u; - -#define wci_link_esr_acc_link_2_illegal_gnid \ - bit.acc_link_2_illegal_gnid -#define wci_link_esr_acc_link_2_illegal_link \ - bit.acc_link_2_illegal_link -#define wci_link_esr_acc_link_1_illegal_gnid \ - bit.acc_link_1_illegal_gnid -#define wci_link_esr_acc_link_1_illegal_link \ - bit.acc_link_1_illegal_link -#define wci_link_esr_acc_link_0_illegal_gnid \ - bit.acc_link_0_illegal_gnid -#define wci_link_esr_acc_link_0_illegal_link \ - bit.acc_link_0_illegal_link -#define wci_link_esr_first_error \ - bit.first_error -#define wci_link_esr_link_2_illegal_gnid \ - bit.link_2_illegal_gnid -#define wci_link_esr_link_2_illegal_link \ - bit.link_2_illegal_link -#define wci_link_esr_link_1_illegal_gnid \ - bit.link_1_illegal_gnid -#define wci_link_esr_link_1_illegal_link \ - bit.link_1_illegal_link -#define wci_link_esr_link_0_illegal_gnid \ - bit.link_0_illegal_gnid -#define wci_link_esr_link_0_illegal_link \ - bit.link_0_illegal_link - - -/* - * wci_link_esr_mask - */ -typedef union { - struct wci_link_esr_mask { - uint64_t rsvd_z : 56; /* 63:8 */ - uint64_t link_2_illegal_gnid : 1; /* 7 */ - uint64_t link_2_illegal_link : 1; /* 6 */ - uint64_t rsvd_y : 1; /* 5 */ - uint64_t link_1_illegal_gnid : 1; /* 4 */ - uint64_t link_1_illegal_link : 1; /* 3 */ - uint64_t rsvd_x : 1; /* 2 */ - uint64_t link_0_illegal_gnid : 1; /* 1 */ - uint64_t link_0_illegal_link : 1; /* 0 */ - } bit; - uint64_t val; -} wci_link_esr_mask_u; - -#define wci_link_esr_mask_link_2_illegal_gnid \ - bit.link_2_illegal_gnid -#define wci_link_esr_mask_link_2_illegal_link \ - bit.link_2_illegal_link -#define wci_link_esr_mask_link_1_illegal_gnid \ - bit.link_1_illegal_gnid -#define wci_link_esr_mask_link_1_illegal_link \ - bit.link_1_illegal_link -#define wci_link_esr_mask_link_0_illegal_gnid \ - bit.link_0_illegal_gnid -#define wci_link_esr_mask_link_0_illegal_link \ - bit.link_0_illegal_link - - -/* - * wci_sw_esr - */ -typedef union { - struct wci_sw_esr { - uint64_t rsvd_z : 36; /* 63:28 */ - uint64_t acc_link_2_failover : 1; /* 27 */ - uint64_t acc_link_1_failover : 1; /* 26 */ - uint64_t acc_link_0_failover : 1; /* 25 */ - uint64_t rsvd_y : 2; /* 24:23 */ - uint64_t acc_link_2_auto_shut : 1; /* 22 */ - uint64_t acc_link_1_auto_shut : 1; /* 21 */ - uint64_t acc_link_0_auto_shut : 1; /* 20 */ - uint64_t acc_addr_lpbk_illegal_gnid : 1; /* 19 */ - uint64_t acc_error_pause_broadcast : 1; /* 18 */ - uint64_t acc_addr_lpbk_fifo_ovf : 1; /* 17 */ - uint64_t acc_data_lpbk_fifo_ovf : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_x : 3; /* 14:12 */ - uint64_t link_2_failover : 1; /* 11 */ - uint64_t link_1_failover : 1; /* 10 */ - uint64_t link_0_failover : 1; /* 9 */ - uint64_t rsvd_w : 2; /* 8:7 */ - uint64_t link_2_auto_shut : 1; /* 6 */ - uint64_t link_1_auto_shut : 1; /* 5 */ - uint64_t link_0_auto_shut : 1; /* 4 */ - uint64_t addr_lpbk_illegal_gnid : 1; /* 3 */ - uint64_t error_pause_broadcast : 1; /* 2 */ - uint64_t addr_lpbk_fifo_ovf : 1; /* 1 */ - uint64_t data_lpbk_fifo_ovf : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sw_esr_u; - -#define wci_sw_esr_acc_link_2_failover \ - bit.acc_link_2_failover -#define wci_sw_esr_acc_link_1_failover \ - bit.acc_link_1_failover -#define wci_sw_esr_acc_link_0_failover \ - bit.acc_link_0_failover -#define wci_sw_esr_acc_link_2_auto_shut \ - bit.acc_link_2_auto_shut -#define wci_sw_esr_acc_link_1_auto_shut \ - bit.acc_link_1_auto_shut -#define wci_sw_esr_acc_link_0_auto_shut \ - bit.acc_link_0_auto_shut -#define wci_sw_esr_acc_addr_lpbk_illegal_gnid \ - bit.acc_addr_lpbk_illegal_gnid -#define wci_sw_esr_acc_error_pause_broadcast \ - bit.acc_error_pause_broadcast -#define wci_sw_esr_acc_addr_lpbk_fifo_ovf \ - bit.acc_addr_lpbk_fifo_ovf -#define wci_sw_esr_acc_data_lpbk_fifo_ovf \ - bit.acc_data_lpbk_fifo_ovf -#define wci_sw_esr_first_error \ - bit.first_error -#define wci_sw_esr_link_2_failover \ - bit.link_2_failover -#define wci_sw_esr_link_1_failover \ - bit.link_1_failover -#define wci_sw_esr_link_0_failover \ - bit.link_0_failover -#define wci_sw_esr_link_2_auto_shut \ - bit.link_2_auto_shut -#define wci_sw_esr_link_1_auto_shut \ - bit.link_1_auto_shut -#define wci_sw_esr_link_0_auto_shut \ - bit.link_0_auto_shut -#define wci_sw_esr_addr_lpbk_illegal_gnid \ - bit.addr_lpbk_illegal_gnid -#define wci_sw_esr_error_pause_broadcast \ - bit.error_pause_broadcast -#define wci_sw_esr_addr_lpbk_fifo_ovf \ - bit.addr_lpbk_fifo_ovf -#define wci_sw_esr_data_lpbk_fifo_ovf \ - bit.data_lpbk_fifo_ovf - - -/* - * wci_sw_esr_mask - */ -typedef union { - struct wci_sw_esr_mask { - uint64_t rsvd_z : 52; /* 63:12 */ - uint64_t link_2_failover : 1; /* 11 */ - uint64_t link_1_failover : 1; /* 10 */ - uint64_t link_0_failover : 1; /* 9 */ - uint64_t rsvd_y : 2; /* 8:7 */ - uint64_t link_2_auto_shut : 1; /* 6 */ - uint64_t link_1_auto_shut : 1; /* 5 */ - uint64_t link_0_auto_shut : 1; /* 4 */ - uint64_t addr_lpbk_illegal_gnid : 1; /* 3 */ - uint64_t error_pause_broadcast : 1; /* 2 */ - uint64_t addr_lpbk_fifo_ovf : 1; /* 1 */ - uint64_t data_lpbk_fifo_ovf : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sw_esr_mask_u; - -#define wci_sw_esr_mask_link_2_failover \ - bit.link_2_failover -#define wci_sw_esr_mask_link_1_failover \ - bit.link_1_failover -#define wci_sw_esr_mask_link_0_failover \ - bit.link_0_failover -#define wci_sw_esr_mask_link_2_auto_shut \ - bit.link_2_auto_shut -#define wci_sw_esr_mask_link_1_auto_shut \ - bit.link_1_auto_shut -#define wci_sw_esr_mask_link_0_auto_shut \ - bit.link_0_auto_shut -#define wci_sw_esr_mask_addr_lpbk_illegal_gnid \ - bit.addr_lpbk_illegal_gnid -#define wci_sw_esr_mask_error_pause_broadcast \ - bit.error_pause_broadcast -#define wci_sw_esr_mask_addr_lpbk_fifo_ovf \ - bit.addr_lpbk_fifo_ovf -#define wci_sw_esr_mask_data_lpbk_fifo_ovf \ - bit.data_lpbk_fifo_ovf - - -/* - * wci_sw_link_control - */ -typedef union { - struct wci_sw_link_control { - uint64_t rsvd_z : 9; /* 63:55 */ - uint64_t rexmit_freeze : 1; /* 54 */ - uint64_t rexmit_mag : 2; /* 53:52 */ - uint64_t rexmit_val : 8; /* 51:44 */ - uint64_t error_inducement : 2; /* 43:42 */ - uint64_t xmit_timeout : 8; /* 41:34 */ - uint64_t usr_data_2 : 2; /* 33:32 */ - uint64_t usr_data_1 : 16; /* 31:16 */ - uint64_t rsvd_y : 3; /* 15:13 */ - uint64_t xmit_enable : 1; /* 12 */ - uint64_t ustat_src : 2; /* 11:10 */ - uint64_t in_domain : 1; /* 9 */ - uint64_t paroli_tck_enable : 1; /* 8 */ - uint64_t laser_enable : 1; /* 7 */ - uint64_t rsvd_x : 1; /* 6 */ - uint64_t rexmit_shutdown_en : 1; /* 5 */ - uint64_t near_end_shutdown_lock : 1; /* 4 */ - uint64_t failover_en : 1; /* 3 */ - uint64_t auto_shut_en : 1; /* 2 */ - uint64_t link_state : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_sw_link_control_u; - -#define wci_sw_link_control_rexmit_freeze \ - bit.rexmit_freeze -#define wci_sw_link_control_rexmit_mag \ - bit.rexmit_mag -#define wci_sw_link_control_rexmit_val \ - bit.rexmit_val -#define wci_sw_link_control_error_inducement \ - bit.error_inducement -#define wci_sw_link_control_xmit_timeout \ - bit.xmit_timeout -#define wci_sw_link_control_usr_data_2 \ - bit.usr_data_2 -#define wci_sw_link_control_usr_data_1 \ - bit.usr_data_1 -#define wci_sw_link_control_xmit_enable \ - bit.xmit_enable -#define wci_sw_link_control_ustat_src \ - bit.ustat_src -#define wci_sw_link_control_in_domain \ - bit.in_domain -#define wci_sw_link_control_paroli_tck_enable \ - bit.paroli_tck_enable -#define wci_sw_link_control_laser_enable \ - bit.laser_enable -#define wci_sw_link_control_rexmit_shutdown_en \ - bit.rexmit_shutdown_en -#define wci_sw_link_control_near_end_shutdown_lock \ - bit.near_end_shutdown_lock -#define wci_sw_link_control_failover_en \ - bit.failover_en -#define wci_sw_link_control_auto_shut_en \ - bit.auto_shut_en -#define wci_sw_link_control_link_state \ - bit.link_state - - -/* - * wci_sw_link_error_count - */ -typedef union { - struct wci_sw_link_error_count { - uint64_t error_count : 24; /* 63:40 */ - uint64_t rsvd_z : 40; /* 39:0 */ - } bit; - uint64_t val; -} wci_sw_link_error_count_u; - -#define wci_sw_link_error_count_error_count \ - bit.error_count - - -/* - * wci_sw_link_status - */ -typedef union { - struct wci_sw_link_status { - uint64_t rsvd_z : 9; /* 63:55 */ - uint64_t paroli_present : 1; /* 54 */ - uint64_t bad_gnid : 4; /* 53:50 */ - uint64_t farend_ustat_2 : 2; /* 49:48 */ - uint64_t farend_ustat_1 : 16; /* 47:32 */ - uint64_t ustat_1 : 16; /* 31:16 */ - uint64_t shutdown_cause : 2; /* 15:14 */ - uint64_t got_fo_pkt : 1; /* 13 */ - uint64_t multiple_link_failover : 1; /* 12 */ - uint64_t failover_cause : 1; /* 11 */ - uint64_t link_idle : 1; /* 10 */ - uint64_t sync_locked : 1; /* 9 */ - uint64_t optical_signal_detect : 1; /* 8 */ - uint64_t reset_pending : 1; /* 7 */ - uint64_t framing_error : 1; /* 6 */ - uint64_t clocking_error : 1; /* 5 */ - uint64_t end_status : 2; /* 4:3 */ - uint64_t crc_error : 1; /* 2 */ - uint64_t rsvd_y : 1; /* 1 */ - uint64_t packets_discarded : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sw_link_status_u; - -#define wci_sw_link_status_paroli_present \ - bit.paroli_present -#define wci_sw_link_status_bad_gnid \ - bit.bad_gnid -#define wci_sw_link_status_farend_ustat_2 \ - bit.farend_ustat_2 -#define wci_sw_link_status_farend_ustat_1 \ - bit.farend_ustat_1 -#define wci_sw_link_status_ustat_1 \ - bit.ustat_1 -#define wci_sw_link_status_shutdown_cause \ - bit.shutdown_cause -#define wci_sw_link_status_got_fo_pkt \ - bit.got_fo_pkt -#define wci_sw_link_status_multiple_link_failover \ - bit.multiple_link_failover -#define wci_sw_link_status_failover_cause \ - bit.failover_cause -#define wci_sw_link_status_link_idle \ - bit.link_idle -#define wci_sw_link_status_sync_locked \ - bit.sync_locked -#define wci_sw_link_status_optical_signal_detect \ - bit.optical_signal_detect -#define wci_sw_link_status_reset_pending \ - bit.reset_pending -#define wci_sw_link_status_framing_error \ - bit.framing_error -#define wci_sw_link_status_clocking_error \ - bit.clocking_error -#define wci_sw_link_status_end_status \ - bit.end_status -#define wci_sw_link_status_crc_error \ - bit.crc_error -#define wci_sw_link_status_packets_discarded \ - bit.packets_discarded - - -/* - * wci_sw_config - */ -typedef union { - struct wci_sw_config { - uint64_t max_errors : 24; /* 63:40 */ - uint64_t rsvd_z : 23; /* 39:17 */ - uint64_t error_pause_shutdown_en : 1; /* 16 */ - uint64_t partner_gnid : 4; /* 15:12 */ - uint64_t gnid : 4; /* 11:8 */ - uint64_t failover_en : 1; /* 7 */ - uint64_t drop_illegal_gnid : 1; /* 6 */ - uint64_t sync_buffer_safety_level : 2; /* 5:4 */ - uint64_t mask_originate_broadcast : 1; /* 3 */ - uint64_t xmit_arb_policy : 2; /* 2:1 */ - uint64_t enable_dx_shortcut : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sw_config_u; - -#define wci_sw_config_max_errors \ - bit.max_errors -#define wci_sw_config_error_pause_shutdown_en \ - bit.error_pause_shutdown_en -#define wci_sw_config_partner_gnid \ - bit.partner_gnid -#define wci_sw_config_gnid \ - bit.gnid -#define wci_sw_config_failover_en \ - bit.failover_en -#define wci_sw_config_drop_illegal_gnid \ - bit.drop_illegal_gnid -#define wci_sw_config_sync_buffer_safety_level \ - bit.sync_buffer_safety_level -#define wci_sw_config_mask_originate_broadcast \ - bit.mask_originate_broadcast -#define wci_sw_config_xmit_arb_policy \ - bit.xmit_arb_policy -#define wci_sw_config_enable_dx_shortcut \ - bit.enable_dx_shortcut - - -/* - * wci_sw_status - */ -typedef union { - struct wci_sw_status { - uint64_t rsvd_z : 55; /* 63:9 */ - uint64_t addr_lpbk_illegal_gnid : 4; /* 8:5 */ - uint64_t error_pause_broadcast_status : 3; /* 4:2 */ - uint64_t originate : 1; /* 1 */ - uint64_t local_source : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sw_status_u; - -#define wci_sw_status_addr_lpbk_illegal_gnid \ - bit.addr_lpbk_illegal_gnid -#define wci_sw_status_error_pause_broadcast_status \ - bit.error_pause_broadcast_status -#define wci_sw_status_originate \ - bit.originate -#define wci_sw_status_local_source \ - bit.local_source - - -/* - * wci_link_ctr_ctl - */ -typedef union { - struct wci_link_ctr_ctl { - uint64_t rsvd_z : 33; /* 63:31 */ - uint64_t cnt1_source_select : 2; /* 30:29 */ - uint64_t cnt1_gnid_target : 4; /* 28:25 */ - uint64_t cnt1_snid_target : 4; /* 24:21 */ - uint64_t cnt1_rcvd_admin_packet : 1; /* 20 */ - uint64_t cnt1_rejected_normal_flit : 1; /* 19 */ - uint64_t cnt1_data_rcvd_data_packet : 1; /* 18 */ - uint64_t cnt1_mhop_rcvd_data_packet : 1; /* 17 */ - uint64_t cnt1_xmitting_admin_packet : 1; /* 16 */ - uint64_t rsvd_y : 1; /* 15 */ - uint64_t cnt0_source_select : 2; /* 14:13 */ - uint64_t cnt0_gnid_target : 4; /* 12:9 */ - uint64_t cnt0_snid_target : 4; /* 8:5 */ - uint64_t cnt0_rcvd_admin_packet : 1; /* 4 */ - uint64_t cnt0_rejected_normal_flit : 1; /* 3 */ - uint64_t cnt0_data_rcvd_data_packet : 1; /* 2 */ - uint64_t cnt0_mhop_rcvd_data_packet : 1; /* 1 */ - uint64_t cnt0_xmitting_admin_packet : 1; /* 0 */ - } bit; - uint64_t val; -} wci_link_ctr_ctl_u; - -#define wci_link_ctr_ctl_cnt1_source_select \ - bit.cnt1_source_select -#define wci_link_ctr_ctl_cnt1_gnid_target \ - bit.cnt1_gnid_target -#define wci_link_ctr_ctl_cnt1_snid_target \ - bit.cnt1_snid_target -#define wci_link_ctr_ctl_cnt1_rcvd_admin_packet \ - bit.cnt1_rcvd_admin_packet -#define wci_link_ctr_ctl_cnt1_rejected_normal_flit \ - bit.cnt1_rejected_normal_flit -#define wci_link_ctr_ctl_cnt1_data_rcvd_data_packet \ - bit.cnt1_data_rcvd_data_packet -#define wci_link_ctr_ctl_cnt1_mhop_rcvd_data_packet \ - bit.cnt1_mhop_rcvd_data_packet -#define wci_link_ctr_ctl_cnt1_xmitting_admin_packet \ - bit.cnt1_xmitting_admin_packet -#define wci_link_ctr_ctl_cnt0_source_select \ - bit.cnt0_source_select -#define wci_link_ctr_ctl_cnt0_gnid_target \ - bit.cnt0_gnid_target -#define wci_link_ctr_ctl_cnt0_snid_target \ - bit.cnt0_snid_target -#define wci_link_ctr_ctl_cnt0_rcvd_admin_packet \ - bit.cnt0_rcvd_admin_packet -#define wci_link_ctr_ctl_cnt0_rejected_normal_flit \ - bit.cnt0_rejected_normal_flit -#define wci_link_ctr_ctl_cnt0_data_rcvd_data_packet \ - bit.cnt0_data_rcvd_data_packet -#define wci_link_ctr_ctl_cnt0_mhop_rcvd_data_packet \ - bit.cnt0_mhop_rcvd_data_packet -#define wci_link_ctr_ctl_cnt0_xmitting_admin_packet \ - bit.cnt0_xmitting_admin_packet - - -/* - * wci_lpbk_ctr_ctl - */ -typedef union { - struct wci_lpbk_ctr_ctl { - uint64_t rsvd_z : 38; /* 63:26 */ - uint64_t cnt1_data_gnid_source_select : 1; /* 25 */ - uint64_t cnt1_data_gnid_target : 4; /* 24:21 */ - uint64_t cnt1_addr_lpbk_full : 1; /* 20 */ - uint64_t cnt1_data_lpbk_full : 1; /* 19 */ - uint64_t cnt1_addr_lpbk_rcvd_addr_1_packet : 1; /* 18 */ - uint64_t cnt1_addr_lpbk_rcvd_addr_2_packet : 1; /* 17 */ - uint64_t cnt1_data_lpbk_rcvd_data_packet : 1; /* 16 */ - uint64_t rsvd_y : 6; /* 15:10 */ - uint64_t cnt0_data_gnid_source_select : 1; /* 9 */ - uint64_t cnt0_data_gnid_target : 4; /* 8:5 */ - uint64_t cnt0_addr_lpbk_full : 1; /* 4 */ - uint64_t cnt0_data_lpbk_full : 1; /* 3 */ - uint64_t cnt0_addr_lpbk_rcvd_addr_1_packet : 1; /* 2 */ - uint64_t cnt0_addr_lpbk_rcvd_addr_2_packet : 1; /* 1 */ - uint64_t cnt0_data_lpbk_rcvd_data_packet : 1; /* 0 */ - } bit; - uint64_t val; -} wci_lpbk_ctr_ctl_u; - -#define wci_lpbk_ctr_ctl_cnt1_data_gnid_source_select \ - bit.cnt1_data_gnid_source_select -#define wci_lpbk_ctr_ctl_cnt1_data_gnid_target \ - bit.cnt1_data_gnid_target -#define wci_lpbk_ctr_ctl_cnt1_addr_lpbk_full \ - bit.cnt1_addr_lpbk_full -#define wci_lpbk_ctr_ctl_cnt1_data_lpbk_full \ - bit.cnt1_data_lpbk_full -#define wci_lpbk_ctr_ctl_cnt1_addr_lpbk_rcvd_addr_1_packet \ - bit.cnt1_addr_lpbk_rcvd_addr_1_packet -#define wci_lpbk_ctr_ctl_cnt1_addr_lpbk_rcvd_addr_2_packet \ - bit.cnt1_addr_lpbk_rcvd_addr_2_packet -#define wci_lpbk_ctr_ctl_cnt1_data_lpbk_rcvd_data_packet \ - bit.cnt1_data_lpbk_rcvd_data_packet -#define wci_lpbk_ctr_ctl_cnt0_data_gnid_source_select \ - bit.cnt0_data_gnid_source_select -#define wci_lpbk_ctr_ctl_cnt0_data_gnid_target \ - bit.cnt0_data_gnid_target -#define wci_lpbk_ctr_ctl_cnt0_addr_lpbk_full \ - bit.cnt0_addr_lpbk_full -#define wci_lpbk_ctr_ctl_cnt0_data_lpbk_full \ - bit.cnt0_data_lpbk_full -#define wci_lpbk_ctr_ctl_cnt0_addr_lpbk_rcvd_addr_1_packet \ - bit.cnt0_addr_lpbk_rcvd_addr_1_packet -#define wci_lpbk_ctr_ctl_cnt0_addr_lpbk_rcvd_addr_2_packet \ - bit.cnt0_addr_lpbk_rcvd_addr_2_packet -#define wci_lpbk_ctr_ctl_cnt0_data_lpbk_rcvd_data_packet \ - bit.cnt0_data_lpbk_rcvd_data_packet - - -/* - * wci_link_ctr - */ -typedef union { - struct wci_link_ctr { - uint64_t cnt1 : 32; /* 63:32 */ - uint64_t cnt0 : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_link_ctr_u; - -#define wci_link_ctr_cnt1 \ - bit.cnt1 -#define wci_link_ctr_cnt0 \ - bit.cnt0 - - -/* - * wci_lpbk_ctr - */ -typedef union { - struct wci_lpbk_ctr { - uint64_t cnt1 : 32; /* 63:32 */ - uint64_t cnt0 : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_lpbk_ctr_u; - -#define wci_lpbk_ctr_cnt1 \ - bit.cnt1 -#define wci_lpbk_ctr_cnt0 \ - bit.cnt0 - - -/* - * wci_sw_esr_a - */ -typedef union { - struct wci_sw_esr_a { - uint64_t rsvd_z : 46; /* 63:18 */ - uint64_t acc_fo_b_fifo_ovf : 1; /* 17 */ - uint64_t acc_fo_a_fifo_ovf : 1; /* 16 */ - uint64_t first_error : 1; /* 15 */ - uint64_t rsvd_y : 13; /* 14:2 */ - uint64_t fo_b_fifo_ovf : 1; /* 1 */ - uint64_t fo_a_fifo_ovf : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sw_esr_a_u; - -#define wci_sw_esr_a_acc_fo_b_fifo_ovf \ - bit.acc_fo_b_fifo_ovf -#define wci_sw_esr_a_acc_fo_a_fifo_ovf \ - bit.acc_fo_a_fifo_ovf -#define wci_sw_esr_a_first_error \ - bit.first_error -#define wci_sw_esr_a_fo_b_fifo_ovf \ - bit.fo_b_fifo_ovf -#define wci_sw_esr_a_fo_a_fifo_ovf \ - bit.fo_a_fifo_ovf - - -/* - * wci_sw_esr_a_mask - */ -typedef union { - struct wci_sw_esr_a_mask { - uint64_t rsvd_z : 62; /* 63:2 */ - uint64_t fo_b_fifo_ovf : 1; /* 1 */ - uint64_t fo_a_fifo_ovf : 1; /* 0 */ - } bit; - uint64_t val; -} wci_sw_esr_a_mask_u; - -#define wci_sw_esr_a_mask_fo_b_fifo_ovf \ - bit.fo_b_fifo_ovf -#define wci_sw_esr_a_mask_fo_a_fifo_ovf \ - bit.fo_a_fifo_ovf - - -/* - * wci_gnid_map0 - */ -typedef union { - struct wci_gnid_map0 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_gnid_map0_u; - -#define wci_gnid_map0_node15_tlink \ - bit.node15_tlink -#define wci_gnid_map0_node14_tlink \ - bit.node14_tlink -#define wci_gnid_map0_node13_tlink \ - bit.node13_tlink -#define wci_gnid_map0_node12_tlink \ - bit.node12_tlink -#define wci_gnid_map0_node11_tlink \ - bit.node11_tlink -#define wci_gnid_map0_node10_tlink \ - bit.node10_tlink -#define wci_gnid_map0_node9_tlink \ - bit.node9_tlink -#define wci_gnid_map0_node8_tlink \ - bit.node8_tlink -#define wci_gnid_map0_node7_tlink \ - bit.node7_tlink -#define wci_gnid_map0_node6_tlink \ - bit.node6_tlink -#define wci_gnid_map0_node5_tlink \ - bit.node5_tlink -#define wci_gnid_map0_node4_tlink \ - bit.node4_tlink -#define wci_gnid_map0_node3_tlink \ - bit.node3_tlink -#define wci_gnid_map0_node2_tlink \ - bit.node2_tlink -#define wci_gnid_map0_node1_tlink \ - bit.node1_tlink -#define wci_gnid_map0_node0_tlink \ - bit.node0_tlink - - -/* - * wci_gnid_map1 - */ -typedef union { - struct wci_gnid_map1 { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_gnid_map1_u; - -#define wci_gnid_map1_node15_tlink \ - bit.node15_tlink -#define wci_gnid_map1_node14_tlink \ - bit.node14_tlink -#define wci_gnid_map1_node13_tlink \ - bit.node13_tlink -#define wci_gnid_map1_node12_tlink \ - bit.node12_tlink -#define wci_gnid_map1_node11_tlink \ - bit.node11_tlink -#define wci_gnid_map1_node10_tlink \ - bit.node10_tlink -#define wci_gnid_map1_node9_tlink \ - bit.node9_tlink -#define wci_gnid_map1_node8_tlink \ - bit.node8_tlink -#define wci_gnid_map1_node7_tlink \ - bit.node7_tlink -#define wci_gnid_map1_node6_tlink \ - bit.node6_tlink -#define wci_gnid_map1_node5_tlink \ - bit.node5_tlink -#define wci_gnid_map1_node4_tlink \ - bit.node4_tlink -#define wci_gnid_map1_node3_tlink \ - bit.node3_tlink -#define wci_gnid_map1_node2_tlink \ - bit.node2_tlink -#define wci_gnid_map1_node1_tlink \ - bit.node1_tlink -#define wci_gnid_map1_node0_tlink \ - bit.node0_tlink - - -/* - * wci_fo_route_map - */ -typedef union { - struct wci_fo_route_map { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_fo_route_map_u; - -#define wci_fo_route_map_node15_tlink \ - bit.node15_tlink -#define wci_fo_route_map_node14_tlink \ - bit.node14_tlink -#define wci_fo_route_map_node13_tlink \ - bit.node13_tlink -#define wci_fo_route_map_node12_tlink \ - bit.node12_tlink -#define wci_fo_route_map_node11_tlink \ - bit.node11_tlink -#define wci_fo_route_map_node10_tlink \ - bit.node10_tlink -#define wci_fo_route_map_node9_tlink \ - bit.node9_tlink -#define wci_fo_route_map_node8_tlink \ - bit.node8_tlink -#define wci_fo_route_map_node7_tlink \ - bit.node7_tlink -#define wci_fo_route_map_node6_tlink \ - bit.node6_tlink -#define wci_fo_route_map_node5_tlink \ - bit.node5_tlink -#define wci_fo_route_map_node4_tlink \ - bit.node4_tlink -#define wci_fo_route_map_node3_tlink \ - bit.node3_tlink -#define wci_fo_route_map_node2_tlink \ - bit.node2_tlink -#define wci_fo_route_map_node1_tlink \ - bit.node1_tlink -#define wci_fo_route_map_node0_tlink \ - bit.node0_tlink - - -/* - * wci_sec_fo_route_map - */ -typedef union { - struct wci_sec_fo_route_map { - uint64_t rsvd_z : 17; /* 63:47 */ - uint64_t node15_tlink : 2; /* 46:45 */ - uint64_t rsvd_y : 1; /* 44 */ - uint64_t node14_tlink : 2; /* 43:42 */ - uint64_t rsvd_x : 1; /* 41 */ - uint64_t node13_tlink : 2; /* 40:39 */ - uint64_t rsvd_w : 1; /* 38 */ - uint64_t node12_tlink : 2; /* 37:36 */ - uint64_t rsvd_v : 1; /* 35 */ - uint64_t node11_tlink : 2; /* 34:33 */ - uint64_t rsvd_u : 1; /* 32 */ - uint64_t node10_tlink : 2; /* 31:30 */ - uint64_t rsvd_t : 1; /* 29 */ - uint64_t node9_tlink : 2; /* 28:27 */ - uint64_t rsvd_s : 1; /* 26 */ - uint64_t node8_tlink : 2; /* 25:24 */ - uint64_t rsvd_r : 1; /* 23 */ - uint64_t node7_tlink : 2; /* 22:21 */ - uint64_t rsvd_q : 1; /* 20 */ - uint64_t node6_tlink : 2; /* 19:18 */ - uint64_t rsvd_p : 1; /* 17 */ - uint64_t node5_tlink : 2; /* 16:15 */ - uint64_t rsvd_o : 1; /* 14 */ - uint64_t node4_tlink : 2; /* 13:12 */ - uint64_t rsvd_n : 1; /* 11 */ - uint64_t node3_tlink : 2; /* 10:9 */ - uint64_t rsvd_m : 1; /* 8 */ - uint64_t node2_tlink : 2; /* 7:6 */ - uint64_t rsvd_l : 1; /* 5 */ - uint64_t node1_tlink : 2; /* 4:3 */ - uint64_t rsvd_k : 1; /* 2 */ - uint64_t node0_tlink : 2; /* 1:0 */ - } bit; - uint64_t val; -} wci_sec_fo_route_map_u; - -#define wci_sec_fo_route_map_node15_tlink \ - bit.node15_tlink -#define wci_sec_fo_route_map_node14_tlink \ - bit.node14_tlink -#define wci_sec_fo_route_map_node13_tlink \ - bit.node13_tlink -#define wci_sec_fo_route_map_node12_tlink \ - bit.node12_tlink -#define wci_sec_fo_route_map_node11_tlink \ - bit.node11_tlink -#define wci_sec_fo_route_map_node10_tlink \ - bit.node10_tlink -#define wci_sec_fo_route_map_node9_tlink \ - bit.node9_tlink -#define wci_sec_fo_route_map_node8_tlink \ - bit.node8_tlink -#define wci_sec_fo_route_map_node7_tlink \ - bit.node7_tlink -#define wci_sec_fo_route_map_node6_tlink \ - bit.node6_tlink -#define wci_sec_fo_route_map_node5_tlink \ - bit.node5_tlink -#define wci_sec_fo_route_map_node4_tlink \ - bit.node4_tlink -#define wci_sec_fo_route_map_node3_tlink \ - bit.node3_tlink -#define wci_sec_fo_route_map_node2_tlink \ - bit.node2_tlink -#define wci_sec_fo_route_map_node1_tlink \ - bit.node1_tlink -#define wci_sec_fo_route_map_node0_tlink \ - bit.node0_tlink - - -/* - * wci_fo_tnid_map - */ -typedef union { - struct wci_fo_tnid_map { - uint64_t rsvd_z : 52; /* 63:12 */ - uint64_t link2_tnid : 4; /* 11:8 */ - uint64_t link1_tnid : 4; /* 7:4 */ - uint64_t link0_tnid : 4; /* 3:0 */ - } bit; - uint64_t val; -} wci_fo_tnid_map_u; - -#define wci_fo_tnid_map_link2_tnid \ - bit.link2_tnid -#define wci_fo_tnid_map_link1_tnid \ - bit.link1_tnid -#define wci_fo_tnid_map_link0_tnid \ - bit.link0_tnid - -/* - * wci_sw_link_rexmit - */ -typedef union { - struct wci_sw_link_rexmit { - uint64_t rsvd_z : 32; /* 63:32 */ - uint64_t rexmit_count : 32; /* 31:0 */ - } bit; - uint64_t val; -} wci_sw_link_rexmit_u; - -#define wci_sw_link_rexmit_rexmit_count \ - bit.rexmit_count - - -/* - * wci_dnid2gnid - */ -typedef union { - struct wci_dnid2gnid { - uint64_t dnid2gnid : 64; /* 63:0 */ - } bit; - uint64_t val; -} wci_dnid2gnid_u; - -#define wci_dnid2gnid_dnid2gnid \ - bit.dnid2gnid - - -/* For compatibility with WCI-1 */ -#define ADDR_WCI_ROUTE_MAP0 ADDR_WCI_JNK_ROUTE_MAP0 -#define ADDR_WCI_ROUTE_MAP1 ADDR_WCI_JNK_ROUTE_MAP1 -typedef wci_jnk_route_map0_u wci_route_map0_u; -typedef wci_jnk_route_map1_u wci_route_map1_u; - -#endif /* _KERNEL && !_ASM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WCI_REGS_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm.h b/usr/src/uts/sun4u/sys/wrsm.h deleted file mode 100644 index 61f7ad7268..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm.h +++ /dev/null @@ -1,360 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_WRSM_H -#define _SYS_WRSM_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/kstat.h> -#include <sys/wrsm_types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define WRSM_CLASS "wrsm" -#define WRSM_SUBCLASS_LINKUP "link-up" -#define WRSM_SUBCLASS_LINKDOWN "link-down" -#define WRSM_SUBCLASS_NEW_NODE "new-node-route" -#define WRSM_SUBCLASS_LOST_NODE "lost-node-route" -#define WRSM_SUBCLASS_NEW_CONFIG "new-config" - -/* - * WRSM ioctl interface. - */ - -#define WRSM_IOC ('W'<<8) - -/* Admin device ioctls */ -#define WRSM_CONTROLLERS (WRSM_IOC|0) /* # of registered rsmctlrs */ -#define WRSM_REPLACECFG (WRSM_IOC|1) -#define WRSM_CHECKCFG (WRSM_IOC|2) -#define WRSM_INSTALLCFG (WRSM_IOC|3) -#define WRSM_INITIALCFG (WRSM_IOC|4) -#define WRSM_REMOVECFG (WRSM_IOC|5) -#define WRSM_GETCFG (WRSM_IOC|6) -#define WRSM_ENABLECFG (WRSM_IOC|7) -#define WRSM_STARTCFG (WRSM_IOC|8) -#define WRSM_STOPCFG (WRSM_IOC|9) - -/* WCI device ioctls */ -#define WRSM_LC_READCSR (WRSM_IOC|20) -#define WRSM_LC_WRITECSR (WRSM_IOC|21) -#define WRSM_LC_READCESR (WRSM_IOC|22) -#define WRSM_LC_WRITECESR (WRSM_IOC|23) -#define WRSM_LC_UPDATECMMU (WRSM_IOC|24) -#define WRSM_LC_READCMMU (WRSM_IOC|25) - -/* RSM-controller device ioctls */ -#define WRSM_CTLR_PING (WRSM_IOC|30) -#define WRSM_CTLR_MBOX (WRSM_IOC|31) -#define WRSM_CTLR_SESS (WRSM_IOC|38) - -/* WCI device ioctl to support link loopback testing */ -#define WRSM_WCI_LOOPBACK_ON (WRSM_IOC|40) /* enable loopback link */ -#define WRSM_WCI_LOOPBACK_OFF (WRSM_IOC|41) /* disable loopback link */ -#define WRSM_WCI_LINKTEST (WRSM_IOC|42) /* test loopback link */ -#define WRSM_WCI_CLAIM (WRSM_IOC|43) /* reserve WCI for testing */ -#define WRSM_WCI_RELEASE (WRSM_IOC|44) -#define WRSM_WCI_LINKUP (WRSM_IOC|45) -#define WRSM_WCI_LINKDOWN (WRSM_IOC|46) - -#define WRSM_CTLR_MEM_LOOPBACK (WRSM_IOC|50) /* memory loopback test */ - -/* Mailbox ioctl sub-commands */ -#define WRSM_CTLR_UPLINK 1 -#define WRSM_CTLR_DOWNLINK 2 -#define WRSM_CTLR_SET_LED 3 -#define WRSM_CTLR_ALLOC_SLICES 4 -#define WRSM_CTLR_SET_SEPROM 5 - -/* Plugin librsmwrsm.so ioctls to request small_puts of the driver */ -#define WRSM_CTLR_PLUGIN_SMALLPUT 7 -#define WRSM_CTLR_PLUGIN_GETLOCALNODE 8 - -/* Session ioctl sub-commands */ -#define WRSM_CTLR_SESS_START 1 -#define WRSM_CTLR_SESS_END 2 -#define WRSM_CTLR_SESS_ENABLE 3 -#define WRSM_CTLR_SESS_DISABLE 4 -#define WRSM_CTLR_SESS_GET 5 - -typedef struct wrsm_linktest_arg { - uint16_t link_num; /* link to test */ - uint32_t pattern; /* data to send via user_data (max 18 bits) */ - uint64_t link_error_count; /* copy of wci_sw_link_error_count */ - uint64_t link_status; /* copy of wci_sw_link_status */ - uint64_t link_esr; /* copy of wci_link_esr */ - uint64_t sw_esr; /* copy of wci_sw_esr */ - uint64_t link_control; /* copy of wci_sw_link_control */ -} wrsm_linktest_arg_t; - - -/* - * 8 pages are allocated, exported through the WCI, and imported from the - * local node. Each requested pattern is written then read in sequential - * 64 byte chunks, starting at offset 0, until the entire page has been - * read/written. (One pattern is completed across the entire page before - * the next is started.) The starting physical address of the first - * allocated page is stored in the paddr field of the arg parameter on - * return from the ioctl. - * - * Around each pattern, a barrier is opened and closed to detect network - * errors. If a barrier close detects an error, the ioctl fails and errno - * is set to ENETRESET. - * - * If a read does not return the written pattern, the ioctl fails and errno - * is set to EIO. The pattern encountering the error is stored in the - * pattern_error field of the arg parameter, and the local physical address - * of the exact 64 byte region with the error is stored in the paddr field. - * - * Other errnos may be returned; these typically indicate problems in the - * OS or with the caller's input. - * - */ - -#define WRSM_SSO_PATTERN 0x01 -#define WRSM_SLOWMARCH_PATTERN 0x02 -#define WRSM_FASTMARCH_PATTERN 0x04 -#define WRSM_XTALK_PATTERN 0x08 - -#define WRSM_MAX_PATTERN 4 /* number of valid bits */ - - -typedef struct wrsm_memloopback_arg { - uint_t patterns; - uint64_t paddr; - uint64_t error_pattern; - unsigned char expected_data[64]; - unsigned char actual_data[64]; -} wrsm_memloopback_arg_t; - -/* - * There are 3 kstats associated with RSM: - * 1. A WCI and its links (status) - * 2. Routes - * 3. RSM controller (rsmpi_stat) - */ - -/* There are two kstat modules */ -#define WRSM_KSTAT_WRSM "wrsm" -#define WRSM_KSTAT_WRSM_ROUTE "wrsm_route" - -/* The following are the names for the kstats */ -#define WRSM_KSTAT_STATUS "status" - -/* - * The name of the route kstat is defined dynamically - * as "FM-node-name" -- this is a name of a remote node. - */ - -/* - * LC Link States - */ -typedef enum { - lc_up, /* lasers have been established */ - lc_down, /* paroli present, lasers are not on */ - lc_not_there, /* no paroli is present */ - sc_wait_down, /* waiting for SC to take down link */ - sc_wait_up, /* waiting for SC to bring up link */ - sc_wait_errdown /* link down wait on sc due to error */ -} wrsm_link_req_state_t; - -/* event types for sys event daemon: syseventd */ -typedef enum { - link_up, - link_down, - new_node_route, /* new or modified routes to get to remote host */ - lost_node_route, /* driver removes route to a remote host */ - new_config /* new configuration has occured */ -} wrsm_sys_event_t; - - -/* - * Phys Link States - */ -typedef enum { - phys_off, /* link is off */ - phys_failover, /* failover mode */ - phys_seek, /* link is in seek state */ - phys_in_use /* link is in use */ -} wrsm_phys_link_state_t; - -/* Names for fields in the status kstat */ -#define WRSMKS_WCI_VERSION_NAMED "wci_version" -#define WRSMKS_CONTROLLER_ID_NAMED "controller_id" -#define WRSMKS_PORTID "portid" -#define WRSMKS_ERROR_LIMIT "error_limit" -#define WRSMKS_ERRSTAT_INTERVAL "errstat_interval" -#define WRSMKS_INTERVALS_PER_LT "intervals_per_lt" -#define WRSMKS_AVG_WEIGHT "avg_weight" -#define WRSMKS_VALID_LINK "valid_link_%d" -#define WRSMKS_REMOTE_CNODE_ID "remote_cnode_id_%d" -#define WRSMKS_REMOTE_WNODE "remote_wnode_id_%d" -#define WRSMKS_REMOTE_WCI_PORTID "remote_wci_portid_%d" -#define WRSMKS_REMOTE_LINKNUM "remote_linknum_%d" -#define WRSMKS_LC_LINK_STATE "LC_link_state_%d" -#define WRSMKS_PHYS_LINK_STATE "phys_link_state_%d" -#define WRSMKS_PHYS_LASER_ENABLE "laser enabled_%d" -#define WRSMKS_PHYS_XMIT_ENABLE "transmit enable_%d" -#define WRSMKS_LINK_STATE "link_state_%d" -#define WRSMKS_LINK_ERR_TAKEDOWNS "link_err_takedowns_%d" -#define WRSMKS_LAST_LINK_ERR_TAKEDOWNS "last_link_err_takedowns_%d" -#define WRSMKS_MAX_LINK_ERR_TAKEDOWNS "max_link_err_takedowns_%d" -#define WRSMKS_AVG_LINK_ERR_TAKEDOWNS "avg_link_err_takedowns_%d" -#define WRSMKS_LINK_DISCON_TAKEDOWNS "link_disconnected_takedowns_%d" -#define WRSMKS_LINK_CFG_TAKEDOWNS "link_cfg_takedowns_%d" -#define WRSMKS_LINK_FAILED_BRINGUPS "link_failed_bringups_%d" -#define WRSMKS_LINK_INTERVAL_COUNT "link_interval_count_%d" -#define WRSMKS_LINK_ENABLED "link_enabled_%d" -#define WRSMKS_LINK_ERRORS "link_errors_%d" -#define WRSMKS_LAST_LINK_ERRORS "last_link_errors_%d" -#define WRSMKS_MAX_LINK_ERRORS "max_link_errors_%d" -#define WRSMKS_AVG_LINK_ERRORS "avg_link_errors_%d" -#define WRSMKS_LAST_LT_LINK_ERRORS "last_lt_link_errors_%d" -#define WRSMKS_MAX_LT_LINK_ERRORS "max_lt_link_errors_%d" -#define WRSMKS_AVG_LT_LINK_ERRORS "avg_lt_link_errors_%d" -#define WRSMKS_AUTO_SHUTDOWN_EN "auto_shutdown_en_%d" -#define WRSMKS_CLUSTER_ERROR_COUNT "cluster_error_count" -#define WRSMKS_UC_SRAM_ECC_ERROR "uc_sram_ecc_error" -#define WRSMKS_SRAM_ECC_ERRORS "sram_ecc_errors" -#define WRSMKS_LAST_SRAM_ECC_ERRORS "last_sram_ecc_errors" -#define WRSMKS_MAX_SRAM_ECC_ERRORS "max_sram_ecc_errors" -#define WRSMKS_AVG_SRAM_ECC_ERRORS "avg_sram_ecc_errors" - -#define WRSM_KSTAT_NO_CTRLR -1 -#define WRSMKS_LINK_PRESENT 1 -#define WRSMKS_LINK_NOT_PRESENT 0 - -typedef struct wrsm_status_kstat { - kstat_named_t ks_version; - kstat_named_t controller_id; - kstat_named_t portid; - kstat_named_t error_limit; - kstat_named_t errstat_interval; - kstat_named_t intervals_per_lt; - kstat_named_t avg_weight; - kstat_named_t valid_link[WRSM_LINKS_PER_WCI]; - kstat_named_t remote_cnode_id[WRSM_LINKS_PER_WCI]; - kstat_named_t remote_wnode_id[WRSM_LINKS_PER_WCI]; - kstat_named_t remote_wci_portid[WRSM_LINKS_PER_WCI]; - kstat_named_t remote_linknum[WRSM_LINKS_PER_WCI]; - kstat_named_t state[WRSM_LINKS_PER_WCI]; - kstat_named_t laser[WRSM_LINKS_PER_WCI]; - kstat_named_t xmit_enable[WRSM_LINKS_PER_WCI]; - kstat_named_t link_state[WRSM_LINKS_PER_WCI]; - kstat_named_t link_err_takedowns[WRSM_LINKS_PER_WCI]; - kstat_named_t last_link_err_takedowns[WRSM_LINKS_PER_WCI]; - kstat_named_t max_link_err_takedowns[WRSM_LINKS_PER_WCI]; - kstat_named_t avg_link_err_takedowns[WRSM_LINKS_PER_WCI]; - kstat_named_t link_disconnected_takedowns[WRSM_LINKS_PER_WCI]; - kstat_named_t link_cfg_takedowns[WRSM_LINKS_PER_WCI]; - kstat_named_t link_failed_bringups[WRSM_LINKS_PER_WCI]; - kstat_named_t link_interval_count[WRSM_LINKS_PER_WCI]; - kstat_named_t link_enabled[WRSM_LINKS_PER_WCI]; - kstat_named_t link_errors[WRSM_LINKS_PER_WCI]; - kstat_named_t last_link_errors[WRSM_LINKS_PER_WCI]; - kstat_named_t max_link_errors[WRSM_LINKS_PER_WCI]; - kstat_named_t avg_link_errors[WRSM_LINKS_PER_WCI]; - kstat_named_t last_lt_link_errors[WRSM_LINKS_PER_WCI]; - kstat_named_t max_lt_link_errors[WRSM_LINKS_PER_WCI]; - kstat_named_t avg_lt_link_errors[WRSM_LINKS_PER_WCI]; - kstat_named_t auto_shutdown_en[WRSM_LINKS_PER_WCI]; - kstat_named_t cluster_error_count; - kstat_named_t uc_sram_ecc_error; - kstat_named_t sram_ecc_errors; - kstat_named_t last_sram_ecc_errors; - kstat_named_t max_sram_ecc_errors; - kstat_named_t avg_sram_ecc_errors; -} wrsm_status_kstat_t; - -/* - * wrsm routes kstat names and struct - */ -#define WRSMKS_CONFIG_VERSION_NAMED "config-version" -#define WRSMKS_ROUTE_TYPE_NAMED "route-type" -#define WRSMKS_NUM_WCIS "num_wcis" -#define WRSMKS_NUM_STRIPES "num_stripes" -#define WRSMKS_NUMCHANGES "num_changes" -#define WRSMKS_CNODEID "cnodeid" -#define WRSMKS_FMNODEID "fmnodeid" -#define WRSMKS_ROUTE_PORTID "route%d_portid" -#define WRSMKS_ROUTE_INSTANCE "route%d_instance" -#define WRSMKS_ROUTE_NUMHOPS "route%d_numhops" -#define WRSMKS_ROUTE_NUMLINKS "route%d_numlinks" -#define WRSMKS_ROUTE_LINKID "route%d_linkid%d" -#define WRSMKS_ROUTE_NODEID "route%d_nodeid%d" -#define WRSMKS_ROUTE_GNID "route%d_gnid%d" - -typedef struct wrsm_route_kstat { - kstat_named_t version; - kstat_named_t type; - kstat_named_t num_wcis; - kstat_named_t num_stripes; - kstat_named_t num_changes; - kstat_named_t cnodeid; - kstat_named_t fmnodeid; - kstat_named_t portid[WRSM_MAX_WCIS_PER_STRIPE]; - kstat_named_t instance[WRSM_MAX_WCIS_PER_STRIPE]; - kstat_named_t numhops[WRSM_MAX_WCIS_PER_STRIPE]; - kstat_named_t numlinks[WRSM_MAX_WCIS_PER_STRIPE]; - kstat_named_t linkid[WRSM_MAX_WCIS_PER_STRIPE][WRSM_MAX_DNIDS]; - kstat_named_t nodeid[WRSM_MAX_WCIS_PER_STRIPE][WRSM_MAX_DNIDS]; - kstat_named_t gnid[WRSM_MAX_WCIS_PER_STRIPE][WRSM_MAX_DNIDS]; -} wrsm_route_kstat_t; - -/* - * rsmpi_stat kstat - * plus four wrsm specific fields - */ - -#define WRSMKS_FREE_CMMU_ENTRIES "free_cmmu_entries" -#define WRSMKS_NUM_RECONFIGS "num_reconfigs" -#define WRSMKS_RSM_NUM_WCIS "num_wcis" -#define WRSMKS_RSM_AVAIL_WCIS "avail_wcis" - -typedef struct wrsm_rsmpi_stat { - kstat_named_t num_reconfigs; - kstat_named_t num_wcis; - kstat_named_t avail_wcis; - kstat_named_t free_cmmu_entries; - kstat_named_t ctlr_state; /* required by rsmpi */ - kstat_named_t addr; /* required by rsmpi */ - kstat_named_t ex_memsegs; /* required by rsmpi */ - kstat_named_t ex_memsegs_pub; /* required by rsmpi */ - kstat_named_t ex_memsegs_con; /* required by rsmpi */ - kstat_named_t bytes_bound; /* required by rsmpi */ - kstat_named_t im_memsegs_con; /* required by rsmpi */ - kstat_named_t sendqs; /* required by rmspi */ - kstat_named_t handlers; /* required by rsmpi */ -} wrsm_rsmpi_stat_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WRSM_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_barrier.h b/usr/src/uts/sun4u/sys/wrsm_barrier.h deleted file mode 100644 index 60c631876d..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_barrier.h +++ /dev/null @@ -1,89 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_BARRIER_H -#define _WRSM_BARRIER_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/rsm/rsm_common.h> -#include <sys/rsm/rsmpi.h> - -/* - * Span of time barriers - */ -int wrsm_open_barrier_ctrl(rsm_controller_handle_t, rsm_barrier_t *); -int wrsm_open_barrier_node(rsm_controller_handle_t, rsm_addr_t, - rsm_barrier_t *); -int wrsm_open_barrier_region(rsm_memseg_import_handle_t, rsm_barrier_t *); -int wrsm_open_barrier_regions(rsm_memseg_import_handle_t *, uint_t num_regions, - rsm_barrier_t *); - -/* - * Thread of code barriers - */ -int wrsm_open_barrier_ctrl_thr(rsm_controller_handle_t, rsm_barrier_t *); -int wrsm_open_barrier_node_thr(rsm_controller_handle_t, rsm_addr_t, - rsm_barrier_t *); -int wrsm_open_barrier_region_thr(rsm_memseg_import_handle_t, rsm_barrier_t *); -int wrsm_open_barrier_regions_thr(rsm_memseg_import_handle_t *, - uint_t num_regions, rsm_barrier_t *); - -/* - * Barrier close/reopen/ordering - */ -int wrsm_close_barrier(rsm_barrier_t *); -int wrsm_reopen_barrier(rsm_barrier_t *); -int wrsm_order_barrier(rsm_barrier_t *); - -/* - * Thread of code init/fini. - */ -int wrsm_thread_init(rsm_controller_handle_t); -int wrsm_thread_fini(rsm_controller_handle_t); - -/* - * Memseg barrier mode control. - */ -int wrsm_get_barrier_mode(rsm_memseg_import_handle_t, rsm_barrier_mode_t *); -int wrsm_set_barrier_mode(rsm_memseg_import_handle_t, rsm_barrier_mode_t); - -/* - * Debug functions. - */ -#ifdef DEBUG -void wrsm_print_barrier(rsm_barrier_t *); -#endif /* DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_BARRIER_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_cf.h b/usr/src/uts/sun4u/sys/wrsm_cf.h deleted file mode 100644 index 5029fc5a97..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_cf.h +++ /dev/null @@ -1,80 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_CF_H -#define _WRSM_CF_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file defines the interfaces between the config layer and - * the other components of the wrsm driver. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/cred.h> -#include <sys/wrsm_config.h> -#include <sys/wrsm_common.h> - -#define WRSM_BAD_RSM_ID 0xffffffff -#define WRSM_LOOPBACK_ID 0xfffffffe - -/* - * functions exported to the LC - */ -int wrsm_cf_newwci(lcwci_handle_t lcwci, safari_port_t port); -int wrsm_cf_remove_wci(lcwci_handle_t lcwci); -void wrsm_cf_is_enabled(uint32_t controller_id); -lcwci_handle_t wrsm_cf_lookup_wci(safari_port_t port); -int wrsm_cf_claim_wci(uint32_t controller_id, safari_port_t wci_id); -void wrsm_cf_release_wci(safari_port_t wci_id); -uint32_t wrsm_cf_wci_owner(safari_port_t wci_id); -boolean_t wrsm_cf_cnode_is_switch(wrsm_controller_t *cont); - -/* - * functions exported to the core driver (wrsm_driver.c) - */ -void wrsm_cf_init(void); -void wrsm_cf_fini(void); -int wrsm_cf_new_controller(int cont_id, dev_info_t *devi); -int wrsm_cf_remove_controller(int cont_id); -int wrsm_cf_admin_ioctl(struct wrsm_soft_state *softsp, int cmd, - intptr_t arg, int flag, cred_t *cred_p, int *rval_p); -int wrsm_cf_ctlr_ioctl(int cont_id, int cmd, intptr_t arg, int flag, - cred_t *cred_p, int *rval_p); -void *wrsm_cf_pack(wrsm_controller_t *cont, int *sizep); -wrsm_controller_t *wrsm_cf_unpack(char *data); -void wrsm_cf_sc_failed(void); - - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_CF_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_cf_impl.h b/usr/src/uts/sun4u/sys/wrsm_cf_impl.h deleted file mode 100644 index d99b306816..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_cf_impl.h +++ /dev/null @@ -1,79 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_CONFIG_IMPL_H -#define _WRSM_CONFIG_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Definitions private to the config layer of the wrsm driver. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/wrsm_config.h> -#include <sys/wrsm_nc.h> - -enum wrsm_cf_state { - cf_invalid, /* no such controller yet */ - cf_replaced, /* REPLACECFG succeeded */ - cf_installed, /* INSTALCFG succeeded */ - cf_enabled /* ENABLECFG succeeded */ -}; - -typedef struct wrsm_wci_dev { - wci_ids_t id; - struct wrsm_wci_dev *next; - uint32_t controller_id; - boolean_t attached; /* _attach has been called on this WCI */ -} wrsm_wci_dev_t; - -typedef struct wrsm_controller_dev { - kmutex_t lock; - boolean_t in_ioctl; /* An ioctl is operating on this controller */ - uint32_t controller_id; - size_t nbytes; /* size of the conroller configuration data */ - size_t pending_nbytes; /* size of the pending configuration */ - dev_info_t *devi; - wrsm_controller_t *controller; - wrsm_controller_t *pending; - ncslice_bitmask_t ncslices; /* ncslices used in config */ - ncslice_bitmask_t pending_ncslices; /* pending config ncslices */ - struct wrsm_controller_dev *next; - enum wrsm_cf_state state; -} wrsm_controller_dev_t; - -void wrsm_cf_free(wrsm_controller_t *cont); - - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_CONFIG_IMPL_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_cmmu.h b/usr/src/uts/sun4u/sys/wrsm_cmmu.h deleted file mode 100644 index 386503d7b5..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_cmmu.h +++ /dev/null @@ -1,198 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_CMMU_H -#define _WRSM_CMMU_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/wrsm_config.h> -#include <sys/wrsm_lc.h> -#include <sys/wrsm_nc.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef uint32_t wrsm_cmmu_index_t; -typedef caddr_t wrsm_cmmu_offset_t; - -typedef wrsm_ncslice_mode_t wrsm_cmmu_page_size_t; -#define CMMU_PAGE_SIZE_SMALL ncslice_small_page -#define CMMU_PAGE_SIZE_LARGE ncslice_large_page - -#define CMMU_SMALL_PAGE_SIZE 0x00002000 /* 8K Bytes */ -#define CMMU_SMALL_PAGE_MASK 0x00001fff -#define CMMU_SMALL_PAGE_SHIFT 13 -#define CMMU_LARGE_PAGE_SIZE 0x00400000 /* 4M Bytes */ -#define CMMU_LARGE_PAGE_MASK 0x003fffff -#define CMMU_LARGE_PAGE_SHIFT 22 - -#define CMMU_NCSLICE_SHIFT 34 -#define CMMU_NCSLICE_OFFSET_MASK ((uint64_t)0x3ffffffff) -#define CMMU_PADDR2NCSLICE(pa) (((pa) >> CMMU_NCSLICE_SHIFT) & 0xff) -#define CMMU_PADDR2OFFSET(pa) ((pa) & CMMU_NCSLICE_OFFSET_MASK) - -/* - * Structure defining the <ncslice, index, count> tuple. - */ -struct wrsm_cmmu_tuple { - ncslice_t ncslice; - wrsm_cmmu_offset_t offset; - wrsm_cmmu_index_t index; - unsigned count; -}; - -/* - * Initializes the CMMU allocator, including providing an initialial list - * of WCIs. This initial list is used to determine the max CMMU entries - * for this instance of the CMMU allocator. - */ -void wrsm_cmmu_init(wrsm_network_t *, unsigned nwcis, struct wci_ids wcis[]); - -/* - * Destroys the CMMU allocator and frees any data structures. - */ -void wrsm_cmmu_fini(wrsm_network_t *); - -/* - * Informs the CMMU allocator of a new WCI. Returns non-zero if the - * new WCI doesn't support a large enough CMMU. - */ -int wrsm_cmmu_newwci(wrsm_network_t *, lcwci_handle_t); - -/* - * Informs the CMMU allocator that a WCI is no longer part of this - * RSM controller. - */ -int wrsm_cmmu_delwci(wrsm_network_t *, lcwci_handle_t); - -/* - * Allocates a range of entries, and allocates and returns a buffer containing - * the tuples describing the CMMU entries and the ncslice they map to. The - * caller frees the CMMU entries AND the buffer by calling wrsm_cmmu_free. - * Arguments: - * net - Pointer to this network. - * page_size - Desired page size, small or large. - * nentries - The number of CMMU entries being requested. - * tuples - An array of tuples allocated by the function. The memory will - * be freed in wrsm_cmmu_free. - * ntuples - The number of tuples actually written by this function. - * Returns: ENOMEM if there aren't enough free CMMU entries for the request. - */ -int wrsm_cmmu_alloc(wrsm_network_t *net, wrsm_cmmu_page_size_t page_size, - unsigned nentries, wrsm_cmmu_tuple_t **tuples, unsigned *ntuples, - boolean_t sleep); - -/* - * Frees a range of entries allocated with wrsm_cmmu_alloc(). The tuples - * pointer must be the unaltered buffer allocated in wrsm_cmmu_alloc. This - * function will free the CMMU entries and free the tuples buffer. - */ -void wrsm_cmmu_free(wrsm_network_t *, unsigned ntuples, - wrsm_cmmu_tuple_t *tuples); - -/* - * Allocates a CMMU entry for driver communication at a specific - * ncslice/offset. Unlike wrsm_cmmu_alloc, this function does not - * allocate any memory -- the caller must provide a single tuple - * buffer where the result is placed. CMMU entries allocated - * with this function must be freed by wrsm_cmmu_comm_free. - * Arguments: - * net - Pointer to this network. - * ncslice - Desired ncslice. - * offset - Desired offset. - * tuple - Returned value indicating ncslice/offset/index/count. The ncslice - * and offset will match the values passed in, and the count will be 1. - */ -int wrsm_cmmu_comm_alloc(wrsm_network_t *net, ncslice_t ncslice, - wrsm_cmmu_offset_t offset, wrsm_cmmu_tuple_t *tuple); - - -/* - * Frees a single cmmu entry allocated by wrsm_cmmu_comm_alloc(). Since - * wrsm_cmmu_comm_alloc does not allocate memory, this function does not - * free the memory pointed to by tuple. - */ -void wrsm_cmmu_comm_free(wrsm_network_t *net, wrsm_cmmu_tuple_t *tuple); - -/* - * Writes an entry, only updating the fields specified by the flags - * parameter. Does not check to make sure the CMMU entry has been allocated. - */ -void wrsm_cmmu_update(wrsm_network_t *, wrsm_cmmu_t *entry, - wrsm_cmmu_index_t index, wrsm_cmmu_flags_t); - -/* - * Reads a CMMU entry, uses an arbitrary WCI. - */ -void wrsm_cmmu_read(wrsm_network_t *, wrsm_cmmu_t *entry, wrsm_cmmu_index_t); - -/* - * Other RSM controller-wide register functions. These don't specifically - * modify the CMMU, but act across all WCIs, like the CMMU manipulation - * functions do. - */ - -/* - * Sets the bit for a particular cnode in the cluster member bits of - * all WCIs associated with this RSM network. - */ -void wrsm_clustermember_add(wrsm_network_t *, cnodeid_t cnode); - -/* - * Clears the bit for a particular cnode in the clsuter member bits of - * all WCIs associated with this RSM network. - */ -void wrsm_clustermember_delete(wrsm_network_t *, cnodeid_t cnode); - -/* - * Returns a list of all cnode bits set in the cluster member bits register. - * Uses a specific WCI's cluster_member_bits register, but all WCIs should - * have the same setting. - */ -void wrsm_clustermember_list(wrsm_network_t *, cnode_bitmask_t *); - -/* - * Sets the mode of a particular ncslice in the wci_nc_slice_config_array. - */ -void wrsm_ncsliceconfig_set(wrsm_network_t *, ncslice_t ncslice, - wrsm_ncslice_mode_t mode); -/* - * Returns the mode of the given ncslice. - */ -wrsm_ncslice_mode_t wrsm_ncsliceconfig_get(wrsm_network_t *, ncslice_t); - -/* - * Returns the number of free cmmu entires - */ -wrsm_cmmu_index_t wrsm_cmmu_num_free(wrsm_network_t *); - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_CMMU_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_common.h b/usr/src/uts/sun4u/sys/wrsm_common.h deleted file mode 100644 index d509ba242f..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_common.h +++ /dev/null @@ -1,358 +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 2001-2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _WRSM_COMMON_H -#define _WRSM_COMMON_H - -#pragma ident "%Z%%M% %I% %E% SMI" - - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/dditypes.h> -#include <sys/mutex.h> -#include <sys/condvar.h> -#include <sys/thread.h> -#include <sys/kstat.h> - -#ifdef _KERNEL -#include <vm/page.h> -#include <sys/ddidevmap.h> -#include <sys/rsm/rsmpi.h> -#endif -#include <sys/wci_offsets.h> -#include <sys/wrsm_types.h> - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef wrsm_ncslice_bitmask_t ncslice_bitmask_t; -typedef wrsm_cnode_bitmask_t cnode_bitmask_t; -typedef wrsm_wnode_bitmask_t wnode_bitmask_t; -typedef wrsm_fmnodeid_t fmnodeid_t; -typedef wrsm_cnodeid_t cnodeid_t; -typedef wrsm_wnodeid_t wnodeid_t; -typedef wrsm_gnid_t gnid_t; -typedef wrsm_ncslice_t ncslice_t; -typedef wrsm_linkid_t linkid_t; -typedef wrsm_safari_port_t safari_port_t; - -/* - * Cacheline-size related constants - */ -#define WRSM_CACHELINE_SIZE 64 -#define WRSM_CACHELINE_SHIFT 6 -#define WRSM_CACHELINE_MASK (WRSM_CACHELINE_SIZE - 1) - -/* - * This is a more meaningful name for the errno return value of 0. It - * is used by functions that return/expect errno values. - */ -#define WRSM_SUCCESS 0 - -/* - * Hash for fmnodeid to node pointer mapping. - * Most likely the fmnodeid will be a low integer. - */ -#define WRSM_CNODE_HASH_SIZE 0x100 /* number of entries in hash table */ -#define WRSM_CNODE_HASH_MASK (WRSM_CNODE_HASH_SIZE - 1) -#define WRSM_CNODE_HASH_FUNC(r) \ - (((uint_t)r) & WRSM_CNODE_HASH_MASK) - -/* - * 8 is the lower bound allowed before we are required to start freezing - * Request Agent (RAG) instances per PRM - */ -#define WRSM_RAG_FREEZE_NODE_LIMIT 8 -/* - * additional bit mask manipulation macros - */ -uint_t wrsmset_cmp(uint32_t *s1, uint32_t *s2, int masksize); -uint_t wrsmset_isnull(uint32_t *s, int masksize); - -/* Copy bits from set1 to set2 */ -#define WRSMSET_COPY(src, dest) bcopy(&(src), &(dest), sizeof (src)) -#define WRSMSET_ISEQUAL(set1, set2) \ - (wrsmset_cmp((uint32_t *)&(set1), (uint32_t *)&(set2), \ - WRSMMASKSIZE(set1))) -#define WRSMSET_ISNULL(set) \ - (wrsmset_isnull((uint32_t *)&(set), WRSMMASKSIZE(set))) - -#define WRSMSET_OR(set1, set2) { \ - int _i; \ - uint32_t *_s1 = (uint32_t *)&(set1); \ - uint32_t *_s2 = (uint32_t *)&(set2); \ - for (_i = 0; _i < WRSMMASKSIZE(set1); _i++) \ - *_s1++ |= *_s2++; \ - } - -#define WRSMSET_AND(set1, set2) { \ - int _i; \ - uint32_t *_s1 = (uint32_t *)&(set1); \ - uint32_t *_s2 = (uint32_t *)&(set2); \ - for (_i = 0; _i < WRSMMASKSIZE(set1); _i++) \ - *_s1++ &= *_s2++; \ - } - -#define WRSMSET_DIFF(set1, set2) { \ - int _i; \ - uint32_t *_s1 = (uint32_t *)&(set1); \ - uint32_t *_s2 = (uint32_t *)&(set2); \ - for (_i = 0; _i < WRSMMASKSIZE(set1); _i++) \ - *_s1++ &= ~*_s2++; \ - } - - -/* - * in the node->link_stripes field, this is the number of bits to - * shift to get to the bit referring to the next link in the same wci - */ -#define BBIT_LINK_STRIDE 4 - - -/* opaque type for LC's handle */ -typedef struct wrsm_soft_state *lcwci_handle_t; -/* opaque type for NC's handle */ -typedef struct wrsm_ncwci *ncwci_handle_t; - - -/* - * typedefs for opaque structure definitions (for structures private to - * particular wrsm modules, declared in module specific header files) - */ -typedef struct wrsm_node_routeinfo wrsm_node_routeinfo_t; -typedef struct wrsm_node_memseg wrsm_node_memseg_t; - -typedef struct wrsm_transport wrsm_transport_t; -typedef struct wrsm_session wrsm_session_t; -typedef struct wrsm_cmmu_alloc wrsm_cmmu_alloc_t; -typedef struct wrsm_interrupt wrsm_interrupt_t; -typedef struct wrsm_nr wrsm_nr_t; -typedef struct wrsm_memseg wrsm_memseg_t; - -typedef struct __rsm_controller_handle wrsm_network_t; -typedef struct wrsm_node wrsm_node_t; - -typedef struct wrsm_cmmu_tuple wrsm_cmmu_tuple_t; - - - -/* - * configuration states - */ -typedef enum { - wrsm_disabled, /* new config, no ncslice rerouting allowed */ - wrsm_pending, /* can reroute using old/new config intersection */ - wrsm_installed, /* ncslice routes are not using old config */ - wrsm_installed_up, /* all links in new config are up */ - wrsm_enabled /* ncslice routes are using new config */ -} wrsm_availability_t; - -#define WRSM_INSTALLED(n) \ - ((n)->availability == wrsm_enabled || \ - (n)->availability == wrsm_installed || \ - (n)->availability == wrsm_installed_up) - -/* - * state of communication to node - */ -typedef enum { - wrsm_node_needroute, /* no ncslice routes to node */ - wrsm_node_haveroute /* ncslice route set up */ -} wrsm_node_comm_state_t; - -#define WRSM_NODE_HAVE_ROUTE(n) ((n)->state == wrsm_node_haveroute) - - - -/* - * information about a remote node participating in an RSM network - */ -struct wrsm_node { - wrsm_network_t *network; /* this node's RSM network */ - wrsm_net_member_t *config; /* node config info */ - wrsm_availability_t availability; /* configuration state */ - wrsm_node_comm_state_t state; /* communication state */ - uint32_t *link_stripesp; /* stripe info for barrier */ - - /* - * wrsm module private info about node - */ - wrsm_node_routeinfo_t *routeinfo; /* routing config for node */ - - /* - * The following structures are for tracking RSMPI data structures. - */ - wrsm_node_memseg_t *memseg; /* RSMPI segments */ - caddr_t cesr_vaddr; /* vaddr of WCI CESRs for barriers */ - caddr_t lockout_vaddr; /* vaddr of write lockout page */ - - /* - * links - */ - struct wrsm_node *hash; /* linked list for hash table */ -}; - - - - -/* - * The RSM controller's view of the RSM network it is participating in. - */ -#ifdef _KERNEL -struct __rsm_controller_handle { - uint32_t rsm_ctlr_id; /* ctlr id == device instance # */ - kmutex_t lock; - dev_info_t *dip; /* dev_info_t for controller */ - uint64_t version_stamp; /* configuration version number */ - boolean_t registered; /* registered with RSMPI module */ - wrsm_availability_t availability; /* state of the configuration */ - cnodeid_t cnodeid; /* local node's cnodeid */ - wrsm_node_t *mynode; /* local node info */ - wrsm_node_ncslice_array_t exported_ncslices; - /* ncslices local node exports */ - int wrsm_ncslice_users[WRSM_MAX_NCSLICES]; - /* per ncslice count of ncslice users */ - boolean_t have_lg_page_ncslice; /* any ncslices for large pages? */ - wrsm_cmmu_tuple_t *errorpage_tuple; /* loopback error CMMU entry */ - pfn_t errorpage_pfn; /* pfn for loopback error page */ - kmutex_t errorpage_lock; /* updating errorpage_mappings */ - uint_t errorpage_mappings; /* # mappings to error page */ - - wrsm_node_t *nodes[WRSM_MAX_CNODES]; /* array of remote node info */ - wrsm_node_t *node_hash[WRSM_CNODE_HASH_SIZE]; /* nodeinfo hashtable */ - - /* - * route_umem is the kernel allocated address space that - * can also be mapped to user space. both route_countp - * and reroutingp will point to an address range within - * route_umem. the wrsm plug-in uses this address range - * when it mmaps route_counter and rerouting to user space - * the plug-in requires these fields when it must preform - * explicit barriers, as the plugin must check to see if the - * routing has changed. - */ - void *route_umem; /* returned by ddi_umem_alloc */ - uint32_t *route_counterp; /* increment on ncslice route change */ - uint32_t *reroutingp; /* in process of ncslice rerouting */ - ddi_umem_cookie_t route_cookie; /* cookie needed to free *route_umem */ - uint_t passthrough_routes; /* how many PT routes been set up? */ - - /* keeps track of controller opened by plugin library */ - boolean_t is_controller_open; - - /* - * wrsm module private info about network - */ - wrsm_interrupt_t *interrupt; - wrsm_transport_t *transport; /* transport info */ - wrsm_session_t *session; /* session info */ - wrsm_cmmu_alloc_t *cmmu; /* cmmu allocator info */ - wrsm_nr_t *nr; /* network router info */ - int wrsm_num_nodes; /* number of nodes in this network */ - boolean_t free_rag_instance; /* frozen RAG instances can be freed */ - - /* - * NC info - */ - boolean_t auto_enable; /* links-up/timeout enables network */ - timeout_id_t enable_timeout_id; - - /* - * links - */ - wrsm_network_t *next; - - /* - * RSMPI information - */ - wrsm_memseg_t *memseg; /* RSMPI segments */ - rsm_controller_attr_t attr; /* RSMPI controller attributes */ - - /* - * Kstat for the controller - */ - kstat_t *wrsm_rsmpi_stat_ksp; - uint_t num_reconfigs; - uint_t sendqs_num; - uint_t handler_num; -}; - -#endif /* KERNEL */ - -extern dev_info_t *wrsm_ncslice_dip; /* devinfo for ncslice mappings */ -#define PROTOCOLS_SUPPORTED 1 -/* - * The protocol_versions_supported is a bit mask representing all the - * protocol versions that this driver supports. - */ -extern uint32_t protocol_versions_supported; -extern int protocol_version; /* version native to this driver */ - -wrsm_node_t * -wrsm_fmnodeid_to_node(wrsm_network_t *network, - fmnodeid_t fmnodeid); - -int -wrsm_fmnodeid_to_cnodeid(wrsm_network_t *network, - fmnodeid_t fmnodeid, cnodeid_t *cnodeidp); - -wrsm_network_t *wrsm_dip_to_network(dev_info_t *dip); - -/* - * initialization and teardown functions for WRSM modules - called from - * driver _init and _fini - */ -extern void wrsm_nc_init(void); -extern int wrsm_nc_fini(void); -/* - * Functions which make up wrsm_nc_fini() - these can be called individually - * to separate checks from cleanup - called from driver _fini - */ -extern int wrsm_nc_check(void); -extern void wrsm_nc_cleanup(void); - -#ifdef DEBUG -#define DEBUG_LOG -extern void dprintnodes(cnode_bitmask_t); -#define DPRINTNODES(c) dprintnodes(c) -extern kmutex_t wrsmdbglock; -extern int wrsmdbginit; -extern char wrsmdbgbuf[]; -extern int wrsmdbgsize; -extern int wrsmdbgnext; -void wrsmdprintf(int ce, const char *fmt, ...); -#else -#define DPRINTNODES(c) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_COMMON_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_config.h b/usr/src/uts/sun4u/sys/wrsm_config.h deleted file mode 100644 index 31c9121233..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_config.h +++ /dev/null @@ -1,386 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _WRSM_CONFIG_H -#define _WRSM_CONFIG_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ASM -#include <sys/types.h> -#include <sys/wrsm_types.h> -#endif /* _ASM */ - -/* - * Macro to guarantee proper pointer alignment in 32 or 64 bit mode - */ -#if defined(_LP64) -#define WRSM_ALIGN_64(t, n) t n -#define WRSM_ALIGN_PTR(n) n -#else -#define WRSM_ALIGN_64(t, n) union { struct {uint32_t pad; t n; } val; \ - uint64_t align; } u_##n -#define WRSM_ALIGN_PTR(n) u_##n.val.n -#endif -/* - * If any of the data structures in this file are changed, - * WRSM_CF_IOCTL_VERSION must be incremented. - */ -#define WRSM_CF_IOCTL_VERSION 0x0e -#define CONFIG_PROTOCOL_VERSION 0x2 - -#define WRSM_MAX_WCIS (18 * 3) /* CPU WIB + IO WIB in Starcat */ -#define WRSM_MAX_SWITCHES 38 -#define WRSM_HOSTNAMELEN 255 - -#ifndef _ASM - -/* - * network routing methods used by preferred_route - */ -typedef enum { - routing_multihop, - routing_passthrough -} wrsm_routing_method_t; - -/* - * network topology types used to give hints to the multihop routing - * algorithm. - */ -typedef enum { - topology_central_switch, - topology_distributed_switch, - topology_san_switch -} wrsm_topology_t; - -typedef enum { - ncslice_invalid = 0x0, - ncslice_passthrough = 0x1, - ncslice_small_page = 0x2, - ncslice_large_page = 0x3 -} wrsm_ncslice_mode_t; - -/* - * information about each link attached to a wci - */ -typedef struct wrsm_link_data { - boolean_t present; /* does this link exist? */ - wrsm_gnid_t remote_gnid; /* gnid of wci on remote side */ - wrsm_safari_port_t remote_port; /* bus port number of remote wci */ - uint32_t remote_link_num; -} wrsm_link_data_t; - - -/* - * routing related information about each wci - */ -struct wrsm_wci_data { - /* - * bus port number - unique within a chassis - */ - wrsm_safari_port_t port; - wrsm_wnodeid_t local_wnode; - wrsm_gnid_t local_gnid; /* This Wci's gnid */ - boolean_t route_map_striping; - wrsm_topology_t topology_type; - /* cnodes potentially accessible through this WCI, indexed by wnodeid */ - wrsm_cnodeid_t reachable[WRSM_MAX_WNODES]; - /* gnid to wnode mapping for this WCI, indexed by gnid */ - wrsm_wnodeid_t gnid_to_wnode[WRSM_MAX_WNODES]; - /* - * if wnode_reachable[n] == B_TRUE then reachable[n] - * contains a valid reachable cnodeid and gnid_to_wnode[n] - * contains a valid wnode. - */ - boolean_t wnode_reachable[WRSM_MAX_WNODES]; - /* Data about links directly connected to this WCI. */ - wrsm_link_data_t links[WRSM_MAX_LINKS_PER_WCI]; -}; - -/* - * identify wcis which may be used together for striping - */ -typedef struct wrsm_stripe_group { - uint32_t group_id; - int nwcis; - /* - * The order of the wcis in this list determines which address - * stripe each wci is assigned. For Starcat, it is required that - * the wcis are in adjacent expanders, that the lower wci is - * specified first, and that the first expander has an expander id - * that's divisible by 2 (0,2,4..). Also, for Starcat a maximum of - * 2 wcis can be striped. - */ - wrsm_safari_port_t wcis[WRSM_MAX_WCIS_PER_STRIPE]; -} wrsm_stripe_group_t; - -/* - * Description of one possible method to route data to a remote node. - */ -typedef struct wrsm_preferred_route { - int striping_level; /* level of striping desired */ - wrsm_routing_method_t method; - /* - * ordered list of preferred passthrough cnodeids - */ - int nswitches; - wrsm_cnodeid_t switches[WRSM_MAX_SWITCHES]; - /* - * A preferred route may indicate either a WCI - * to use or a stripe group, but not both. - */ - enum { - route_stripe_group = 1, - route_wci - } route_type; - union { - uint_t stripe_group_id; - wrsm_safari_port_t wci_id; - } route; -} wrsm_preferred_route_t; - -/* - * Information about how to route data to remote network members. - */ -typedef struct wrsm_routing_policy { - wrsm_cnodeid_t cnodeid; /* destination cnodeid */ - /* - * must the number of links per WCI be equal? - */ - boolean_t wcis_balanced; - /* - * Is the number of stripes more important than the order of - * the preferred routes? - */ - boolean_t striping_important; - /* - * is passthrough forwarding to this node allowed? - */ - boolean_t forwarding_allowed; - /* - * If forwarding is allowed, this bitmask contains import ncslice ids - * each remote network member uses to access ncslices exported by this - * node. - */ - wrsm_ncslice_bitmask_t forwarding_ncslices; - - int nroutes; /* number of preferred routes */ - WRSM_ALIGN_64(wrsm_preferred_route_t **, preferred_routes); -} wrsm_routing_policy_t; - -/* - * Information on how to communicate with all the remote rsm nodes. - */ -typedef struct wrsm_routing_data { - int nwcis; - int ngroups; - int npolicy; - boolean_t other_routes_allowed; - - /* - * WCIs owned by this controller, sorted in ascending - * order by the safari port id of the wci. - */ - WRSM_ALIGN_64(wrsm_wci_data_t **, wcis); - /* - * List of stripe groups sorted in ascending - * order by stripe group id. - */ - WRSM_ALIGN_64(wrsm_stripe_group_t **, stripe_groups); - /* - * list of routing policies for each remote cnode, - * sorted in ascending order by cnodeid. - */ - WRSM_ALIGN_64(wrsm_routing_policy_t **, policy); - /* - * Are routes not explicitly listed permitted given the - * available connectivity in the network? - */ -} wrsm_routing_data_t; - -/* - * Information the local node needs to know about every other rsm node - * in the network. - */ -struct wrsm_net_member { - wrsm_cnodeid_t cnodeid; /* wrsm_net member's cnode id */ - wrsm_fmnodeid_t fmnodeid; /* FM node id */ - char hostname[WRSM_HOSTNAMELEN]; - - /* - * Exported_ncslices is the ncslices the remote node (the node this - * wrsm_net_member is describing) exports memory through; these are - * the ncslices the local node (the node that is using the config - * containing this wrsm_net_member) uses to import the remote - * node's memory. - */ - wrsm_node_ncslice_array_t exported_ncslices; - - /* - * Imported ncslices is the set of ncslices the remote node uses to - * access the local node's exported memory. Each node may use - * different ncslices to import memory from the local node. The - * local node sets up the WCI hardware to allow access using these - * ncslices. - */ - wrsm_node_ncslice_array_t imported_ncslices; - - /* - * ncslice and offset to use to send interrupt based communication to - * wrsm_net_member's driver - */ - wrsm_ncslice_t comm_ncslice; - uint64_t comm_offset; - /* - * offset that should be set up to allow interrupts to be received - * from wrsm_net_member's driver (the ncslice is the small page - * ncslice specified in the exported_ncslices structure of the - * wrsm_net_member structure for the local controller). - */ - uint64_t local_offset; -}; - - -/* - * Configuration data about a particular rsm controller. - * - * An RSM network is a set of communicating RSM nodes. A "controller" is - * the node-local view of an RSM network. The wrsm_controller_t structure - * contains the configuration information the node needs to participate in - * the network. There is one controller for each node in a network, and - * the controller_id of each communicating controller matches the network - * id of the network it is part of. - */ -typedef struct wrsm_controller { - /* - * version number to track changes in the definition of - * the data structures in this file. - */ - uint32_t config_protocol_version; - uint32_t controller_id; /* RSM network id */ - wrsm_fmnodeid_t fmnodeid; /* FM node id */ - char hostname[WRSM_HOSTNAMELEN]; /* solaris hostname of local node */ - /* - * version number to identify the version of the RSM network - * this wrsm_controller_t is participating in. - */ - uint64_t version_stamp; - wrsm_cnodeid_t cnodeid; - int nmembers; /* number of elements in the members list */ - /* - * routing data - */ - WRSM_ALIGN_64(wrsm_routing_data_t *, routing); - /* - * List of network members sorted by cnodeid - */ - WRSM_ALIGN_64(wrsm_net_member_t **, members); -} wrsm_controller_t; - - - -/* - * Used as argument to INITIALCFG, REPLACECFG and GETCFG ioctls - */ -typedef struct wrsm_admin_arg_config { - uint32_t ioctl_version; - uint32_t controller_id; - uint64_t controller_data_size; - WRSM_ALIGN_64(wrsm_controller_t *, controller); -} wrsm_admin_arg_config_t; - -/* - * Used as argument to INSTALLCFG, CHECKCFG, and ENABLECFG ioctls - */ -typedef struct wrsm_admin_arg_wci { - uint32_t ioctl_version; - uint32_t controller_id; - uint64_t nwcis; - WRSM_ALIGN_64(wrsm_safari_port_t *, wci_ids); -} wrsm_admin_arg_wci_t; - -/* - * Used as argument to CTLR_PING ioctl - */ -typedef struct wrsm_ping_arg { - uint32_t ioctl_version; - wrsm_cnodeid_t target; - uint32_t count; - uint64_t time; /* total ping time in us */ -} wrsm_ping_arg_t; - -/* - * Used as argument to CTLR_MBOX ioctl - */ -typedef struct wrsm_link_arg { - uint32_t ioctl_version; - int cmd; - wrsm_safari_port_t wci_id; - wrsm_linkid_t link_num; - uint32_t led_state; - uint32_t link_state; -} wrsm_link_arg_t; - - -/* - * Used as argument to CTLR_SEG ioctl - */ -typedef struct wrsm_seg_arg { - uint32_t ioctl_version; - int cmd; - uint_t segid; - uint_t addr; - uint64_t bytes; - uint64_t offset; - uint64_t length; - char *datap; - uint_t barrier_mode; -} wrsm_seg_arg_t; - - -/* - * Used as argument to CTLR_SESS ioctls - */ -typedef struct wrsm_sess_arg { - uint32_t ioctl_version; - int cmd; - wrsm_cnodeid_t cnodeid; - wrsm_cnode_bitmask_t cnode_bitmask; -} wrsm_sess_arg_t; - -extern void *wrsm_cf_pack(wrsm_controller_t *cont, int *sizep); - -#endif /* _ASM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_CONFIG_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_driver.h b/usr/src/uts/sun4u/sys/wrsm_driver.h deleted file mode 100644 index 5251d0bb7b..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_driver.h +++ /dev/null @@ -1,251 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_WRSM_DRIVER_H -#define _SYS_WRSM_DRIVER_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/wci_offsets.h> -#include <sys/wrsm_common.h> -#include <sys/wrsm_config.h> -#include <sys/wci_common.h> -#include <sys/wrsm.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * only wrsm_driver.c should include this header. - * all others should include wrsm_lc.c - */ - -/* - * Timeout periods in seconds. (Multiplied by MICROSEC to get the number - * of microsecs for the requested number of seconds - for drv_to_hz().) - */ -#define WRSM_POLL_TIMEOUT_USEC (1 * MICROSEC) /* interval for polling links */ -#define WRSM_RESTART_TIMEOUT_USEC (120 * MICROSEC) /* link restart timeout */ -/* shortterm interval is given in minutes */ -#define WRSM_SHORTTERM_USEC (wrsm_shortterm_interval * 60 * MICROSEC) -#define WRSM_LINK_MAX_WAIT_COUNT 60 /* Poll periods */ -#define WRSM_AVG_WEIGHT 10 -#define WRSM_SHORTTERM_INTERVAL 60 -#define WRSM_SHORTS_PER_LONGTERM 24 - - -/* - * index of register ranges in "registers" property - */ -#define WRSM_REGS 0 -#define WRSM_SRAM 1 -#define ROUTEMAPRESET 0x0FFFFFFFFFFFFULL /* set 16 link 3 bits = 0x7 */ -#define CE_CNTMAX 0xFF /* reset value for ce_count */ -#define REGMASK 0x1F /* mask for lower reg bits */ - -#define UNMASKALL 0x0ULL /* unmask all bit fields */ -#define MASKALL 0xFFFFFFFFFFFFFFFFULL - -/* - * WRSM OBP properties - */ - -#define OBP_WRSM_PORTID "portid" -#define WRSM_RSM_CTR "rsm_controller" -#define WRSM_ADMIN "admin" - -#define MAXERRORS 1000 - -typedef union { - struct { - boolean_t bad_linknum : 1; - boolean_t bad_safari_port_id : 1; - boolean_t bad_gnid : 1; - boolean_t bad_cnode : 1; - boolean_t bad_ctlr_version : 1; - boolean_t bad_ctlr_id : 1; - boolean_t bad_reachablewnode : 1; - boolean_t bad_common_version : 1; - } reasons; - uint32_t val; -} wrsm_linkbadconfig_reasons_t; - -typedef enum { - wrsm_device, /* a real WCI */ - wrsm_rsm_controller, /* a pseudo dev for an RSM controller */ - wrsm_admin /* the wrsm admin pseudo dev */ -} wrsm_devi_type_t; - - -typedef struct { - volatile uint64_t *wrsm_link_err_cnt_addr; /* pre-calc offset */ - wrsm_link_req_state_t link_req_state; /* link state */ - wrsm_linkbadconfig_reasons_t badconfig_reasons; - boolean_t tell_mh_link_is_up; /* if TRUE call call mh_link_is_up */ - /* for links just coming up */ - boolean_t user_down_requested; /* user ioctl requested link down */ - boolean_t loopback_test_mode; - wnodeid_t remote_wnode; - uint32_t interval_count; - uint32_t cont_errs; /* # of times in a row polling found errors */ - uint32_t err_takedown_sum; - uint32_t num_err_takedown; - uint32_t last_err_takedown; - uint32_t max_err_takedown; - uint32_t avg_err_takedown; - uint32_t num_cfg_takedown; - uint32_t num_disconnected_takedown; - uint32_t num_requested_bringups; - uint32_t num_completed_bringups; - uint32_t num_errors; - uint32_t shortterm_errsum; - uint32_t shortterm_last_errors; - uint32_t shortterm_max_errors; - uint32_t shortterm_avg_errors; - uint32_t longterm_shortterms; - uint32_t longterm_errsum; - uint32_t longterm_last_errors; - uint32_t longterm_max_errors; - uint32_t longterm_avg_errors; - uint16_t remote_gnids_active; - uint32_t waiting_count; - boolean_t poll_reachable; /* remote end is wcx ready to be polled */ -} link_t; - -/* globals */ -/* weight of old average in error average */ -extern uint_t wrsm_avg_weight; -/* minutes in shortterm error interval */ -extern uint_t wrsm_shortterm_interval; -/* number of shortterm intervals per long term interval */ -extern uint_t wrsm_shorts_per_longterm; - -/* - * lc_mutex primarily is used to secure changes to the link states - * however, in addition to protecting per link states changes, the counters: - * oldlink_waitdown_cnt and newlink_waitup_cnt must also - * be protected from changes of different threads. lc_mutex is also - * used to protect any access to softsp->config. - * newlink_waitup_cnt is important for keeping track of the NEW bringup - * link requested initiated in lc_installconfig. - * oldlink_waitdown_cnt is important for keeping track of the lc_cleanconfig - * initiated takedown request. - * the count of oldlink_waitdown_cnt & newlink_waitup_cnt is how the LC - * differentiates between events in the LC forcing takedowns and bringup - * and external events requesting takedown and bringups. These two counters - * increment on request and they are decremented when the task is done. - * They are both 0 when there are no pending external request. - * Polling on a link starts in wciinit and ends in wcifini - */ -struct wrsm_soft_state { - dev_info_t *dip; /* dev info of myself */ - timeout_id_t err_timeout_id; /* non-zero means link polling active */ - boolean_t need_err_timeout; /* err timeout was DDI_SUSPENDED */ - timeout_id_t restart_timeout_id; /* timeout handle for link restart */ - boolean_t need_restart_timeout; /* restart timeout was DDI_SUSPENDED */ - boolean_t suspended; /* ddi-suspended */ - int instance; /* DDI instance */ - int minor; /* device minor number */ - int board; /* Board number */ - cnodeid_t local_cnode; - wnodeid_t local_wnode; - gnid_t local_gnid; - wnodeid_t gnid_to_wnode[WRSM_MAX_WNODES]; - - safari_port_t portid; /* safari extended agent id */ - kmutex_t lc_mutex; /* lock for link related task */ - kmutex_t wrsm_mutex; /* mutex to protect open file flag */ - kmutex_t cmmu_mutex; /* CMMU FLUSH mutex */ - kcondvar_t goinstallconfig; /* condition var to signal */ - /* lc_installconfig clear to go */ - int oldlink_waitdown_cnt; /* cnt of takedown request on old */ - /* links/existing links */ - int newlink_waitup_cnt; /* cnt of new bringup link request */ - int open; /* flag indicates if device is open */ - link_t links[WRSM_LINKS_PER_WCI]; /* optical links */ - clock_t shortterm_start; - wrsm_devi_type_t type; /* type of device */ - - off_t sramsize; - unsigned char *wrsm_sram; /* paddr for SRAM */ - volatile unsigned char *wrsm_regs; /* vaddr WRSM regs */ - - /* - * wci revision: wci1, wci2 or wci3 where - * wci 1 wci_id.parid = 0x4776 - * wci 2 wci_id.parid = 0x4147 - * wci 3 wci_id.parid = 0x4063 - */ - int wci_rev; /* wci1, wci2, wci3 .. ? */ - /* pre-calc offset of ecc registers */ - volatile uint64_t *wci_dco_ce_cnt_vaddr; - volatile uint64_t *wci_dc_esr_vaddr; - volatile uint64_t *wci_dco_state_vaddr; - - volatile uint64_t *wci_ca_esr_0_vaddr; - volatile uint64_t *wci_ra_esr_1_vaddr; - - volatile uint64_t *wci_ca_ecc_addr_vaddr; - volatile uint64_t *wci_ra_ecc_addr_vaddr; - - volatile uint64_t *wci_cci_esr_vaddr; - - wrsm_wci_data_t *config; /* configuration data for wci */ - wrsm_controller_t *ctlr_config; /* config for entire controller */ - ncwci_handle_t nc; /* opaque NC handles */ - - /* WCI common soft state */ - struct wci_common_soft_state wci_common_softst; - - /* kstat structs */ - kstat_t *wrsm_wci_ksp; - /* kstat saved values */ - uint32_t uc_sram_ecc_error; - uint32_t sram_ecc_errsum; - uint32_t num_sram_ecc_errors; - uint32_t last_sram_ecc_errors; - uint32_t max_sram_ecc_errors; - uint32_t avg_sram_ecc_errors; /* weighted average */ -}; - - -typedef struct wrsm_soft_state wrsm_softstate_t; - -/* Use physical address for SRAM loads/stores */ -#define LOADPHYS(a, b) ((a) = lddphysio((uint64_t)(b))) -#define STOREPHYS(a, b) stdphysio((uint64_t)(b), (a)) - -/* - * wrsm open flag - */ -#define WRSM_OPEN_EXCLUSIVE (-1) - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WRSM_DRIVER_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_intr.h b/usr/src/uts/sun4u/sys/wrsm_intr.h deleted file mode 100644 index 00792dcbb6..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_intr.h +++ /dev/null @@ -1,178 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_INTR_H -#define _WRSM_INTR_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifndef _ASM - -#include <sys/wrsm_common.h> -#include <sys/wrsm_cmmu.h> -#include <sys/processor.h> -#include <sys/rsm/rsmpi.h> - -#endif /* _ASM */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Limit for rsm_intr_t */ -#define WRSM_INTR_TYPE_MAX RSM_INTR_T_NSVC -#define WRSM_TL_INTR_TYPE (RSM_INTR_T_DRV_BASE + 1) /* transport */ -#define WRSM_SMPUT_INTR_TYPE (RSM_INTR_T_DRV_BASE + 2) /* small put */ - -/* Flags for wrsm_intr_create_recvq */ -#define WRSM_CREATE_RECVQ_NOFLAGS 0x0 -#define WRSM_CREATE_RECVQ_SLEEP 0x1 -#define WRSM_CREATE_RECVQ_USER 0x2 -#define WRSM_CREATE_RECVQ_INVALID 0x4 - -/* Default value for is_wait in wrsm_intr_send() */ -#define WRSM_INTR_WAIT_DEFAULT -1 - -#ifndef _ASM - -/* - * Receive Queue structures - */ -struct wrsm_intr_recvq; -typedef struct wrsm_intr_recvq wrsm_intr_recvq_t; - -/* - * Client functions - */ - -/* Initialize the interrupt component for this network */ -int wrsm_intr_init(wrsm_network_t *); - -/* Destroy the interrupt component for this network */ -void wrsm_intr_fini(wrsm_network_t *); - -/* The following prints all intr data structures, for debug only */ -void wrsm_intr_print(wrsm_network_t *); - -/* - * WCI Functions - */ - -/* Inform the interrupt component of a new WCI. Returns -1 if add_intr fails */ -int wrsm_intr_newwci(wrsm_network_t *, lcwci_handle_t); - -/* Inform the interrupt component that a WCI is going away */ -void wrsm_intr_delwci(wrsm_network_t *, lcwci_handle_t); - -/* - * Handler Management Functions - */ - -/* Registers a handler for a specific interrupt type - rsmpi function */ -int wrsmrsm_register_handler(rsm_controller_handle_t, - rsm_controller_object_t *controller_obj, rsm_intr_t type, rsm_intr_hand_t, - rsm_intr_hand_arg_t, rsm_addr_t senders_list[], - uint_t senders_list_length); - -/* Registers a handler for a specific interrupt type - driver function */ -int wrsm_register_handler(wrsm_network_t *, - rsm_controller_object_t *controller_obj, rsm_intr_t type, rsm_intr_hand_t, - rsm_intr_hand_arg_t, rsm_addr_t senders_list[], - uint_t senders_list_length); - -/* Unregisters a handler - rsmpi function */ -int wrsmrsm_unregister_handler(rsm_controller_handle_t, rsm_intr_t type, - rsm_intr_hand_t, rsm_intr_hand_arg_t); - -/* Unregisters a handler - driver function */ -int wrsm_unregister_handler(wrsm_network_t *, rsm_intr_t type, rsm_intr_hand_t, - rsm_intr_hand_arg_t); - -/* - * Receive Queue Functions - */ - -/* - * Creates a receive queue of a given type. User must have allocated a - * CMMU tuple in advance. - */ -int wrsm_intr_create_recvq(wrsm_network_t *, rsm_intr_t type, - size_t num_packets, wrsm_cmmu_index_t cmmu_index, wrsm_intr_recvq_t **, - cnodeid_t from_cnode, void *exportseg, int flags); - -/* Destroys the receive queue. Caller must free the CMMU tuple. */ -void wrsm_intr_destroy_recvq(wrsm_network_t *, wrsm_intr_recvq_t *); - -/* Flushes in progress interrupts for the receive queue. */ -void wrsm_intr_flush_recvq(wrsm_intr_recvq_t *); - -/* Sends a message */ -int wrsm_intr_send(wrsm_network_t *, void *remote_addr, cnodeid_t remote_cnode, - void *aligned_buf, int is_flags, clock_t is_wait, int sendq_flags); - -/* - * RSMPI Functions - */ - -/* Initializes RSMPI portions of intr */ -void wrsm_intr_rsminit(wrsm_network_t *); - -/* Cleans-up RSMPI portions of intr */ -void wrsm_intr_rsmfini(wrsm_network_t *); - -/* Creates a send queue */ -int wrsm_sendq_create(rsm_controller_handle_t, rsm_addr_t, rsm_intr_t, - rsm_intr_pri_t, size_t qdepth, uint_t flags, rsm_resource_callback_t, - rsm_resource_callback_arg_t, rsm_send_q_handle_t *); - -/* Reconfigure some of the attributes of an interrupt queue */ -int wrsm_sendq_config(rsm_send_q_handle_t, rsm_intr_pri_t, size_t qdepth, - uint_t flags, rsm_resource_callback_t, rsm_resource_callback_arg_t); - -/* Destroys an interrupt queue, freeing all resources allocated */ -int wrsm_sendq_destroy(rsm_send_q_handle_t); - -/* Enqueues a datagram on an interrupt queue */ -int wrsm_send(rsm_send_q_handle_t, rsm_send_t *, rsm_barrier_t *); - -/* - * Performs a 64-byte block remote read. - * Assumes source addressis 64-byte aligned, and does no checking. - */ -void wrsm_blkread(void *src, void *dst, size_t num_blocks); -/* - * Performs a 64-byte block write. - * Assumes destination address is 64-byte aligned, and does no checking. - */ -void wrsm_blkwrite(void *src, void *dst, size_t num_blocks); - -#endif /* _ASM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_INTR_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_intr_impl.h b/usr/src/uts/sun4u/sys/wrsm_intr_impl.h deleted file mode 100644 index 8bd83b5f61..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_intr_impl.h +++ /dev/null @@ -1,326 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _WRSM_INTR_IMPL_H -#define _WRSM_INTR_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Setting up recvq overflow */ -#define WRSM_CMMU_0_ERROR_BIT 0x2 -#define WRSM_CMMU_0_VALID 0x4000000 -#define WRSM_CMMU_0_TYPE (2 << 24) -#define WRSM_CMMU_0_FROMALL (1 << 27) -#define WRSM_CMMU_0_WRITABLE (1 << 28) -#define WRSM_CMMU_0_DISABLE (WRSM_CMMU_0_ERROR_BIT | WRSM_CMMU_0_VALID | \ - WRSM_CMMU_0_TYPE | WRSM_CMMU_0_FROMALL | \ - WRSM_CMMU_0_WRITABLE) - -/* - * Recvq pointers are stored in a 2-level tree, implemented as an array of - * pointers to an array of recvq pointers. The recvq_tables array gives access - * to a table of 256 pointers. Each entry in recvq_tables will remain NULL - * until all the entries in all the existing tables are used, and a new - * table needs to be allocated. Tables will never be deleted to eliminate the - * need to lock a table from a TL1 interrupt. Given a 16-bit mondo vector - * argument, the macro MONDOARG2TABLE generates the index into recvq_tables, - * while the macro MONDOARG2TABLEINDEX generates the index into the selected - * table, which provides the recvq pointer. - * - * - * recvq_tables[256] - * _____________________________..__________ - * |0 |1 |2 |3 |4 |5 |6 | |254|255| - * | * |nul|nul|nul|nul|nul|nul| |nul|nul| - * |_|_|___|___|___|___|___|___|_..__|___|___| - * | - * | table[256] - * _V_ - * |0 | - * | *-+--> recvq with mondo arg 0 - * |___| - * |1 | - * | *-+--> recvq with mondo arg 1 - * |___| - * |2 | - * |nul| - * |___| - * | | - * ~ ~ - * | | - * |___| - * |255| - * |nul| - * |___| - * - */ -#define WRSM_INTR_RECVQ_TABLE_SIZE 256 -#define WRSM_INTR_RECVQ_TABLES 256 -#define WRSM_INTR_TABLE_MASK 0xff -#define WRSM_INTR_TABLE_SHIFT 8 -#define WRSM_INTR_INDEX_MASK 0xff -#define WRSM_INTR_INDEX_SHIFT 0 - -/* Values for the PSL when it is empty */ - -/* Empty, but softint is active */ -#define WRSM_INTR_PSL_EMPTY (wrsm_intr_recvq_t *)2 -/* Empty and no softint running; can't cast, as used in wrsm_trap.s */ -#define WRSM_INTR_PSL_IDLE 1 - - -#define WRSM_MONDO2TABLE(m) \ - (((m) >> WRSM_INTR_TABLE_SHIFT) & WRSM_INTR_TABLE_MASK) -#define WRSM_MONDO2INDEX(m) \ - (((m) >> WRSM_INTR_INDEX_SHIFT) & WRSM_INTR_INDEX_MASK) - -/* Each table array contains pointers to WRSM_INTR_RECVQ_TABLES tables */ -#define WRSM_INTR_RECVQ_TABLES_ARRAY_SIZE \ - (WRSM_INTR_RECVQ_TABLES * sizeof (void *)) - -#define WRSM_INTR_PACKET_SIZE 64 - -#ifndef _ASM - -/* - * Receive Queue structures - */ -typedef struct __rsm_send_q_handle wrsm_sendq_t; - -typedef uint64_t wrsm_intr_packet_t[WRSM_INTR_PACKET_SIZE/sizeof (uint64_t)]; - -/* Describes an interrupt drainer (software interrupt thread) */ -typedef struct wrsm_intr_drainer { - uint64_t drainer_inum; /* Softint vector for drainer */ - struct wrsm_intr_recvq *drainer_psl; - struct wrsm_intr_drainer *next; /* Next in circular list */ -} wrsm_intr_drainer_t; - -/* Describes an interrupt target CPU */ -typedef struct wrsm_intr_target { - processorid_t cpu_id; - struct wrsm_intr_recvq *recvq_list; - wrsm_intr_drainer_t *drainer; - uint32_t index; - int intr_dist_mondo; - struct wrsm_intr_target *next; /* Next in circular list */ -} wrsm_intr_target_t; - -/* An element in a linked-list of intr handlers, part of wrsm_intr_service */ -typedef struct wrsm_intr_handler { - rsm_intr_hand_t func; - rsm_intr_hand_arg_t arg; - rsm_controller_object_t *controller_obj; - cnode_bitmask_t cnodes; - struct wrsm_intr_handler *next; -} wrsm_intr_handler_t; - -/* Describes an interrupt service, including list of handlers and a recvq */ -typedef struct wrsm_intr_service { - wrsm_network_t *net; - rsm_intr_t type; - wrsm_intr_handler_t *handler_list; - kmutex_t handler_mutex; /* Protects access to handler_list */ - struct wrsm_intr_recvq *recvq_list; - kmutex_t recvq_mutex; /* Protects access to recvq_list */ -} wrsm_intr_service_t; - -/* State of packet ring. Must be 64-bits for casx */ -typedef struct { - uint16_t lock; /* If non-zero, trap is running */ - uint16_t head; /* Next available packet */ - uint16_t tail; /* Last consumed packet */ - uint16_t size; /* Size, in packets */ -} wrsm_intr_packet_ring_info_t; - -typedef union { - wrsm_intr_packet_ring_info_t info; - uint64_t val; -} wrsm_intr_packet_ring_union_t; - -/* The receive queue structure */ -struct wrsm_intr_recvq { - wrsm_intr_packet_t *packet_ring; /* Pointer to packet ring */ - wrsm_intr_packet_ring_union_t packet_ring_info; - uint32_t high_water_mark; /* If head-tail>hwm, set user_err */ - uint32_t low_water_mark; /* If head-tail<lwm, clear user_err */ - caddr_t *sram_paddr; /* Points to array of WCI sram addr */ - - boolean_t in_use; - boolean_t delete_me; - - uint_t cmmu_mondo; - wrsm_cmmu_index_t cmmu_index; - cnodeid_t from_cnode; - - wrsm_intr_drainer_t *drainer; /* Drainer of this recvq */ - wrsm_intr_target_t *target; /* Target CPU of this recvq */ - wrsm_intr_service_t *service; /* Service for this recvq */ - - /* Pointers for various linked lists */ - struct wrsm_intr_recvq *service_next; - struct wrsm_intr_recvq *target_next; - struct wrsm_intr_recvq *drainer_next; - struct wrsm_intr_recvq *recvq_next; - - boolean_t user_interrupt; - void *exportseg; /* info for small puts */ - wrsm_cmmu_tuple_t *tuples; /* used for remote recvq destroys */ - kmutex_t mutex; - - wrsm_network_t *net; - /* count of how often high-water mark has been reached */ - uint64_t high_water_count; -}; - -/* - * Used to map a DMV argument (16-bits) to a recvq struct pointer. The - * The wrsm_interrupt_t structure contains an array of 256 pointers to - * recvq_table, which contains 256 recvq pointers. Use the macros - * MONDOARG2TABLE to get the table pointer from the wrsm_interrupt structure, - * the the macro MONDOARG2TABLEINDEX to index into the wrsm_intr_recvq_table - * to select the correct recvq pointer. - */ -typedef wrsm_intr_recvq_t *wrsm_intr_recvq_table_t[WRSM_INTR_RECVQ_TABLE_SIZE]; - -/* The sendq structure */ -struct __rsm_send_q_handle { - wrsm_network_t *net; - caddr_t vaddr; - uint_t nc_slice; - off_t nc_off; - uint_t offset; - uint64_t qid; - uint_t mondo; - kmutex_t mutex; - cnodeid_t dest_cnode; - size_t qdepth; - rsm_intr_t service; - int flags; - boolean_t net_reset; - boolean_t fence_up; - wrsm_sendq_t *next; -}; - -/* - * Interrupt Structure part of wrsm_network_t - */ -struct wrsm_interrupt { - wrsm_intr_recvq_table_t *recvq_tables[WRSM_INTR_RECVQ_TABLES]; - wrsm_intr_service_t services[WRSM_INTR_TYPE_MAX]; - wrsm_intr_drainer_t *drainers; /* Circular list of drainers */ - wrsm_intr_target_t *targets; /* Circular list of targets */ - wrsm_intr_recvq_t *recvq_list[WRSM_MAX_CNODES]; /* List of recvqs */ - wrsm_sendq_t *sendq_list[WRSM_MAX_CNODES]; /* List of sendq's */ - kmutex_t mutex; /* Take before any other interrupt locks */ - kcondvar_t resource_cv; - safari_port_t wci_safari_port; /* Sample WCI used for DMV inums */ - /* - * The following arrays is used for flow control. If the trap - * handler detects a high water condition on a recvq, it must - * set the user_error flag in that recvq's cmmu for all WCIs - * (actually, it's sufficient to set the cmmu entry to valid - * and user_error). To do that, it must know the address of - * the sram. The array cmmu_paddr contains the physical address - * of the CMMU entry in sram (or NULL) for every WCI in this - * controller. - */ - caddr_t sram_paddr[WRSM_MAX_WCIS]; - safari_port_t wci_ids[WRSM_MAX_WCIS]; -}; - -/* - * Local Function Prototypes - */ -static void handler_init(wrsm_intr_handler_t *, rsm_intr_hand_t, - rsm_intr_hand_arg_t, cnode_bitmask_t, rsm_controller_object_t *); -static void handler_fini(wrsm_intr_handler_t *); -static rsm_intr_hand_ret_t handler_callback(wrsm_intr_handler_t *, - rsm_intr_q_op_t q_op, cnodeid_t, void *, size_t); - -static void service_init(wrsm_intr_service_t *, wrsm_network_t *, rsm_intr_t); -static void service_fini(wrsm_intr_service_t *); -static void service_add_recvq(wrsm_intr_service_t *, wrsm_intr_recvq_t *); -static void service_rem_recvq(wrsm_intr_service_t *, wrsm_intr_recvq_t *); -static void service_add_handler(wrsm_intr_service_t *, wrsm_intr_handler_t *); -static wrsm_intr_handler_t *service_rem_handler(wrsm_intr_service_t *, - rsm_intr_hand_t, rsm_intr_hand_arg_t); -static void service_callback(wrsm_intr_service_t *, void *, size_t, cnodeid_t); - -static void service_list_init(wrsm_interrupt_t *, wrsm_network_t *); -static void service_list_fini(wrsm_interrupt_t *); - -static void target_init(wrsm_intr_target_t *, wrsm_intr_drainer_t *, uint32_t); -static void target_fini(wrsm_intr_target_t *); -static void target_readd_cpu(wrsm_network_t *, wrsm_intr_target_t *); -static void target_retarget(wrsm_network_t *, wrsm_intr_target_t *); -static void target_add_recvq(wrsm_intr_target_t *, wrsm_intr_recvq_t *); -static void target_rem_recvq(wrsm_intr_target_t *, wrsm_intr_recvq_t *); -static void target_print(wrsm_intr_target_t *); - -static void target_list_init(wrsm_interrupt_t *); -static void target_list_fini(wrsm_interrupt_t *); -static void target_list_readd_cpu(wrsm_network_t *net); -static wrsm_intr_target_t *target_list_get_next(wrsm_interrupt_t *); -static void target_list_print(wrsm_interrupt_t *); - -static int drainer_init(wrsm_intr_drainer_t *); -static void drainer_fini(wrsm_intr_drainer_t *); -static uint_t drainer_handler(caddr_t arg); -static void drainer_print(wrsm_intr_drainer_t *); - -static int drainer_list_init(wrsm_interrupt_t *); -static void drainer_list_fini(wrsm_interrupt_t *); -static wrsm_intr_drainer_t *drainer_list_get_next(wrsm_interrupt_t *); -static void drainer_list_print(wrsm_interrupt_t *); - -static void recvq_fini(wrsm_network_t *, wrsm_intr_recvq_t *); -static size_t recvq_get_packet(wrsm_intr_recvq_t *, wrsm_intr_packet_t, - uint32_t *num_packets); -static void recvq_callback(wrsm_intr_recvq_t *); -static void recvq_print(wrsm_intr_recvq_t *); - -static void recvq_table_init(wrsm_interrupt_t *); -static void recvq_table_fini(wrsm_interrupt_t *, wrsm_network_t *); -static void recvq_table_alloc_table(wrsm_interrupt_t *, unsigned table); -static int recvq_table_alloc_entry(wrsm_interrupt_t *); -static void recvq_table_free_entry(wrsm_interrupt_t *, int cmmu_mondo); -static void recvq_table_set(wrsm_interrupt_t *, int pos, wrsm_intr_recvq_t *); -static void recvq_table_print(wrsm_interrupt_t *); - -extern void wrsm_tl1_handler(); - - -#endif /* _ASM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_INTR_IMPL_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_lc.h b/usr/src/uts/sun4u/sys/wrsm_lc.h deleted file mode 100644 index 5880f7e6a2..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_lc.h +++ /dev/null @@ -1,154 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_WRSM_LC_H -#define _SYS_WRSM_LC_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/wci_cmmu.h> -#include <sys/wrsm.h> -#include <sys/wrsm_driver.h> -#include <sys/wrsm_config.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * function return values - */ -#define WRSM_LC_SUCCESS 0 -#define WRSM_LC_NOPAROLI 1 -#define WRSM_LC_INVALIDARG 2 - -typedef enum { - CMMU_TYPE_CACHEABLE = 0, - CMMU_TYPE_STICK = 1, - CMMU_TYPE_INTERRUPT = 2, - CMMU_TYPE_ATOMIC = 3 -} wrsm_cmmu_type_t; - -/* Declaration of abstract CMMU entry */ -typedef struct { - wci_sram_array_as_cmmu_0_u entry_0; - union { - struct wci_sram_array_as_cmmu_1_int intr; - struct wci_sram_array_as_cmmu_1_addr addr; - uint64_t val; - } entry_1; -} wrsm_cmmu_t; - -#define WRSM_GNID_IS_WCX(w) (w >= WRSM_MAX_WNODES) - -/* cmmu_update flags */ -#define CMMU_UPDATE_MONDO 0x00001 -#define CMMU_UPDATE_FROMNODE 0x00002 -#define CMMU_UPDATE_TYPE 0x00004 -#define CMMU_UPDATE_VALID 0x00008 -#define CMMU_UPDATE_FROMALL 0x00010 -#define CMMU_UPDATE_WRITABLE 0x00020 -#define CMMU_UPDATE_USERERROR 0x00040 -#define CMMU_UPDATE_LARGEPAGE 0x00080 -#define CMMU_UPDATE_ENABLEPERF 0x00100 -#define CMMU_UPDATE_LPA 0x00200 -#define CMMU_UPDATE_INTRDEST 0x00400 -#define CMMU_UPDATE_FLUSH 0x08000 -#define CMMU_UPDATE_ALL 0x0FFFF -#define CMMU_UPDATE_WRITEONLY 0x10000 -#define CMMU_UPDATE_WRITE_0 0x20000 -#define CMMU_UPDATE_WRITE_1 0x40000 - -typedef uint32_t wrsm_cmmu_flags_t; - -int wrsm_lc_loopback_enable(wrsm_softstate_t *softsp, - uint32_t local_link_num); -int wrsm_lc_loopback_disable(wrsm_softstate_t *softsp, - uint32_t local_link_num); -int wrsm_lc_linktest(wrsm_softstate_t *softsp, - wrsm_linktest_arg_t *local_link_num); -int wrsm_lc_user_linkdown(wrsm_softstate_t *softsp, int linkno); -int wrsm_lc_user_linkup(wrsm_softstate_t *softsp, int linkno); - -void wrsm_lc_setup_timeout_speeds(void); -safari_port_t wrsm_lc_get_safid(lcwci_handle_t lcwci); -int wrsm_lc_get_instance(lcwci_handle_t lcwci); -boolean_t wrsm_lc_verifyconfig(lcwci_handle_t lcwci, wrsm_wci_data_t *config); -void wrsm_lc_replaceconfig(lcwci_handle_t lcwci, ncwci_handle_t nc, - wrsm_wci_data_t *config, wrsm_controller_t *ctlr_config); -void wrsm_lc_cleanconfig(lcwci_handle_t lcwci); -void wrsm_lc_installconfig(lcwci_handle_t lcwci); -void wrsm_lc_enableconfig(lcwci_handle_t lcwci); - -/* for DDI_SUSPEND, DDI_RESUME */ -void wrsm_lc_suspend(wrsm_softstate_t *softsp); -void wrsm_lc_resume(wrsm_softstate_t *softsp); - -/* register manipulation functions - read/write */ -void wrsm_lc_cesr_read(lcwci_handle_t lc, safari_port_t dev_id, - uint64_t *entry); -void wrsm_lc_cesr_write(lcwci_handle_t lc, safari_port_t dev_id, - uint64_t entry); -void wrsm_lc_csr_read(lcwci_handle_t lc, uint64_t reg_offset, uint64_t *entry); -void wrsm_lc_csr_write(lcwci_handle_t lc, uint64_t reg_offset, uint64_t entry); - -void wrsm_lc_cmmu_read(lcwci_handle_t lc, wrsm_cmmu_t *cmmu_entry, - uint32_t index); -void wrsm_lc_cmmu_update(lcwci_handle_t lc, wrsm_cmmu_t *cmmu_entry, - uint32_t index, wrsm_cmmu_flags_t flag); -int wrsm_lc_num_cmmu_entries_get(lcwci_handle_t lc); - -void wrsm_lc_phys_link_up(safari_port_t local_port, uint32_t local_link_num, - fmnodeid_t remote_fmnodeid, gnid_t remote_gnid, - uint32_t remote_link_num, safari_port_t remote_port, - uint64_t remote_partition_version, uint32_t remote_partition_id); -void wrsm_lc_phys_link_down(safari_port_t local_port, uint32_t local_link_num); -void wrsm_lc_sc_crash(lcwci_handle_t lc); - -/* the following are supplied for the mh to modify the map registers */ -void wrsm_lc_set_route(wrsm_softstate_t *softsp, wnodeid_t wnode, - linkid_t linknum, int map); -linkid_t wrsm_lc_get_route(wrsm_softstate_t *softsp, wnodeid_t wnode, int map); - -/* The following is for the interrupt trap handler only */ -caddr_t wrsm_lc_get_sram_paddr(lcwci_handle_t lc); - -/* the following is for standalone use, when system controller can't be used */ -void get_remote_config_data(safari_port_t wci_id, uint32_t link_num, - fmnodeid_t *remote_fmnodeid, gnid_t *remote_gnid, linkid_t *remote_link, - safari_port_t *remote_port, volatile uchar_t **wrsm_regs); - -/* the following handles ioctl requests to modify wci registers */ -int wrsm_lc_register_ioctl(wrsm_softstate_t *softsp, int cmd, - intptr_t arg, int flag, cred_t *cred_p, int *rval_p); - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WRSM_LC_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_memseg.h b/usr/src/uts/sun4u/sys/wrsm_memseg.h deleted file mode 100644 index cee9c8bcd8..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_memseg.h +++ /dev/null @@ -1,158 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _WRSM_MEMSEG_H -#define _WRSM_MEMSEG_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * stuff exported by the RSMPI memseg module - */ - -#include <sys/rsm/rsmpi.h> -#include <sys/wrsm_transport.h> - -#ifdef __cplusplus -extern "C" { -#endif - - -void wrsm_memseg_init(void); -void wrsm_memseg_fini(void); -void wrsm_memseg_network_init(wrsm_network_t *); -void wrsm_memseg_network_fini(wrsm_network_t *); -void wrsm_memseg_node_init(wrsm_node_t *); -void wrsm_memseg_node_fini(wrsm_node_t *); -void *wrsm_alloc(size_t, int); -void wrsm_free(void *, size_t); - -int wrsmrsm_seg_create(rsm_controller_handle_t controller, - rsm_memseg_export_handle_t *memsegp, - size_t size, uint_t flags, rsm_memory_local_t *memory, - rsm_resource_callback_t callback, - rsm_resource_callback_arg_t callback_arg); - -int wrsmrsm_seg_destroy(rsm_memseg_export_handle_t handle); - -int wrsmrsm_bind(rsm_memseg_export_handle_t memseg, - off_t offset, - rsm_memory_local_t *memory, - rsm_resource_callback_t callback, - rsm_resource_callback_arg_t callback_arg); - -int wrsmrsm_unbind(rsm_memseg_export_handle_t memseg, off_t offset, - size_t length); - -int wrsmrsm_rebind(rsm_memseg_export_handle_t memseg, off_t offset, - rsm_memory_local_t *memory, rsm_resource_callback_t callback, - rsm_resource_callback_arg_t callback_arg); - -int wrsmrsm_publish(rsm_memseg_export_handle_t memseg, - rsm_access_entry_t access_list[], - uint_t access_list_length, - rsm_memseg_id_t segid, - rsm_resource_callback_t callback, - rsm_resource_callback_arg_t callback_arg); - -int wrsmrsm_unpublish(rsm_memseg_export_handle_t memseg); - -int wrsmrsm_republish(rsm_memseg_export_handle_t memseg, - rsm_access_entry_t access_list[], uint_t access_list_length, - rsm_resource_callback_t callback, rsm_resource_callback_arg_t callback_arg); - -int wrsmrsm_connect(rsm_controller_handle_t controller, - rsm_addr_t addr, rsm_memseg_id_t segid, - rsm_memseg_import_handle_t *im_memseg); - -int wrsmrsm_disconnect(rsm_memseg_import_handle_t im_memseg); - -int wrsmrsm_map(rsm_memseg_import_handle_t im_memseg, off_t offset, - size_t len, size_t *map_len, dev_info_t **dipp, uint_t *dev_register, - off_t *dev_offset, rsm_resource_callback_t callback, - rsm_resource_callback_arg_t arg); - -int wrsmrsm_unmap(rsm_memseg_import_handle_t im_memseg); - -int wrsmrsm_put(rsm_memseg_import_handle_t im_memseg, off_t offset, - void *datap, size_t length); -int wrsmrsm_put8(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint8_t *data, ulong_t rep_cnt, boolean_t byte_swap); -int wrsmrsm_put16(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint16_t *data, ulong_t rep_cnt, boolean_t byte_swap); -int wrsmrsm_put32(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint32_t *data, ulong_t rep_cnt, boolean_t byte_swap); -int wrsmrsm_put64(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint64_t *data, ulong_t rep_cnt, boolean_t byte_swap); - -int wrsmrsm_get(rsm_memseg_import_handle_t im_memseg, off_t offset, - void *datap, size_t length); -int wrsmrsm_get8(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint8_t *datap, ulong_t rep_cnt, boolean_t byte_swap); -int wrsmrsm_get16(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint16_t *datap, ulong_t rep_cnt, boolean_t byte_swap); -int wrsmrsm_get32(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint32_t *datap, ulong_t rep_cnt, boolean_t byte_swap); -int wrsmrsm_get64(rsm_memseg_import_handle_t im_memseg, off_t offset, - uint64_t *datap, ulong_t rep_cnt, boolean_t byte_swap); - - -void wrsm_free_exportsegs(wrsm_network_t *network); -void wrsm_free_importsegs(wrsm_network_t *network); - -/* for controller kstat */ -typedef struct memseg_stat_data { - uint_t export_count; - uint_t import_count; - uint_t export_published; - uint_t export_connected; - uint_t bytes_bound; -} wrsm_memseg_stat_data_t; - -void wrsm_memseg_stat(wrsm_network_t *network, wrsm_memseg_stat_data_t *data); - -typedef struct wrsm_memseg_evt_args { - wrsm_network_t *network; - wrsm_message_t msg; -} wrsm_memseg_evt_args_t; - -/* - * event functions for delivering incoming remote messages asynchronously - */ -boolean_t wrsm_memseg_msg_hdlr(wrsm_network_t *network, wrsm_message_t *msg); -void wrsm_connect_msg_evt(void *arg); -void wrsm_smallputmap_msg_evt(void *arg); -void wrsm_barriermap_msg_evt(void *arg); -void wrsm_segmap_msg_evt(void *arg); -void wrsm_disconnect_msg_evt(void *arg); -void wrsm_unpublish_msg_evt(void *arg); -void wrsm_access_msg_evt(void *arg); - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_MEMSEG_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_memseg_impl.h b/usr/src/uts/sun4u/sys/wrsm_memseg_impl.h deleted file mode 100644 index bdcd13cc72..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_memseg_impl.h +++ /dev/null @@ -1,436 +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 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _WRSM_MEMSEG_IMPL_H -#define _WRSM_MEMSEG_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * this file is included by the RSM memory segment module - */ - -#ifndef _ASM - -#include <sys/wrsm_common.h> -#include <sys/wrsm_cmmu.h> -#include <sys/wrsm_transport.h> -#include <sys/wrsm_intr.h> - -#endif /* _ASM */ - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define WRSM_SMPUT_PACKETRING_SIZE 50 - -#define WRSM_LONG_SIZE (sizeof (long)) -#define WRSM_LONG_SHIFT 3 -#define WRSM_LONG_MASK (sizeof (long) - 1) - - -#ifndef _ASM - -/* - * Hash for segid to iseginfo pointer mapping. - * Hash for segid to exportseg pointer mapping. - * Hash for segid to importset pointer mapping. - * - * Most likely the segid will be a low integer, so use lower bits - * of dev_t for hash index. - */ -#define WRSM_SEGID_HASH_SIZE 0x100 /* # of entries in hash table */ -#define WRSM_SEGID_HASH_SHIFT 0 -#define WRSM_SEGID_HASH_MASK \ - ((WRSM_SEGID_HASH_SIZE - 1) << WRSM_SEGID_HASH_SHIFT) -#define WRSM_SEGID_HASH_FUNC(r) \ - ((((uint_t)r) & WRSM_SEGID_HASH_MASK) >> WRSM_SEGID_HASH_SHIFT) - - - - -/* - * choose some middle bits of the pointer for the hash index - */ -#define WRSM_PTR_HASH_SIZE 0x100 /* # of entries in hash table */ -#define WRSM_PTR_HASH_SHIFT 7 -#define WRSM_PTR_HASH_MASK \ - ((WRSM_PTR_HASH_SIZE - 1) << WRSM_PTR_HASH_SHIFT) -#define WRSM_PTR_HASH_FUNC(r) \ - ((((uint_t)(uintptr_t)r) & WRSM_PTR_HASH_MASK) >> WRSM_PTR_HASH_SHIFT) - - - -typedef struct __rsm_memseg_export_handle exportseg_t; -typedef struct __rsm_memseg_import_handle importseg_t; -typedef struct iseginfo iseginfo_t; - - -/* - * list of cmmu entries, all one page size - */ -typedef struct cmmugrp { - off_t offset; /* offset into segment */ - off_t len; /* length (bytes) of region mapped */ - size_t pgbytes; /* size of page cmmu entry maps */ - unsigned num_tuples; /* number of cmmu tuples */ - wrsm_cmmu_tuple_t *tuples; /* array of cmmu tuples */ - struct cmmugrp *next; -} cmmugrp_t; - - -typedef struct mseg_intr_page { - wrsm_cmmu_tuple_t *tuple; - wrsm_intr_recvq_t *recvq; -} mseg_intr_page_t; - - -typedef struct barrier_page { - wrsm_cmmu_tuple_t *tuple; - caddr_t vaddr; -} barrier_page_t; - - -typedef struct mseg_node_export { - boolean_t allow_import; /* this node can access this seg? */ - rsm_permission_t perms; /* last set permissions for node */ - rsm_permission_t actual_perms; /* actual permissions for node */ - boolean_t inuse; /* is node connected to this seg? */ - - /* - * if hardware access protection is used, need to set up - * private cmmu entries for this node - */ - cmmugrp_t *hw_cmmugrps; /* node private cmmu entries */ - mseg_intr_page_t hw_small_put_intr; /* node private intr page */ - barrier_page_t hw_barrier_page; /* node private barrier page */ -} mseg_node_export_t; - - -/* flags for cmmu_update_fields() function */ -typedef enum { - memseg_set_valid, - memseg_unset_valid, - memseg_set_writeable, - memseg_unset_writeable -} memseg_cmmufield_t; - -#define CMMU_UPDATE_STR(a) \ - (((a) == memseg_set_valid) ? "memseg_set_valid" : \ - ((a) == memseg_unset_valid) ? "memseg_unset_valid" : \ - ((a) == memseg_set_writeable) ? "memseg_set_writeable" : \ - ((a) == memseg_unset_writeable) ? "memseg_unset_writeable" : \ - "unknown") - - -typedef enum { - memseg_unpublished, /* unpublished */ - memseg_wait_for_disconnects, /* unpublishing */ - memseg_published /* published */ -} exportseg_state_t; - -/* - * an exportseg structure is create for each segment created with - * rsm_create_seg(). - */ -struct __rsm_memseg_export_handle { - kmutex_t lock; - boolean_t valid; /* is exportseg being removed? */ - wrsm_network_t *network; - exportseg_state_t state; /* is segment published? */ - rsm_memseg_id_t segid; /* user assigned segment id */ - size_t size; /* length of segment */ - int num_pages; /* number of 8k pages in segment */ - pfn_t *pfn_list; /* 8k pfns backing the segment */ - boolean_t allow_rebind; /* unbind/rebind allowed? */ - int total_tuples; /* total number of cmmu tuples */ - int num_cmmugrps; /* # of cmmugrps */ - cmmugrp_t *cmmugrps; /* linked list of cmmugrps */ - mseg_intr_page_t small_put_intr; /* CMMU/handler for small put intr */ - barrier_page_t barrier_page; /* page/CMMU for barriers */ - mseg_node_export_t nodes[WRSM_MAX_CNODES]; /* per node info */ - cnode_bitmask_t import_bitmask; /* nodes with import permission */ - uint_t wait_for_disconnects; /* post-unpublish node cleanup count */ - boolean_t writeable; /* how to set generic CMMU entries */ - exportseg_t *segid_next; /* linked list for segid hash table */ - exportseg_t *all_next; /* all_exportsegs_hash pointer */ -}; - - - -typedef struct import_ncslice { - off_t seg_offset; - ncslice_t ncslice; - off_t ncslice_offset; - size_t len; -} import_ncslice_t; - - - -/* - * each connection to a segment is represented with an importseg structure - */ -struct __rsm_memseg_import_handle { - krwlock_t rw_lock; /* lock for put/get and disconnect */ - boolean_t valid; /* is importseg being removed? */ - boolean_t unpublished; /* is segment still published? */ - iseginfo_t *iseginfo; /* iseginfo for this segment */ - wrsm_network_t *network; /* local controller info */ - boolean_t kernel_user; /* is a kernel thread using put/get? */ - rsm_barrier_mode_t barrier_mode; /* barrier mode for this connection */ - boolean_t mappings; /* user has mappings of segment */ - void *barrier_page; /* user as mapping of barrier page */ - void *intr_page; /* user as mapping of interrupt page */ - void *cesr_page; /* user as mapping of CESR regs */ - void *reroute_page; /* user as mapping of reroutecounters */ - boolean_t have_mappings; /* segment mapped into user vaddr */ - rsm_resource_callback_t mapping_callback; /* callwhen segment invalid */ - rsm_resource_callback_arg_t mapping_callback_arg; /* arg for callback */ - - importseg_t *iseg_next; /* linked list off iseginfo */ - importseg_t *all_next; /* all_importsegs_hash pointer */ -}; - - - -/* - * if a connection is requested by a kernel RSMPI client, the following - * mappings are automatically set up - */ -#define MEMSEG_DEVLOAD_ATTRS (HAT_NEVERSWAP | HAT_STRICTORDER) - -typedef struct mseg_kmap { - caddr_t seg; /* hidden segment mapping */ - caddr_t barrier_page; /* kernel mapping of barrier page */ - caddr_t small_put_intr; /* kernel mapping of interrupt page */ - caddr_t small_put_offset; /* address for striped small puts */ -} mseg_kmap_t; - - -typedef struct errorpage_t { - wrsm_cmmu_tuple_t *tuple; - pfn_t pfn; -} wrsm_errorpage_t; - - -/* - * An iseginfo structure is created the first time a segment is imported - * from a remote node through rsm_import_connect_memseg(). It is destroyed - * after the last disconnect, when a session is torn down, or when the - * remote node removes this node's access to the segment. - */ -struct iseginfo { - kmutex_t lock; - wrsm_network_t *network; /* this iseginfo's network */ - cnodeid_t cnodeid; /* cnodeid of exporting node */ - rsm_memseg_id_t segid; /* segment id */ - size_t size; /* length of segment */ - boolean_t unpublished; /* node unpublished the segment */ - boolean_t send_disconnect; /* notify when disconnecting */ - rsm_permission_t perms; /* last set permissions for node */ - uint_t num_seg_tuples; /* # of tuples in seg_tuples */ - import_ncslice_t *seg_tuples; /* array of ncslice tuples for seg */ - pfn_t *pfns; /* array of pfns for kernel mapping */ - import_ncslice_t barrier_tuple; /* ncslice/offset for barrier page */ - import_ncslice_t small_put_tuple; /* ncslice/offset for smallput intr */ - mseg_kmap_t kernel_mapping; /* kernel mapping info */ - int kernel_users; /* # kernel connections (imports) */ - int errorpages; /* reserved error pages */ - wrsm_errorpage_t *errorpage_info; /* error pages for kernel mapping */ - uint_t transfer_errors; /* count of non-EIO errors on seg */ - int last_transfer_error; /* reason transfer_errors incremented */ - importseg_t *importsegs; /* connections to imported segment */ - uint_t wait_for_unmaps; /* number of outstanding client maps */ - struct iseginfo *segid_next; /* linked list for hash table */ -}; - - - - -/* - * local node's RSMPI memory segment information (in network structure) - */ -struct wrsm_memseg { - uint_t transfer_errors; /* count of non-EIO errors */ - int last_transfer_error; /* reason transfer_errors incremented */ - uint_t import_count; /* # of importsegs for this network */ - uint_t export_count; /* # of exportsegs for this network */ - uint_t export_published; /* # of exportsegs published */ - uint_t export_connected; /* # of connections (one per node) */ - uint_t bytes_bound; /* total bound memory */ - exportseg_t *exportseg_hash[WRSM_SEGID_HASH_SIZE]; - /* published exportsegs */ -}; - - -kmutex_t all_exportsegs_lock; -kmutex_t all_importsegs_lock; - - -/* - * remote node info - */ - -typedef struct connect_info { - exportseg_t *exportseg; - struct connect_info *next; -} connect_info_t; - - -struct wrsm_node_memseg { - kmutex_t lock; - boolean_t removing_session; /* removing session to node */ - connect_info_t *connected; /* local segments node has imported */ - iseginfo_t *iseginfo_hash[WRSM_SEGID_HASH_SIZE]; - /* segments imported from node */ - uint_t wait_for_unmaps; /* importsegs with client maps */ - uint_t transfer_errors; /* count of non-EIO errors */ - int last_transfer_error; /* reason transfer_errors incremented */ -}; - - - -/* - * messages - */ - -typedef struct connect_msg { - rsm_memseg_id_t segid; -} connect_msg_t; - - -typedef struct connect_resp { - uint_t err; - rsm_permission_t perms; - size_t size; - uint_t num_seg_tuples; -} connect_resp_t; - - -typedef struct smallputmap_msg { - rsm_memseg_id_t segid; -} smallputmap_msg_t; - -typedef struct smallputmap_resp { - uint_t err; - import_ncslice_t small_put_tuple; -} smallputmap_resp_t; - - -typedef struct barriermap_msg { - rsm_memseg_id_t segid; -} barriermap_msg_t; - -typedef struct barriermap_resp { - uint_t err; - import_ncslice_t barrier_tuple; -} barriermap_resp_t; - - -typedef struct segmap_msg { - rsm_memseg_id_t segid; - uint_t tuple_index; -} segmap_msg_t; - -#define MAP_MSG_TUPLES ((WRSM_MESSAGE_BODY_SIZE - (2 * sizeof (uint_t))) \ - / sizeof (import_ncslice_t)) - -typedef struct segmap_resp { - uint_t err; - uint_t num_tuples; - import_ncslice_t tuples[MAP_MSG_TUPLES]; -} segmap_resp_t; - - -typedef struct disconnect_msg { - rsm_memseg_id_t segid; -} disconnect_msg_t; - -typedef struct unpublish_msg { - rsm_memseg_id_t segid; -} unpublish_msg_t; - -typedef struct unpublish_resp { - int status; -} unpublish_resp_t; - -/* status values for unpublish_resp */ -#define WC_DISCONNECTED 0x01 -#define WC_CONNECTED 0x02 - - -typedef struct access_msg { - rsm_memseg_id_t segid; - rsm_permission_t perms; -} access_msg_t; - -int wrsm_lock_importseg(importseg_t *importseg, krw_t rw); -boolean_t iseginfo_sess_teardown(wrsm_node_t *node); -int create_segment_mapping(iseginfo_t *iseginfo); - -boolean_t exportseg_sess_teardown(wrsm_node_t *node); - -/* Support for plugin library for RSMAPI */ -int -wrsm_memseg_remote_node_to_iseginfo(uint32_t ctrl_num, - cnodeid_t remote_cnode, rsm_memseg_id_t segid, iseginfo_t **iseginfo); -int wrsm_memseg_segmap(dev_t dev, off_t off, struct as *asp, caddr_t *addrp, - off_t len, unsigned int prot, unsigned int maxprot, - unsigned int flags, cred_t *cred); -int wrsm_memseg_devmap(dev_t dev, devmap_cookie_t handle, offset_t off, - size_t len, size_t *maplen, uint_t model); -int wrsm_smallput_plugin_ioctl(int minor, int cmd, intptr_t arg, int flag, - cred_t *cred_p, int *rval_p); - -typedef struct smallput_header { - uint32_t reserved; /* reserved for DMV interrupt info */ - uint8_t len; /* value ranges from 1 - 64 */ - uint8_t start; /* start byte in putdata (to allow alignment) */ - uint8_t sending_cnode; - uint8_t byte_filler; - off_t offset; -} smallput_header_t; - -#define WRSM_SMALLPUT_BODY_SIZE (WRSM_TL_MSG_SIZE - \ - sizeof (smallput_header_t)) - -typedef struct wrsm_smallput_msg { - smallput_header_t header; - uint8_t putdata[WRSM_SMALLPUT_BODY_SIZE]; -} wrsm_smallput_msg_t; - - - -#endif /* _ASM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_MEMSEG_IMPL_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_nc.h b/usr/src/uts/sun4u/sys/wrsm_nc.h deleted file mode 100644 index 033c735ff9..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_nc.h +++ /dev/null @@ -1,294 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_NC_H -#define _WRSM_NC_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * this file is include by consumers of NC interfaces - */ - -#include <sys/wrsm_config.h> -#include <sys/wrsm_common.h> -#include <sys/wrsm.h> -#include <sys/wrsm_transport.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct wci_ids { - int port; /* safari port id */ - lcwci_handle_t lcwci; -} wci_ids_t; - - -/* - * wrsm_mh data structures - */ - -typedef struct wrsm_mh_reachable { - int nhops[WRSM_MAX_WNODES]; - int stripes[WRSM_MAX_WNODES]; - boolean_t changed[WRSM_MAX_WNODES]; - wnodeid_t first_hop[WRSM_MAX_WNODES]; -} wrsm_mh_reachable_t; - - -/* - * The following data structures are to support for queueing events to the - * per controller NR event thread. - */ - -typedef enum { - wrsm_evt_mhdirect, - wrsm_evt_mhreroute, - wrsm_evt_force_reroute, - wrsm_evt_add_passthrough, - wrsm_evt_send_ptlist, - wrsm_evt_recv_ptlist, - wrsm_evt_wakeup, - wrsm_evt_sessup, - wrsm_evt_sessdown, - wrsm_evt_connect, - wrsm_evt_smallputmap, - wrsm_evt_barriermap, - wrsm_evt_segmap, - wrsm_evt_disconnect, - wrsm_evt_unpublish, - wrsm_evt_access -} wrsm_nr_event_type_t; - -#ifdef DEBUG -#define WRSM_EVTSTRING(e) \ - ((e == wrsm_evt_mhdirect) ? "mhdirect" : \ - (e == wrsm_evt_mhreroute) ? "mhreroute" : \ - (e == wrsm_evt_force_reroute) ? "force_reroute" : \ - (e == wrsm_evt_add_passthrough) ? "add_passthrough" : \ - (e == wrsm_evt_send_ptlist) ? "send_ptlist" : \ - (e == wrsm_evt_recv_ptlist) ? "recv_ptlist" : \ - (e == wrsm_evt_sessup) ? "sessup" : \ - (e == wrsm_evt_sessdown) ? "sessdown" : \ - (e == wrsm_evt_connect) ? "connect" : \ - (e == wrsm_evt_smallputmap) ? "smallputmap" : \ - (e == wrsm_evt_barriermap) ? "barriermap" : \ - (e == wrsm_evt_segmap) ? "segmap" : \ - (e == wrsm_evt_disconnect) ? "disconnect" : \ - (e == wrsm_evt_unpublish) ? "unpublish" : \ - (e == wrsm_evt_access) ? "access" : \ - (e == wrsm_evt_wakeup) ? "wakeup" : "unknown") -#endif - - -typedef struct wrsm_evt_mhevent { - ncwci_handle_t wci; - wrsm_mh_reachable_t mh_reachable; -} wrsm_evt_mhevent_t; - -typedef struct wrsm_evt_forcereroute { - ncwci_handle_t wci; -} wrsm_evt_forcereroute_t; - -typedef struct wrsm_evt_addpt { - wrsm_node_t *node; -} wrsm_evt_addpt_t; - -typedef struct wrsm_evt_send_ptlist { - cnode_bitmask_t list; /* cnodes to send pt_counter msg to */ -} wrsm_evt_send_ptlist_t; - -typedef struct wrsm_evt_recv_ptlist { - cnodeid_t cnodeid; - cnode_bitmask_t pt_provided; /* cnodes allowed PT forwarding */ - int pt_route_counter; /* incr when pt_provided changes */ -} wrsm_evt_recv_ptlist_t; - -typedef struct wrsm_evt_sess { - cnodeid_t cnodeid; -} wrsm_evt_sess_t; - -typedef struct wrsm_nr_event { - wrsm_nr_event_type_t type; - union { - wrsm_evt_mhevent_t mhevent; - wrsm_evt_forcereroute_t forcereroute; - wrsm_evt_addpt_t addpt; - wrsm_evt_send_ptlist_t send_ptlist; - wrsm_evt_recv_ptlist_t recv_ptlist; - wrsm_evt_sess_t sess; - wrsm_message_t msg; - } data; - struct wrsm_nr_event *next; -} wrsm_nr_event_t; - -void wrsm_nr_add_event(wrsm_network_t *network, wrsm_nr_event_t *event_data, - boolean_t release_lock); - - - -/* - * the following functions are used by the Config Layer - */ - -/* - * find network structure from controller id or dev_info_t pointer - */ -wrsm_network_t *wrsm_nc_ctlr_to_network(uint32_t rsm_ctrl_id); -wrsm_network_t *wrsm_nc_cnodeid_to_network(cnodeid_t); - -/* - * save away new config info; disable current config - */ -int wrsm_nc_replaceconfig(uint32_t rsm_ctlr_id, - wrsm_controller_t *config, dev_info_t *dip, int num_attached, - wci_ids_t *attached_wcis); - -/* - * clean up/stop using old nodes, wcis, links - */ -int wrsm_nc_cleanconfig(uint32_t rsm_ctlr_id, int num_reconfig, - wci_ids_t *reconfig_wcis); - -/* - * make sure all old links are down; bring up new links - */ -int wrsm_nc_installconfig(uint32_t rsm_ctlr_id); - -/* - * start using new links - */ -int wrsm_nc_enableconfig(uint32_t rsm_ctlr_id, int num_reconfig, - wci_ids_t *reconfig_wcis); - -/* - * check whether config is in installed_up state - */ -boolean_t wrsm_nc_is_installed_up(uint_t rsm_ctlr_id); - - -/* - * install and enable new config - */ -int wrsm_nc_initialconfig(uint32_t rsm_ctlr_id, - wrsm_controller_t *config, dev_info_t *dip, int num_attached, - wci_ids_t *attached_wcis); - -/* - * uninstall config for an RSM controller; delete RSM controller - */ -int wrsm_nc_removeconfig(uint32_t rsm_ctlr_id); - -/* - * enable sessions in RSM controller - */ -int wrsm_nc_startconfig(uint32_t rsm_ctlr_id); - -/* - * enable sessions in RSM controller - */ -int wrsm_nc_stopconfig(uint32_t rsm_ctlr_id); - -/* - * notify the NR that all links on a WCI are up - */ -void wrsm_nr_all_links_up(ncwci_handle_t nc); - -/* - * find out if node connected to a link has a valid session - */ -int wrsm_nr_session_up(ncwci_handle_t ncwci, wnodeid_t wnid); - -/* - * clear cluster write lockout on a remote cnode - */ -void wrsm_nr_clear_lockout(ncwci_handle_t wci, ncslice_t ncslice); - -/* - * a new WCI has been attached - */ -int wrsm_nc_newwci(uint32_t rsm_ctlr_id, safari_port_t safid, - lcwci_handle_t lcwci, wrsm_controller_t *config); - -/* - * an attached wci is being detached - */ -int wrsm_nc_removewci(uint32_t rsm_ctlr_id, safari_port_t safid); - -/* - * the following functions are used by memory segments - */ -int wrsm_nc_create_errorpage(wrsm_network_t *network, - wrsm_cmmu_tuple_t **errorpage_tuplep, pfn_t *errorpage_pfnp, - boolean_t sleep); - - -/* - * the following functions are used by the LC - */ -void wrsm_mh_link_is_up(ncwci_handle_t ncwci, uint32_t - local_linknum, wnodeid_t remote_wnode); -void wrsm_mh_link_is_down(ncwci_handle_t ncwci, uint32_t - local_linknum, wnodeid_t remote_wnode); - -/* - * the following functions are used by the driver - */ - -int wrsm_nc_suspend(uint_t rsm_ctlr_id); -int wrsm_nc_resume(uint_t rsm_ctlr_id); - - -/* this is an RSMPI function */ -int wrsm_get_peers(rsm_controller_handle_t controller, rsm_addr_t *addr_list, - uint_t count, uint_t *num_addrs); - -/* - * returns controller number given nc handle. Used by lc since the lc - * cannot dereference the config fields in softstate as they may be null - */ -uint32_t wrsm_nr_getcontroller_id(ncwci_handle_t ncwci); -/* - * The plugin library (librsmwrsm) opens controllers, in order to prevent the - * the config layer from removing a controller (network) that the plugin is - * using, the driver must return busy. open and close controller below - * increment/decrement a counter for the removeconfig to check before removing - * a config. - */ -int wrsm_nc_open_controller(uint_t rsm_ctlr_id); -void wrsm_nc_close_controller(uint_t rsm_ctlr_id); -int wrsm_nc_getlocalnode_ioctl(int minor, int cmd, intptr_t arg, int flag, - cred_t *cred_p, int *rval_p); - -/* logs system events for use by user applications via the sysdaemond to see */ -void wrsm_nr_logevent(wrsm_network_t *network, wrsm_node_t *node, - wrsm_sys_event_t eventtype, char *reason); -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_NC_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_nc_impl.h b/usr/src/uts/sun4u/sys/wrsm_nc_impl.h deleted file mode 100644 index 638873e153..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_nc_impl.h +++ /dev/null @@ -1,333 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_NC_IMPL_H -#define _WRSM_NC_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * this file is included by modules that are part of the NC - */ - -#include <sys/wrsm_common.h> -#include <sys/wrsm_config.h> -#include <sys/wrsm_plat.h> - - -#ifdef __cplusplus -extern "C" { -#endif - -#define WRSM_PTRETRY_TIMEOUT (10 * hz) -#define WRSM_ENABLE_TIMEOUT (5 * hz) - -#define WRSM_INID2DNID_ENTRIES 16 -#define WRSM_MAX_STRIPEWCIS 4 -#define WNODE_UNREACHABLE (-1) - -typedef unsigned char wrsm_linknum_t; -typedef unsigned char inid_t; - -typedef struct wrsm_mh_reroute_state wrsm_mh_reroute_state_t; -typedef struct wrsm_nc_strgrp wrsm_nc_strgrp_t; - - - - -/* - * arg to wci_routechange() - * - * controls how the gain or loss of a wnode route affects which - * nodes have their ncslice routes re-evaluated. - */ -typedef enum { - wci_reroute_all, /* route eval on all interested nodes */ - wci_reroute_direct, /* route eval only on direct connect nodes */ - wci_reroute_pending, /* only route eval nodes using lost routes */ - wci_reroute_disabled, /* teardown routes on nodes using lost routes */ - wci_reroute_force /* reroute_all, changed and unchanged wnodes */ -} wrsm_wci_reroute_t; - -#ifdef DEBUG -#define WCI_RTSTRING(e) \ - ((e == wci_reroute_all) ? "reroute_all" : \ - (e == wci_reroute_direct) ? "reroute_direct" : \ - (e == wci_reroute_pending) ? "reroute_pending" : \ - (e == wci_reroute_disabled) ? "reroute_disabled" : \ - (e == wci_reroute_force) ? "reroute_force" : "unknown") -#endif - - -typedef enum { - wci_rerouted, /* no multi-hop reroute needed */ - wci_in_reroute, /* MH currently recalculating routes */ - wci_need_reroute, /* wci needs an MH reroute */ - wci_force_reroute /* force an MH reroute */ -} wrsm_wci_state_t; - - -typedef struct wrsm_inid2dnid_entry { - int stripes; /* 0 - unique wnodes: 1, 2, 3, or 4 */ - boolean_t changed; /* different than the installed entry */ - wnode_bitmask_t wnode_bitmask; /* wnodes this inid uses */ - wnodeid_t wnode_list[WRSM_MAX_DNIDS]; /* wnodes this inid uses */ - cnode_bitmask_t cnode_routes; /* cnodes this inid routes to */ - cnode_bitmask_t users; /* cnodes using this route */ - cnode_bitmask_t reserved; /* cnodes that plan to use this route */ -} wrsm_inid2dnid_entry_t; - -typedef struct wrsm_wnodeinfo { - boolean_t valid; /* valid wnode in this configuration */ - cnodeid_t cnodeid; /* cnode this wnode routes to */ - cnode_bitmask_t interested; /* cnodes that could use this route */ - cnode_bitmask_t users; /* cnodes using this route */ - cnode_bitmask_t reserved; /* cnodes that plan to use this route */ -} wrsm_wnodeinfo_t; - - -/* - * wci related information private to the NR - */ -typedef struct nrwci { - wrsm_mh_reachable_t mh_reachable; /* wnode reachability */ - wrsm_wnodeinfo_t wnodeinfo[WRSM_MAX_WNODES]; /* wrsm_node, users */ - wrsm_inid2dnid_entry_t inid2dnid[WRSM_INID2DNID_ENTRIES]; - /* inid2dnid table settings */ - boolean_t using_inids; /* current/new routes use inids */ - boolean_t reserved_inids; /* reserved inids for 1-wnode routes */ - boolean_t inids_enabled; /* inids enabled in the hardware */ - boolean_t need_hw_update; /* # inids changed since HW write */ - wrsm_nc_strgrp_t *sg; /* stripe group wci is in */ - cnode_bitmask_t cnode_retry; /* cnodes should retry using this wci */ -} nr_wci_t; - - -typedef struct wrsm_ncwci { - wrsm_network_t *network; /* RSM controller this belongs to */ - lcwci_handle_t lcwci; /* LC's handle for this wci */ - wrsm_availability_t availability; /* configuration state */ - wrsm_wci_state_t reroute_state; /* multi-hop rereroute needed? */ - wrsm_wci_data_t *config; /* configuration data for wci links */ - nr_wci_t nr; /* NR state */ - wrsm_mh_reroute_state_t *mh_state; /* MH state */ - boolean_t linksup; /* used during install/enable */ - struct wrsm_ncwci *next; /* next wci in controller */ -} wrsm_ncwci_t; - - -struct wrsm_nc_strgrp { - wrsm_network_t *network; /* RSM controller this belongs to */ - wrsm_stripe_group_t *config; /* config info */ - wrsm_availability_t availability; /* configuration state */ - int attached_wcis; /* attached wcis in stripe group */ - boolean_t striping_on; /* are wcis programmed to stripe? */ - wrsm_ncwci_t *wcis[WRSM_MAX_STRIPEWCIS]; /* wcis in stripe order */ - ncslice_bitmask_t wci_ncslices[WRSM_MAX_STRIPEWCIS]; - /* ncslices forced onto single wci */ - cnode_bitmask_t users; /* cnodes using this stripe group */ - cnode_bitmask_t cnode_retry; /* cnodes should try using this sg */ - struct wrsm_nc_strgrp *next; /* next stripe group in ctlr */ -}; - - -typedef struct inidwnode_route { - wrsm_ncwci_t *wci; - enum { - nid_route_inid, - nid_route_wnode - } route_type; - wnodeid_t id; /* inids and wnids are the same size */ -} inidwnode_route_t; - - -typedef struct ncslice_route { - wrsm_preferred_route_t *proute; /* preferred route used */ - wrsm_nc_strgrp_t *sg; - /* - * total # links used in ncslice route; combined striping provided - * by route map striping, inid2dnid striping, and wci striping - */ - int stripes; - int nwcis; /* number of wcis used */ - cnode_bitmask_t switches; /* switches used by this route */ - /* - * the actual inid/wnode routes used; one per wci - */ - inidwnode_route_t wroutes[WRSM_MAX_STRIPEWCIS]; - boolean_t nostripe; /* is wci striping disabled on this route? */ -} ncslice_route_t; - -/* - * This state is used by ncslice_apply_routes to update ncslice routes for - * each node. - */ -typedef enum { - ncslice_use_current, /* current route is still ok */ - ncslice_use_new_route, /* use a new route */ - ncslice_remove_route, /* remove route (to remove node) */ - ncslice_use_errloopback, /* use errloopack route */ - ncslice_no_route /* route has been removed */ -} reroute_type_t; - -#ifdef DEBUG -#define ROUTEINFO_MSGSTRING(e) \ - ((e == ncslice_use_current) ? "use_current" : \ - (e == ncslice_use_new_route) ? "use_new_route" : \ - (e == ncslice_remove_route) ? "remove_route" : \ - (e == ncslice_use_errloopback) ? "use_errloopback" :\ - (e == ncslice_no_route) ? "no_route" : "unknown") -#endif - -struct wrsm_node_routeinfo { - wrsm_routing_policy_t *policy; /* routing config policy */ - boolean_t check_route; /* route needs to be checked */ - reroute_type_t route_state; /* what routing should be applied? */ - ncslice_route_t current_route; /* installed route */ - ncslice_route_t new_route; /* newly chosen route */ - boolean_t direct_connect; /* using a direct connect route */ - cnode_bitmask_t pt_provided; /* cnodes allowed PT forwarding */ - int pt_route_counter; /* incr when pt_provided changes */ - int pt_rerouting; /* remote node is rerouting */ - cnode_bitmask_t pt_interested; /* cnodes could use this PT route */ - cnode_bitmask_t pt_users; /* cnodes using this PT route */ - wrsm_preferred_route_t *extended_routes; /* wci loopback routes */ - wrsm_preferred_route_t **orig_routes; /* policy supplied routes */ - int orig_nroutes; /* count of policy supplied routes */ - uint32_t num_rte_changes; /* count of route changes */ - kstat_t *wrsm_route_ksp; /* pointer to route kstat */ -}; - - -typedef enum { - pt_route_counter, - pt_reroute_start, - pt_reroute_finish -} pt_msgtype_t; - -typedef struct wrsm_ptlist_msg { - cnode_bitmask_t pt_provided; /* cnodes allowed PT forwarding */ - int pt_route_counter; /* incr when pt_provided changes */ - pt_msgtype_t pt_msgtype; /* routechange, or rerouting? */ -} wrsm_ptlist_msg_t; - -#ifdef DEBUG -#define PT_MSGSTRING(e) \ - ((e == pt_route_counter) ? "route_counter" : \ - (e == pt_reroute_start) ? "reroute_start" : \ - (e == pt_reroute_finish) ? "reroute_finish" : "unknown") -#endif - - -/* - * wcis and stripe groups are linked lists. wci list is ordered by - * (safari) port, and stripe group list is ordered by stripe group id - */ -struct wrsm_nr { - kmutex_t lock; - wrsm_ncwci_t *wcis; /* pointers to wcis */ - krwlock_t wcilist_rw; /* protects wcis linked list */ - wrsm_nc_strgrp_t *sgs; /* pointer to stripe groups */ - cnode_bitmask_t pt_provided; /* passthru to these nodes is on */ - cnode_bitmask_t pt_retrylist; /* need to send pt message to these */ - timeout_id_t pt_retry_timeout_id; /* timeout to resend pt messages */ - boolean_t need_pt_retry_timeout; /* resched timeout after suspend */ - int pt_route_counter; /* incr when pt_provided changes */ - boolean_t init_cmmu; /* cmmu init needed on new config */ - kthread_t *event_thread; - kcondvar_t event_cv; /* cv for event thread */ - boolean_t stop_event_thr; /* flag telling event thread to exit */ - uint64_t event_thr_loopcnt; /* number of time evt thr has looped */ - wrsm_nr_event_t *events; /* events to be processed */ - wrsm_nr_event_t *last_event; /* last event on queue */ - boolean_t wait_wcis_rerouting; /* waiting for wci reroutes */ - boolean_t wait_eventdrain; /* waiting for event drain */ - uint_t wait_pause; /* waiting for evt thr to pause */ - boolean_t pausing; /* evt thread is paused */ - kcondvar_t config_cv; /* cv for config related events */ - timeout_id_t wcireroute_timeout_id; /* wci reroute timeout */ - boolean_t need_wcireroute_timeout; /* resched timeout after suspend */ - int waiting_linksup; /* # wcis whose links aren't all up */ - int suspended; /* controller is suspended */ - wrsm_ncowner_map_t ncslice_responder[WRSM_MAX_NCSLICES]; - /* - * which wci/stripe group responds - * to this ncslice - */ -}; - -/* - * counting wcis for kstats - */ -void wrsm_get_wci_num(wrsm_network_t *network, uint_t *num_wcis, - uint_t *avail_wcis); - -/* - * register control interfaces - */ -void wrsm_nc_config_linksup(void *arg); - -/* - * NR interfaces - */ -int wrsm_nr_verifyconfig(wrsm_network_t *network, wrsm_controller_t *config, - int attached_cnt, wci_ids_t *attached_wcis); -boolean_t wrsm_nr_initialconfig(wrsm_network_t *network, int attached_cnt, - wci_ids_t *attached_wcis); -int wrsm_nr_replaceconfig(wrsm_network_t *network, wrsm_controller_t *config, - int num_wcis, wci_ids_t *attached_wcis); -int wrsm_nr_cleanconfig(wrsm_network_t *network, int num_wcis, - wci_ids_t *reroute_wcis); -int wrsm_nr_installconfig(wrsm_network_t *network); -int wrsm_nr_enableconfig(wrsm_network_t *network, int num_wcis, - wci_ids_t *reroute_wcis); -void wrsm_nr_removeconfig(wrsm_network_t *network); -int wrsm_nr_attachwci(wrsm_network_t *network, safari_port_t saf_id, - lcwci_handle_t lcwci, wrsm_controller_t *config, boolean_t init_cmmu, - boolean_t pause_evt_thread); -int wrsm_nr_enablewci(wrsm_network_t *network, safari_port_t saf_id, - boolean_t dr_attach); -int wrsm_nr_detachwci(wrsm_network_t *network, safari_port_t saf_id, - boolean_t force); -void wrsm_nr_mhdirect(wrsm_ncwci_t *wci, wrsm_mh_reachable_t *reachable); -void wrsm_nr_mhreroute(wrsm_ncwci_t *wci, wrsm_mh_reachable_t *reachable); -int wrsm_nr_suspend(wrsm_network_t *network); -int wrsm_nr_resume(wrsm_network_t *network); - -/* - * MH interfaces - */ -void wrsm_mh_new_wci(wrsm_ncwci_t *wci); -void wrsm_mh_remove_wci(wrsm_ncwci_t *wci); -boolean_t wrsm_mh_reroute(wrsm_ncwci_t *wci); -int wrsm_mh_wnode_to_link(ncwci_handle_t ncwci, int wnodeid); -boolean_t wrsm_mh_link_to_wnode(ncwci_handle_t ncwci, int link, int wnodeid); - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_NC_IMPL_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_plat.h b/usr/src/uts/sun4u/sys/wrsm_plat.h deleted file mode 100644 index d24192867e..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_plat.h +++ /dev/null @@ -1,160 +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 2001-2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _WRSM_PLAT_H -#define _WRSM_PLAT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * WildCat RSM driver platform-specific module interface - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/wrsm.h> -#include <sys/wrsm_types.h> -#include <sys/wrsm_common.h> - -/* Possible per-link LED states */ -#define LEDBOTHOFF 0 -#define LEDLOWERON 1 -#define LEDUPPERON 2 -#define LEDBOTHON 3 - -/* Possible values for link_state */ -#define LINK_STATE_OFF 0 -#define LINK_STATE_SEEK 2 -#define LINK_STATE_IN_USE 3 -#define LINK_STATE_NO_CHANGE 4 - -#define END_STATUS_NOT_READY 0 -#define END_STATUS_NEAR_READY 1 -#define END_STATUS_ALL_READY 3 - -/* - * remote wnode argument to _uplink and _downlink to indicate link - * should be in loopback mode - */ -#define LOOPBACK_WNODE WRSM_MAX_WNODES+1 - -/* I have no idea how big this should actually be */ -#define WIB_SEPROM_MSG_SIZE 64 - -/* Typedefs for ncslice programming */ -typedef enum { - WRSM_NCOWNER_NOT_CLAIMED = 0, - WRSM_NCOWNER_NONE = 1, - WRSM_NCOWNER_WCI = 2, - WRSM_NCOWNER_STRIPEGROUP = 3 -} wrsm_ncowner_t; - -typedef enum { - wrsm_node_serengeti, - wrsm_node_wssm, - wrsm_node_starcat -} wrsm_node_types_t; - -typedef union { - safari_port_t wci_id; - wrsm_stripe_group_t *stripe_group; -} wrsm_ncowner_id_t; - -typedef struct { - wrsm_ncowner_t owner_type; - wrsm_ncowner_id_t owner; -} wrsm_ncowner_map_t; - -typedef struct wrsm_plat_ops { - void (*link_up)(safari_port_t wci_id, uint32_t link_num, - fmnodeid_t remote_fmnodeid, gnid_t remote_gnid, - uint32_t remote_link_num, safari_port_t remote_port, - uint64_t remote_partition_version, uint32_t remote_partition_id); - - void (*link_down)(safari_port_t wci_id, uint32_t local_link_num); - void (*sc_failed)(); - - /* The following callbacks are for testing purposes only */ - struct wrsm_soft_state *(*get_softstate)(safari_port_t - wci_id); - void (*get_remote_data)(safari_port_t wci_id, - uint32_t link_num, fmnodeid_t *remote_fmnodeid, - gnid_t *remote_gnid, linkid_t *remote_link, - safari_port_t *remote_port, volatile uchar_t **wrsm_regs); -} wrsm_plat_ops_t; - -/* Format of data for wrsmplat_set_seprom data */ -typedef struct wrsm_wib_ecc_error { - uint32_t ce : 1; - uint32_t syndrome : 7; - uint32_t address : 24; -} wrsm_wib_ecc_error_t; - -#define WRSM_WIB_SEPROM_TYPE_ECCERR 1 - -typedef struct wrsm_seprom_data { - uint32_t type; - union { - wrsm_wib_ecc_error_t eccerr; - } data; - -} wrsm_seprom_data_t; - -int wrsmplat_reg_callbacks(wrsm_plat_ops_t *ops); -int wrsmplat_unreg_callbacks(void); -void wrsmplat_suspend(safari_port_t wci); -void wrsmplat_resume(safari_port_t wci); - -int wrsmplat_uplink(safari_port_t wci, linkid_t link, gnid_t gnid, - fmnodeid_t fmnodeid, uint64_t partition_version, uint32_t controller_id, - boolean_t loopback); -int wrsmplat_downlink(safari_port_t wci, linkid_t link, boolean_t loopback); -int wrsmplat_set_led(safari_port_t wci, linkid_t link, int led_state); -int wrsmplat_alloc_slices(ncslice_bitmask_t requested, - ncslice_bitmask_t *granted); -int wrsmplat_set_seprom(safari_port_t wci, uchar_t *seprom_data, size_t - length); -int wrsmplat_linktest(safari_port_t wci, wrsm_linktest_arg_t *linktest); - -int wrsmplat_stripegroup_verify(const wrsm_stripe_group_t *); -void wrsmplat_ncslice_setup(wrsm_ncowner_map_t owner[WRSM_MAX_NCSLICES]); -void wrsmplat_ncslice_enter(void); -void wrsmplat_ncslice_exit(void); - -void wrsmplat_xt_sync(int cpu_id); -wrsm_node_types_t wrsmplat_get_node_type(void); -void wrsmplat_wci_init(volatile uchar_t *wrsm_regs); - -void wrsmplat_set_asi_cesr_id(void); -void wrsmplat_clr_asi_cesr_id(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_PLAT_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_plat_impl.h b/usr/src/uts/sun4u/sys/wrsm_plat_impl.h deleted file mode 100644 index 7ba23094f6..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_plat_impl.h +++ /dev/null @@ -1,141 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_PLAT_IMPL_H -#define _WRSM_PLAT_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Private definitions for the wrsm_plat module - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/wrsm_plat.h> - -/* LC to SC message types */ -/* (message codes defined in firmware - do not change) */ - -#define UPLINK 0x3000 /* Request that a link be brought up */ -#define DOWNLINK 0x3001 /* Request that a link be brought down */ -#define LINKDATA 0x3002 /* Get discovery data for specified link */ -#define NCSLICE 0x3003 /* Request allocation of NC slices */ -#define SETLEDSTATE 0x3004 /* Set the LED to specified state */ -#define SETSEPROM 0x3005 /* Set SEPROM with error message */ - -/* Asynchronous SC to LC message types */ -#define LINKISUP 0x000e /* Link has come up */ - -/* - * During UPLINK request LC fills this in with local data. During - * LINKDATA request, SC fills this in with data from the remote node. - */ -typedef struct wrsm_uplink_data { - uint64_t partition_version; - uint32_t partition_id; - uint32_t fmnodeid; - uint32_t gnid; -} wrsm_uplink_data_t; -/* - * In the comments below, a request is any message from the kernel to - * the SC and a response is any message from the SC to the kernel. - */ - -/* Message body for UPLINK and LINKDATA request/response */ -typedef struct wrsm_uplink_msg { - wrsm_uplink_data_t config_data; - uint32_t wci_port_id; - uint32_t link_num; - uint32_t status; -} wrsm_uplink_msg_t; - -/* - * A synchronous response message from the SC acknowledging a message. The - * format of the message body is defined by the wrsm_status_msg_t structure. - * A status of 0 indicates the SC was able to process the message as expected. - * NOTE: not used on a serengeti platform, errors are reported using the - * provided mechanism of returing an error code from the mailbox function call - */ -typedef struct wrsm_status_msg { - uint32_t status; -} wrsm_status_msg_t; - -/* - * Message body used for DOWNLINK request - */ -typedef struct wrsm_link_msg { - uint32_t wci_port_id; - uint32_t link_num; -} wrsm_link_msg_t; - -/* Message body used for NCSLICE request/response */ -typedef struct wrsm_ncslice_claim_msg { - uint32_t status; - ncslice_bitmask_t requested_ncslices; -} wrsm_ncslice_claim_msg_t; - -/* Message body used for SETLEDSTATE request/response */ -typedef struct wrsm_link_led_msg { - uint32_t wci_port_id; - uint32_t link_num; - uint32_t led_state; -} wrsm_link_led_msg_t; - -/* Message body used for SETSEPROM request */ -typedef struct wrsm_wib_seprom_msg { - uint32_t wci_port_id; - uchar_t seprom_data[WIB_SEPROM_MSG_SIZE]; -} wrsm_wib_seprom_msg_t; - -/* - * A synchronous response message from the SC acknowledges the message. The - * format of the message body is defined by the wrsm_status_msg_t structure - * (above). A status of 0 indicates the SC was able to process the message as - * expected. - */ - -/* - * This message is sent by the SC to the wrmsplat module when link activation - * is complete. This message is only sent in response to an UPLINK message. - * The format of the message body is defined by the wrsm_linkisup_msg_t - * structure. The async_msg_type field is set to 1, and the link_info - * structure is filled in with the wci portid and link number of the link on - * which activiation is complete. - */ - -typedef struct wrsm_linkisup_msg { - uint32_t async_msg_type; - wrsm_link_msg_t link_info; -} wrsm_linkisup_msg_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_PLAT_IMPL_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_plugin.h b/usr/src/uts/sun4u/sys/wrsm_plugin.h deleted file mode 100644 index 58fbb411ef..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_plugin.h +++ /dev/null @@ -1,94 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_WRSM_PLUGIN_H -#define _SYS_WRSM_PLUGIN_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types32.h> -#include <sys/rsm/rsm_common.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * the plugin_offset is passed by mmap to the wrsm driver. the driver - * breaks the offset into pieces to accurately determine the real offset - * required to map in the page(s) the plugin (librsmwrsm.so) is requesting - * The following represent valid values for page_type: - * 0X0 = interrupt INTR page map type (small put) - * 0x2000 = BARRIER page - * 0x4000 BARRIER_REGS - wci_cluster_error_count register and CESR - * 0x6000 RECONFIG - network->reroutingp and network->route_count to check - * for configuration changes. - */ - -#define WRSM_PAGESIZE 0x2000 /* 8 k */ - - -#define WRSM_MMAP_BARRIER_SCRATCH 0x2000 -#define WRSM_MMAP_BARRIER_REGS 0x4000 -#define WRSM_MMAP_RECONFIG 0x6000 - -/* structure used to pass PUT args between plugin and driver */ -typedef struct msg_pluginput_args { - rsm_memseg_id_t segment_id; - caddr_t buf; - uint64_t len; - off64_t offset; - uint64_t remote_cnodeid; -} msg_pluginput_args_t; - -typedef struct msg_pluginput_args32 { - rsm_memseg_id_t segment_id; - caddr32_t buf; - uint64_t len; - off64_t offset; - uint64_t remote_cnodeid; -} msg_pluginput_args32_t; -/* - * The plugin (librsmwrsm.so) creates an wrsm_plugin_offset_t to pass to the - * driver during mmap with the offset arg. The driver breaks down the - * components of wrsm_plugin_offset_t to determine the real offset of the page - * requested by the plug-in. - */ - -typedef union { - struct plugin_offset { - rsm_memseg_id_t segment_id : 32; /* 63:32 */ - unsigned char export_cnodeid : 8; /* 31:24 */ - uint32_t page_type : 24; /* 23:0 */ - } bit; - off64_t val; -} wrsm_plugin_offset_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WRSM_PLUGIN_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_rsmpi.h b/usr/src/uts/sun4u/sys/wrsm_rsmpi.h deleted file mode 100644 index 4d55afe0ce..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_rsmpi.h +++ /dev/null @@ -1,50 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _SYS_WRSM_RSMPI_H -#define _SYS_WRSM_RSMPI_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/wrsm_common.h> - - -#ifdef __cplusplus -extern "C" { -#endif - -int wrsmrsm_get_controller_handler(const char *name, uint32_t number, - rsm_controller_object_t *controller, uint32_t version); - -int wrsmrsm_release_controller_handler(const char *name, uint32_t number, - rsm_controller_object_t *controller); - -void wrsm_rsm_setup_controller_attr(wrsm_network_t *network); -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_WRSM_RSMPI_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_sess_impl.h b/usr/src/uts/sun4u/sys/wrsm_sess_impl.h deleted file mode 100644 index 7d53585524..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_sess_impl.h +++ /dev/null @@ -1,113 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_SESS_IMPL_H -#define _WRSM_SESS_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/wrsm_common.h> -#include <sys/wrsm_session.h> -#include <sys/wrsm_cmmu.h> -#include <sys/wrsm_transport.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define SESS_SUCCESS 0 -#define SESS_TIMEOUT 1000000 /* in usec */ - -/* - * Type declarations - */ - -/* - * Session state to a remote cnode - * Note: there is an array of session statea strings used for debugging - * purposes that must be kept in sync with this enum. - */ -typedef enum { - SESS_STATE_UNREACH, /* newcnode not reachable */ - SESS_STATE_DOWN, /* No valid session */ - SESS_STATE_ESTAB, /* Waiting for reply to sess_start message */ - SESS_STATE_UP /* A valid session exists */ -} sess_state; - -/* Per-remote-cnode state structure */ -typedef struct wrsm_node_session { - cnodeid_t cnodeid; - kmutex_t mutex; - kcondvar_t cv_session_up; - boolean_t enabled; - sess_state state; - boolean_t state_changing; - boolean_t event_queued; - kcondvar_t cv_state_changing; - wrsm_sessionid_t session_id; - wrsm_sessionid_t last_session_id; - caddr_t barrier_page; - caddr_t barrier_mem; - wrsm_cmmu_tuple_t *barrier_tuple; - wrsm_cmmu_tuple_t remote_tuple; - uint_t dereferences_needed; - kcondvar_t cv_await_dereferences; -} wrsm_node_session_t; - -/* Session state structure */ -#define MAX_CLIENTS 10 -struct wrsm_session { - wrsm_network_t *network; - wrsm_sess_func_t cb[MAX_CLIENTS]; - wrsm_node_session_t node[WRSM_MAX_CNODES]; -}; - -/* Message formats */ -typedef struct { - wrsm_message_header_t header; - wrsm_sessionid_t session_id; - ncslice_t barrier_ncslice; - wrsm_cmmu_offset_t barrier_offset; -} msg_session_start_t; - -typedef struct { - wrsm_message_header_t header; - wrsm_sessionid_t session_id; - ncslice_t barrier_ncslice; - off_t barrier_offset; - int result; -} msg_session_start_rsp_t; - -typedef struct { - wrsm_message_header_t header; - wrsm_sessionid_t session_id; -} msg_session_end_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_SESS_IMPL_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_session.h b/usr/src/uts/sun4u/sys/wrsm_session.h deleted file mode 100644 index 18a5d2bdfa..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_session.h +++ /dev/null @@ -1,128 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_SESS_H -#define _WRSM_SESS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/wrsm_transport.h> - -/* - * Type Declarations - */ - -typedef enum { - SESSION_UP, - SESSION_DOWN -} wrsm_sess_state; - - -/* - * Definition of the user's callback function. - * - * The boolean return value should be set to true if teardown is complete, - * or false if there are still references to this node from this subsystem. - * If false was returned, the client should eventually call - * wrsm_sess_unreferenced() to indicate when teardown is finally complete. - */ -typedef boolean_t (*wrsm_sess_func_t)(wrsm_network_t *, cnodeid_t, - wrsm_sess_state); - - -/* - * Config functions, should be called by transport. - */ - -/* Init function. */ -void wrsm_sess_init(wrsm_network_t *); - -/* Fini function. */ -void wrsm_sess_fini(wrsm_network_t *); - -/* Informs session that a new cnode is reachable */ -void wrsm_sess_reachable(wrsm_network_t *, cnodeid_t); - -/* Informs session that a cnode is no longer reachable */ -void wrsm_sess_unreachable(wrsm_network_t *, cnodeid_t); - -/* Establishes a session with a remote cnode, if enabled. */ -wrsm_sessionid_t wrsm_sess_establish(wrsm_network_t *, cnodeid_t); - -/* Asynchronously tears down a session to a cnode. */ -void wrsm_sess_teardown(wrsm_network_t *, cnodeid_t); - -/* Returns the current session. */ -wrsm_sessionid_t wrsm_sess_get(wrsm_network_t *, cnodeid_t); - -/* - * Functions for client use. - */ - -/* Allows user to register for callbacks. */ -void wrsm_sess_register(wrsm_network_t *, wrsm_sess_func_t); - -/* Removes a user callback registration. */ -void wrsm_sess_unregister(wrsm_network_t *, wrsm_sess_func_t); - -/* - * Notify session layer of final dereference of node, - * completing earlier session down callback. - */ -void wrsm_sess_unreferenced(wrsm_network_t *net, cnodeid_t cnode); - -/* - * Functions for use by some topology management entitiy. - */ - -/* Enables communication with a cnode. */ -void wrsm_sess_enable(wrsm_network_t *, cnodeid_t); - -/* Disables communication with a cnode. May cause a teardown. */ -int wrsm_sess_disable(wrsm_network_t *, cnodeid_t); - -/* Returns a cnode bitmask indicating which cnodes have valid sessions */ -void wrsm_sess_get_cnodes(wrsm_network_t *, cnode_bitmask_t *); - -/* - * call to initiate an immediate session establish/teardown - */ -void wrsm_sess_establish_immediate(wrsm_network_t *net, cnodeid_t cnodeid); -void wrsm_sess_teardown_immediate(wrsm_network_t *net, cnodeid_t cnodeid); - -/* Does write/read to remote node */ -int wrsm_sess_touch_node(wrsm_network_t *net, cnodeid_t cnodeid, - uint32_t stripes); - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_SESS_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_transport.h b/usr/src/uts/sun4u/sys/wrsm_transport.h deleted file mode 100644 index fe7c37af6e..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_transport.h +++ /dev/null @@ -1,245 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_TRANSPORT_H -#define _WRSM_TRANSPORT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/wrsm_common.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * WRSM_TL_VERSION - If any message formats change, this constant must - * change in the next release, to ensure that imcompatible drivers - * recognize the version skew. - */ -#define WRSM_TL_VERSION 0x1 - -/* - * Messagetypes - * When you add a message here, remember to add it to fuction - * messagetypes2string in wrsm_tl.c. - */ -enum { - /* Common message types */ - WRSM_MSG_ACK, - WRSM_MSG_NACK, - WRSM_MSG_PING, - WRSM_MSG_PING_RESPONSE, - /* Config message types */ - WRSM_MSG_CONFIG_COOKIE, - WRSM_MSG_CONFIG_PASSTHROUGH_LIST, - WRSM_MSG_CONFIG_PASSTHROUGH_LIST_RESPONSE, - WRSM_MSG_CONFIG_CNODE_ACCESS, - /* Multihop message types */ - /* Session message types */ - WRSM_MSG_SESSION_START, - WRSM_MSG_SESSION_START_RESPONSE, - WRSM_MSG_SESSION_END, - /* RSMPI Segment message types */ - WRSM_MSG_SEGMENT_CONNECT, - WRSM_MSG_SEGMENT_CONNECT_RESPONSE, - WRSM_MSG_SEGMENT_SMALLPUTMAP, - WRSM_MSG_SEGMENT_SMALLPUTMAP_RESPONSE, - WRSM_MSG_SEGMENT_BARRIERMAP, - WRSM_MSG_SEGMENT_BARRIERMAP_RESPONSE, - WRSM_MSG_SEGMENT_SEGMAP, - WRSM_MSG_SEGMENT_SEGMAP_RESPONSE, - WRSM_MSG_SEGMENT_DISCONNECT, - WRSM_MSG_SEGMENT_UNPUBLISH, - WRSM_MSG_SEGMENT_UNPUBLISH_RESPONSE, - WRSM_MSG_SEGMENT_ACCESS, - WRSM_MSG_SEGMENT_ACCESS_RESPONSE, - /* RSMPI Interrupt message types */ - WRSM_MSG_INTR_RECVQ_CREATE, - WRSM_MSG_INTR_RECVQ_CREATE_RESPONSE, - WRSM_MSG_INTR_RECVQ_CONFIG, - WRSM_MSG_INTR_RECVQ_CONFIG_RESPONSE, - WRSM_MSG_INTR_RECVQ_DESTROY, - /* RSMPI Barrier message types */ - /* RSMAPI Segment message types */ - /* RSMAPI Interrupt message types */ - /* RSMAPI Barrier message types */ - WRSM_MSG_TYPES_MAX -}; -typedef uint8_t wrsm_message_type_t; - -/* - * Format of messages - */ -#define WRSM_TL_MSG_SIZE (WRSM_CACHELINE_SIZE) - -typedef uint32_t wrsm_messageid_t; -typedef uint8_t wrsm_version_t; -typedef uint8_t wrsm_sessionid_t; -#define SESS_ID_INVALID 0 - -typedef struct wrsm_message_header { - uint32_t reserved1; - wrsm_version_t version; - wrsm_sessionid_t session_id; - cnodeid_t source_cnode; - wrsm_message_type_t message_type; - wrsm_messageid_t message_id; - uint32_t reserved2; -} wrsm_message_header_t; - -#define WRSM_MESSAGE_BODY_SIZE (WRSM_TL_MSG_SIZE - \ - sizeof (wrsm_message_header_t)) - -/* - * An object of type wrsm_message_t must be 64-byte aligned. The user can - * cast the body to message-specific structures. - */ -typedef struct wrsm_message { - wrsm_message_header_t header; - uint8_t body[WRSM_MESSAGE_BODY_SIZE]; -} wrsm_message_t; - -/* - * The following type may be allocated on the stack, it has the - * right size for the wrsm message, optimal aignment for wrsm_blkread/blkwrite - * and can be casted into either wrsm_message_t type or wrsm_smallput_msg. - * The wrsm_message_t requires 32 bit allignment, the wrsm_raw_message - * is declared as an array of uint64_t - giving it 8 byte alignment - */ -typedef uint64_t wrsm_raw_message_t[WRSM_TL_MSG_SIZE / sizeof (uint64_t)]; - -/* - * Definition of the user's message handler function. rxhandler is called - * when a given message type is received. Returns boolean to indicate - * if the message was successfully processed. For datagrams, the return - * value is ignored. For RPC messages, this function is called before the - * thread calling rpc() is awakened, so returning FALSE will result in the - * message being ignored, and the pending thread will eventually timeout. - * The message buffer will be allcoated and freed by the transport, and - * should not be freed by the user. - */ -typedef boolean_t (*wrsm_message_rxhandler_t)(wrsm_network_t *network, - wrsm_message_t *message); - -/* - * Definition of the user's message handler function. txhandler is used for - * formatting any transmit messages. Returns boolean to indicate if the - * message was successfully processed. Returning FALSE will cause the - * message to be discarded without being sent to the remote node (used, - * for example, if a session cannot be established with the remote cnode). - * The message buffer will be allcoated and freed by the - * transport, and should not be freed by the user. - */ -typedef boolean_t (*wrsm_message_txhandler_t)(wrsm_network_t *network, - cnodeid_t destination, - wrsm_message_t *message); - -/* - * Transport functions - * - * The following functions return 0 for success. - */ - -/* Initializes the transport for a specific RSM network */ -int wrsm_tl_init(wrsm_network_t *rsm_network); - -/* Cleans-up the transport for a specific RSM network */ -void wrsm_tl_fini(wrsm_network_t *rsm_network); - -/* Informs the transport that a new cnode is part of the config */ -int wrsm_tl_newcnode(wrsm_network_t *rsm_network, cnodeid_t cnodeid); - -/* Informs the transport that a cnode is no longer part of config */ -int wrsm_tl_removecnode(wrsm_network_t *rsm_network, cnodeid_t cnodeid); - -/* Informs the transport that a cnode is reachable */ -void wrsm_tl_reachable(wrsm_network_t *rsm_network, cnodeid_t cnodeid); - -/* Informs the transport that a cnode is no longer reachable */ -void wrsm_tl_unreachable(wrsm_network_t *rsm_network, cnodeid_t cnodeid); - -/* Adds user-defined handlers for a specific message type */ -int wrsm_tl_add_handler(wrsm_network_t *rsm_network, wrsm_message_type_t, - wrsm_message_txhandler_t send_func, wrsm_message_rxhandler_t receive_func); - -/* Sends a datagram. Caller must allocate and free msg buffer. */ -int wrsm_tl_dg(wrsm_network_t *rsm_network, cnodeid_t destination, - wrsm_message_t *msg); - -/* - * Sends a message, waits for a response. If successful (return code is 0), - * the response structure will contain the message from the remote node. - * The caller must allocate and free both the msg and response buffer. - * The caller may use the same message buffer for both the msg and response, - * and the response will overwrite the original message. - */ -int wrsm_tl_rpc(wrsm_network_t *rsm_network, cnodeid_t destination, - wrsm_message_t *msg, wrsm_message_t *response); - -/* - * Response to an rpc message, called by a receive message handler. The - * orig_msg must be an unmodified version of the message buffer provided - * to the receive message handler. The caller must allocate and free the - * response buffer. - */ -int wrsm_tl_rsp(wrsm_network_t *rsm_network, wrsm_message_t *orig_msg, - wrsm_message_t *response); - -/* - * The macro WRSM_TL_DUMP_MESSAGE dumps the contents of a message to the - * console for debugging. If DEBUG is not defined, the macro results in - * no code being generated. - */ -#ifdef DEBUG -#define WRSM_TL_DUMP_MESSAGE(txt, msg) wrsm_tl_dump_message(txt, msg) -void wrsm_tl_dump_message(char *txt, wrsm_message_t *msg); -#else -#define WRSM_TL_DUMP_MESSAGE(txt, msg) -#endif /* DEBUG */ -/* - * Standard handler functions - */ - -/* Use WRSM_TL_NO_HANDLER if you don't need a send/receive handler. */ -#define WRSM_TL_NO_HANDLER NULL - -/* - * Adds the session id to the message header. If there is currently no - * session with the destination node, it will attempt to establish a new - * session. - */ -boolean_t wrsm_tl_txhandler_sessionid(wrsm_network_t *, cnodeid_t, - wrsm_message_t *); - -/* Validates the session id for an incoming rpc response. */ -boolean_t wrsm_tl_rxhandler_sessionid(wrsm_network_t *, wrsm_message_t *); - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_TRANSPORT_H */ diff --git a/usr/src/uts/sun4u/sys/wrsm_types.h b/usr/src/uts/sun4u/sys/wrsm_types.h deleted file mode 100644 index 8a256b1bc3..0000000000 --- a/usr/src/uts/sun4u/sys/wrsm_types.h +++ /dev/null @@ -1,126 +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 (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _WRSM_TYPES_H -#define _WRSM_TYPES_H - -#pragma ident "%Z%%M% %I% %E% SMI" - - -#include <sys/types.h> - -#ifdef _KERNEL -#include <sys/rsm/rsmpi.h> -#endif -#include <sys/wci_offsets.h> - - -#ifdef __cplusplus -extern "C" { -#endif - -#define WRSM_NAME "wrsm" -#define WRSM_MAX_RAG_INSTANCE 32 -#define WRSM_MAX_CNODES 256 -#define WRSM_MAX_NCSLICES 256 -#define WRSM_MAX_WNODES 16 -#define WRSM_LINKS_PER_WCI ENTRIES_WCI_SW_LINK_STATUS -#define WRSM_MAX_LINKS_PER_WCI 3 -#define WRSM_MAX_WCIS_PER_STRIPE 4 -#define WRSM_MAX_DNIDS 4 -#define WRSM_NODE_NCSLICES 8 - -/* - * macros for manipulating bitmask sets that use arrays of 32-bit ints - * (lifted from cpuvar.h) - */ -#define WRSMBPM (sizeof (uint32_t) * NBBY) /* Number of bits in mask */ -#define WRSMSHIFT 5 /* divide by 32 */ -#define WRSMBPM (sizeof (uint32_t) * NBBY) /* Number of bits in mask */ -#define WRSMBIT(bit) ((uint32_t)1 << (((uint32_t)bit) & 0x1f)) -#define WRSMMASKS(x, y) (((x)+((y)-1))/(y)) /* Number of masks in set */ -#define WRSMMASKSIZE(set) (sizeof (set) / sizeof (uint32_t)) - -/* - * bit mask manipulation macros - */ -#define WRSM_IN_SET(set, bit) (((set).b[(bit)>>WRSMSHIFT]) & WRSMBIT(bit)) -#define WRSMSET_ADD(set, bit) (((set).b[(bit)>>WRSMSHIFT]) |= WRSMBIT(bit)) -#define WRSMSET_DEL(set, bit) (((set).b[(bit)>>WRSMSHIFT]) &= ~WRSMBIT(bit)) -#define WRSMSET_ZERO(set) bzero(&(set), sizeof (set)) - - -#define NCSLICE_MASKS WRSMMASKS(WRSM_MAX_NCSLICES, WRSMBPM) -typedef struct wrsm_ncslice_bitmask { - uint32_t b[NCSLICE_MASKS]; -} wrsm_ncslice_bitmask_t; - -#define CNODE_MASKS WRSMMASKS(WRSM_MAX_CNODES, WRSMBPM) -typedef struct wrsm_cnode_bitmask { - uint32_t b[CNODE_MASKS]; -} wrsm_cnode_bitmask_t; - -#define WNODE_MASKS WRSMMASKS(WRSM_MAX_WNODES, WRSMBPM) -typedef struct wrsm_wnode_bitmask { - uint32_t b[WNODE_MASKS]; -} wrsm_wnode_bitmask_t; - - -typedef int64_t wrsm_fmnodeid_t; -typedef unsigned char wrsm_cnodeid_t; -typedef unsigned char wrsm_wnodeid_t; -typedef uint16_t wrsm_gnid_t; -typedef unsigned char wrsm_ncslice_t; -typedef unsigned char wrsm_linkid_t; -typedef uint32_t wrsm_safari_port_t; - - -/* - * This is an ordered list. The first entry (entry 0) is the small page - * ncslice. The remaining 7 entries are large page slices; each entry maps - * to a well defined range of CMMU entries, as described in the WCI PRM. - * The ncslice for entry 1 must end with b'001', the ncslice for entry 2 - * must end with b'010', entry 3 with b'011' and so on. An ncslice value - * of 0 indicates that the entry is invalid. - */ -typedef struct node_ncslice_array { - wrsm_ncslice_t id[WRSM_NODE_NCSLICES]; -} wrsm_node_ncslice_array_t; - - -/* - * typedefs for opaque structure definitions (for structures private to - * particular wrsm modules, declared in module specific header files) - */ -typedef struct wrsm_net_member wrsm_net_member_t; -typedef struct wrsm_wci_data wrsm_wci_data_t; -typedef struct wrsm_ncslice_info wrsm_ncslice_info_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _WRSM_TYPES_H */ diff --git a/usr/src/uts/sun4u/sys/wrsmd.h b/usr/src/uts/sun4u/sys/wrsmd.h deleted file mode 100644 index 65ea7e6cbe..0000000000 --- a/usr/src/uts/sun4u/sys/wrsmd.h +++ /dev/null @@ -1,997 +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 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * DLPI driver for RSM over Wildcat - */ - -#ifndef _SYS_WRSMD_H_ -#define _SYS_WRSMD_H_ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/ethernet.h> -#include <sys/rsm/rsmpi.h> - -/* - * This driver is only supported on sparc systems, so there is no - * need to worry about byte ordering issues. - * However, need to update this version number whenever there is a - * change in the layout of wrsmd remote shared memory that could - * lead to incompatibilities between systems. - */ - -#define WRSMD_VERSION (2) - -/* - * static limits - */ - -#define WRSMD_DUMP_IOCTL (5618) -#define WRSMD_DUMP_DEST (5619) - -#define RSM_MAX_DESTADDR 256 /* Wildcat maximum -- (must be power of 2) */ - -#define RSM_DLPI_QPRI 8 /* XXX what is the priority range?? */ -#define RSM_DLPI_QDEPTH 100 -#define RSM_DLPI_QFLAGS (RSM_INTR_SEND_Q_NO_FENCE) - -#ifdef _KERNEL - -#define WRSMD_CACHELINE_SIZE (0x40) -#define WRSMD_CACHELINE_SHIFT 6 -#define WRSMD_CACHELINE_OFFSET (WRSMD_CACHELINE_SIZE - 1) -#define WRSMD_CACHELINE_MASK (~WRSMD_CACHELINE_OFFSET) -#define WRSMD_CACHELINE_ROUNDUP(b) \ - (((uint64_t)(b) + WRSMD_CACHELINE_OFFSET) & WRSMD_CACHELINE_MASK) - - - -/* - * Use the same format address as ethernet when interacting with higher - * level modules. - */ -typedef struct dl_rsm_addr { - union { - rsm_addr_t rsm; /* real RSM HW address */ - struct { - unsigned char zeroes[7]; - unsigned char addr; - } wrsm; - struct { /* address in ethernet format */ - ushort_t zero; - struct ether_addr addr; - } ether; - } m; -} dl_rsm_addr_t; - - - -/* - * Declarations specific to the medium - */ - -#define MEDIUM_MTU (64*1024-1) /* max frame w/o header */ -#define MEDIUM_MIN (1) /* min frame w/header w/o fcs */ - -#define MEDIUMSAP_MAX (0xffff) /* max valid medium sap */ - - -/* - * Definitions for module_info. - */ - -#define WRSMDIDNUM (726) /* module ID number */ -#define WRSMDNAME "wrsmd" /* module name */ -#define WRSMDMINPSZ (0) /* min packet size */ -#define WRSMDMAXPSZ (65536) /* max packet size */ -#define WRSMDHIWAT (65536) /* hi-water mark */ -#define WRSMDLOWAT (1) /* lo-water mark */ - -/* - * Driver parameters, from .conf file - */ - -struct wrsmd_param { - /* Size of packet buffers (must be multiple of 64 bytes) */ - uint_t wrsmd_buffer_size; - - /* Mask of base ID bits in IP address */ - uint_t wrsmd_netmask; - - /* Number of packet buffers exported to each communicating peer */ - ushort_t wrsmd_buffers; - - /* Size of communications queues (must be at least wrsmd_buffers) */ - ushort_t wrsmd_queue_size; - - /* Number of buffers which won't be loaned upstream */ - ushort_t wrsmd_buffers_retained; - - /* Time to reclaim idle connection after (in seconds) UNIMPLEMENTED */ - uint_t wrsmd_idle_reclaim_time; - - /* Number of retries after a read or write error */ - ushort_t wrsmd_err_retries; - - /* Maximum # of queue packets per destination */ - ushort_t wrsmd_max_queued_pkts; - - /* Initial FQE timeout interval */ - int wrsmd_nobuf_init_tmo; - - /* Maximum FQE timeout interval */ - int wrsmd_nobuf_max_tmo; - - /* Time after which we drop packets instead of doing FQE timeout */ - uint_t wrsmd_nobuf_drop_tmo; - - /* Initial message timeout interval */ - int wrsmd_msg_init_tmo; - - /* Maximum message timeout interval */ - int wrsmd_msg_max_tmo; - - /* Time after which we drop connection instead of doing msg timeout */ - uint_t wrsmd_msg_drop_tmo; - - /* Acknowledgment timeout interval */ - int wrsmd_ack_tmo; - - /* Queue element sync timeout interval */ - uint_t wrsmd_sync_tmo; - - /* - * timeout interval to wait before tearing down connection - * after last attach to device is removed. - */ - uint_t wrsmd_teardown_tmo; - - /* Number of packets to try and batch up in one transmission. */ - ushort_t wrsmd_train_size; - - /* Number of free buffers to try and batch up in one transmission. */ - ushort_t wrsmd_fqe_sync_size; -}; - -/* - * Defaults and limits for parameters - * Timeout parameter values now given in milliseconds, - * rather than ticks. Any values modified in wrsmd.conf - * must now be in milliseconds. Values get rounded up to - * the next tick value, with granularity 10 ms for the default - * 100 hz. - */ - -#define WRSMD_BUFFERS_DFLT 32 -#define WRSMD_BUFFER_SIZE_DFLT 16384 -#define WRSMD_QUEUE_SIZE_DFLT 64 -#define WRSMD_BUFFERS_RETAINED_DFLT 32 -#define WRSMD_IDLE_RECLAIM_TIME_DFLT 36000 -#define WRSMD_ERR_RETRIES_DFLT 1 -#define WRSMD_MAX_QUEUED_PKTS_DFLT 100 -#define WRSMD_NOBUF_INIT_TMO_DFLT 10 -#define WRSMD_NOBUF_MAX_TMO_DFLT 2560 -#define WRSMD_NOBUF_DROP_TMO_DFLT 5000 -#define WRSMD_MSG_INIT_TMO_DFLT 10 -#define WRSMD_MSG_MAX_TMO_DFLT 1280 -#define WRSMD_MSG_DROP_TMO_DFLT 30000 -#define WRSMD_ACK_TMO_DFLT 1000 -#define WRSMD_SYNC_TMO_DFLT 10 -/* - * We set this to two clock ticks to allow free destination timeouts - * (<= 1 tick) to complete first, before next teardown timeout, - * allowing fewer iterations of the latter. - */ -#define WRSMD_TEARDOWN_TMO_DFLT 20 - -#define WRSMD_TRAIN_SIZE_DFLT 8 -#define WRSMD_FQE_SYNC_SIZE_DFLT 16 - -/* - * Macro to convert millisecond timeout parameters to clock ticks. - */ -#define WRSMD_TICKS(x) (drv_usectohz(1000 * (x))) - -/* Definition of each possible event type */ -#define WRSMD_EVT_FREEDEST 0 -#define WRSMD_EVT_SYNC 1 -#define WRSMD_EVT_SYNC_DQE 2 - -/* - * Per-Stream instance state information. - * - * Each instance is dynamically allocated at open() and freed at - * close(). Each per-stream instance points to at most one per-device - * structure using the ss_wrsmdp field. All instances are threaded - * together into one list of active instances ordered on minor device - * number. - */ - -typedef struct wrsmdstr { - struct wrsmdstr *ss_nextp; /* next in list */ - queue_t *ss_rq; /* ptr to our read queue */ - struct wrsmd *ss_wrsmdp; /* attached device, if any */ - ushort_t ss_state; /* current state */ - ushort_t ss_flags; /* misc flags */ - t_uscalar_t ss_sap; /* bound sap (from dl_bind_req_t) */ - minor_t ss_minor; /* minor device number */ - kmutex_t ss_lock; /* protect this struct */ -} wrsmdstr_t; - -_NOTE(READ_ONLY_DATA(wrsmdstr::ss_rq)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmdstr::ss_lock, wrsmdstr::ss_wrsmdp)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmdstr::ss_lock, wrsmdstr::ss_state)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmdstr::ss_lock, wrsmdstr::ss_sap)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmdstr::ss_lock, wrsmdstr::ss_flags)) -_NOTE(READ_ONLY_DATA(wrsmdstr::ss_minor)) - -/* - * For performance reasons, we read the following things in wrsmdsendup() - * without getting ss_lock. As long as accesses to these variables are atomic, - * we believe nothing bad will happen. - */ -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmdstr::ss_wrsmdp)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmdstr::ss_sap)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmdstr::ss_flags)) - -/* Per-stream flags */ - -#define WRSMD_SLRAW 0x02 /* M_DATA plain raw mode */ -#define WRSMD_SLALLPHYS 0x04 /* "promiscuous mode" */ -#define WRSMD_SLALLSAP 0x08 /* enable all ether type values */ -#define WRSMD_SLFAST 0x10 /* "fast mode" */ - -typedef struct wrsmd_event { - struct wrsmd_event *next; - int type; - void *arg; -} wrsmd_event_t; - - -/* - * Per-Device instance state information. - * - * Each instance is dynamically allocated on first attach. - */ -typedef struct wrsmd { - struct wrsmd *wrsmd_nextp; /* next in linked list */ - queue_t *wrsmd_wq; /* ptr to one of our wq's, doesn't */ - /* matter which one, to run wsrv */ - queue_t *wrsmd_ipq; /* IP queue, iff there's only one */ - krwlock_t wrsmd_ipq_rwlock; /* protects wrsmd_ipq */ - - dev_info_t *wrsmd_dip; /* dev info */ - ushort_t wrsmd_flags; /* misc. flags */ - ushort_t wrsmd_promisc; /* # of WRSMD_SLALLPHYS streams */ - ushort_t wrsmd_attached_streams; /* streams attached to device */ - kmutex_t wrsmd_lock; /* protect this struct */ - kmutex_t wrsmd_dest_lock; /* protect dest table (below) */ - - /* Counters to keep stats for netstat support */ - uint64_t wrsmd_ipackets; /* # packets received */ - uint32_t wrsmd_ierrors; /* # total input errors */ - uint64_t wrsmd_opackets; /* # packets sent */ - uint32_t wrsmd_oerrors; /* # total output errors */ - uint32_t wrsmd_collisions; /* # collisions (FQE waits) */ - - uint32_t wrsmd_in_bytes; /* # bytes input (32 bit) */ - uint32_t wrsmd_in_bytes64; /* # bytes input (64 bit) */ - uint64_t wrsmd_out_bytes; /* # bytes output (32 bit) */ - uint64_t wrsmd_out_bytes64; /* # bytes output (64 bit) */ - - /* Other counters, for internal use */ - uint32_t wrsmd_xfers; /* # calls to wrsmd_xmit */ - uint32_t wrsmd_xfer_pkts; /* # pkts sent out by xmit */ - uint32_t wrsmd_syncdqes; /* # syncdqe-ints sent out by xmit */ - uint32_t wrsmd_lbufs; /* # times we loaned bufs */ - uint32_t wrsmd_nlbufs; /* # times we had to alloc buf */ - uint32_t wrsmd_pullup; /* # times we had to coalesce pkts */ - uint32_t wrsmd_pullup_fail; /* # times we couldn't pullup */ - uint32_t wrsmd_starts; /* # calls to wrsmdstart */ - uint32_t wrsmd_start_xfers; /* # calls to wrsmdxfer from start */ - uint32_t wrsmd_fqetmo_hint; /* # times fqe tmo ended by hint */ - uint32_t wrsmd_fqetmo_drops; /* # pkts dropped by fqetmo */ - uint32_t wrsmd_maxq_drops; /* # pkts dropped 'cause q too long */ - uint32_t wrsmd_errs; /* # errors on transfers */ - - struct wrsmd_param wrsmd_param; /* parameters */ - struct kstat *wrsmd_ksp; /* our kstats */ - dl_rsm_addr_t wrsmd_rsm_addr; /* our RSM hardware address */ - uint_t wrsmd_ctlr_id; /* our RSM controller id */ - rsm_controller_object_t wrsmd_ctlr; - rsm_controller_attr_t *wrsmd_ctlr_attr; - int wrsmd_numdest; /* Number of valid entries in desttbl */ - - struct wrsmd_dest /* table for destination structures */ - *wrsmd_desttbl[RSM_MAX_DESTADDR]; - - struct wrsmd_dest *wrsmd_runq; /* service routine run queue */ - kmutex_t wrsmd_runq_lock; /* protects wrsmd_runq, among others */ - - timeout_id_t wrsmd_teardown_tmo_id; /* teardown device */ - - /* Event thread for making RSM calles from non callback context */ - kmutex_t event_lock; - kthread_t *event_thread; - kcondvar_t event_cv; - boolean_t stop_events; - kcondvar_t event_thread_exit_cv; - wrsmd_event_t *events; - -} wrsmd_t; - - -_NOTE(READ_ONLY_DATA(wrsmd::wrsmd_dip)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd::wrsmd_lock, wrsmd::wrsmd_flags)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd::wrsmd_lock, wrsmd::wrsmd_promisc)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd::wrsmd_promisc)) - -_NOTE(READ_ONLY_DATA(wrsmd::wrsmd_param)) -_NOTE(READ_ONLY_DATA(wrsmd_param)) - -_NOTE(MUTEX_PROTECTS_DATA(wrsmd::wrsmd_lock, wrsmd::wrsmd_ksp)) -_NOTE(READ_ONLY_DATA(wrsmd::wrsmd_ctlr_id)) - -_NOTE(MUTEX_PROTECTS_DATA(wrsmd::wrsmd_runq_lock, wrsmd::wrsmd_runq)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd::wrsmd_runq_lock, wrsmd::wrsmd_wq)) - -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd::wrsmd_dip)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd::wrsmd_ipackets)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd::wrsmd_ierrors)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd::wrsmd_opackets)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd::wrsmd_oerrors)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd::wrsmd_collisions)) - -/* RSMPI progress flags */ -#define WRSMDREGHANDLER 0x01 -#define WRSMDGOTCTLR 0x02 - -/* Attach progress bitmask */ -#define WRSMD_ATT_MUTEX 0x01 -#define WRSMD_ATT_LINKED 0x02 -#define WRSMD_ATT_MINOR 0x04 -#define WRSMD_ATT_KSTAT 0x08 -#define WRSMD_ATT_EVT_THREAD 0x10 - -#define WRSMD_ATT_ALL \ - (WRSMD_ATT_MUTEX | WRSMD_ATT_LINKED | WRSMD_ATT_MINOR \ - | WRSMD_ATT_KSTAT | WRSMD_ATT_EVT_THREAD) - - -/* - * Number of bytes to add to buffer size to leave room for - * headers from other streams modules: - * - * TCP Header is 14 bytes - * IP Header is 20 bytes - */ -#define WRSMDHEADROOM 34 - -/* - * Full dlsap address format - */ - -typedef struct wrsmddladdr { - struct ether_addr dl_addr; /* RSM hardware addr */ - ushort_t dl_sap; /* SAP */ -} wrsmddladdr_t; - - -/* - * Full DLSAP address length - */ -#define WRSMD_DEVICE_ADDRL (sizeof (ushort_t) + sizeof (struct ether_addr)) -#define WRSMD_IP_SAP 0x800 /* IP's sap */ - -#define WRSMD_BCAST_ADDRL (sizeof (struct ether_addr)) - -#define DLADDRL (80) - -/* - * Export some of the error counters via the kstats mechanism. - */ -typedef struct wrsmd_stat { - struct kstat_named rsm_ipackets; - struct kstat_named rsm_ipackets64; - struct kstat_named rsm_ierrors; - struct kstat_named rsm_opackets; - struct kstat_named rsm_opackets64; - struct kstat_named rsm_oerrors; - struct kstat_named rsm_collisions; - struct kstat_named rsm_xfers; - struct kstat_named rsm_xfer_pkts; - struct kstat_named rsm_syncdqes; - struct kstat_named rsm_lbufs; - struct kstat_named rsm_nlbufs; - struct kstat_named rsm_pullup; - struct kstat_named rsm_pullup_fail; - struct kstat_named rsm_starts; - struct kstat_named rsm_start_xfers; - struct kstat_named rsm_fqetmo_hint; - struct kstat_named rsm_fqetmo_drops; - struct kstat_named rsm_maxq_drops; - struct kstat_named rsm_errs; - struct kstat_named rsm_in_bytes; - struct kstat_named rsm_in_bytes64; - struct kstat_named rsm_out_bytes; - struct kstat_named rsm_out_bytes64; -} wrsmd_stat_t; - -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_ipackets)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_ierrors)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_opackets)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_oerrors)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_collisions)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_xfers)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_xfer_pkts)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_lbufs)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_nlbufs)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_pullup)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_pullup_fail)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_starts)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_start_xfers)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_fqetmo_hint)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_fqetmo_drops)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_maxq_drops)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_errs)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_in_bytes)) -_NOTE(SCHEME_PROTECTS_DATA("inconsistency OK", wrsmd_stat::rsm_out_bytes)) - -/* Some streams defines */ - -#define DB_BASE(mp) ((mp)->b_datap->db_base) -#define DB_LIM(mp) ((mp)->b_datap->db_lim) -#define DB_REF(mp) ((mp)->b_datap->db_ref) -#define DB_TYPE(mp) ((mp)->b_datap->db_type) - -#define MBLKL(mp) ((mp)->b_wptr - (mp)->b_rptr) -#define MBLKSIZE(mp) ((mp)->b_datap->db_lim - (mp)->b_datap->db_base) -#define MBLKHEAD(mp) ((mp)->b_rptr - (mp)->b_datap->db_base) -#define MBLKTAIL(mp) ((mp)->b_datap->db_lim - (mp)->b_wptr) - -/* - * On Wildcat, if there is a data delivery problem with one of the 32 byte - * halves of a 64 byte write to the remote node, the remote side writes all - * 0's to that 32 byte region of memory. We guarantee that the 4 byte fqe - * entries and 8 byte byte dqe entries (described below) are aligned in a - * way that guarantees that each fits within a single 32 byte region, so - * checking for any non-zero value within the entry is sufficient to - * guarantee that the write was successful. - * - * We use the seqnum as the write validity check, which means it must never - * be 0. A non-0 value ensures that the remote write was successful. - * - * Each fqe and dqe is 64 bytes in size. This guarantees that - * we can write one entry at a time atomically, without disturbing any other - * entries. This also quarantees alignment to wildcat hardware. It does, - * however, waste some space. - * - */ - -struct align_64byte { /* Align to 64 bytes */ - uint64_t pad[8]; -}; - -/* - * Delivery Queue Entry, used to denote buffers containing new packets. - */ -#define WRSMD_DQE_SEQ_MASK 0xFF /* All 1's sequence */ -typedef union wrsmd_dqe { - struct align_64byte align; /* Align to 64 bytes */ - struct wrsmd_dqe_s { /* actual structure */ - ushort_t dq_length; /* True length of packet */ - ushort_t dq_sap; /* Packet's SAP */ - uchar_t dq_seqnum; /* Sequence number - validity check */ - uchar_t dq_offset; /* Packet offset within buffer */ - ushort_t dq_bufnum; /* Buffer number */ - } s; -} wrsmd_dqe_t; - -/* - * Free Queue Entry, used to denote buffers which are available to be filled. - */ -#define WRSMD_FQE_SEQ_MASK 0xFF /* All 1's sequence */ -typedef union wrsmd_fqe { - struct align_64byte align; /* Align to 64 bytes */ - struct wrsmd_fqe_s { - uchar_t fq_seqnum; /* Sequence number - validity check */ - uchar_t fq_filler; /* Unused */ - ushort_t fq_bufnum; /* Buffer number */ - } s; -} wrsmd_fqe_t; - -/* - * Segment data formats - */ - -/* - * The major version should be bumped whenever the contents of the - * xfer segments are changed in a non-upward-compatible way, to prevent - * confused attempts at communication with machines running older protocol - * versions. - */ -#define WRSMD_VERS_MAJOR 1 -#define WRSMD_VERS_MINOR 0 - -/* - * Header for the data transfer segment. - */ -typedef struct wrsmd_xfer_hdr { - size_t rx_segsize; /* size of segment */ - uint32_t rx_cookie; /* magic cookie */ - uint32_t rx_bufsize; /* size of buffers */ - ushort_t rx_numbufs; /* number of buffers */ - ushort_t rx_numfqes; /* number of elements in free queue */ - ushort_t rx_numdqes; /* num of elements in delivery queue */ - uint32_t rx_buf_offset; /* offset to start of buffers */ - uint32_t rx_fq_offset; /* offset to start of free queue */ - uint32_t rx_dq_offset; /* offset to start of delivery queue */ -} wrsmd_xfer_hdr_t; - -#define WRSMD_XFER_COOKIE 0x58664572 /* 'XfEr' */ - -/* - * Structure describing a loaned-up buffer - */ - -typedef struct wrsmdbuf { - frtn_t rb_frtn; /* Pointer to our free routine */ - int rb_bufnum; /* Number of loaned buffer */ - struct wrsmd_dest *rb_rd; /* Destination buffer belongs to */ -} wrsmdbuf_t; - -_NOTE(READ_ONLY_DATA(wrsmdbuf::rb_frtn)) -_NOTE(READ_ONLY_DATA(wrsmdbuf::rb_bufnum)) -_NOTE(READ_ONLY_DATA(wrsmdbuf::rb_rd)) - -/* - * Structure describing a packet which is currently being sent - */ - -typedef struct wrsmd_pkt { - mblk_t *rd_pkt_ptr; /* packet pointer */ - ushort_t rd_pkt_offset; /* packet offset within buffer */ - uint_t rd_pkt_len; /* real length of packet */ - ushort_t rd_pkt_sap; /* packet SAP */ -} wrsmd_pkt_t; - - -/* - * WRSMD message types - */ - -#define WRSMD_MSG_REQ_CONNECT 1 -#define WRSMD_MSG_CON_ACCEPT 2 -#define WRSMD_MSG_CON_ACK 3 -#define WRSMD_MSG_SYNC_DQE 4 - -#define WRSMD_REXMIT 127 - - - -/* - * - * R S M D C O N N E C T I O N P R O T O C O L - * - * - * The connection protocol for the RSM DLPI driver is a follows: - * - * INITIATOR RESPONDER - * - * 1 Send RSDM_REQ_CONNECT - * Includes xfer segment ID - * - * 2 Send WRSMD_CON_ACCEPT - * Includes xfer segment ID - * - * 3 Send WRSMD_CON_ACK - * - * If an WRSMD_REQ_CONNECT message is received while an - * WRSMD_REQ_CONNECT is outstanding to the same node ID: if the - * node receiving the duplicate WRSMD_REQ_CONNECT has a higher - * numbered ID, it will accept the connection. The lower numbered - * node will reject the duplicate. - * - * The special message type WRSMD_REXMIT causes us to retransmit the - * last message we sent (unsuccessfully or successfully), without - * incrementing the sequence number on the message. This is used when - * we get a timeout waiting for a response to an WRSMDM_REQ_CONNECT - * request and want to resend it. - * - */ - -typedef struct wrsmd_msg_header { - uint8_t wrsmd_version; /* Increment when incompatible change made */ - uint8_t reqtype; /* One of the above */ - uint16_t seqno; /* Sequence number */ -} wrsmd_msg_header_t; - -typedef struct wrsmd_con_request { - rsm_memseg_id_t send_segid; /* Segment you should use to talk to me */ -} wrsmd_con_request_t; - -typedef struct wrsmd_con_accept { - rsm_memseg_id_t send_segid; /* Segment you should use to talk to me */ - rsm_memseg_id_t rcv_segid; /* Segment I use to talk to you */ -} wrsmd_con_accept_t; - -typedef struct wrsmd_con_ack { - rsm_memseg_id_t send_segid; /* Segment you should use to talk to me */ - rsm_memseg_id_t rcv_segid; /* Segment I use to talk to you */ -} wrsmd_con_ack_t; - -typedef struct wrsmd_syncdqe { - rsm_memseg_id_t rcv_segid; /* Segment I use to talk to you */ -} wrsmd_syncdqe_t; - - - -typedef union wrsmd_msg { - uint64_t align; - struct { - wrsmd_msg_header_t hdr; - union { - wrsmd_con_request_t con_request; - wrsmd_con_accept_t con_accept; - wrsmd_con_ack_t con_ack; - wrsmd_syncdqe_t syncdqe; - } m; - } p; -} wrsmd_msg_t; - -/* - * Structure describing someone else communicating with us (a destination) - */ - -typedef struct wrsmd_dest { - - /* Basics */ - wrsmd_t *rd_wrsmdp; /* Pointer to our device structure */ - rsm_addr_t rd_rsm_addr; /* Address of destination */ - - /* Interrupt queue */ - rsm_send_q_handle_t rsm_sendq; - wrsmd_msg_t rsm_previous_msg; - int rsm_previous_msg_valid; - - /* Packet queue */ - mblk_t *rd_queue_h, /* queue of packets waiting to go out */ - *rd_queue_t; - ushort_t rd_queue_len; /* number of packets on above queue */ - - - /* Local transfer segment */ - caddr_t rd_rawmem_base_addr; - size_t rd_rawmem_base_size; - rsm_memory_local_t rd_memory; - rsm_memseg_id_t rd_lxfersegid; - rsm_memseg_export_handle_t rd_lxferhand; - - - /* Remote transfer segment */ - wrsmd_xfer_hdr_t rd_rxferhdr; - int rd_rxferhdr_valid; - off_t rd_rbufoff; - boolean_t rd_segid_valid; - rsm_memseg_id_t rd_rxfersegid; - rsm_memseg_import_handle_t rd_rxferhand; - uint16_t rd_lastconnmsg_seq; - - - /* - * Free queue we're writing to (describing buffers on our node - * available to partner; lives on partner) - */ - off_t rd_fqw_f_off; /* First usable element in queue */ - ushort_t rd_fqw_seq; /* Sequence number we will write next */ - ushort_t rd_num_fqws; /* Number of usable elements in queue */ - - - /* - * Delivery queue that we're writing to (describing buffers on - * partner that we've filled with data; lives on partner) - */ - off_t rd_dqw_f_off; /* First usable element in queue */ - ushort_t rd_dqw_seq; /* Sequence number we will write next */ - ushort_t rd_num_dqws; /* Number of usable elements in queue */ - - - /* Buffers (on partner) that we're writing to */ - uint_t rd_rbuflen; /* Length of remote buffers */ - ushort_t rd_numrbuf; /* Number of remote buffers */ - - - /* - * Free queue we're reading from (describing buffers on partner - * available to us; lives on our node) - */ - volatile wrsmd_fqe_t /* Pointers to ... */ - *rd_fqr_f, /* First usable element in queue */ - *rd_fqr_l, /* Last usable element in queue */ - *rd_fqr_n; /* Element we'll read next */ - ushort_t rd_fqr_seq; /* Sequence number we expect to read next */ - ushort_t rd_num_fqrs; /* Number of usable elements in queue */ - - - /* - * Delivery queue we're reading from (describing buffers on our - * node that the partner has filled with data; lives on our node) - */ - volatile wrsmd_dqe_t /* Pointers to ... */ - *rd_dqr_f, /* First usable element in queue */ - *rd_dqr_l, /* Last usable element in queue */ - *rd_dqr_n; /* Element we'll read next */ - ushort_t rd_dqr_seq; /* Sequence number we expect to read next */ - ushort_t rd_num_dqrs; /* Number of usable elements in queue */ - - - /* (Local) buffers we're reading from */ - volatile void *rd_lbuf; /* Start of first local buffer */ - uint_t rd_lbuflen; /* Length of each local buffer */ - ushort_t rd_numlbufs; /* Number of local buffers */ - wrsmdbuf_t *rd_bufbase; /* Local buffer description structures, */ - /* for use in loaning buffers upward */ - - - /* Information on cached FQE's */ - ushort_t rd_cached_fqr_cnt; /* number of cached fqe's */ - ushort_t *rd_cached_fqr; /* buffer numbers from cached fqe's */ - - - /* - * Shadow free queue - local copy of free queue that lives on - * partner - */ - wrsmd_fqe_t /* Pointers to ... */ - *rd_shdwfqw_f_addr, /* Start of alloc'd memory for queue */ - *rd_shdwfqw_f, /* First usable element */ - *rd_shdwfqw_l, /* Last usable element */ - *rd_shdwfqw_i, /* Next element added to queue goes here */ - *rd_shdwfqw_o; /* Next element transmitted comes from here */ - - /* - * Shadow delivery queue - local copy of delivery queue that lives - * on partner - */ - wrsmd_dqe_t /* Pointers to ... */ - *rd_shdwdqw_f_addr, /* Start of alloc'd memory for queue */ - *rd_shdwdqw_f, /* First usable element */ - *rd_shdwdqw_l, /* Last usable element */ - *rd_shdwdqw_i, /* Next element added to queue goes here */ - *rd_shdwdqw_o; /* Next element transmitted comes from here */ - - ushort_t rd_shdwfqw_errflag; /* If nonzero, we had an error last */ - /* time we tried to write an FQE */ - ushort_t rd_shdwdqw_errflag; /* If nonzero, we had an error last */ - /* time we tried to write a DQE */ - ushort_t rd_stopq; /* If nonzero, we shouldn't try to */ - /* sync queues, the network is down */ - - - /* State information */ - ushort_t rd_state; /* State (WRSMD_STATE_xxx, see below) */ - ushort_t rd_estate; /* Event State */ - ushort_t rd_sstate; /* Segment state (bitmask of WRSMD_RSMS_xxx) */ - ushort_t rd_dstate; /* Delete state (0-2), != 0 means deleting */ - short rd_refcnt; /* Destination reference count */ - - - /* Command/sequence information */ - ushort_t rd_nseq; /* Seq # we'll put on next message */ - uchar_t rd_recvdack; /* Nonzero if we've gotten a valid ACK */ - uchar_t rd_sentconn; /* Nonzero if we've sent a CONN */ - - - /* Last message transmitted, for rexmits if needed */ - wrsmd_msg_t rd_lastobmsg; /* Last outbound message */ - - - - /* Timeout information */ - - timeout_id_t rd_fqe_tmo_id; /* timeout ID for free queue retry. */ - timeout_id_t rd_tmo_id; /* timeout ID for empty queue retry, etc. */ - int rd_tmo_int; /* backoff interval for timeout */ - int rd_tmo_tot; /* ticks we've waited so far this timeout */ - - ushort_t rd_nlb; /* number of outstanding loaned buffers */ - ushort_t rd_nlb_del; /* if nonzero, we're being deleted, and are */ - /* waiting for rd_nlb to go to 0 */ - - - kmutex_t rd_nlb_lock; /* mutex to protect rd_nlb/rd_nlb_del */ - kmutex_t rd_lock; /* mutex to protect this data structure */ - kmutex_t rd_net_lock; /* mutex to protect segment data/pointers */ - kmutex_t rd_xmit_lock; /* mutex to protect xmit stuff */ - - - struct wrsmd_dest *rd_next; /* ptrs for svc routine run queue */ -} wrsmd_dest_t; - -_NOTE(READ_ONLY_DATA(wrsmd_dest::rd_wrsmdp)) -_NOTE(READ_ONLY_DATA(wrsmd_dest::rd_rsm_addr)) - -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_xmit_lock, wrsmd_dest::rd_queue_h)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_xmit_lock, wrsmd_dest::rd_queue_t)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_xmit_lock, wrsmd_dest::rd_queue_len)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_lock, wrsmd_dest::rd_lxferhand)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_lock, wrsmd_dest::rd_rbuflen)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd_dest::rd_rbuflen)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_lock, wrsmd_dest::rd_numrbuf)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd_dest::rd_numrbuf)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_lock, wrsmd_dest::rd_lbuf)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd_dest::rd_lbuf)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_lock, wrsmd_dest::rd_lbuflen)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd_dest::rd_lbuflen)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_lock, wrsmd_dest::rd_numlbufs)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd_dest::rd_numlbufs)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_lock, wrsmd_dest::rd_bufbase)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd_dest::rd_bufbase)) - -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_shdwfqw_f)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_shdwfqw_l)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_shdwfqw_i)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_shdwfqw_o)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_fqw_seq)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_shdwdqw_f)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_shdwdqw_l)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_shdwdqw_i)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_shdwdqw_o)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_dqw_seq)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_fqr_f)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_fqr_l)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_fqr_n)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_fqr_seq)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_dqr_f)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_dqr_l)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_dqr_n)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_dqr_seq)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, - wrsmd_dest::rd_cached_fqr_cnt)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_cached_fqr)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, - wrsmd_dest::rd_shdwfqw_errflag)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, - wrsmd_dest::rd_shdwdqw_errflag)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_net_lock, wrsmd_dest::rd_stopq)) - -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_xmit_lock, wrsmd_dest::rd_tmo_id)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(wrsmd_dest::rd_tmo_id)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_xmit_lock, wrsmd_dest::rd_tmo_int)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_xmit_lock, wrsmd_dest::rd_tmo_tot)) - -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_nlb_lock, wrsmd_dest::rd_nlb)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd_dest::rd_nlb_lock, wrsmd_dest::rd_nlb_del)) - -_NOTE(MUTEX_PROTECTS_DATA(wrsmd::wrsmd_runq_lock, wrsmd_dest::rd_state)) -_NOTE(SCHEME_PROTECTS_DATA("see comment below", wrsmd_dest::rd_next)) - -_NOTE(MUTEX_PROTECTS_DATA(wrsmd::wrsmd_dest_lock, wrsmd_dest::rd_dstate)) -_NOTE(MUTEX_PROTECTS_DATA(wrsmd::wrsmd_dest_lock, wrsmd_dest::rd_refcnt)) - - -/* - * Run queue: - * - * Certain operations on destinations are performed by the driver's write - * service routine (wrsmd_wsrv). In order to arrange for this, there is a - * queue of destinations waiting to be processed by the service routine. - * Each device's wrsmd_runq points to the head of this queue of destinations, - * which are linked together via rd_next. Whenever the service routine - * runs, after it has served its usual purpose of processing messages from - * the stream's service queue, it traverses its list of destinations and - * performs appropriate operations on them, depending on their state. - * - * The rd_next pointer is protected by the runq_lock everywhere but in the - * middle of the service routine. Essentially, the service routine takes a - * whole chain of destination entries off of the run queue at once (inside - * the runq_lock), and then traverses the list (outside the runq_lock). Since - * a scheduled destination should never be given a new state except by the - * service routine, there should be no conflicting updates to rd_next. - * - * Destination states: - * - * A scheduled state means the destination is on the run queue; an unscheduled - * state means the destination is not. State transitions are always from - * scheduled to unscheduled or vice versa. - * - * A state with a name of the form WRSMD_STATE_S_xxx is a scheduled state where - * the service routine is going to do xxx next. These states have odd numbers. - * - * A state with a name of the form WRSMD_STATE_W_xxx is an unscheduled state - * where we are waiting for xxx to happen. These states have even numbers. - */ - -#define WRSMD_STATE_NEW 0 /* Newly created */ -#define WRSMD_STATE_INPROGRESS 1000 /* Being processed */ -#define WRSMD_STATE_DELETING 2000 /* Being deleted */ - -#define WRSMD_STATE_W_SCONNTMO 2 /* Waiting for conn rxmit tmo */ -#define WRSMD_STATE_W_ACCEPT 4 /* Waiting for accept msg */ -#define WRSMD_STATE_W_ACK 6 /* Waiting for ack msg */ -#define WRSMD_STATE_W_READY 8 /* Connected, wait for pkt */ -#define WRSMD_STATE_W_FQE 10 /* Waiting for fqe to xmit */ - -#define WRSMD_STATE_S_REQ_CONNECT 1 /* Srv: send conn request */ -#define WRSMD_STATE_S_NEWCONN 3 /* Srv: setup/accept new conn */ -#define WRSMD_STATE_S_CONNXFER_ACCEPT 5 /* Srv: connxfer, then accept */ -#define WRSMD_STATE_S_CONNXFER_ACK 7 /* Srv: connxfer, then ack */ -#define WRSMD_STATE_S_XFER 9 /* Srv: xfer data */ -#define WRSMD_STATE_S_DELETE 11 /* Srv: delete this dest */ -#define WRSMD_STATE_S_SCONN 13 /* Srv: resend last conn */ - -#define WRSMD_SCHED_STATE(s) ((s) & 1) - -#define WRSMD_STATE_STR(x) ( \ - (x == WRSMD_STATE_NEW) ? "WRSMD_STATE_NEW" : \ - (x == WRSMD_STATE_INPROGRESS) ? "WRSMD_STATE_INPROGRESS" : \ - (x == WRSMD_STATE_DELETING) ? "WRSMD_STATE_DELETING" : \ - (x == WRSMD_STATE_W_SCONNTMO) ? "WRSMD_STATE_W_SCONNTMO" : \ - (x == WRSMD_STATE_W_ACCEPT) ? "WRSMD_STATE_W_ACCEPT" : \ - (x == WRSMD_STATE_W_ACK) ? "WRSMD_STATE_W_ACK" : \ - (x == WRSMD_STATE_W_READY) ? "WRSMD_STATE_W_READY" : \ - (x == WRSMD_STATE_W_FQE) ? "WRSMD_STATE_W_FQE" : \ - (x == WRSMD_STATE_S_REQ_CONNECT) ? "WRSMD_STATE_S_REQ_CONNECT" :\ - (x == WRSMD_STATE_S_NEWCONN) ? "WRSMD_STATE_S_NEWCONN" : \ - (x == WRSMD_STATE_S_CONNXFER_ACCEPT) ? \ - "WRSMD_STATE_S_CONNXFER_ACCEPT" : \ - (x == WRSMD_STATE_S_CONNXFER_ACK) ? "WRSMD_STATE_S_CONNXFER_ACK" : \ - (x == WRSMD_STATE_S_XFER) ? "WRSMD_STATE_S_XFER" : \ - (x == WRSMD_STATE_S_DELETE) ? "WRSMD_STATE_S_DELETE" : \ - (x == WRSMD_STATE_S_SCONN) ? "WRSMD_STATE_S_SCONN" : \ - "unknown") - - -/* - * RSM driver state - basically, what segments we've created/connected. We - * keep a bitmask of the ones we've done, so that when we delete a - * destination we don't try and undo something we never did. Also, we - * sometimes check to make sure rd_sstate is WRSMD_RSMS_ALL before trying to - * perform an operation on a destination, to ensure we don't get ahead of - * our initialization. - */ - -#define WRSMD_RSMS_LXFER_C 0x01 /* Create local xfer segment */ -#define WRSMD_RSMS_LXFER_P 0x02 /* Publish local xfer segment */ -#define WRSMD_RSMS_RXFER_S 0x04 /* Create send queue to remote node */ -#define WRSMD_RSMS_RXFER_C 0x10 /* Connect to remote xfer */ - -#define WRSMD_RSMS_ALL \ - (WRSMD_RSMS_LXFER_C | WRSMD_RSMS_LXFER_P | WRSMD_RSMS_RXFER_S | \ - WRSMD_RSMS_RXFER_C) - -#endif /* _KERNEL */ - - -#ifdef __cplusplus -} -#endif - - -#endif /* _SYS_WRSMD_H_ */ diff --git a/usr/src/uts/sun4u/wrsmd/Makefile b/usr/src/uts/sun4u/wrsmd/Makefile deleted file mode 100644 index 4a608ea473..0000000000 --- a/usr/src/uts/sun4u/wrsmd/Makefile +++ /dev/null @@ -1,123 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -#ident "%Z%%M% %I% %E% SMI" -# -# uts/sun4u/wrsmd/Makefile -# -# This makefile drives the production of the sun4u "wrsmd" driver module. -# -# sun4u implementation architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = wrsmd -OBJECTS = $(WRSMD_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WRSMD_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE) -CONF_SRCDIR = $(UTSBASE)/sun4u/io - -# -# Include common rules. -# -include $(UTSBASE)/sun4u/Makefile.sun4u - -# -# Include path for rsm header files -# -INC_PATH += -I$(UTSBASE)/common - - -# -# Define targets -# -ALL_TARGET = $(BINARY) $(SRC_CONFILE) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE) - -# -# -# Turn on doubleword alignment for 64 bit registers -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) -dalign - -# -# module dependencies -# -LDFLAGS += -dy -Nmisc/rsmops - -# -# to turn on TNF, add this line -# -LDFLAGS += -Ndrv/tnf - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED -LINTTAGS += -erroff=E_SUSPICIOUS_COMPARISON -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -ll: $(ALL_DEPS) - $(CC) $(CFLAGS) $(CPPFLAGS) $(CCVERBOSE) -Zll ../io/wrsmd.c - - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sun4u/Makefile.targ |