PSARC/2006/217 Access and Dma Handle Error Clear Functions
authordilpreet
Sun, 23 Apr 2006 15:26:28 -0700
changeset 1865 c8b524cdb631
parent 1864 f9cff5467c06
child 1866 a55148473528
PSARC/2006/217 Access and Dma Handle Error Clear Functions PSARC/2006/235 FMA for PCI Express and Leaf Devices 6193463 hostbridge .esc files don't fully handle pci-pci bridges 6195325 pci eversholt rules need to support multiple levels of pci-pci bridges 6202643 libtopo should provide pcibus information on x86 boxen 6207403 bridge error callbacks need to participate in handle lookup 6236885 ddi_fm_init leaks resources if parent not fm capable 6236895 ddi_fm_dma_err_get and ddi_fm_acc_err_get need to be more resilient 6239835 Need common diagnosis rules for PCI Express 6239838 Need common ereport generation routines for PCI Express error telemetry 6239840 Need common PCI error handling routines 6245935 RFE: enhance bge driver with FMA support 6304815 ddifm.c DDI_DEV_T_ANY ddi_prop_remove(9F) calls should use DDI_DEV_T_NONE 6326796 pci_check_regs() can match wrong node when an error occurs on a config space access 6327032 Provide FMA support for CK8-04/IO-4 PCI express chipsets 6347217 eversholt rules for handling of pci dto errors need changing 6351025 eft assertion failure: ffep != NULL 6360437 check_if_device_is_pciex should add properties for pciex nodes during pci device discovery 6360749 ddi_fm_service_impact() should raise an service impact ereport 6360764 It would be nice for a driver to have some way to clear err_status in a access or dma handle 6373233 bofi fault simulation should be made compatible with fma 6373293 Solaris 10 may not be properly diagnosing the faulty component after injecting an 'IOUE' 6373322 could define generic device driver ereports for internal chip errors 6393895 TOMATILLO_IOMMU_INVALID_ERR is treated as fatal when it need not be 6398325 eversholt can leak memory if there are constraints on both sides of a propagation 6411683 donot bind driver to PCI express disabled slots 6416496 reduce eversholt memory consumption by trimming open fmes
usr/src/cmd/fm/dicts/Makefile
usr/src/cmd/fm/dicts/PCI.dict
usr/src/cmd/fm/dicts/PCI.po
usr/src/cmd/fm/dicts/PCIEX.dict
usr/src/cmd/fm/dicts/PCIEX.po
usr/src/cmd/fm/dicts/SUN4U.dict
usr/src/cmd/fm/dicts/SUN4U.po
usr/src/cmd/fm/eversholt/files/common/pci.esc
usr/src/cmd/fm/eversholt/files/common/pciex.esc
usr/src/cmd/fm/eversholt/files/i386/Makefile
usr/src/cmd/fm/eversholt/files/sparc/Makefile
usr/src/cmd/fm/eversholt/files/sparc/sun4u/psycho.esc
usr/src/cmd/fm/eversholt/files/sparc/sun4u/schizo.esc
usr/src/cmd/fm/eversholt/files/sparc/sun4u/tomatillo.esc
usr/src/cmd/fm/eversholt/files/sparc/sun4u/xmits.esc
usr/src/cmd/fm/modules/common/eversholt/fme.c
usr/src/cmd/fm/modules/common/eversholt/iexpr.c
usr/src/cmd/fm/modules/common/eversholt/iexpr.h
usr/src/cmd/fm/modules/common/eversholt/itree.c
usr/src/cmd/fm/modules/common/eversholt/itree.h
usr/src/cmd/th_tools/th_script.sh
usr/src/lib/fm/topo/files/i86pc/hc-topology.xml
usr/src/lib/fm/topo/modules/common/did.c
usr/src/lib/fm/topo/modules/common/did.h
usr/src/lib/fm/topo/modules/common/did_impl.h
usr/src/lib/fm/topo/modules/common/did_props.c
usr/src/lib/fm/topo/modules/common/did_props.h
usr/src/lib/fm/topo/modules/common/hostbridge.h
usr/src/lib/fm/topo/modules/common/pcibus.c
usr/src/lib/fm/topo/modules/common/pcibus_labels.c
usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c
usr/src/pkgdefs/SUNW0on/prototype_com
usr/src/pkgdefs/SUNWfmd/prototype_com
usr/src/uts/common/Makefile.files
usr/src/uts/common/crypto/io/dca.c
usr/src/uts/common/io/bge/bge_chip2.c
usr/src/uts/common/io/bge/bge_kstats.c
usr/src/uts/common/io/bge/bge_log.c
usr/src/uts/common/io/bge/bge_main2.c
usr/src/uts/common/io/bge/bge_mii.c
usr/src/uts/common/io/bge/bge_recv2.c
usr/src/uts/common/io/bge/bge_send.c
usr/src/uts/common/io/bofi.c
usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c
usr/src/uts/common/io/hotplug/pcihp/pcihp.c
usr/src/uts/common/io/pci_pci/pci_pci.c
usr/src/uts/common/os/ddifm.c
usr/src/uts/common/os/ndifm.c
usr/src/uts/common/os/pcifm.c
usr/src/uts/common/os/sunpci.c
usr/src/uts/common/sys/bge_impl2.h
usr/src/uts/common/sys/ddi_implfuncs.h
usr/src/uts/common/sys/ddifm.h
usr/src/uts/common/sys/ddifm_impl.h
usr/src/uts/common/sys/fm/io/ddi.h
usr/src/uts/common/sys/fm/io/pci.h
usr/src/uts/common/sys/ndifm.h
usr/src/uts/common/sys/pci.h
usr/src/uts/common/sys/pcie.h
usr/src/uts/common/sys/pcifm.h
usr/src/uts/common/sys/sunddi.h
usr/src/uts/i86pc/io/mc/mcamd_drv.c
usr/src/uts/i86pc/io/pci/pci.c
usr/src/uts/i86pc/io/pci/pci_boot.c
usr/src/uts/i86pc/io/pci/pci_common.c
usr/src/uts/i86pc/io/pci/pci_common.h
usr/src/uts/i86pc/io/pciex/npe.c
usr/src/uts/i86pc/io/pciex/pcie_ck804_boot.c
usr/src/uts/i86pc/io/pciex/pcie_ck804_boot.h
usr/src/uts/i86pc/io/pciex/pcie_error.c
usr/src/uts/i86pc/io/pciex/pcie_pci.c
usr/src/uts/i86pc/io/rootnex.c
usr/src/uts/i86pc/os/ddi_impl.c
usr/src/uts/intel/ia32/os/ddi_i86.c
usr/src/uts/intel/sys/ddi_isa.h
usr/src/uts/sun4/io/px/px.c
usr/src/uts/sun4/io/px/px_dma.c
usr/src/uts/sun4/io/px/px_fm.c
usr/src/uts/sun4/io/px/px_pci.c
usr/src/uts/sun4/os/ddi_impl.c
usr/src/uts/sun4u/io/pci/db21554.c
usr/src/uts/sun4u/io/pci/pci.c
usr/src/uts/sun4u/io/pci/pci_dma.c
usr/src/uts/sun4u/io/pci/pci_fm.c
usr/src/uts/sun4u/io/pci/pci_pbm.c
usr/src/uts/sun4u/io/pci/pci_pci.c
usr/src/uts/sun4u/io/pci/pci_util.c
usr/src/uts/sun4u/io/pci/pcipsy.c
usr/src/uts/sun4u/io/pci/pcisch.c
usr/src/uts/sun4u/io/pci/simba.c
usr/src/uts/sun4u/sys/pci/db21554_ctrl.h
usr/src/uts/sun4u/sys/pci/pci_fm.h
usr/src/uts/sun4u/sys/pci/pci_var.h
--- a/usr/src/cmd/fm/dicts/Makefile	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/dicts/Makefile	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -32,6 +31,7 @@
 	SMF \
 	SUNOS \
 	PCI \
+	PCIEX \
 	ZFS \
 	SCA500 \
 	SCA1000
--- a/usr/src/cmd/fm/dicts/PCI.dict	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/dicts/PCI.dict	Sun Apr 23 15:26:28 2006 -0700
@@ -1,13 +1,12 @@
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, 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.
@@ -23,8 +22,11 @@
 # CDDL HEADER END
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
+#
+# DO NOT EDIT -- this file is generated by the Event Registry.
+#
 
-FMDICT: name=PCI version=1 maxkey=3
+FMDICT: name=PCI version=1 maxkey=3 dictid=0x5043
 
 defect.io.pci.driver=0
 fault.io.pci.bus=1
@@ -33,3 +35,8 @@
 defect.io.pci.driver fault.io.pci.device=4
 fault.io.pci.bus fault.io.pci.device=5
 defect.io.pci.driver fault.io.pci.bus fault.io.pci.device=6
+fault.io.pci.device-interr=7
+fault.io.pci.bus-linkerr fault.io.pci.device-interr=8
+fault.io.pci.device-invreq fault.io.pci.device-noresp=9
+fault.io.pci.device-interr fault.io.pci.device-invreq=10
+fault.io.pci.device-noresp=11
--- a/usr/src/cmd/fm/dicts/PCI.po	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/dicts/PCI.po	Sun Apr 23 15:26:28 2006 -0700
@@ -1,13 +1,12 @@
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, 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.
@@ -23,7 +22,9 @@
 # CDDL HEADER END
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
-
+#
+# DO NOT EDIT -- this file is generated by the Event Registry.
+#
 #
 # code: PCI-8000-0C
 # keys: defect.io.pci.driver
@@ -33,13 +34,13 @@
 msgid "PCI-8000-0C.severity"
 msgstr "Critical"
 msgid "PCI-8000-0C.description"
-msgstr "A problem was detected in the PCI controller software"
+msgstr "A problem was detected in the PCI controller software.  Refer to %s for more information."
 msgid "PCI-8000-0C.response"
-msgstr "One or more of device instances may be disabled"
+msgstr "One or more of device instances may be disabled."
 msgid "PCI-8000-0C.impact"
-msgstr "Loss of services provided by the device instances associated with this fault"
+msgstr "Loss of services provided by the device instances associated with this problem."
 msgid "PCI-8000-0C.action"
-msgstr "Ensure latest drivers and patches are installed. Use fmdump -v -u <EVENT_ID> to identify the module/package, or contact Sun for support."
+msgstr "Ensure latest drivers and patches are installed.  Use fmdump -v -u <EVENT_ID> to identify the module/package, or contact Sun for support."
 #
 # code: PCI-8000-1Q
 # keys: fault.io.pci.bus
@@ -51,9 +52,9 @@
 msgid "PCI-8000-1Q.description"
 msgstr "A problem was detected for a PCI bus.  Refer to %s for more information."
 msgid "PCI-8000-1Q.response"
-msgstr "One or more device instances may be disabled"
+msgstr "One or more device instances may be disabled."
 msgid "PCI-8000-1Q.impact"
-msgstr "Loss of services provided by the device instances associated with this fault"
+msgstr "Loss of services provided by the device instances associated with this fault."
 msgid "PCI-8000-1Q.action"
 msgstr "Schedule a repair procedure to replace the affected device.  Use fmdump -v -u <EVENT_ID> to identify the device or contact Sun for support."
 #
@@ -65,13 +66,13 @@
 msgid "PCI-8000-24.severity"
 msgstr "Critical"
 msgid "PCI-8000-24.description"
-msgstr "A problem was detected in the PCI subsystem or controlling software.  Refer to %s for more information."
+msgstr "The system has diagnosed a problem, the suspects include one or more \nPCI buses and one or more PCI controller drivers.  Refer to %s for more information."
 msgid "PCI-8000-24.response"
-msgstr "One or more device instances may be disabled"
+msgstr "This fault requires user and/or service interaction and currently does not have an automated response agent."
 msgid "PCI-8000-24.impact"
-msgstr "Loss of services provided by the device instances associated with this fault"
+msgstr "Possible loss of devices that may be attached to the system via this device/bus and/or system downtime."
 msgid "PCI-8000-24.action"
-msgstr "Ensure that the latest drivers and patches are installed, schedule a repair procedure to replace the affected device if necessary, or contact Sun for support."
+msgstr "Use fmdump -v -u <EVENT_ID> to identify the \nsuspected device(s)or driver(s).\n\nCheck for patches to identified device drivers, schedule a repair for \nindicated hardware.\n"
 #
 # code: PCI-8000-3R
 # keys: fault.io.pci.device
@@ -81,13 +82,13 @@
 msgid "PCI-8000-3R.severity"
 msgstr "Critical"
 msgid "PCI-8000-3R.description"
-msgstr "A problem was detected for a PCI controller.  Refer to %s for more information."
+msgstr "The system has diagnosed a problem in one or more PCI buses or devices, \nbased on the error telemetry detected by the PCI subsystem.  Refer to %s for more information."
 msgid "PCI-8000-3R.response"
-msgstr "One or more device instances may be disabled"
+msgstr "This fault requires user and/or service interaction and currently does not have an automated response agent."
 msgid "PCI-8000-3R.impact"
-msgstr "Loss of services provided by the device instances associated with this fault"
+msgstr "Possible loss of devices that may be attached to the system via this device/bus and/or system downtime."
 msgid "PCI-8000-3R.action"
-msgstr "Schedule a repair procedure to replace the affected device.  Use fmdump -v -u <EVENT_ID> to identify the device or contact Sun for support."
+msgstr "Use fmdump -v -u <EVENT_ID> to identify the \nsuspected device(s).\n\nSchedule a repair procedure to replace the affected device."
 #
 # code: PCI-8000-42
 # keys: defect.io.pci.driver fault.io.pci.device
@@ -97,13 +98,13 @@
 msgid "PCI-8000-42.severity"
 msgstr "Critical"
 msgid "PCI-8000-42.description"
-msgstr "A problem was detected in the SUNOS subsystem or controlling software.  Refer to %s for more information."
+msgstr "The system has diagnosed a problem, the suspects include one or more \nPCI buses and one or more PCI controller drivers.  Refer to %s for more information."
 msgid "PCI-8000-42.response"
-msgstr "One or more device instances may be disabled"
+msgstr "This fault requires user and/or service interaction and currently does not have an automated response agent."
 msgid "PCI-8000-42.impact"
-msgstr "Loss of services provided by the device instances associated with this fault"
+msgstr "Possible loss of devices that may be attached to the system via this device/bus and/or system downtime."
 msgid "PCI-8000-42.action"
-msgstr "Ensure that the latest drivers and patches are installed, schedule a repair procedure to replace the affected device if necessary, or contact Sun for support."
+msgstr "Use fmdump -v -u <EVENT_ID> to identify the \nsuspected device(s)or driver(s).\n\nCheck for patches to identified device drivers, schedule a repair for \nindicated hardware.\n"
 #
 # code: PCI-8000-5X
 # keys: fault.io.pci.bus fault.io.pci.device
@@ -113,13 +114,13 @@
 msgid "PCI-8000-5X.severity"
 msgstr "Critical"
 msgid "PCI-8000-5X.description"
-msgstr "A problem was detected in the PCI subsystem.  Refer to %s for more information."
+msgstr "The system has diagnosed a problem in one or more PCI buses or devices, \nbased on the error telemetry detected by the PCI subsystem.  Refer to %s for more information."
 msgid "PCI-8000-5X.response"
-msgstr "One or more device instances may be disabled"
+msgstr "This fault requires user and/or service interaction and currently does not have an automated response agent."
 msgid "PCI-8000-5X.impact"
-msgstr "Loss of services provided by the device instances associated with this fault"
+msgstr "Possible loss of devices that may be attached to the system via this device/bus and/or system downtime."
 msgid "PCI-8000-5X.action"
-msgstr "Schedule a repair procedure to replace the affected device.  Use fmdump -v -u <EVENT_ID> to identify the device or contact Sun for support."
+msgstr "Use fmdump -v -u <EVENT_ID> to identify the \nsuspected device(s).\n\nSchedule a repair procedure to replace the affected device."
 #
 # code: PCI-8000-6E
 # keys: defect.io.pci.driver fault.io.pci.bus fault.io.pci.device
@@ -129,10 +130,90 @@
 msgid "PCI-8000-6E.severity"
 msgstr "Critical"
 msgid "PCI-8000-6E.description"
-msgstr "A problem was detected in the SUNOS subsystem or controlling software. Refer to %s for more information."
+msgstr "The system has diagnosed a problem, the suspects include one or more \nPCI buses and one or more PCI controller drivers.  Refer to %s for more information."
 msgid "PCI-8000-6E.response"
-msgstr "One or more device instances may be disabled"
+msgstr "This fault requires user and/or service interaction and currently does not have an automated response agent."
 msgid "PCI-8000-6E.impact"
-msgstr "Loss of services provided by the device instances associated with this fault"
+msgstr "Possible loss of devices that may be attached to the system via this device/bus and/or system downtime."
 msgid "PCI-8000-6E.action"
-msgstr "Ensure that the latest drivers and patches are installed, schedule a repair procedure to replace the affected device if necessary, or contact Sun for support."
+msgstr "Use fmdump -v -u <EVENT_ID> to identify the \nsuspected device(s)or driver(s).\n\nCheck for patches to identified device drivers, schedule a repair for \nindicated hardware.\n"
+#
+# code: PCI-8000-7J
+# keys: fault.io.pci.device-interr
+#
+msgid "PCI-8000-7J.type"
+msgstr "Fault"
+msgid "PCI-8000-7J.severity"
+msgstr "Critical"
+msgid "PCI-8000-7J.description"
+msgstr "A problem was detected for a PCI device.\n  Refer to %s for more information."
+msgid "PCI-8000-7J.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCI-8000-7J.impact"
+msgstr "Possible loss of services provided by the device instances associated with this fault\n"
+msgid "PCI-8000-7J.action"
+msgstr "Schedule a repair procedure to replace the affected device.  Use fmdump -v -u  to identify the device or contact Sun for support.\n"
+#
+# code: PCI-8000-8S
+# keys: fault.io.pci.bus-linkerr fault.io.pci.device-interr
+#
+msgid "PCI-8000-8S.type"
+msgstr "Fault"
+msgid "PCI-8000-8S.severity"
+msgstr "Critical"
+msgid "PCI-8000-8S.description"
+msgstr "A problem has been detected on the specified bus or on the specified transmitting device.\n  Refer to %s for more information."
+msgid "PCI-8000-8S.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCI-8000-8S.impact"
+msgstr "Possible loss of services provided by the device instances associated with this fault\n"
+msgid "PCI-8000-8S.action"
+msgstr "If a plug-in card is involved check for badly-seated cards or bent pins. Otherwise schedule a repair procedure to replace the affected device.  Use fmdump -v -u  to identify the device and bus or contact Sun for support.\n"
+#
+# code: PCI-8000-95
+# keys: fault.io.pci.device-invreq fault.io.pci.device-noresp
+#
+msgid "PCI-8000-95.type"
+msgstr "Fault"
+msgid "PCI-8000-95.severity"
+msgstr "Critical"
+msgid "PCI-8000-95.description"
+msgstr "Either the transmitting device sent an invalid request or the receiving device failed to respond.\n  Refer to %s for more information."
+msgid "PCI-8000-95.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCI-8000-95.impact"
+msgstr "Possible loss of services provided by the device instances associated with this fault\n"
+msgid "PCI-8000-95.action"
+msgstr "Ensure that the latest drivers and patches are installed. If a plug-in card is involved check for badly-seated cards or bent pins.  Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCI-8000-AP
+# keys: fault.io.pci.device-interr fault.io.pci.device-invreq
+#
+msgid "PCI-8000-AP.type"
+msgstr "Fault"
+msgid "PCI-8000-AP.severity"
+msgstr "Critical"
+msgid "PCI-8000-AP.description"
+msgstr "Either the transmitting device sent an invalid request or the receiving device is reporting an internal fault.\n  Refer to %s for more information."
+msgid "PCI-8000-AP.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCI-8000-AP.impact"
+msgstr "Possible loss of services provided by the device instances associated with this fault\n"
+msgid "PCI-8000-AP.action"
+msgstr "Ensure that the latest drivers and patches are installed.  Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCI-8000-CA
+# keys: fault.io.pci.device-noresp
+#
+msgid "PCI-8000-CA.type"
+msgstr "Fault"
+msgid "PCI-8000-CA.severity"
+msgstr "Critical"
+msgid "PCI-8000-CA.description"
+msgstr "Device is failing to respond\n  Refer to %s for more information."
+msgid "PCI-8000-CA.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCI-8000-CA.impact"
+msgstr "Possible loss of services provided by the device instances associated with this fault\n"
+msgid "PCI-8000-CA.action"
+msgstr "Schedule a repair procedure to replace the affected device.  Use fmdump -v -u  to identify the device or contact Sun for support.\n"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/dicts/PCIEX.dict	Sun Apr 23 15:26:28 2006 -0700
@@ -0,0 +1,44 @@
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+#
+# DO NOT EDIT -- this file is generated by the Event Registry.
+#
+
+FMDICT: name=PCIEX version=1 maxkey=4 dictid=0x4558
+
+fault.io.pciex.device-interr=0
+fault.io.pciex.device-interr fault.io.pciex.device-invreq=1
+fault.io.pciex.bus-noresp fault.io.pciex.device-noresp=2
+fault.io.pciex.bus-linkerr fault.io.pciex.device-interr=3
+fault.io.pci.bus-linkerr fault.io.pciex.device-interr=4
+fault.io.pci.device-invreq=5
+fault.io.pci.device-invreq fault.io.pciex.device-interr=6
+fault.io.pci.device-interr fault.io.pciex.device-invreq=7
+fault.io.pciex.device-invreq=8
+fault.io.pci.device-noresp fault.io.pciex.device-invreq=9
+fault.io.pci.device-invreq fault.io.pciex.device-noresp=10
+fault.io.pci.bus-linkerr fault.io.pci.device-interr fault.io.pciex.device-interr=11
+fault.io.pciex.bus-noresp fault.io.pciex.device-interr fault.io.pciex.device-noresp=12
+fault.io.pciex.bus-linkerr fault.io.pciex.bus-noresp fault.io.pciex.device-interr fault.io.pciex.device-noresp=13
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/dicts/PCIEX.po	Sun Apr 23 15:26:28 2006 -0700
@@ -0,0 +1,251 @@
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#ident	"%Z%%M%	%I%	%E% SMI"
+#
+# DO NOT EDIT -- this file is generated by the Event Registry.
+#
+#
+# code: PCIEX-8000-0A
+# keys: fault.io.pciex.device-interr
+#
+msgid "PCIEX-8000-0A.type"
+msgstr "Fault"
+msgid "PCIEX-8000-0A.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-0A.description"
+msgstr "A problem was detected for a PCIEX device.\n  Refer to %s for more information."
+msgid "PCIEX-8000-0A.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-0A.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-0A.action"
+msgstr "Schedule a repair procedure to replace the affected device.  Use fmdump -v -u  to identify the device or contact Sun for support.\n"
+#
+# code: PCIEX-8000-1P
+# keys: fault.io.pciex.device-interr fault.io.pciex.device-invreq
+#
+msgid "PCIEX-8000-1P.type"
+msgstr "Fault"
+msgid "PCIEX-8000-1P.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-1P.description"
+msgstr "Either the transmitting device sent an invalid request or the receiving device is reporting an internal fault.\n  Refer to %s for more information."
+msgid "PCIEX-8000-1P.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-1P.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-1P.action"
+msgstr "Ensure that the latest drivers and patches are installed.  Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-25
+# keys: fault.io.pciex.bus-noresp fault.io.pciex.device-noresp
+#
+msgid "PCIEX-8000-25.type"
+msgstr "Fault"
+msgid "PCIEX-8000-25.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-25.description"
+msgstr "The receiving device failed to respond.\n  Refer to %s for more information."
+msgid "PCIEX-8000-25.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-25.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-25.action"
+msgstr "If a plug-in card is involved check for badly-seated cards or bent pins. Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-3S
+# keys: fault.io.pciex.bus-linkerr fault.io.pciex.device-interr
+#
+msgid "PCIEX-8000-3S.type"
+msgstr "Fault"
+msgid "PCIEX-8000-3S.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-3S.description"
+msgstr "A problem has been detected on one of the specified devices or on one of the specified connecting buses.\n  Refer to %s for more information."
+msgid "PCIEX-8000-3S.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-3S.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-3S.action"
+msgstr "If a plug-in card is involved check for badly-seated cards or bent pins. Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-43
+# keys: fault.io.pci.bus-linkerr fault.io.pciex.device-interr
+#
+msgid "PCIEX-8000-43.type"
+msgstr "Fault"
+msgid "PCIEX-8000-43.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-43.description"
+msgstr "A problem has been detected on one of the specified devices or on one of the specified connecting buses.\n  Refer to %s for more information."
+msgid "PCIEX-8000-43.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-43.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-43.action"
+msgstr "If a plug-in card is involved check for badly-seated cards or bent pins. Otherwise schedule a repair procedure to replace the affected device.  Use fmdump -v -u  to identify the device and bus or contact Sun for support.\n"
+#
+# code: PCIEX-8000-5Y
+# keys: fault.io.pci.device-invreq
+#
+msgid "PCIEX-8000-5Y.type"
+msgstr "Fault"
+msgid "PCIEX-8000-5Y.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-5Y.description"
+msgstr "The transmitting device sent an invalid request.\n  Refer to %s for more information."
+msgid "PCIEX-8000-5Y.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-5Y.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-5Y.action"
+msgstr "Ensure that the latest drivers and patches are installed. Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-6D
+# keys: fault.io.pci.device-invreq fault.io.pciex.device-interr
+#
+msgid "PCIEX-8000-6D.type"
+msgstr "Fault"
+msgid "PCIEX-8000-6D.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-6D.description"
+msgstr "Either the transmitting device sent an invalid request or the receiving device is reporting an internal fault.\n  Refer to %s for more information."
+msgid "PCIEX-8000-6D.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-6D.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-6D.action"
+msgstr "Ensure that the latest drivers and patches are installed.  Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-7H
+# keys: fault.io.pci.device-interr fault.io.pciex.device-invreq
+#
+msgid "PCIEX-8000-7H.type"
+msgstr "Fault"
+msgid "PCIEX-8000-7H.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-7H.description"
+msgstr "Either the transmitting device sent an invalid request or the receiving device is reporting an internal fault.\n  Refer to %s for more information."
+msgid "PCIEX-8000-7H.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-7H.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-7H.action"
+msgstr "Ensure that the latest drivers and patches are installed.  Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-8R
+# keys: fault.io.pciex.device-invreq
+#
+msgid "PCIEX-8000-8R.type"
+msgstr "Fault"
+msgid "PCIEX-8000-8R.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-8R.description"
+msgstr "The transmitting device sent an invalid request.\n  Refer to %s for more information."
+msgid "PCIEX-8000-8R.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-8R.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-8R.action"
+msgstr "Ensure that the latest drivers and patches are installed. Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-94
+# keys: fault.io.pci.device-noresp fault.io.pciex.device-invreq
+#
+msgid "PCIEX-8000-94.type"
+msgstr "Fault"
+msgid "PCIEX-8000-94.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-94.description"
+msgstr "Either the transmitting device sent an invalid request or the receiving device failed to respond.\n  Refer to %s for more information."
+msgid "PCIEX-8000-94.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-94.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-94.action"
+msgstr "Ensure that the latest drivers and patches are installed. If a plug-in card is involved check for badly-seated cards or bent pins.  Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-AQ
+# keys: fault.io.pci.device-invreq fault.io.pciex.device-noresp
+#
+msgid "PCIEX-8000-AQ.type"
+msgstr "Fault"
+msgid "PCIEX-8000-AQ.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-AQ.description"
+msgstr "Either the transmitting device sent an invalid request or the receiving device failed to respond.\n  Refer to %s for more information."
+msgid "PCIEX-8000-AQ.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-AQ.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-AQ.action"
+msgstr "Ensure that the latest drivers and patches are installed. If a plug-in card is involved check for badly-seated cards or bent pins.  Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-CC
+# keys: fault.io.pci.bus-linkerr fault.io.pci.device-interr fault.io.pciex.device-interr
+#
+msgid "PCIEX-8000-CC.type"
+msgstr "Fault"
+msgid "PCIEX-8000-CC.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-CC.description"
+msgstr "A problem has been detected on one of the specified devices or on one of the specified connecting buses.\n  Refer to %s for more information."
+msgid "PCIEX-8000-CC.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-CC.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-CC.action"
+msgstr "If a plug-in card is involved check for badly-seated cards or bent pins. Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-DJ
+# keys: fault.io.pciex.bus-noresp fault.io.pciex.device-interr fault.io.pciex.device-noresp
+#
+msgid "PCIEX-8000-DJ.type"
+msgstr "Fault"
+msgid "PCIEX-8000-DJ.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-DJ.description"
+msgstr "A problem has been detected on one of the specified devices or on one of the specified connecting buses.\n  Refer to %s for more information."
+msgid "PCIEX-8000-DJ.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-DJ.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-DJ.action"
+msgstr "If a plug-in card is involved check for badly-seated cards or bent pins. Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
+#
+# code: PCIEX-8000-EE
+# keys: fault.io.pciex.bus-linkerr fault.io.pciex.bus-noresp fault.io.pciex.device-interr fault.io.pciex.device-noresp
+#
+msgid "PCIEX-8000-EE.type"
+msgstr "Fault"
+msgid "PCIEX-8000-EE.severity"
+msgstr "Critical"
+msgid "PCIEX-8000-EE.description"
+msgstr "A problem has been detected on one of the specified devices or on one of the specified connecting buses.\n  Refer to %s for more information."
+msgid "PCIEX-8000-EE.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "PCIEX-8000-EE.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "PCIEX-8000-EE.action"
+msgstr "If a plug-in card is involved check for badly-seated cards or bent pins. Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
--- a/usr/src/cmd/fm/dicts/SUN4U.dict	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/dicts/SUN4U.dict	Sun Apr 23 15:26:28 2006 -0700
@@ -261,3 +261,4 @@
 fault.cpu.SPARC64-VI.chip=231
 fault.cpu.SPARC64-VI.core=232
 fault.cpu.SPARC64-VI.strand=233
+fault.io.pci.device-invreq fault.io.tomatillo=234
--- a/usr/src/cmd/fm/dicts/SUN4U.po	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/dicts/SUN4U.po	Sun Apr 23 15:26:28 2006 -0700
@@ -3753,3 +3753,19 @@
 msgstr "The system will not be functioning at the same performance level with the STRAND removal.\n"
 msgid "SUN4U-8007-9E.action"
 msgstr "Schedule a repair procedure to replace the affected STRAND.  Use fmdump -v -u\n to identify the smallest CPU/Strand ID of the affected CORE on this\nSTRAND.\n"
+#
+# code: SUN4U-8007-AX
+# keys: fault.io.pci.device-invreq fault.io.tomatillo
+#
+msgid "SUN4U-8007-AX.type"
+msgstr "Fault"
+msgid "SUN4U-8007-AX.severity"
+msgstr "Critical"
+msgid "SUN4U-8007-AX.description"
+msgstr "Either the transmitting device sent an invalid request or the receiving device failed to respond.\n  Refer to %s for more information."
+msgid "SUN4U-8007-AX.response"
+msgstr "One or more device instances may be disabled\n"
+msgid "SUN4U-8007-AX.impact"
+msgstr "Loss of services provided by the device instances associated with this fault\n"
+msgid "SUN4U-8007-AX.action"
+msgstr "Ensure that the latest drivers and patches are installed. If a plug-in card is involved check for badly-seated cards or bent pins.  Otherwise schedule a repair procedure to replace the affected device(s).  Use fmdump -v -u  to identify the devices or contact Sun for support.\n"
--- a/usr/src/cmd/fm/eversholt/files/common/pci.esc	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/eversholt/files/common/pci.esc	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -31,850 +30,1239 @@
 #define PCI_DEV_FIT 1000
 #define PCI_BUS_FIT 500
 
+/*
+ * SERD parameters.
+ *
+ * Nonfatal dpe errors have to be recovered by the hardened driver which may
+ * cause intermittant performance/responsiveness problems, so we have tighter
+ * serd parameters for these. These are most likely errors in buffers/caches
+ * within devices and bridges, so use similar rates to cpu data cache parity
+ * errors.
+ * 
+ * We will be more conservative about nonfatal internal errors reported
+ * by the driver.
+ */
+#define NONFATAL_COUNT 6
+#define NONFATAL_TIME 2h
+#define NONFATAL_DPE_U_COUNT 3
+#define NONFATAL_DPE_U_TIME 168h
+#define NONFATAL_DPE_D_COUNT 3
+#define NONFATAL_DPE_D_TIME 168h
+
+#define	IS_LEAF \
+	(confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") != "60400" && \
+	confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") != "60401")
+
+#define	IS_BDG \
+	(confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") == "60400" || \
+	confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") == "60401")
+
+#define	FD_IS_LEAF \
+	(confprop(asru(pcibus/pcidev[fromdev]/pcifn), "CLASS-CODE") != \
+	"60400" && \
+	confprop(asru(pcibus/pcidev[fromdev]/pcifn), "CLASS-CODE") != "60401")
+
+/*
+ * note general rule for errors is that for upstream propagations
+ * @pcibus/pcidev/pcifn is the sending device while  for downstream
+ * propagations it is the receiving device.
+ */
+
 asru pcibus/pcidev/pcifn;
 fru pcibus/pcidev;
 
-/*
- * Faulty PCI device
- */
-event fault.io.pci.device@pcibus/pcidev/pcifn,
+event fault.io.pci.device-interr@pcibus/pcidev/pcifn,
+        FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
+
+event fault.io.pci.device-invreq@pcibus/pcidev/pcifn,
+        FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
+
+event fault.io.pci.device-noresp@pcibus/pcidev/pcifn,
         FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
 
-event error.io.pci.tx-ma@pcibus/pcidev/pcifn;
-event error.io.pci.rx-ma@pcibus/pcidev/pcifn;
-event error.io.pci.tx-serr@pcibus/pcidev/pcifn;
-event error.io.pci.serr@pcibus;
-event error.io.pci.rx-ta@pcibus/pcidev/pcifn;
-event error.io.pci.tx-dpe@pcibus/pcidev/pcifn;
-event error.io.pci.tx-wdpe@pcibus/pcidev/pcifn;
-event error.io.pci.rec-ma@pcibus/pcidev/pcifn;
-event error.io.pci.rec-ta@pcibus/pcidev/pcifn;
-event error.io.pci.rec-mdpe@pcibus/pcidev/pcifn;
-event error.io.pci.tx-pma@pcibus/pcidev/pcifn;
-event error.io.pci.tx-dma@pcibus/pcidev/pcifn;
-event error.io.pci.tx-rdpe@pcibus/pcidev/pcifn;
-event error.io.pci.tx-pwdpe@pcibus/pcidev/pcifn;
-event error.io.pci.tx-dwdpe@pcibus/pcidev/pcifn;
-event error.io.pci.bdg-tx-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.bdg-tx-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.bdg-tx-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.bdg-tx-sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.bdg-tx-sec-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.bdg-tx-sec-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.sta@pcibus/pcidev/pcifn;
-event error.io.pci.rx-pma@pcibus/pcidev/pcifn;
-event error.io.pci.rx-dma@pcibus/pcidev/pcifn;
-event error.io.pci.sec-tx-ta@pcibus/pcidev/pcifn;
-event error.io.pci.sec-rx-pta@pcibus/pcidev/pcifn;
-event error.io.pci.sec-rx-dta@pcibus/pcidev/pcifn;
-event error.io.pci.rx-pta@pcibus/pcidev/pcifn;
-event error.io.pci.tx-pta@pcibus/pcidev/pcifn;
-event error.io.pci.rx-dta@pcibus/pcidev/pcifn;
-event error.io.pci.bdg-rx-dpe@pcibus/pcidev/pcifn;
-event error.io.pci.sec-rx-dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.bdg-pwdpe@pcibus/pcidev/pcifn;
-event error.io.pci.bdg-dwdpe@pcibus/pcidev/pcifn;
-event error.io.pci.rx-rdpe@pcibus/pcidev/pcifn;
-event error.io.pci.rx-wdpe@pcibus/pcidev/pcifn;
-event error.io.pci.sec-rx-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.sec-target-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.sec-target-ma@pcibus/pcidev/pcifn;
-event error.io.pci.sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.tx-ape@pcibus/pcidev/pcifn;
-event error.io.pci.tx-ape-bdg@pcibus/pcidev/pcifn;
-event error.io.pci.bdg-tx-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.bdg-tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pcix.tx-oor@pcibus/pcidev/pcifn;
-event error.io.pcix.rx-discard@pcibus/pcidev/pcifn;
-event error.io.pcix.rx-unex-sc@pcibus/pcidev/pcifn;
+/*
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * A faulty hostbridge may cause:
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ *  - nr-pw-d:	the device not to respond to an upstream request
+ *  - nr-drw-d:	the device not to respond to an upstream request
+ *  - ta-pw-d:	the device to send a target abort to an upstream request
+ *  - ta-drw-d:	the device to send a target abort to an upstream request
+ *  - serr-u:	the device to report itself in error
+ *  - badreq-pw-d:a bad downstream request - not parity error (may cause target
+ * 		to target abort or master abort)
+ *  - badreq-drw-d:a bad downstream request - not parity error (may cause
+ * 		target to target abort or master abort)
+ *  - ape-d:	address/parity to get corrupted during downstream transmission
+ *  - scpe-d:	split completion to get corrupted during downstream transmission
+ *  - dpe-d:	the device to transfer bad data and/or bad parity downstream
+ *  - retry-to-d:	the device to exceed the set timeout for a delayed
+ *			transaction retry.
+ */
+#define	PCI_TO_HB pcibus/pcidev<todev>/pcifn<> {fromdev != 32 && todev == 32}
+#define	PCI_FROM_HB pcibus/pcidev<todev>/pcifn<> {fromdev == 32 && todev != 32}
 
-event ereport.io.pci.dto@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.target-ma@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.target-ma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
+event error.io.pci.retry-to-d@pcibus/pcidev/pcifn;
+event error.io.pci.nr-pw-d@pcibus/pcidev/pcifn;
+event error.io.pci.nr-drw-d@pcibus/pcidev/pcifn;
+event error.io.pci.ta-pw-d@pcibus/pcidev/pcifn;
+event error.io.pci.ta-drw-d@pcibus/pcidev/pcifn;
+event error.io.pci.badreq-pw-d@pcibus/pcidev/pcifn;
+event error.io.pci.badreq-drw-d@pcibus/pcidev/pcifn;
+event error.io.pci.f-dpe-d@pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpe-d@pcibus/pcidev/pcifn;
+event error.io.pci.nonfatal-dpe-d@pcibus/pcidev/pcifn;
+event error.io.pci.ape-d@pcibus/pcidev/pcifn;
+event error.io.pci.ape-u@pcibus/pcidev/pcifn;
+event error.io.pci.f-dpdata-dw-d@pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpdata-dw-d@pcibus/pcidev/pcifn;
+event error.io.pci.f-dpdata-pw-d@pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpdata-pw-d@pcibus/pcidev/pcifn;
+event error.io.pci.f-dpdata-dr-d@pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpdata-dr-d@pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-pw-u@pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dw-u@pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dr-u@pcibus/pcidev/pcifn;
+event error.io.pci.ta-u@pcibus/pcidev/pcifn;
+event error.io.pci.ma-u@pcibus/pcidev/pcifn;
+event error.io.pci.perr-dw-u@pcibus/pcidev/pcifn;
+event error.io.pci.perr-pw-u@pcibus/pcidev/pcifn;
+event error.io.pci.perr-dr-u@pcibus/pcidev/pcifn;
+event error.io.pci.badreq-drw-u@pcibus/pcidev/pcifn;
+event error.io.pci.badreq-pw-u@pcibus/pcidev/pcifn;
+event error.io.pci.device-serr@pcibus/pcidev/pcifn;
+event error.io.pci.device-ta@pcibus/pcidev/pcifn;
+event error.io.pci.device-par@pcibus/pcidev/pcifn;
+event error.io.pci.serr-u@pcibus/pcidev/pcifn;
+event error.io.pcix.scpe-d@pcibus/pcidev/pcifn;
+event error.io.pcix.scpe-u@pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ma-u@pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ta-u@pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ma-d@pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ta-d@pcibus/pcidev/pcifn;
+
 event ereport.io.pci.ma@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.ma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sec-rserr@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sserr@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sec-ma@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sserr@pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.pci.rta@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.target-rta@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sta@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.dpe@pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.pci.mdpe@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.sta@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.sserr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.dpe@pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sec-sta@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.rta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sec-rta@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.target-rta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pcix.oor@pcibus/pcidev/pcifn;
-event ereport.io.pcix.discard@pcibus/pcidev/pcifn;
-event ereport.io.pcix.unex-sc@pcibus/pcidev/pcifn;
+event ereport.io.pci.target-rta@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.target-ma@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.discard@pcibus/pcidev/pcifn{within(5s)};
+
+prop fault.io.pci.device-noresp@pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.pci.nr-pw-d@PCI_FROM_HB,
+    error.io.pci.nr-drw-d@PCI_FROM_HB,
+    error.io.pci.retry-to-d@PCI_FROM_HB;
+
+prop fault.io.pci.device-invreq@pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.pci.badreq-pw-d@PCI_FROM_HB,
+    error.io.pci.badreq-drw-d@PCI_FROM_HB;
+
+prop fault.io.pci.device-interr@pcibus/pcidev/pcifn (0)->
+    error.io.pci.device-par@pcibus/pcidev/pcifn,
+    error.io.pci.device-ta@pcibus/pcidev/pcifn,
+    error.io.pci.device-serr@pcibus/pcidev/pcifn;
+
+prop error.io.pci.device-par@pcibus/pcidev[fromdev]/pcifn (1)->
+    error.io.pci.f-dpe-d@PCI_FROM_HB,
+    error.io.pci.nf-dpe-d@PCI_FROM_HB,
+    error.io.pcix.scpe-d@PCI_FROM_HB,
+    error.io.pci.ape-d@PCI_FROM_HB;
+
+prop error.io.pci.device-ta@pcibus/pcidev[fromdev]/pcifn (1)->
+    error.io.pci.ta-pw-d@PCI_FROM_HB,
+    error.io.pci.ta-drw-d@PCI_FROM_HB;
+
+prop error.io.pci.device-ta@pcibus/pcidev[fromdev]/pcifn (1)->
+    ereport.io.pci.sta@pcibus/pcidev<todev>/pcifn {
+	todev == fromdev && fromdev == 32 };
+
+prop error.io.pci.device-serr@pcibus/pcidev/pcifn (2)->
+    error.io.pci.serr-u@pcibus/pcidev/pcifn,
+    ereport.io.pci.sserr@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpe-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.f-dpdata-pw-d@pcibus/pcidev/pcifn,
+    error.io.pci.f-dpdata-dw-d@pcibus/pcidev/pcifn,
+    error.io.pci.f-dpdata-dr-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nonfatal-dpe-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.nf-dpdata-pw-d@pcibus/pcidev/pcifn,
+    error.io.pci.nf-dpdata-dw-d@pcibus/pcidev/pcifn,
+    error.io.pci.nf-dpdata-dr-d@pcibus/pcidev/pcifn;
 
 /*
- * A faulty PCI device may cause:
- *
- *  - tx-ma:	the device to not respond to a valid request.
- *  - rx-ma:	the device to issue an errant address.
- *  - tx-serr:	the device to signal an serr.
- *  - rx-ta:	the device to receive a target abort from an unhappy target.
- *  - tx-dpe:	the device to trasmit data data and/or parity.
- *  - tx-ape:	address/parity to get corrupted during transmission -
- *		only the serr is a must - sserr/dpe will show up if 
- *		target driver is hardened. In addition the target could target
- *		abort or master abort.
- *
- * A fault PCI-X device may cause:
- *
- *  - tx-oor:	the device sends a byte count larger than the completers
- *           	address range.
- *  - tx-discard a DMA split completion received a master abort or a
- *		target abort which caused the device to discard the
- *		split completion
- *  - rx-unex-sc the device recieved a split completion with a tag
- * 		which does not match any outstanding transaction.
- *
- * NOTE: The rules below are for pci-pci bridge support
- *
- *  - tx-pma:	the device not to respond to a posted request across a bridge.
- *  - tx-dma:	the device not to respond to a delayed request across a bridge.
- *  - rx-pta:	the device to receive a target abort from a posted transaction
- *		across a bridge.
- *  - rx-dta:	the device to receive a target abort from a delayed transaction
- *		across a bridge.
- *  - tx-ape-bdg:	address/parity to get corrupted during transmission.
- *		Must see serr/serr/dpe. In addition the pci-pci bridge
- * 		could target abort or master abort or let the request through
- *		to the secondary bus causing an ape there.
- *  - tx-rdpe:	the device to transfer bad data and/or bad parity during a read
- *		request to a bridge.
- *  - tx-pwdpe:	the device to transfer bad data and/or bad parity during a
- *		posted write request to a bridge.
- *  - tx-dwdpe: the device to transfer bad data and/or bad parity during a
- *		delayed write request to a bridge.
- *
- * NOTE: The rules below are specifically for the pci-pci bridge, in which it
- * sends incorrect data/parity when receiving correct data/parity.
- *
- *  - bdg-tx-ape:	address/parity to get corrupted during transmission
- *			on the primary side bus. Must see sserr/dpe/rec_serr.
- *			In addition the hostbridge could target abort
- *			or master abort and if this was a delayed access
- *			we could get target abort propagated to secondary bus.
- *  - bdg-tx-dwdpe:	the bridge sends bad data/parity during a delayed write
- *			request to the primary side bus.
- *  - bdg-tx-pwdpe:	the bridge sends bad data/parity during a posted write
- *			request to the primary side bus.
- *  - bdg-tx-rdpe:	the bridge sends bad data/parity during a read request
- *			to the primary side bus.
- *  - bdg-tx-sec-ape:	address/parity to get corrupted during transmission
- *			on the secondary side bus. Only the sec-rserr/sserr/
- *			serr *must* happen. In addition any hardened leaf
- *			driver on the secondary bus that detects the ape will
- *			report sserr/dpe. Also the target device can target
- *			abort or master abort.
- *  - bdg-tx-sec-rdpe:	the bridge sends bad data/parity during a read request
- *			to the secondary side bus.
- *  - bdg-tx-sec-pwdpe: the bridge sends bad data/parity during a posted write
- *			request to the secondary side bus.
- *  - bdg-tx-sec-dwdpe: the bridge sends bad data/parity during a delayed write
- *			request to the secondary side bus.
- *
- *  - dto:	the device could exceed the timeout alloted for a delayed
- *		transaction, causing the bridge to signal a discard timeout.
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * ereport generation rules for hostbridge
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  */
-prop fault.io.pci.device@pcibus/pcidev/pcifn (0)->
-    error.io.pci.tx-ma@pcibus/pcidev/pcifn,
-    error.io.pci.rx-ma@pcibus/pcidev/pcifn,
-    error.io.pci.tx-serr@pcibus/pcidev/pcifn,
-    error.io.pci.rx-ta@pcibus/pcidev/pcifn,
-    error.io.pci.tx-ape@pcibus/pcidev/pcifn,
-    error.io.pci.tx-dpe@pcibus/pcidev/pcifn,
-    error.io.pcix.rx-discard@pcibus/pcidev/pcifn,
-    error.io.pcix.tx-oor@pcibus/pcidev/pcifn,
-    error.io.pcix.rx-unex-sc@pcibus/pcidev/pcifn,
-    ereport.io.pci.dto@pcibus/pcidev<>/pcifn<>;
+prop error.io.pci.dpdata-pw-u@pcibus/pcidev[fromdev]/pcifn (1)->
+    ereport.io.pci.dpe@PCI_TO_HB;
+
+prop error.io.pci.dpdata-dw-u@pcibus/pcidev[fromdev]/pcifn (1)->
+    ereport.io.pci.dpe@PCI_TO_HB;
+
+prop error.io.pci.dpdata-dr-u@pcibus/pcidev[fromdev]/pcifn (2)->
+    ereport.io.pci.mdpe@PCI_TO_HB,
+    ereport.io.pci.dpe@PCI_TO_HB;
+
+prop error.io.pci.ape-u@pcibus/pcidev[fromdev]/pcifn (3)->
+    ereport.io.pci.dpe@PCI_TO_HB,
+    error.io.pci.serr-u@PCI_TO_HB,
+    ereport.io.pci.sserr@PCI_TO_HB;
+
+prop error.io.pci.ape-u@pcibus/pcidev[fromdev]/pcifn (0)->
+    ereport.io.pci.sta@PCI_TO_HB;
+
+prop error.io.pci.ma-u@pcibus/pcidev[fromdev]/pcifn (1)->
+    ereport.io.pci.ma@PCI_TO_HB;
+
+prop error.io.pci.ta-u@pcibus/pcidev[fromdev]/pcifn (1)->
+    ereport.io.pci.rta@PCI_TO_HB;
+
+prop error.io.pci.perr-dw-u@pcibus/pcidev[fromdev]/pcifn (1)->
+    ereport.io.pci.mdpe@PCI_TO_HB;
 
-prop fault.io.pci.device@pcibus/pcidev/pcifn (0)->
-    error.io.pci.tx-pma@pcibus/pcidev/pcifn,
-    error.io.pci.tx-dma@pcibus/pcidev/pcifn,
-    error.io.pci.rx-pta@pcibus/pcidev/pcifn,
-    error.io.pci.rx-dta@pcibus/pcidev/pcifn,
-    error.io.pci.tx-ape-bdg@pcibus/pcidev/pcifn,
-    error.io.pci.tx-rdpe@pcibus/pcidev/pcifn,
-    error.io.pci.tx-pwdpe@pcibus/pcidev/pcifn,
-    error.io.pci.tx-dwdpe@pcibus/pcidev/pcifn;
+prop error.io.pci.perr-pw-u@pcibus/pcidev[fromdev]/pcifn (1)->
+    ereport.io.pci.mdpe@PCI_TO_HB;
+
+prop error.io.pci.badreq-drw-u@pcibus/pcidev[fromdev]/pcifn (0)->
+    ereport.io.pci.sta@PCI_TO_HB;
+
+prop error.io.pci.badreq-pw-u@pcibus/pcidev[fromdev]/pcifn (0)->
+    ereport.io.pci.sta@PCI_TO_HB;
+
+prop error.io.pcix.scpe-u@pcibus/pcidev/pcifn (1)->
+    error.io.pcix.spl-comp-ma-d@pcibus/pcidev/pcifn,
+    error.io.pcix.spl-comp-ta-d@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.scpe-u@pcibus/pcidev[fromdev]/pcifn (0)->
+    ereport.io.pci.dpe@PCI_TO_HB,
+    error.io.pci.serr-u@PCI_TO_HB,
+    ereport.io.pci.sserr@PCI_TO_HB,
+    ereport.io.pci.sta@PCI_TO_HB;
+
+prop error.io.pcix.spl-comp-ma-u@pcibus/pcidev[fromdev]/pcifn (3)->
+    ereport.io.pcix.discard@PCI_TO_HB,
+    error.io.pci.serr-u@PCI_TO_HB,
+    ereport.io.pci.sserr@PCI_TO_HB;
+
+prop error.io.pcix.spl-comp-ta-u@pcibus/pcidev[fromdev]/pcifn (3)->
+    ereport.io.pcix.discard@PCI_TO_HB,
+    error.io.pci.serr-u@PCI_TO_HB,
+    ereport.io.pci.sserr@PCI_TO_HB;
 
-prop fault.io.pci.device@pcibus/pcidev/pcifn (0)->
-    error.io.pci.bdg-tx-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-sec-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-sec-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-ma@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-ma@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-ma@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.rec-ma@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.rx-ma@pcibus/pcidev/pcifn (1)->
-    error.io.pci.rec-ma@pcibus/pcidev/pcifn;
+/*
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * A faulty PCI leaf device or pci-pci bridge may cause:
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ *  - nr-pw-u:		the device not to respond to a valid downstream request
+ *  - nr-drw-u:		the device not to respond to a valid downstream request
+ *  - ta-pw-u:		the device responds with a ta to a valid downstream
+ *			request
+ *  - ta-drw-u:		the device responds with a ta to a valid downstream
+ *			request
+ *  - serr-u:		the device to report itself in error
+ *  - badreq-pw-u:	a bad upstream request (may cause target to target
+ *			abort or master abort)
+ *  - badreq-drw-u:	a bad upstream request (may cause target to target
+ *			abort or master abort)
+ *  - ape-u:		the transfer of bad address/parity upstream.
+ *  - scpe-u:		the transfer of bad split completion upstream.
+ *  - dpe-u:		the device to deliver bad data/parity upstream.
+ *  - retry-to-u:	the device to exceed the set timeout for a delayed
+ *			transaction retry.
+ *
+ * A faulty PCI-X leaf device or bridge may also cause:
+ *
+ *  - tx-oor:		the device sends a byte count larger than the completers
+ *			address range.
+ *  - rx-unex-sc:	the device recieved a split completion with a tag
+ * 			which does not match any outstanding transaction.
+ */
 
-prop error.io.pci.rx-ma@pcibus/pcidev[fromdev]/pcifn (1)->
-    ereport.io.pci.target-ma@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev},
-    error.io.pci.sec-target-ma@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.sec-target-ma@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-ma@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
-
-prop error.io.pci.rec-ma@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.ma@pcibus/pcidev/pcifn;
-
-prop error.io.pci.rec-ta@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.rta@pcibus/pcidev/pcifn;
-
-prop error.io.pci.rec-mdpe@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-serr@pcibus/pcidev/pcifn (1)->
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.tx-serr@pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn;
-
-prop error.io.pci.rx-ta@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.rec-ta@pcibus/pcidev[fromdev]/pcifn,
-    error.io.pci.sta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
+#define	PCI_NOT_HB pcibus/pcidev[fromdev]/pcifn {fromdev != 32}
 
-prop error.io.pci.sta@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.sta@pcibus/pcidev/pcifn,
-    ereport.io.pci.target-rta@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-dpe@pcibus/pcidev/pcifn (1)->
-    error.io.pci.tx-rdpe@pcibus/pcidev/pcifn,
-    error.io.pci.tx-wdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-rdpe@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.rx-rdpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.rx-rdpe@pcibus/pcidev/pcifn (2)->
-    error.io.pci.rec-mdpe@pcibus/pcidev/pcifn,
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-rdpe@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-wdpe@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.rx-wdpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.tx-wdpe@pcibus/pcidev/pcifn (0)->
-    error.io.pci.rec-mdpe@pcibus/pcidev/pcifn;
+event error.io.pci.retry-to-u@pcibus/pcidev/pcifn;
+event error.io.pci.nr-pw-u@pcibus/pcidev/pcifn;
+event error.io.pci.nr-drw-u@pcibus/pcidev/pcifn;
+event error.io.pci.ta-pw-u@pcibus/pcidev/pcifn;
+event error.io.pci.ta-drw-u@pcibus/pcidev/pcifn;
+event error.io.pci.f-dpe-u@pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpe-u@pcibus/pcidev/pcifn;
+event error.io.pci.nonfatal-dpe-u@pcibus/pcidev/pcifn;
+event error.io.pci.flt-f-dpdata-pw-u@pcibus/pcidev/pcifn;
+event error.io.pci.flt-nf-dpdata-pw-u@pcibus/pcidev/pcifn;
+event error.io.pci.flt-f-dpdata-dw-u@pcibus/pcidev/pcifn;
+event error.io.pci.flt-nf-dpdata-dw-u@pcibus/pcidev/pcifn;
+event error.io.pci.flt-f-dpdata-dr-u@pcibus/pcidev/pcifn;
+event error.io.pci.flt-nf-dpdata-dr-u@pcibus/pcidev/pcifn;
+event error.io.pci.perr-d@pcibus/pcidev/pcifn;
+event error.io.pci.target-mdpe-d@pcibus/pcidev/pcifn;
+event error.io.pci.target-mdpe-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.target-rta-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.target-ma-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pcix.tx-oor@pcibus/pcidev/pcifn;
+event error.io.pcix.rx-unex-sc@pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-w-u@pcibus/pcidev/pcifn;
+event error.io.pci.source-f-dpdata-w-u@pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-r-u@pcibus/pcidev/pcifn;
+event error.io.pci.source-f-dpdata-r-u@pcibus/pcidev/pcifn;
+event error.io.device.nf-device@pcibus/pcidev/pcifn;
+event error.io.device.f-device@pcibus/pcidev/pcifn;
+event error.io.pciex.flt-badreq-u@pcibus/pcidev/pcifn;
 
-prop error.io.pci.rx-wdpe@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn;
+event ereport.io.pcix.oor@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.unex-sc@pcibus/pcidev/pcifn{within(5s)};
 
-prop error.io.pci.tx-ape@pcibus/pcidev/pcifn (1)->
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.tx-ape@pcibus/pcidev[fromdev]/pcifn (0)->
-    ereport.io.pci.sserr@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev},
-    ereport.io.pci.dpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
+prop fault.io.pci.device-noresp@pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.pci.nr-pw-u@PCI_NOT_HB,
+    error.io.pci.nr-drw-u@PCI_NOT_HB,
+    error.io.pci.retry-to-u@PCI_NOT_HB;
 
-prop error.io.pci.tx-ape@pcibus/pcidev[fromdev]/pcifn (0)->
-    ereport.io.pci.target-rta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev},
-    ereport.io.pci.sta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
+prop fault.io.pci.device-interr@pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.pci.ta-pw-u@PCI_NOT_HB,
+    error.io.pci.ta-drw-u@PCI_NOT_HB,
+    error.io.pci.serr-u@PCI_NOT_HB,
+    error.io.pci.ape-u@PCI_NOT_HB,
+    error.io.pci.f-dpe-u@PCI_NOT_HB,
+    error.io.pci.nf-dpe-u@PCI_NOT_HB,
+    error.io.device.f-device@PCI_NOT_HB,
+    error.io.device.nf-device@PCI_NOT_HB,
+    error.io.pcix.scpe-u@PCI_NOT_HB,
+    error.io.pcix.tx-oor@PCI_NOT_HB,
+    error.io.pcix.rx-unex-sc@PCI_NOT_HB;
 
-prop error.io.pci.tx-ape@pcibus/pcidev/pcifn (0)->
-    error.io.pci.rec-ta@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-ape@pcibus/pcidev[fromdev]/pcifn (0)->
-    ereport.io.pci.target-ma@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.tx-ape@pcibus/pcidev/pcifn (0)->
-    error.io.pci.rec-ma@pcibus/pcidev/pcifn;
+prop fault.io.pci.device-invreq@pcibus/pcidev[fromdev]/pcifn {FD_IS_LEAF} (0)->
+    error.io.pciex.flt-badreq-u@PCI_NOT_HB,
+    error.io.pci.badreq-drw-u@PCI_NOT_HB,
+    error.io.pci.badreq-pw-u@PCI_NOT_HB;
 
 prop error.io.pcix.tx-oor@pcibus/pcidev/pcifn (1)->
     ereport.io.pcix.oor@pcibus/pcidev/pcifn;
 
-prop error.io.pcix.rx-discard@pcibus/pcidev/pcifn (1)->
-    ereport.io.pcix.discard@pcibus/pcidev/pcifn;
+prop error.io.pcix.rx-unex-sc@pcibus/pcidev[fromdev]/pcifn (1)->
+    ereport.io.pcix.unex-sc@pcibus/pcidev<todev>/pcifn<> {fromdev != todev};
+
+prop error.io.pci.f-dpe-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.flt-f-dpdata-pw-u@pcibus/pcidev/pcifn,
+    error.io.pci.flt-f-dpdata-dw-u@pcibus/pcidev/pcifn,
+    error.io.pci.flt-f-dpdata-dr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.flt-f-dpdata-pw-u@pcibus/pcidev/pcifn (2)->
+    error.io.pci.source-f-dpdata-w-u@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-pw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.flt-f-dpdata-pw-u@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.flt-f-dpdata-dw-u@pcibus/pcidev/pcifn (3)->
+    error.io.pci.source-f-dpdata-w-u@pcibus/pcidev/pcifn,
+    error.io.pci.perr-d@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-dw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.flt-f-dpdata-dr-u@pcibus/pcidev/pcifn (2)->
+    error.io.pci.source-f-dpdata-r-u@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-dr-u@pcibus/pcidev/pcifn;
 
-prop error.io.pcix.rx-unex-sc@pcibus/pcidev[fromdev]/pcifn (0)->
-    ereport.io.pcix.unex-sc@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
+prop error.io.pci.flt-f-dpdata-dr-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.target-mdpe-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nonfatal-dpe-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.flt-nf-dpdata-pw-u@pcibus/pcidev/pcifn,
+    error.io.pci.flt-nf-dpdata-dw-u@pcibus/pcidev/pcifn,
+    error.io.pci.flt-nf-dpdata-dr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.flt-nf-dpdata-pw-u@pcibus/pcidev/pcifn (2)->
+    error.io.pci.source-nf-dpdata-w-u@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-pw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.flt-nf-dpdata-pw-u@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.flt-nf-dpdata-dw-u@pcibus/pcidev/pcifn (3)->
+    error.io.pci.source-nf-dpdata-w-u@pcibus/pcidev/pcifn,
+    error.io.pci.perr-d@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-dw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.flt-nf-dpdata-dr-u@pcibus/pcidev/pcifn (2)->
+    error.io.pci.source-nf-dpdata-r-u@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-dr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.flt-nf-dpdata-dr-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.target-mdpe-d@pcibus/pcidev/pcifn;
 
 /*
- * the rules below are for hostbridge faults above a pci-pci bridge
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * A faulty pci-pci bridge may also cause
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ *  - nr-pw-d:		the device not to respond to a valid upstream request
+ *  - nr-drw-d:		the device not to respond to a valid upstream request
+ *  - ta-pw-d:		the device responds with a ta to a valid upstream
+ *			request
+ *  - ta-drw-d:		the device responds with a ta to a valid upstream
+ *			request
+ *  - ape-d:	address/parity to get corrupted during downstream transmission.
+ *  - scpe-d:	split completion gets corrupted during downstream transmission.
+ *  - dpe-d:	data/parity to get corrupted during downstream transmission.
+ *  - retry-to-d:	the device to exceed the set timeout for a delayed
+ *			transaction retry.
  */
 
-prop error.io.pci.tx-pma@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-ma@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-pma@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.rx-pma@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.rx-pma@pcibus/pcidev/pcifn (3)->
-    error.io.pci.serr@pcibus,
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn,
-    error.io.pci.rec-ma@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-dma@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-ma@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-dma@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.rx-dma@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.rx-dma@pcibus/pcidev/pcifn (2)->
-    error.io.pci.rec-ma@pcibus/pcidev/pcifn<>,
-    error.io.pci.sec-tx-ta@pcibus/pcidev/pcifn;
-
-prop error.io.pci.sec-tx-ta@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn;
-
-prop error.io.pci.sec-tx-ta@pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.target-rta@pcibus/pcidev/pcifn,
-    ereport.io.pci.rta@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
-
-prop error.io.pci.rx-pta@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.tx-pta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.tx-pta@pcibus/pcidev/pcifn (3)->
-    error.io.pci.serr@pcibus,
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn<>,
-    error.io.pci.sec-rx-pta@pcibus/pcidev/pcifn;
-
-prop error.io.pci.sec-rx-pta@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.sec-rta@pcibus/pcidev/pcifn;
-
-prop error.io.pci.sec-rx-pta@pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sta@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
-
-prop error.io.pci.rx-dta@pcibus/pcidev/pcifn (1)->
-    error.io.pci.rec-ta@pcibus/pcidev/pcifn;
-
-prop error.io.pci.rx-dta@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.sec-rx-dta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.sec-rx-dta@pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.sec-rta@pcibus/pcidev/pcifn,
-    ereport.io.pci.sta@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.sec-rx-dta@pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sta@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
-
-prop error.io.pci.sec-rx-dta@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-rta@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
-
-prop error.io.pci.tx-rdpe@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-rdpe@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.bdg-rx-dpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
+event error.io.pci.ape-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.f-dpe-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpe-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.retry-to-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.nr-pw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.nr-drw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.ta-pw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.ta-drw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pcix.scpe-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 
-prop error.io.pci.bdg-rx-dpe@pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn,
-    error.io.pci.rec-mdpe@pcibus/pcidev/pcifn<>,
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.bdg-rx-dpe@pcibus/pcidev/pcifn (0)->
-    error.io.pci.sec-rx-mdpe@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
-
-prop error.io.pci.sec-rx-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-pwdpe@pcibus/pcidev/pcifn (1)->
-    error.io.pci.rec-mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-pwdpe@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.bdg-pwdpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.bdg-pwdpe@pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn<>,
-    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-pwdpe@pcibus/pcidev/pcifn (1)->
-    error.io.pci.sec-target-mdpe@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
-
-prop error.io.pci.sec-target-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.sec-target-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-dwdpe@pcibus/pcidev/pcifn (1)->
-    error.io.pci.rec-mdpe@pcibus/pcidev/pcifn;
+prop fault.io.pci.device-noresp@pcibus/pcidev/pcifn (0)->
+    error.io.pci.nr-pw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
+    error.io.pci.nr-drw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
+    error.io.pci.retry-to-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 
-prop error.io.pci.tx-dwdpe@pcibus/pcidev[fromdev]/pcifn (1)->
-    error.io.pci.bdg-dwdpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.bdg-dwdpe@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.bdg-dwdpe@pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
- 
-prop error.io.pci.tx-ape-bdg@pcibus/pcidev/pcifn (1)->
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.tx-ape-bdg@pcibus/pcidev[fromdev]/pcifn (2)->
-    ereport.io.pci.sserr@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev},
-    ereport.io.pci.dpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.tx-ape-bdg@pcibus/pcidev[fromdev]/pcifn (0)->
-    ereport.io.pci.target-rta@pcibus/pcidev<todev>/pcifn<>/pcibus/pcidev/pcifn
-    {fromdev != todev},
-    ereport.io.pci.sta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.tx-ape-bdg@pcibus/pcidev/pcifn (0)->
-    error.io.pci.rec-ta@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-ape-bdg@pcibus/pcidev[fromdev]/pcifn (0)->
-    ereport.io.pci.target-ma@pcibus/pcidev<todev>/pcifn<>/pcibus/pcidev/pcifn
-    {fromdev != todev};
-
-prop error.io.pci.tx-ape-bdg@pcibus/pcidev/pcifn (0)->
-    error.io.pci.rec-ma@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-ape-bdg@pcibus/pcidev[fromdev]/pcifn (0)->
-    error.io.pci.bdg-tx-sec-ape@pcibus/pcidev<todev>/pcifn<>/pcibus/pcidev/pcifn
-    {fromdev != todev};
+prop fault.io.pci.device-interr@pcibus/pcidev/pcifn (0)->
+    error.io.pci.ta-pw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
+    error.io.pci.ta-drw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
+    error.io.pci.ape-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
+    error.io.pcix.scpe-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
+    error.io.pci.f-dpe-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
+    error.io.pci.nf-dpe-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 
 /*
- * The rules below are specifically for the pci-pci bridge, in which it
- * sends incorrect data/parity when receiving correct data/parity.
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * A faulty PCI bus may cause:
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ *  - ape-d:	address/parity to get corrupted during downstream transmission.
+ *  - scpe-d:	split completion gets corrupted during downstream transmission.
+ *  - dpe-d:	data/parity to get corrupted during downstream transmission.
+ *  - ape-u:	address/parity to get corrupted during upstream transmission.
+ *  - dpe-u:	data/parity to get corrupted during read upstream transmission.
+ *  - scpe-u:	split completion to get corrupted during upstream transmission.
  */
 
-prop error.io.pci.bdg-tx-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.rec-mdpe@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.bdg-tx-dwdpe@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.rx-wdpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.bdg-tx-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn<>,
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.bdg-tx-pwdpe@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.rx-wdpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.bdg-tx-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.rec-mdpe@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.bdg-tx-rdpe@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.rx-rdpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.bdg-tx-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-sec-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn<>,
-    error.io.pci.serr@pcibus,
-    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-sec-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-sec-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-sec-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.sec-rx-dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-sec-dwdpe@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.rec-mdpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.sec-rx-dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-ape@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (3)->
-    ereport.io.pci.sserr@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev},
-    ereport.io.pci.dpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev},
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.bdg-tx-ape@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev},
-    ereport.io.pci.target-rta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.bdg-tx-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    error.io.pci.rec-ta@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.bdg-tx-ape@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.target-ma@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.bdg-tx-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    error.io.pci.rec-ma@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.bdg-tx-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn,
-    ereport.io.pci.target-rta@pcibus/pcidev/pcifn,
-    ereport.io.pci.rta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
-    ereport.io.pci.sec-rserr@pcibus/pcidev/pcifn,
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn<>,
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.bdg-tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.bdg-tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.sec-rta@pcibus/pcidev/pcifn,
-    ereport.io.pci.target-rta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.sta@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.bdg-tx-sec-ape@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (0)->
-    error.io.pci.rec-ta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.bdg-tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sec-ma@pcibus/pcidev/pcifn,
-    ereport.io.pci.target-ma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.sta@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.bdg-tx-sec-ape@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (0)->
-    error.io.pci.rec-ta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
 fru pcibus;
 asru pcibus;
 
-event fault.io.pci.bus@pcibus,
+event fault.io.pci.bus-linkerr@pcibus,
         FITrate=PCI_BUS_FIT, FRU=pcibus, ASRU=pcibus;
 
-/* A faulty PCI bus may cause:
- *
- *  - tx-dpe:	data/parity to get corrupted during transmission.
- *  - tx-ape:	address/parity to get corrupted during transmission.
- *
- * NOTE: The rules below are valid for pci-pci bridge transactions.
- *
- *  - tx-ape-bdg:	address/parity to get corrupted during transmission.
- *  - tx-pwdpe:	data/parity to get corrupted during posted write transmission
- *		to a pci-pci bridge.
- *  - tx-dwdpe:	data/parity to get corrupted during delayed write transmission
- *		to a pci-pci bridge.
- *  - tx-rdpe:	data/parity to get corrupted during read transmission
- *		to a pci-pci bridge.
- *  - bdg-tx-ape:	address/parity to get corrupted during transmission
- *			from a pci-pci bridge.
- *  - bdg-tx-pwdpe:	data/parity to get corrupted during posted write
- *			transmission from a pci-pci bridge.
- *  - bdg-tx-dwdpe:	data/parity to get corrupted during delayed write
- *			transmission from a pci-pci bridge.
- *  - bdg-tx-rdpe:	data/parity to get corrupted during read transmission
- *			from a pci-pci bridge.
- */
-
-prop fault.io.pci.bus@pcibus (0)->
-    error.io.pci.tx-dpe@pcibus/pcidev/pcifn,
-    error.io.pci.tx-ape@pcibus/pcidev/pcifn,
-    error.io.pcix.tx-oor@pcibus/pcidev/pcifn,
-    error.io.pcix.rx-unex-sc@pcibus/pcidev/pcifn;
-
-prop fault.io.pci.bus@pcibus (0)->
-    error.io.pci.tx-ape-bdg@pcibus/pcidev/pcifn,
-    error.io.pci.tx-pwdpe@pcibus/pcidev/pcifn,
-    error.io.pci.tx-rdpe@pcibus/pcidev/pcifn,
-    error.io.pci.tx-dwdpe@pcibus/pcidev/pcifn;
-
-prop fault.io.pci.bus@pcibus (0)->
-    error.io.pci.bdg-tx-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+prop fault.io.pci.bus-linkerr@pcibus (0)->
+    error.io.pci.ape-d@pcibus/pcidev<todev>/pcifn { todev != 32},
+    error.io.pci.f-dpe-d@pcibus/pcidev<todev>/pcifn { todev != 32},
+    error.io.pci.nf-dpe-d@pcibus/pcidev<todev>/pcifn { todev != 32},
+    error.io.pci.ape-u@pcibus/pcidev<todev>/pcifn { todev != 32},
+    error.io.pci.f-dpe-u@pcibus/pcidev<todev>/pcifn { todev != 32},
+    error.io.pci.nf-dpe-u@pcibus/pcidev<todev>/pcifn { todev != 32},
+    error.io.pcix.scpe-d@pcibus/pcidev<todev>/pcifn { todev != 32},
+    error.io.pcix.scpe-u@pcibus/pcidev<todev>/pcifn { todev != 32},
+    error.io.pcix.tx-oor@pcibus/pcidev<todev>/pcifn { todev != 32},
+    error.io.pcix.rx-unex-sc@pcibus/pcidev<todev>/pcifn { todev != 32};
 
 /*
- * A defective PCI device driver may cause:
- *
- *  - tx-ma:	a device to not respond because it was power managed and the
- *		driver attempted to access it.
- *  - rx-ma:	a device to address a non-existent device.
- *  - rx-ta:	a device to request a transaction from a target that is invalid
- *		causing a target abort to be received.
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * recursive rules for pci-pci bridges
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  */
 
-event defect.io.pci.driver@pcibus/pcidev/pcifn;
+event error.io.pci.serr-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.perr-dw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.perr-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.perr-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dr-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-pw-fwd-d@pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-pw-fwd-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dw-fwd-d@pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dw-fwd-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.f-dpdata-dr-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpdata-dr-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.leaf-ape-d@pcibus/pcidev/pcifn;
+event error.io.pci.ape-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.source-ape-u@pcibus/pcidev/pcifn;
+event error.io.pci.source-f-perr-u@pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-perr-u@pcibus/pcidev/pcifn;
+event error.io.pci.badreq-pw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.badreq-drw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.badreq-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.badreq-drw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.ta-d@pcibus/pcidev/pcifn;
+event error.io.pci.ta-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.ta-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.target-rta-d@pcibus/pcidev/pcifn;
+event error.io.pci.target-ma-d@pcibus/pcidev/pcifn;
+event error.io.pci.ta-pw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.ta-drw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.nr-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.ta-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.retry-to-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pcix.scpe-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pcix.source-scpe-u@pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ma-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ta-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.ma-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 
-prop defect.io.pci.driver@pcibus/pcidev/pcifn (0)->
-    error.io.pci.tx-ma@pcibus/pcidev/pcifn,
-    error.io.pci.rx-ma@pcibus/pcidev/pcifn,
-    error.io.pci.rx-ta@pcibus/pcidev/pcifn,
-    error.io.pcix.tx-oor@pcibus/pcidev/pcifn;
+event ereport.io.pci.sec-ma@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.sec-sta@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.sec-rta@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.sec-rserr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pci.dto@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-spl-dis@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.spl-dis@pcibus/pcidev/pcifn{within(5s)};
+
+/*
+ * SERR# can propagate upstream and may be seen by other devices on the bus
+ */
+prop error.io.pci.serr-u@pcibus/pcidev[fromdev]/pcifn (0)->
+    ereport.io.pci.sserr@pcibus/pcidev<todev>/pcifn<> {todev!=fromdev};
+
+prop error.io.pci.serr-u@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    ereport.io.pci.sserr@pcibus/pcidev/pcifn;
+
+prop error.io.pci.serr-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)->
+    ereport.io.pci.sec-rserr@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
 
-/* PCI-PCI devices */
-asru pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-fru pcibus/pcidev/pcifn/pcibus/pcidev;
+/*
+ * PERR# can propagate upstream for delayed writes. For posted writes
+ * it turns into an SERR#.
+ */
+prop error.io.pci.perr-dw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)->
+    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn,
+    error.io.pci.perr-dw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.perr-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)->
+    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+/*
+ * PERR# can propagate downstream (only for downstream dw parity error)
+ */
+prop error.io.pci.perr-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.perr-d@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.perr-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.perr-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
 
-event fault.io.pci.device@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev/pcifn/pcibus/pcidev,
-    ASRU=pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+/*
+ * downstream target ereports are for any descendant device
+ *
+ * A hostbridge driver may generate "target-" ereports when knowledge of the
+ * physical address associated with a fault allows the target device to be
+ * determined. This is not a requirement of the Diagnosis Engine, but can be
+ * valuable when available.
+ */
+prop error.io.pci.target-mdpe-d@pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.target-mdpe-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.target-mdpe-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.target-rta-d@pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.target-rta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.target-rta-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.target-rta-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.target-ma-d@pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.target-ma@pcibus/pcidev/pcifn;
+
+prop error.io.pci.target-ma-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.target-ma-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+/*
+ * target aborts propagate upstream
+ */
+prop error.io.pci.ta-u@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    ereport.io.pci.sta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-u@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.sta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)->
+    ereport.io.pci.sec-rta@pcibus/pcidev/pcifn,
+    error.io.pci.ta-u@pcibus/pcidev/pcifn;
 
-event error.io.pci.tx-sec-pma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.tx-sec-dma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.rx-sec-pta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.rx-sec-dta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.tx-sec-serr@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.tx-sec-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.tx-sec-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.tx-sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-event error.io.pci.sec-dpe@pcibus/pcidev/pcifn;
+/*
+ * bad data (ie invalid but not an ape or dpe) can propagate downstream,
+ * and at some point may result in a target or master abort
+ */
+prop error.io.pci.badreq-pw-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.badreq-pw-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.nr-pw-u@pcibus/pcidev/pcifn,
+    error.io.pci.ta-pw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.badreq-pw-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    error.io.pci.nr-pw-u@pcibus/pcidev/pcifn,
+    error.io.pci.ta-pw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.badreq-drw-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.badreq-drw-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.nr-drw-u@pcibus/pcidev/pcifn,
+    error.io.pci.ta-drw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.badreq-drw-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    error.io.pci.nr-drw-u@pcibus/pcidev/pcifn,
+    error.io.pci.ta-drw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nr-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)-> 
+    ereport.io.pci.sec-ma@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-pw-u@pcibus/pcidev/pcifn { IS_LEAF } (0)-> 
+    ereport.io.pci.sta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-pw-u@pcibus/pcidev/pcifn { IS_BDG } (1)-> 
+    ereport.io.pci.sta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)-> 
+    ereport.io.pci.sec-rta@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nr-drw-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.ma-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nr-drw-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.target-rta-d@pcibus/pcidev/pcifn,
+    error.io.pci.target-ma-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ma-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    ereport.io.pci.sec-ma@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ma-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    error.io.pci.ma-u@pcibus/pcidev/pcifn,
+    error.io.pci.ta-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-drw-u@pcibus/pcidev/pcifn (1)-> 
+    error.io.pci.ta-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-drw-u@pcibus/pcidev/pcifn (1)-> 
+    error.io.pci.target-rta-d@pcibus/pcidev/pcifn;
+
+/*
+ * bad data (ie invalid but not an ape or dpe) can propagate upstream,
+ * and at some point may result in a target or master abort
+ */
+prop error.io.pci.badreq-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    error.io.pci.badreq-pw-u@pcibus/pcidev/pcifn,
+    error.io.pci.nr-pw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
+    error.io.pci.ta-pw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 
-event ereport.io.pci.target-rta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.rta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sec-sta@pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn{within(5s)};
+prop error.io.pci.badreq-pw-u@pcibus/pcidev/pcifn (0)->
+    error.io.pci.nr-pw-d@pcibus/pcidev/pcifn,
+    error.io.pci.ta-pw-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nr-pw-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.ma@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nr-pw-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pci.ma@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-pw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-pw-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.rta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-pw-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pci.rta@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+/*
+ * for delayed writes we treat upstream badreq specially as rta always
+ * propagates back downstream to the leaf
+ */
+prop error.io.pci.badreq-drw-u@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.rta@pcibus/pcidev/pcifn,
+    ereport.io.pci.ma@pcibus/pcidev/pcifn; 
+
+prop error.io.pci.badreq-drw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    ereport.io.pci.ma@pcibus/pcidev/pcifn,
+    ereport.io.pci.rta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.badreq-drw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.badreq-drw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
+    error.io.pci.badreq-drw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nr-drw-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.ma@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nr-drw-d@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    ereport.io.pci.ma@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nr-drw-d@pcibus/pcidev/pcifn { IS_BDG } (0)->
+    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nr-drw-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.ta-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.nr-drw-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.ta-drw-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-drw-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.ta-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.rta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn,
+    ereport.io.pci.rta@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ta-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.ta-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
 
 /*
- * A faulty PCI device off of a pci-pci bridge may cause:
+ * Request with address parity error must be detected by parent device
+ * and can optionally result in a target or master abort.
+ * It may also be detected by sibling devices on a bus
+ */
+prop error.io.pci.ape-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
+    ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-rserr@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ape-u@pcibus/pcidev/pcifn (0)->
+    error.io.pci.nr-drw-d@pcibus/pcidev/pcifn,
+    error.io.pci.ta-drw-d@pcibus/pcidev/pcifn,
+    error.io.pci.nr-pw-d@pcibus/pcidev/pcifn,
+    error.io.pci.ta-pw-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ape-u@pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ape-u@pcibus/pcidev[fromdev]/pcifn (0)->
+    ereport.io.pci.dpe@pcibus/pcidev<todev>/pcifn<> {fromdev != todev},
+    ereport.io.pci.sserr@pcibus/pcidev<todev>/pcifn<> {fromdev != todev};
+
+prop error.io.pci.ape-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.source-ape-u@pcibus/pcidev/pcifn;
+
+/*
+ * If the bridge sees an upstream split completion error (pci-x only) it could
+ * result in a number of things
+ * - for various faults in the split completion (eg address parity error)
+ *   we will respond with a target abort (which the child device will treat
+ *   as a split completion ta)
+ * - for other faults we can't tell who send the split completion and so
+ *   just drop the request (which the child device sees as a split
+ *   completion ma)
+ */
+prop error.io.pcix.scpe-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-rserr@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.scpe-u@pcibus/pcidev/pcifn (1)->
+    error.io.pcix.spl-comp-ma-d@pcibus/pcidev/pcifn,
+    error.io.pcix.spl-comp-ta-d@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.spl-comp-ma-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.spl-comp-ma-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.sserr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.spl-dis@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.spl-comp-ma-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pcix.spl-dis@pcibus/pcidev/pcifn,
+    ereport.io.pci.ma@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.spl-comp-ta-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.spl-comp-ta-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.sserr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.spl-dis@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.spl-comp-ta-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pcix.spl-dis@pcibus/pcidev/pcifn,
+    ereport.io.pci.rta@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.scpe-u@pcibus/pcidev/pcifn (1)->
+    error.io.pcix.source-scpe-u@pcibus/pcidev/pcifn;
+
+/*
+ * request with address parity error must be detected by child device
+ * and can optionally result in a target or master abort.
+ */
+prop error.io.pci.ape-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ape-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    error.io.pci.leaf-ape-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.leaf-ape-d@pcibus/pcidev/pcifn { IS_LEAF } (2)->
+    ereport.io.pci.sserr@pcibus/pcidev/pcifn,
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ape-d@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.ape-d@pcibus/pcidev/pcifn (0)->
+    error.io.pci.ta-pw-u@pcibus/pcidev/pcifn,
+    error.io.pci.ta-drw-u@pcibus/pcidev/pcifn,
+    error.io.pci.nr-pw-u@pcibus/pcidev/pcifn,
+    error.io.pci.nr-drw-u@pcibus/pcidev/pcifn;
+
+/*
+ * If the device sees a downstream split completion error (pci-x only) it could
+ * result in a number of things
+ * - for various faults in the split completion (eg address parity error)
+ *   we will respond with a target abort (which the parent bridge will treat
+ *   as a split completion ta)
+ * - for other faults we can't tell who send the split completion and so
+ *   just drop the request (which the parent bridge sees as a split
+ *   completion ma)
+ */
+prop error.io.pcix.scpe-d@pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.sta@pcibus/pcidev/pcifn,
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.sserr@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.scpe-d@pcibus/pcidev/pcifn (1)->
+    error.io.pcix.spl-comp-ma-u@pcibus/pcidev/pcifn,
+    error.io.pcix.spl-comp-ta-u@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.spl-comp-ma-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
+    ereport.io.pcix.sec-spl-dis@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-ma@pcibus/pcidev/pcifn;
+
+prop error.io.pcix.spl-comp-ta-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
+    ereport.io.pcix.sec-spl-dis@pcibus/pcidev/pcifn,
+    error.io.pci.serr-u@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-rta@pcibus/pcidev/pcifn;
+
+/*
+ * request with data parity error can propagate upstream
+ *
+ * for PCI/X (but not PCI) the split write can optionally be forwarded across
+ * the bridge, maintaining bad parity/ecc
  *
- *  - tx-sec-pma:	the device not to respond to a valid request during a
- *			posted transaction.
- *  - tx-sec-dma:	the device not to respond to a valid request during a
- *			delayed transaction.
- *  - rx-sec-pta:	the device to receive a target abort during a posted
- *			transaction.
- *  - rx-sec-dta:	the device to receive a target abort during a delayed
- *			transaction.
- *  - tx-sec-serr:	the device to signal a system error.
- *  - tx-sec-ape:	the transfer of bad address/parity. We must see sec_dpe/
- *			sserr/rec_serr. The initiator will only see the PERR# -
- *			so may raise mdpe. Another device on the secondary bus
- *			could detect and report the ape. The bridge could target
- *			abort or master abort or pass the request up to the 
- *			primary bus.
- *  - tx-sec-pwdpe:	the device to deliver bad data/parity during a posted
- *			write.
- *  - tx-sec-dwdpe:	the device to deliver bad data/parity during a delayed
- *			write.
- *  - tx-sec-rdpe:	the device to deliver bad data/parity during a read.
- *  - dto:		the device to exceed the set timeout for a delayed
- *			transaction.
- *  - rx-pma:		the device to send a bad address to the primary side
- *			bus during a posted transaction.
- *  - rx-dma:		the device to send a bad address to the primary side bus
- *			during a delayed transaction.
+ * if there is a dpe on a retry on a delayed write, we don't send another
+ * retry, and eventually the dto timer will expire
+ */
+prop error.io.pci.dpdata-pw-u@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.dpdata-pw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-pw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.dpdata-dw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.dpdata-dw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-dw-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.dpdata-dw-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
+    error.io.pci.retry-to-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+
+prop error.io.pci.dpdata-dr-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
+    ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-dr-u@pcibus/pcidev/pcifn;
+
+/*
+ * Request with data parity error can propagate downstream. A hardened
+ * leaf driver should handle the error, but may or may not be able to
+ * avoid service impact. We handle to two cases separately. If there is
+ * service impact we will fail immediately, if not we will feed into a SERD
+ * engine.
+ *
+ * for PCI/X (but not PCI) the split write can optionally be forwarded across
+ * the bridge, maintaining bad parity/ecc
+ *
+ * if there is a dpe on a retry on a delayed write, we don't send another
+ * retry, and eventually the dto timer will expire
  */
-prop fault.io.pci.device@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    error.io.pci.tx-sec-pma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-dma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.rx-sec-pta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.rx-sec-dta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-serr@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.rx-pma@pcibus/pcidev/pcifn,
-    error.io.pci.rx-dma@pcibus/pcidev/pcifn,
+prop error.io.pci.f-dpdata-pw-d@pcibus/pcidev/pcifn (2)->
+    error.io.pci.perr-pw-u@pcibus/pcidev/pcifn,
+    error.io.pci.source-f-perr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpdata-pw-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpdata-pw-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpdata-pw-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.dpdata-pw-fwd-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.nf-dpdata-pw-d@pcibus/pcidev/pcifn (2)->
+    error.io.pci.perr-pw-u@pcibus/pcidev/pcifn,
+    error.io.pci.source-nf-perr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpdata-pw-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpdata-pw-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpdata-pw-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.dpdata-pw-fwd-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.dpdata-pw-fwd-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.dpdata-pw-fwd-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.dpdata-pw-fwd-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.dpdata-pw-fwd-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.f-dpdata-dw-d@pcibus/pcidev/pcifn (3)->
+    error.io.pci.perr-dw-u@pcibus/pcidev/pcifn,
+    error.io.pci.source-f-perr-u@pcibus/pcidev/pcifn,
+    error.io.pci.target-mdpe-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpdata-dw-d@pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-dw-fwd-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.f-dpdata-dw-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpdata-dw-d@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpdata-dw-d@pcibus/pcidev/pcifn { IS_BDG } (0)->
+    error.io.pci.retry-to-d@pcibus/pcidev/pcifn;
 
+prop error.io.pci.nf-dpdata-dw-d@pcibus/pcidev/pcifn (3)->
+    error.io.pci.perr-dw-u@pcibus/pcidev/pcifn,
+    error.io.pci.source-nf-perr-u@pcibus/pcidev/pcifn,
+    error.io.pci.target-mdpe-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpdata-dw-d@pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-dw-fwd-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.nf-dpdata-dw-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpdata-dw-d@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpdata-dw-d@pcibus/pcidev/pcifn { IS_BDG } (0)->
+    error.io.pci.retry-to-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.dpdata-dw-fwd-d@pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn,
+    error.io.pci.dpdata-dw-fwd-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.f-dpdata-dr-d@pcibus/pcidev/pcifn (2)->
+    error.io.pci.perr-dr-u@pcibus/pcidev/pcifn,
+    error.io.pci.source-f-perr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpdata-dr-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpdata-dr-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.f-dpdata-dr-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.f-dpdata-dr-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.nf-dpdata-dr-d@pcibus/pcidev/pcifn (2)->
+    error.io.pci.perr-dr-u@pcibus/pcidev/pcifn,
+    error.io.pci.source-nf-perr-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpdata-dr-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpdata-dr-d@pcibus/pcidev/pcifn { IS_BDG } (2)->
+    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
+    ereport.io.pci.mdpe@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpdata-dr-d@pcibus/pcidev/pcifn (1)->
+    error.io.pci.nf-dpdata-dr-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+/*
+ * delayed read/write retry timeout can cause dto at a bridge
+ */
+prop error.io.pci.retry-to-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
+    error.io.pci.retry-to-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.retry-to-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
     ereport.io.pci.dto@pcibus/pcidev/pcifn;
 
-prop error.io.pci.tx-sec-pma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
-    ereport.io.pci.sec-ma@pcibus/pcidev/pcifn,
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn<>,
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.tx-sec-dma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
-    ereport.io.pci.target-rta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.sec-ma@pcibus/pcidev/pcifn,
-    ereport.io.pci.sta@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.tx-sec-dma@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.rec-ta@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.rx-sec-pta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
-    error.io.pci.rx-ta@pcibus/pcidev/pcifn<>,
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn<>,
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.rx-sec-dta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.target-rta@pcibus/pcidev/pcifn,
-    ereport.io.pci.rta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+prop error.io.pci.retry-to-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
 
-prop error.io.pci.rx-sec-dta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn,
-    error.io.pci.rx-ta@pcibus/pcidev/pcifn<>;
-
-prop error.io.pci.tx-sec-serr@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.sec-rserr@pcibus/pcidev/pcifn,
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn<>,
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.tx-sec-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn,
-    error.io.pci.rec-mdpe@pcibus/pcidev/pcifn<>,
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-sec-pwdpe@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.sec-dpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.sec-dpe@pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn,
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn;
+prop error.io.pci.retry-to-d@pcibus/pcidev/pcifn (0)->
+    error.io.pci.retry-to-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 
-prop error.io.pci.tx-sec-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn,
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.sec-mdpe@pcibus/pcidev/pcifn,
-    ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-sec-rdpe@pcibus/pcidev[fromdev]/pcifn/pcibus/pcidev/pcifn (1)->
-    error.io.pci.rx-rdpe@pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (3)->
-    ereport.io.pci.sec-dpe@pcibus/pcidev/pcifn,
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn<>,
-    error.io.pci.serr@pcibus;
-
-prop error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.mdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    ereport.io.pci.target-mdpe@pcibus/pcidev/pcifn;
+prop error.io.pci.retry-to-d@pcibus/pcidev/pcifn { IS_BDG } (1)->
+    ereport.io.pci.dto@pcibus/pcidev/pcifn;
 
-prop error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev[fromdev]/pcifn (0)->
-    ereport.io.pci.dpe@pcibus/pcidev/pcifn/pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev},
-    ereport.io.pci.sserr@pcibus/pcidev/pcifn/pcibus/pcidev<todev>/pcifn<>
-    {fromdev != todev};
-
-prop error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sec-rserr@pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.sec-sta@pcibus/pcidev/pcifn,
-    ereport.io.pci.target-rta@pcibus/pcidev/pcifn,
-    ereport.io.pci.rta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.target-ma@pcibus/pcidev/pcifn,
-    ereport.io.pci.ma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-prop error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    error.io.pci.bdg-tx-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
-
-asru pcibus/pcidev;
-fru pcibus/pcidev/pcifn/pcibus;
+prop error.io.pci.retry-to-d@pcibus/pcidev/pcifn { IS_BDG } (0)->
+    error.io.pci.serr-u@pcibus/pcidev/pcifn;
 
 /*
- * A faulty secondary side PCI bus may cause:
- *
- *  - tx-sec-ape:	the transfer of bad address/parity when the secondary
- *			bus is the originator.
- *  - tx-sec-pwdpe:	the transfer of bad data/parity during a posted write.
- *  - tx-sec-dwdpe:	the transfer of bad data/parity during a delayed write.
- *  - tx-sec-rdpe:	the transfer of bad data/parity during a read.
- *  - bdg-tx-sec-ape:	the transfer of bad address/parity when the secondary
- *			bus is the destination.
- *  - bdg-tx-sec-rdpe:	the transfer from the bridge of bad data/parity during a
- *			read.
- *  - bdg-tx-sec-pwdpe:	the transfer from the bridge of bad data/parity during a
- *			posted write.
- *  - bdg-tx-sec-dwdpe:	the transfer from the bridge of bad data/parity during a
- *			delayed write.
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * source- propagations.
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  */
-event fault.io.pci.bus@pcibus/pcidev/pcifn/pcibus,
-    FITrate=PCI_BUS_FIT, FRU=pcibus/pcidev/pcifn/pcibus,
-    ASRU=pcibus/pcidev;
+event error.io.pci.source-f-dpdata-w-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-w-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.source-f-dpdata-r-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-r-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.source-f-perr-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-perr-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.source-ape-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pcix.source-scpe-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.service.restored@pcibus/pcidev/pcifn;
+
+event ereport.io.service.lost@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.service.degraded@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.service.unaffected@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.service.restored@pcibus/pcidev/pcifn{within(30s)};
+
+prop error.io.pci.source-f-dpdata-w-u@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.service.lost@pcibus/pcidev/pcifn,
+    ereport.io.service.degraded@pcibus/pcidev/pcifn;
 
+prop error.io.pci.source-nf-dpdata-w-u@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn,
+    error.io.service.restored@pcibus/pcidev/pcifn;
+
+prop error.io.pci.source-f-dpdata-r-u@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.service.lost@pcibus/pcidev/pcifn,
+    ereport.io.service.degraded@pcibus/pcidev/pcifn;
+
+prop error.io.pci.source-nf-dpdata-r-u@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn,
+    error.io.service.restored@pcibus/pcidev/pcifn;
+
+prop error.io.pci.source-f-perr-u@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.service.lost@pcibus/pcidev/pcifn,
+    ereport.io.service.degraded@pcibus/pcidev/pcifn;
+
+prop error.io.pci.source-nf-perr-u@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn,
+    error.io.service.restored@pcibus/pcidev/pcifn;
 
-prop fault.io.pci.bus@pcibus/pcidev/pcifn/pcibus (0)->
-    error.io.pci.tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-sec-ape@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-sec-rdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-sec-pwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.bdg-tx-sec-dwdpe@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+prop error.io.pci.source-f-perr-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.source-f-perr-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pci.source-nf-perr-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.source-nf-perr-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pci.source-f-dpdata-w-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.source-f-dpdata-w-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pci.source-nf-dpdata-w-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.source-nf-dpdata-w-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pci.source-f-dpdata-r-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.source-f-dpdata-r-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pci.source-nf-dpdata-r-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.source-nf-dpdata-r-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pci.source-ape-u@pcibus/pcidev/pcifn (1)->
+    error.io.pci.source-ape-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pcix.source-scpe-u@pcibus/pcidev/pcifn (1)->
+    error.io.pcix.source-scpe-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Handling of leaf driver detected internal errors. Use serd engine if
+ * no service impact - otherwise fail immediately
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+event ereport.io.device.inval_state@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.device.no_response@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.device.stall@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.device.badint_limit@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.device.nf-device@pcibus/pcidev/pcifn;
+
+prop error.io.service.restored@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.service.lost@pcibus/pcidev/pcifn,
+    ereport.io.service.degraded@pcibus/pcidev/pcifn;
+
+prop error.io.service.restored@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.service.restored@pcibus/pcidev/pcifn;
+
+prop error.io.device.f-device@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.device.inval_state@pcibus/pcidev/pcifn,
+    ereport.io.device.no_response@pcibus/pcidev/pcifn,
+    ereport.io.device.stall@pcibus/pcidev/pcifn,
+    ereport.io.device.badint_limit@pcibus/pcidev/pcifn;
+
+prop error.io.device.f-device@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.service.lost@pcibus/pcidev/pcifn,
+    ereport.io.service.degraded@pcibus/pcidev/pcifn;
+
+engine serd.io.device.nonfatal@pcibus/pcidev/pcifn,
+    N=NONFATAL_COUNT, T=NONFATAL_TIME, method=persistent,
+    trip=ereport.io.device.nf-device@pcibus/pcidev/pcifn;
+
+event upset.io.device.nonfatal@pcibus/pcidev/pcifn,
+    engine=serd.io.device.nonfatal@pcibus/pcidev/pcifn;
+
+prop error.io.device.nf-device@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.device.nf-device@pcibus/pcidev/pcifn;
+
+prop error.io.device.nf-device@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    ereport.io.device.inval_state@pcibus/pcidev/pcifn,
+    ereport.io.device.no_response@pcibus/pcidev/pcifn,
+    ereport.io.device.stall@pcibus/pcidev/pcifn,
+    ereport.io.device.badint_limit@pcibus/pcidev/pcifn,
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn,
+    error.io.service.restored@pcibus/pcidev/pcifn;
+
+prop upset.io.device.nonfatal@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.device.inval_state@pcibus/pcidev/pcifn,
+    ereport.io.device.no_response@pcibus/pcidev/pcifn,
+    ereport.io.device.stall@pcibus/pcidev/pcifn,
+    ereport.io.device.badint_limit@pcibus/pcidev/pcifn;
+
+prop upset.io.device.nonfatal@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn,
+    error.io.service.restored@pcibus/pcidev/pcifn;
 
 /*
- * A defective device driver of a device that is off of a pci-pci bridge may
- * cause:
- *
- *  - tx-sec-pma:	the device to not respond to a posted transaction.
- *  - tx-sec-dma:	the device to not respond to a delayed transaction.
- *  - rx-sec-pta:	the device to receive a target abort during a posted
- *			transaction.
- *  - rx-sec-dta:	the device to receive a target abort during a delayed
- *			transaction.
- *  - rx-pma:		the device to send a bad address to the primary side bus
- *			during a posted transaction.
- *  - rx-dma:		the device to send a bad address to the primary side bus
- *			during a delayed transaction.
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Handling of pci express nonfatal errors (dpe). Use serd engine if
+ * no service impact - otherwise fail immediately
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+event ereport.io.pci.nf-dpe-d@pcibus/pcidev/pcifn;
+event ereport.io.pci.nf-dpe-u@pcibus/pcidev/pcifn;
+
+engine serd.io.pci.nf-dpe-u@pcibus/pcidev/pcifn,
+    N=NONFATAL_DPE_U_COUNT, T=NONFATAL_DPE_U_TIME, method=persistent,
+    trip=ereport.io.pci.nf-dpe-u@pcibus/pcidev/pcifn;
+
+event upset.io.pci.nf-dpe-u@pcibus/pcidev/pcifn,
+    engine=serd.io.pci.nf-dpe-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpe-u@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.pci.nf-dpe-u@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpe-u@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    error.io.pci.nonfatal-dpe-u@pcibus/pcidev/pcifn,
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn,
+    error.io.service.restored@pcibus/pcidev/pcifn;
+
+prop upset.io.pci.nf-dpe-u@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    error.io.pci.nonfatal-dpe-u@pcibus/pcidev/pcifn;
+
+prop upset.io.pci.nf-dpe-u@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn,
+    error.io.service.restored@pcibus/pcidev/pcifn;
+
+engine serd.io.pci.nf-dpe-d@pcibus/pcidev/pcifn,
+    N=NONFATAL_DPE_D_COUNT, T=NONFATAL_DPE_D_TIME, method=persistent,
+    trip=ereport.io.pci.nf-dpe-d@pcibus/pcidev/pcifn;
+
+event upset.io.pci.nf-dpe-d@pcibus/pcidev/pcifn,
+    engine=serd.io.pci.nf-dpe-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpe-d@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.pci.nf-dpe-d@pcibus/pcidev/pcifn;
+
+prop error.io.pci.nf-dpe-d@pcibus/pcidev/pcifn { IS_LEAF } (0)->
+    error.io.pci.nonfatal-dpe-d@pcibus/pcidev/pcifn,
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn,
+    error.io.service.restored@pcibus/pcidev/pcifn;
+
+prop upset.io.pci.nf-dpe-d@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    error.io.pci.nonfatal-dpe-d@pcibus/pcidev/pcifn;
+
+prop upset.io.pci.nf-dpe-d@pcibus/pcidev/pcifn { IS_LEAF } (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn,
+    error.io.service.restored@pcibus/pcidev/pcifn;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * stub unused ereports
+ * - ignore rx-spl as we can't tell what message it was (and we should have
+ *   diagnosed the problem anyway from standard pci ereports)
+ * - ignore sec-spl-or/sec-spl-dly as these aren't really faults (tuning info)
+ * - ignore unex-spl/sec-unex-spl
+ * - ignore ecc.ue ereports (we get everything we need from dpe/mdpe)
+ * - ignore ecc.ce ereports for now (could do serd on these)
+ * - ignore nr ereport
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  */
 
-event defect.io.pci.driver@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event ereport.io.pci.nr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.unex-spl@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.rx-spl@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-unex-spl@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-spl-or@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-spl-dly@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.ecc.ce-addr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.ecc.ce-attr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.ecc.ce-data@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.ecc.ue-addr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.ecc.ue-attr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.ecc.ue-data@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.s-ce@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.s-ue@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-ecc.ce-addr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-ecc.ce-attr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-ecc.ce-data@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-ecc.ue-addr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-ecc.ue-attr@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-ecc.ue-data@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-s-ce@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pcix.sec-s-ue@pcibus/pcidev/pcifn{within(5s)};
 
-prop defect.io.pci.driver@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (0)->
-    error.io.pci.tx-sec-pma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.tx-sec-dma@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.rx-sec-pta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.rx-sec-dta@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn,
-    error.io.pci.rx-pma@pcibus/pcidev/pcifn,
-    error.io.pci.rx-dma@pcibus/pcidev/pcifn;
+event upset.io.pcix.discard@pcibus/pcidev/pcifn;
+
+prop upset.io.pcix.discard@pcibus/pcidev/pcifn (1)->
+    ereport.io.pci.nr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.rx-spl@pcibus/pcidev/pcifn,
+    ereport.io.pcix.unex-spl@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-unex-spl@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-spl-or@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-spl-dly@pcibus/pcidev/pcifn,
+    ereport.io.pcix.ecc.ce-addr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.ecc.ce-attr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.ecc.ce-data@pcibus/pcidev/pcifn,
+    ereport.io.pcix.ecc.ue-addr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.ecc.ue-attr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.ecc.ue-data@pcibus/pcidev/pcifn,
+    ereport.io.pcix.s-ce@pcibus/pcidev/pcifn,
+    ereport.io.pcix.s-ue@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-ecc.ce-addr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-ecc.ce-attr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-ecc.ce-data@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-ecc.ue-addr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-ecc.ue-attr@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-ecc.ue-data@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-s-ce@pcibus/pcidev/pcifn,
+    ereport.io.pcix.sec-s-ue@pcibus/pcidev/pcifn;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/fm/eversholt/files/common/pciex.esc	Sun Apr 23 15:26:28 2006 -0700
@@ -0,0 +1,2446 @@
+/*
+ * 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"
+
+#pragma dictionary "PCIEX"
+
+/*
+ * FIT rates - assume leaf devices are somewhat less reliable than
+ * root complexes, switches and bridges
+ */
+#define PCIEX_RC_FIT 500
+#define PCIEX_SW_FIT 500
+#define PCIEX_BDG_FIT 500
+#define PCIEX_DEV_FIT 1000
+#define PCIEX_RC_INV_FIT 500
+#define PCIEX_DEV_INV_FIT 1000
+#define PCIEX_RC_NR_FIT 500
+#define PCIEX_SW_NR_FIT 500
+#define PCIEX_BDG_NR_FIT 500
+#define PCIEX_DEV_NR_FIT 1000
+#define PCIEX_BUS_FIT 500
+#define PCIEX_BUS_NR_FIT 500
+
+/*
+ * SERD parameters.
+ * 
+ * PCI Express correctable link errors are automatically handled by the
+ * hardware, so have relatively little impact and we can allow quite a
+ * high frequency. We will also be quite conservative about nonfatal internal
+ * errors reported by the driver.
+ *
+ * Nonfatal dpe errors (ptlp/ecrc errors) have to be recovered by the hardened
+ * driver which may cause intermittant performance/responsiveness problems, so
+ * we have tighter serd parameters for these. These are most likely errors in
+ * buffers/caches within devices and bridges, so use similar rates to cpu
+ * data cache parity errors.
+ */
+#define CORRLINK_COUNT 6
+#define CORRLINK_TIME 2h
+#define NONFATAL_COUNT 6
+#define NONFATAL_TIME 2h
+#define NONFATAL_DPE_U_COUNT 3
+#define NONFATAL_DPE_U_TIME 168h
+#define NONFATAL_DPE_D_COUNT 3
+#define NONFATAL_DPE_D_TIME 168h
+
+/*
+ * if the source-id payload is valid, then check it matches
+ */
+#define SOURCE_ID_MATCHES_BDF \
+	(payloadprop("source-valid") == 0 || \
+	payloadprop("source-id") == ((b << 8) | (d << 3) | f))
+
+/*
+ * for request from device behind pci-express/pci bridge, source-id could be
+ * either the originator's bdf or the bus number of the secondary bus of the
+ * bridge with dev/fn both 0 (if for various reasons the bridge takes ownership
+ * of the transaction)
+ */
+#define SOURCE_ID_MATCHES_BDF_OR_B \
+	(payloadprop("source-valid") == 0 || \
+	payloadprop("source-id") == ((b << 8) | (d << 3) | f) || \
+	payloadprop("source-id") == (b << 8))
+
+#define SOURCE_ID_MATCHES_OWN_BDF \
+	(payloadprop("source-valid") == 1 && \
+	payloadprop("source-id") == (confprop(asru(pciexrc), "BDF") + 0))
+
+/*
+ * Other useful macros. These use the EXCAP property (PCI Express Capabilities
+ * register) to find the type for PCI Express devices, and the CLASS-CODE
+ * property (PCI Class Code register) for to find the type of PCI devices behind
+ * a PCI Express-PCI bridge - note that 60400 and 60401 are defined as PCI-PCI
+ * bridges, everything else is consider a PCI leaf device.
+ */
+#define BDF_IS_UNDER_RC \
+	is_under(pciexrc<>, pciexbus[b]/pciexdev[d]/pciexfn[f])
+
+#define PCIBDF_IS_UNDER_RC \
+	is_under(pciexrc<>, pcibus[b]/pcidev[d]/pcifn[f])
+
+#define IMM_PCIBDF_IS_UNDER_RC \
+	is_under(pciexrc<>, pciexfn/pcibus[b]/pcidev[d]/pcifn[f])
+
+#define PCIBDF_IS_UNDER_DEV \
+	is_under(pciexbus/pciexdev/pciexfn, pcibus[b]/pcidev[d]/pcifn[f])
+
+#define IS_SWD \
+	(confprop(asru(pciexbus/pciexdev/pciexfn), "EXCAP") == "pciexswd")
+
+#define IS_SWU \
+	(confprop(asru(pciexbus/pciexdev/pciexfn), "EXCAP") == "pciexswu")
+
+#define IS_LEAF \
+	(confprop(asru(pciexbus/pciexdev/pciexfn), "EXCAP") == "pciexdev")
+
+#define	IS_PCI_LEAF \
+	(confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") != "60400" && \
+	confprop(asru(pcibus/pcidev/pcifn), "CLASS-CODE") != "60401")
+
+#define	BDF_IS_PCI_LEAF \
+	(confprop(asru(pcibus[b]/pcidev[d]/pcifn[f]),"CLASS-CODE") != \
+	"60400" && \
+	confprop(asru(pcibus[b]/pcidev[d]/pcifn[f]), "CLASS-CODE") != "60401")
+
+#define	BDF_IS_PCI_IMM_LEAF \
+	(confprop(asru(pciexfn/pcibus[b]/pcidev[d]/pcifn[f]),"CLASS-CODE") != \
+	"60400" && \
+	confprop(asru(pciexfn/pcibus[b]/pcidev[d]/pcifn[f]), "CLASS-CODE") != \
+	"60401")
+
+#define IS_BDG \
+	(confprop(asru(pciexbus/pciexdev/pciexfn), "EXCAP") == "pcibus")
+
+#define BDF_IS_LEAF \
+	(confprop(asru(pciexbus[b]/pciexdev[d]/pciexfn[f]), "EXCAP") == \
+	"pciexdev")
+
+/*
+ * define faults
+ */
+asru pciexrc;
+fru pciexrc;
+asru pciexbus/pciexdev/pciexfn;
+fru pciexbus/pciexdev;
+fru pciexbus;
+asru pciexbus;
+
+event fault.io.pciex.device-interr@pciexbus/pciexdev/pciexfn,
+	FITrate=PCIEX_DEV_FIT, FRU=pciexbus/pciexdev,
+	ASRU=pciexbus/pciexdev/pciexfn;
+
+event fault.io.pciex.device-interr@pciexrc,
+	FITrate=PCIEX_RC_FIT, FRU=pciexrc, ASRU=pciexrc;
+
+event fault.io.pciex.device-invreq@pciexbus/pciexdev/pciexfn,
+	FITrate=PCIEX_DEV_INV_FIT, FRU=pciexbus/pciexdev,
+	ASRU=pciexbus/pciexdev/pciexfn;
+
+event fault.io.pciex.device-invreq@pciexrc,
+	FITrate=PCIEX_RC_INV_FIT, FRU=pciexrc, ASRU=pciexrc;
+
+event fault.io.pciex.device-noresp@pciexbus/pciexdev/pciexfn,
+	FITrate=PCIEX_DEV_NR_FIT, FRU=pciexbus/pciexdev,
+	ASRU=pciexbus/pciexdev/pciexfn;
+
+event fault.io.pciex.device-noresp@pciexrc,
+	FITrate=PCIEX_RC_NR_FIT, FRU=pciexrc, ASRU=pciexrc;
+
+event fault.io.pciex.bus-noresp@pciexbus/pciexdev/pciexfn,
+        FITrate=PCIEX_BUS_NR_FIT, FRU=pciexbus, ASRU=pciexbus/pciexdev/pciexfn;
+
+event fault.io.pciex.bus-linkerr@pciexbus/pciexdev/pciexfn,
+        FITrate=PCIEX_BUS_FIT, FRU=pciexbus, ASRU=pciexbus/pciexdev/pciexfn;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * serd engine for correctable link errors
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+event error.io.pciex.corrlink@pciexbus;
+event error.io.pciex.corrlink@pciexrc/pciexbus;
+event error.io.pciex.corrlink@pciexbus/pciexdev/pciexfn/pciexbus;
+event ereport.io.pciex.corrlink_trip@pciexbus;
+
+engine serd.io.pciex.corrlink@pciexbus,
+    N=CORRLINK_COUNT, T=CORRLINK_TIME, method=persistent,
+    trip=ereport.io.pciex.corrlink_trip@pciexbus;
+
+event upset.io.pciex.corrlink@pciexbus,
+    engine=serd.io.pciex.corrlink@pciexbus;
+
+prop upset.io.pciex.corrlink@pciexbus (1)->
+    error.io.pciex.corrlink@pciexbus;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Handling of leaf driver detected internal errors. Use serd engine if
+ * no service impact - otherwise fail immediately
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+event ereport.io.device.inval_state@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.device.no_response@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.device.stall@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.device.badint_limit@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.service.lost@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.service.degraded@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.service.restored@pciexbus/pciexdev/pciexfn{within(30s)};
+event ereport.io.device.nf-device@pciexbus/pciexdev/pciexfn;
+
+event error.io.service.restored@pciexbus/pciexdev/pciexfn;
+event error.io.device.nf-device@pciexbus/pciexdev/pciexfn;
+event error.io.device.f-device@pciexbus/pciexdev/pciexfn;
+
+prop error.io.device.f-device@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.device.inval_state@pciexbus/pciexdev/pciexfn,
+    ereport.io.device.no_response@pciexbus/pciexdev/pciexfn,
+    ereport.io.device.stall@pciexbus/pciexdev/pciexfn,
+    ereport.io.device.badint_limit@pciexbus/pciexdev/pciexfn;
+
+prop error.io.device.f-device@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn,
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn;
+
+engine serd.io.device.nonfatal@pciexbus/pciexdev/pciexfn,
+    N=NONFATAL_COUNT, T=NONFATAL_TIME, method=persistent,
+    trip=ereport.io.device.nf-device@pciexbus/pciexdev/pciexfn;
+
+event upset.io.device.nonfatal@pciexbus/pciexdev/pciexfn,
+    engine=serd.io.device.nonfatal@pciexbus/pciexdev/pciexfn;
+
+prop error.io.device.nf-device@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.device.nf-device@pciexbus/pciexdev/pciexfn;
+
+prop error.io.device.nf-device@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.device.inval_state@pciexbus/pciexdev/pciexfn,
+    ereport.io.device.no_response@pciexbus/pciexdev/pciexfn,
+    ereport.io.device.stall@pciexbus/pciexdev/pciexfn,
+    ereport.io.device.badint_limit@pciexbus/pciexdev/pciexfn,
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn,
+    error.io.service.restored@pciexbus/pciexdev/pciexfn;
+
+prop upset.io.device.nonfatal@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.device.inval_state@pciexbus/pciexdev/pciexfn,
+    ereport.io.device.no_response@pciexbus/pciexdev/pciexfn,
+    ereport.io.device.stall@pciexbus/pciexdev/pciexfn,
+    ereport.io.device.badint_limit@pciexbus/pciexdev/pciexfn;
+
+prop upset.io.device.nonfatal@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn,
+    error.io.service.restored@pciexbus/pciexdev/pciexfn;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Handling of pci express nonfatal errors (ptlp/ecrc). Use serd engine if
+ * no service impact - otherwise fail immediately
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+event ereport.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn;
+event ereport.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn;
+
+event error.io.pciex.flt-f-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-ecrcreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-ecrccomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-poisreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-poiscomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-ecrcreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-ecrccomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-poisreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-poiscomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-poisreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-poiscomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-ecrcreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-ecrccomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-poisreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-poiscomp-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-f-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-f-ecrcreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-f-ecrccomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-f-poisreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-f-poiscomp-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-f-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-f-ecrcreq-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-f-ecrccomp-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-f-poisreq-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-f-poiscomp-d@pciexbus/pciexdev/pciexfn;
+
+engine serd.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn,
+    N=NONFATAL_DPE_U_COUNT, T=NONFATAL_DPE_U_TIME, method=persistent,
+    trip=ereport.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn;
+
+event upset.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn,
+    engine=serd.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.flt-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-poisreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-poiscomp-u@pciexbus/pciexdev/pciexfn;
+
+prop upset.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-poisreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-poiscomp-u@pciexbus/pciexdev/pciexfn;
+
+engine serd.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn,
+    N=NONFATAL_DPE_D_COUNT, T=NONFATAL_DPE_D_TIME, method=persistent,
+    trip=ereport.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn;
+
+event upset.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn,
+    engine=serd.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.flt-nf-ecrcreq-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-ecrccomp-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-poisreq-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-poiscomp-d@pciexbus/pciexdev/pciexfn;
+
+prop upset.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-nf-ecrcreq-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-ecrccomp-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-poisreq-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-nf-poiscomp-d@pciexbus/pciexdev/pciexfn;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * A faulty PCI Express hostbridge (root complex) may cause:
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * - nr-d:		the device not to respond to a valid upstream request
+ * - ca-d:		the device to completer abort a valid upstream request
+ * - mtlp-d:		a malformed tlp to be transmitted downstream
+ * - badreq-d:		a bad downstream request - not CRC error (may cause
+ *			completer to respond with ur or ca)
+ * - ecrcreq-d:		TLP with end-to-end CRC error transmitted downstream
+ * - ecrccomp-d:	TLP with end-to-end CRC error transmitted downstream
+ * - poisreq-d:		poisoned request transmitted downstream
+ * - poiscomp-d:	poisoned completion transmitted downstream
+ * - corrlink:		correctable link or physical level error
+ * - fatlink:		fatal link or physical level error
+ */
+event error.io.pciex.nr-d@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ca-d@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.mtlp-d@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.badreq-d@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-d@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-d@pciexrc/pciexbus/pciexdev/pciexfn;
+event ereport.io.pciex.corrlink_trip@pciexrc/pciexbus;
+event error.io.pciex.fatlink@pciexrc/pciexbus/pciexdev/pciexfn;
+
+prop fault.io.pciex.device-noresp@pciexrc (1)->
+    error.io.pciex.nr-d@pciexrc/pciexbus<>/pciexdev<>/pciexfn<>;
+
+prop fault.io.pciex.device-invreq@pciexrc (1)->
+    error.io.pciex.badreq-d@pciexrc/pciexbus<>/pciexdev<>/pciexfn<>;
+
+prop fault.io.pciex.device-interr@pciexrc (1)->
+    error.io.pciex.flt-nf-d@pciexrc/pciexbus<>/pciexdev<>/pciexfn<>,
+    error.io.pciex.flt-f-d@pciexrc/pciexbus<>/pciexdev<>/pciexfn<>,
+    error.io.pciex.ca-d@pciexrc/pciexbus<>/pciexdev<>/pciexfn<>,
+    error.io.pciex.mtlp-d@pciexrc/pciexbus<>/pciexdev<>/pciexfn<>,
+    ereport.io.pciex.corrlink_trip@pciexrc/pciexbus<>,
+    error.io.pciex.fatlink@pciexrc/pciexbus<>/pciexdev<>/pciexfn<>;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * A faulty PCI Express leaf device or upstream switch port may cause:
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * - nr-u:		the device not to respond to a valid downstream request
+ * - ca-u:		the device to completer abort a valid downstream request
+ * - badreq-u:		a bad upstream request - not CRC error (may cause
+ *			completer to respond with ur or ca) - leaf only
+ * - mtlp-u:		a malformed tlp transmitted upstream - leaf only
+ * - ecrcreq-u:		request with end-to-end CRC error transmitted upstream
+ * - ecrccomp-u:	compl with end-to-end CRC error transmitted upstream
+ * - poisreq-u:		poisoned request transmitted upstream
+ * - poiscomp-u:	poisoned completion transmitted upstream
+ * - device:		internal error reported by leaf device
+ * - corrlink:		correctable link or physical level error
+ * - fatlink:		fatal link or physical level error
+ */
+
+event error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.mtlp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-badreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn;
+
+prop fault.io.pciex.device-noresp@pciexbus/pciexdev/pciexfn { IS_LEAF } (1)->
+    error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn;
+
+prop fault.io.pciex.device-noresp@pciexbus/pciexdev/pciexfn { IS_SWU } (1)->
+    error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn;
+
+prop fault.io.pciex.device-invreq@pciexbus/pciexdev/pciexfn { IS_LEAF } (1)->
+    error.io.pciex.flt-badreq-u@pciexbus/pciexdev/pciexfn;
+
+prop fault.io.pciex.device-interr@pciexbus/pciexdev/pciexfn { IS_SWU } (1)->
+    error.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-f-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.corrlink_trip@pciexbus,
+    error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn;
+
+prop fault.io.pciex.device-interr@pciexbus/pciexdev/pciexfn { IS_LEAF } (1)->
+    error.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-f-u@pciexbus/pciexdev/pciexfn,
+    error.io.device.nf-device@pciexbus/pciexdev/pciexfn,
+    error.io.device.f-device@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.mtlp-u@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.corrlink_trip@pciexbus,
+    error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * A faulty PCI Express downstream switch port may cause
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * - nr-d:		the device not to respond to an upstream request
+ * - ca-d:		the device to completer abort an upstream request
+ * - ecrcreq-d:		TLP with end-to-end CRC error transmitted upstream
+ * - ecrccomp-d:	TLP with end-to-end CRC error transmitted upstream
+ * - poisreq-d:		poisoned request transmitted upstream
+ * - poiscomp-d:	poisoned completion transmitted upstream
+ * - corrlink:		correctable link or physical level error
+ * - fatlink:		fatal link or physical level error
+ */
+
+event error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-ca-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-f-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event ereport.io.pciex.corrlink_trip@pciexbus/pciexdev/pciexfn/pciexbus;
+event error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+
+prop fault.io.pciex.device-noresp@pciexbus/pciexdev/pciexfn { IS_SWD } (1)->
+    error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+
+prop fault.io.pciex.device-interr@pciexbus/pciexdev/pciexfn { IS_SWD } (1)->
+    error.io.pciex.flt-ca-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>,
+    error.io.pciex.flt-nf-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>,
+    error.io.pciex.flt-f-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>,
+    ereport.io.pciex.corrlink_trip@pciexbus/pciexdev/pciexfn/pciexbus<>,
+    error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * A faulty PCIEX bus may cause:
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * - nr-u:		a device to not respond because the link is down
+ * - nr-d:		a device to not respond because the link is down
+ * - corrlink:		correctable link or physical level error
+ * - fatlink:		fatal link or physical level error
+ */
+
+event error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn;
+
+prop fault.io.pciex.bus-noresp@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG },
+    error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG };
+
+prop fault.io.pciex.bus-linkerr@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.corrlink_trip@pciexbus,
+    error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG };
+
+/*
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * A faulty pciex-pci bridge may cause
+ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * The following errors to propagate onto the PCI Express fabric
+ * - nr-u:		the device not to respond to a valid downstream request
+ * - ca-u:		the device to completer abort a valid downstream request
+ * - ecrcreq-u:		request with end-to-end CRC error transmitted upstream
+ * - ecrccomp-u:	compl with end-to-end CRC error transmitted upstream
+ * - poisreq-u:		poisoned request transmitted upstream
+ * - poiscomp-u:	poisoned completion transmitted upstream
+ * - corrlink:		correctable link or physical level error upstream
+ * - fatlink:		fatal link or physical level error upstream
+ * - sec-interr:	internal error on pci express to pci bridge
+ *
+ * And the following errors to propagate onto the secondary pci or pci/x bus
+ * (these will be handled by code in the pci.esc file).
+ * - nr-pw-d:		the device not to respond to a valid upstream request
+ * - nr-drw-d:		the device not to respond to a valid upstream request
+ * - retry-to-d:	failure to retry an downstream delayed request
+ * - ta-pw-d:		the device responds with a ta to a valid upstream
+ *			request
+ * - ta-drw-d:		the device responds with a ta to a valid upstream
+ *			request
+ * - ape-d:	address/parity to get corrupted during downstream transmission.
+ * - dpe-d:	data/parity to get corrupted during downstream transmission.
+ * - scpe-d:	split completion to get corrupted during downstream transmission
+ */
+
+event error.io.pci.ape-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.f-dpe-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpe-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.retry-to-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.nr-pw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.nr-drw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.ta-pw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.ta-drw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pcix.scpe-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.sec-interr@pciexbus/pciexdev/pciexfn;
+event ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn{within(5s)};
+
+prop fault.io.pciex.device-noresp@pciexbus/pciexdev/pciexfn { IS_BDG } (1)->
+    error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn,
+    error.io.pci.retry-to-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.nr-pw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.nr-drw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+prop fault.io.pciex.device-interr@pciexbus/pciexdev/pciexfn { IS_BDG } (1)->
+    error.io.pciex.flt-nf-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-f-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.mtlp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.sec-interr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.corrlink_trip@pciexbus,
+    error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn,
+    error.io.pci.ta-pw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.ta-drw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.ape-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pcix.scpe-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.f-dpe-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.nf-dpe-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+prop fault.io.pciex.device-interr@pciexbus/pciexdev/pciexfn { IS_BDG } (0)->
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * declarations
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+event error.io.pciex.fatal@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ur-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ur-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ur-u@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nr-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nr-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nr-u@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ca-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ca-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ca-u@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.mtlp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.sw-mtlp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.mtlp-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.flt-ca-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ca-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ca-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.poisreq-d@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.sw-poisreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.poiscomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ecrcreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.sw-ecrcreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ecrccomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.badreq-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.badreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.badreq-u@pciexbus/pciexdev;
+event error.io.pciex.badreq-u@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ecrcreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ecrcreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-f-ecrcreq-u@pcibus/pcidev/pcifn;
+event error.io.pciex.source-nf-ecrcreq-u@pcibus/pcidev/pcifn;
+event error.io.pciex.source-f-ecrcreq-u@pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-nf-ecrcreq-u@pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.ecrccomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.ecrccomp-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-f-ecrccomp-u@pcibus/pcidev/pcifn;
+event error.io.pciex.source-nf-ecrccomp-u@pcibus/pcidev/pcifn;
+event error.io.pciex.source-f-ecrccomp-u@pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-nf-ecrccomp-u@pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.poiscomp-u@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-f-poiscomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-nf-poiscomp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pci.source-f-dpdata-r-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-r-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.source-f-dpdata-r-u@pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-r-u@pcibus/pcidev/pcifn;
+event error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.poisreq-u@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-f-poisreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pci.source-f-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.source-f-dpdata-w-u@pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-w-u@pcibus/pcidev/pcifn;
+event error.io.pciex.source-f-poisreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-mtlp-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-mtlp-u@pcibus/pcidev/pcifn;
+event error.io.pci.badreq-pw-u@pcibus/pcidev/pcifn;
+event error.io.pci.badreq-drw-u@pcibus/pcidev/pcifn;
+event error.io.pci.badreq-pw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.badreq-drw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn;
+event error.io.pci.target-rta-d@pciexbus/pciexdev/pciexfn;
+event error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-poisreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-poisreq-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-lf-poisreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-poiscomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-poiscomp-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-lf-poiscomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.f-ecrcreq-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pciex.f-ecrcreq-d@pcibus/pcidev/pcifn;
+event error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.nf-ecrcreq-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pciex.nf-ecrcreq-d@pcibus/pcidev/pcifn;
+event error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.f-ecrccomp-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pciex.f-ecrccomp-d@pcibus/pcidev/pcifn;
+event error.io.pciex.f-lf-ecrccomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.nf-ecrccomp-d@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pciex.nf-ecrccomp-d@pcibus/pcidev/pcifn;
+event error.io.pciex.f-lf-poisreq-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.fatal-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nonfatal-u@pciexbus/pciexdev/pciexfn;
+event error.io.pciex.fatal-u@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nonfatal-u@pciexrc/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.fatal-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.nonfatal-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.service.restored@pcibus/pcidev/pcifn;
+
+event ereport.io.pci.ma@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.rta@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.sta@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.service.lost@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.service.degraded@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.service.unaffected@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.pciex.dl.dllp@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.dl.btlp@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.dl.bdllp@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.dl.rto@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.dl.rnr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.pl.re@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.pl.te@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.tl.fcp@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.tl.rof@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.tl.mtlp@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.tl.ur@pciexfn{within(5s)};
+event ereport.io.pciex.tl.ca@pciexfn{within(5s)};
+event ereport.io.pciex.tl.ur@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.tl.ca@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.tl.uc@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.tl.cto@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.dl.dllp@pciexrc{within(5s)};
+event ereport.io.pciex.dl.btlp@pciexrc{within(5s)};
+event ereport.io.pciex.dl.bdllp@pciexrc{within(5s)};
+event ereport.io.pciex.dl.rto@pciexrc{within(5s)};
+event ereport.io.pciex.dl.rnr@pciexrc{within(5s)};
+event ereport.io.pciex.pl.re@pciexrc{within(5s)};
+event ereport.io.pciex.pl.te@pciexrc{within(5s)};
+event ereport.io.pciex.tl.fcp@pciexrc{within(5s)};
+event ereport.io.pciex.tl.rof@pciexrc{within(5s)};
+event ereport.io.pciex.tl.mtlp@pciexrc{within(5s)};
+event ereport.io.pciex.tl.ur@pciexrc{within(5s)};
+event ereport.io.pciex.tl.ca@pciexrc{within(5s)};
+event ereport.io.pciex.tl.ptlp@pciexrc{within(5s)};
+event ereport.io.pciex.tl.ecrc@pciexrc{within(5s)};
+event ereport.io.pciex.tl.cto@pciexrc{within(5s)};
+event ereport.io.pci.sec-ma@pciexrc{within(5s)};
+event ereport.io.pci.sec-mdpe@pciexrc{within(5s)};
+event ereport.io.pci.sec-dpe@pciexrc{within(5s)};
+event ereport.io.pci.sec-rta@pciexrc{within(5s)};
+event ereport.io.pci.sec-sta@pciexrc{within(5s)};
+event ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.sec-rserr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.sserr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.sec-rserr@pciexrc{within(5s)};
+event ereport.io.pciex.rc.fe-msg@pciexrc{within(5s)};
+event ereport.io.pciex.rc.nfe-msg@pciexrc{within(5s)};
+event ereport.io.pciex.bdg.sec-interr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-ude@pciexbus/pciexdev/pciexfn{within(5s)};
+
+/*
+ * handling of fatal and nonfatal error messages propagated up to root complex
+ *
+ * Use these for errors reported by root-complex on behalf of another device.
+ * Can use source-id payload to identify where the message came from.
+ */
+prop error.io.pciex.fatal@pciexbus[b]/pciexdev[d]/pciexfn[f] (0)->
+    ereport.io.pciex.rc.fe-msg@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pciex.fatal@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.fatal-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.fatal-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sserr@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.fatal-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.fatal-u@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-rserr@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.fatal-u@pciexrc/pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-rserr@pciexrc;
+
+prop error.io.pciex.nonfatal@pciexbus[b]/pciexdev[d]/pciexfn[f] (0)->
+    ereport.io.pciex.rc.nfe-msg@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nonfatal-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nonfatal-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sserr@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nonfatal-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.nonfatal-u@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-rserr@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nonfatal-u@pciexrc/pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-rserr@pciexrc;
+
+/*
+ * link-level errors - could generate ereports at either end of link
+ * 
+ * can use may propagations here as these ereports are only seen for these
+ * faults.
+ */
+prop error.io.pciex.corrlink@pciexbus (0)->
+    ereport.io.pciex.dl.btlp@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG },
+    ereport.io.pciex.dl.bdllp@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG },
+    ereport.io.pciex.dl.rto@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG },
+    ereport.io.pciex.dl.rnr@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG },
+    ereport.io.pciex.pl.re@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG };
+
+prop error.io.pciex.corrlink@pciexbus/pciexdev/pciexfn/pciexbus (0)->
+    ereport.io.pciex.dl.btlp@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.dl.bdllp@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.dl.rto@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.dl.rnr@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.pl.re@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.corrlink@pciexrc/pciexbus (0)->
+    ereport.io.pciex.dl.btlp@pciexrc,
+    ereport.io.pciex.dl.bdllp@pciexrc,
+    ereport.io.pciex.dl.rto@pciexrc,
+    ereport.io.pciex.dl.rnr@pciexrc,
+    ereport.io.pciex.pl.re@pciexrc;
+
+prop error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.fatal@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG };
+
+prop error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.dl.dllp@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG },
+    ereport.io.pciex.tl.fcp@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG },
+    ereport.io.pciex.tl.rof@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG };
+
+prop error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn
+(0)->
+    error.io.pciex.fatal@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.fatlink@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.dl.dllp@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.pl.te@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.tl.fcp@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.tl.rof@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.fatlink@pciexrc/pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.dl.dllp@pciexrc,
+    ereport.io.pciex.pl.te@pciexrc,
+    ereport.io.pciex.tl.fcp@pciexrc,
+    ereport.io.pciex.tl.rof@pciexrc;
+
+/*
+ * bridge internal error
+ */
+prop error.io.pciex.sec-interr@pciexbus/pciexdev/pciexfn (2) ->
+    error.io.pciex.fatal@pciexbus/pciexdev/pciexfn { IS_BDG },
+    ereport.io.pciex.bdg.sec-interr@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+/*
+ * downstream poisoned request
+ *
+ * - poisreq-d cascades down to the leaf device/bridge and any switch ports
+ *   on route must raise a ptlp ereport while any switch ports forwarding
+ *   the poisoned request must raise sec-mdpe ereports. The originator of the
+ *   poisoning (be it root complex or downstream port of a switch) also raises
+ *   sec-mdpe. A hardened leaf driver will also raise ptlp. A target-mdpe
+ *   cascades down to the leaf (which may be a pci device beyond the bridge).
+ *
+ * Additionally, the leaf/bridge may treat the request as a ur, which the
+ * root complex will see and report an ma. Use flt-ur-u to represent this.
+ * Note that sw-poisreq-d is to handle the case where the switch is actually
+ * the target of the packet (config request etc).
+ *
+ * The fault can always be recognized and the source identified using the ptlp
+ * and sec-mdpe ereports.
+ */
+prop error.io.pciex.flt-f-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.f-poisreq-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.sw-poisreq-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.f-poisreq-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.f-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-poisreq-d@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.f-lf-poisreq-d@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.f-lf-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-lf-poisreq-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn,
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn,
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-nf-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    error.io.service.restored@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.service.restored@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn,
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn;
+
+prop error.io.service.restored@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.restored@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.poisreq-d@pciexrc/pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.sec-mdpe@pciexrc;
+
+prop error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+prop error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn { IS_SWU || IS_BDG },
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_SWU || IS_BDG };
+
+prop error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.sw-poisreq-d@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+prop error.io.pciex.sw-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+/*
+ * downstream poisoned completion
+ *
+ * - poiscomp-d cascades down to the leaf device/bridge and any switch ports on
+ *   route must raise ptlp and mdpe ereports.  A hardened leaf driver will also
+ *   raise pltp and mdpe. For non-hardened leaf devices, no ptlp/mdpe may be
+ *   reported, and though we should still see a nonfatal error reported from
+ *   the root complex identifying the leaf device, we won't actually be informed
+ *   that the error was an ptlp.
+ */
+prop error.io.pciex.flt-f-poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.f-poiscomp-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.f-poiscomp-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.f-poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.poiscomp-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-poiscomp-d@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.f-lf-poiscomp-d@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.f-lf-poiscomp-d@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-lf-poiscomp-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn,
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn,
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-nf-poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.poiscomp-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    error.io.service.restored@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.poiscomp-d@pciexbus/pciexdev/pciexfn (3)->
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn { IS_BDG },
+    ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn { IS_BDG },
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop error.io.pciex.poiscomp-d@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn { IS_SWU },
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+prop error.io.pciex.poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn { IS_SWU },
+    ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+prop error.io.pciex.poiscomp-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pci.dpe@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+/*
+ * downstream request with ecrc error.
+ *
+ * - ecrcreq-d cascades down to the leaf device/bridge and any switches on
+ *   route can optionally raise an ecrc ereport. A hardened leaf driver may also
+ *   raise ecrc. For non-hardened leaf devices, no ecrc may be reported, and
+ *   though we should still see a nonfatal error reported from the root complex
+ *   identifying the leaf device, we won't actually be informed that the error
+ *   was an ecrc.
+ *
+ * Additionally, as the leaf/bridge will just throw away the packet, we should
+ * eventually get a cto at the root complex - so use an flt-nr-u at the pciex
+ * leaf or bridge to get the appropriate behaviour. For the case where the leaf
+ * driver wasn't hardened we may be able to identify the leaf device (and
+ * therefore any intermediate switches which might have caused the problem)
+ * either via a target-ma ereport if available or via the nonfatal error
+ * reported from the root complex identifying the leaf device. The combination
+ * of a nonfatal error reported from the root complex and a cto from the root
+ * complex is sufficient to positively identify this case.
+ *
+ * Note that sw-ecrcreq-d is to handle the case where the switch is actually
+ * the target of the packet (config request etc).
+ */
+prop error.io.pciex.flt-f-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.sw-ecrcreq-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>; 
+
+prop error.io.pciex.f-ecrcreq-d@pcibus/pcidev/pcifn (1)->
+    error.io.pciex.f-ecrcreq-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>; 
+
+prop error.io.pciex.f-ecrcreq-d@pcibus/pcidev/pcifn (0)->
+    ereport.io.service.lost@pcibus/pcidev/pcifn { IS_PCI_LEAF },
+    ereport.io.service.degraded@pcibus/pcidev/pcifn { IS_PCI_LEAF };
+
+prop error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ecrcreq-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-ecrcreq-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.flt-nf-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>; 
+
+prop error.io.pciex.nf-ecrcreq-d@pcibus/pcidev/pcifn (1)->
+    error.io.pciex.nf-ecrcreq-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>; 
+
+prop error.io.pciex.nf-ecrcreq-d@pcibus/pcidev/pcifn (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn { IS_PCI_LEAF },
+    error.io.service.restored@pcibus/pcidev/pcifn { IS_PCI_LEAF };
+
+prop error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ecrcreq-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.nf-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    error.io.service.restored@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop error.io.pciex.ecrcreq-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn { IS_SWU || IS_SWD };
+
+prop error.io.pciex.sw-ecrcreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+/*
+ * downstream completion with ecrc error.
+ *
+ * - ecrccomp-d cascades down to the leaf device/bridge and any switches on
+ *   route can optionally raise an ecrc ereport. A hardened leaf driver may
+ *   also raise ecrc. For non-hardened leaf devices, no ecrc may be reported,
+ *   and though we should still see a nonfatal error reported from the root
+ *   complex identifying the leaf device, we won't actually be informed that
+ *   the error was an ecrc.
+ *
+ * Additionally, as the leaf/bridge will just throw away the packet, we should
+ * eventually get a cto. Note the leaf ereports are optional (ie in case driver
+ * not hardened) but if we get both ecrc and cto we need to distinguish from
+ * cto only which would be an nr-d.
+ */
+prop error.io.pciex.flt-f-ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>; 
+
+prop error.io.pciex.f-ecrccomp-d@pcibus/pcidev/pcifn (1)->
+    error.io.pciex.f-ecrccomp-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>; 
+
+prop error.io.pciex.f-ecrccomp-d@pcibus/pcidev/pcifn (0)->
+    ereport.io.service.lost@pcibus/pcidev/pcifn { IS_PCI_LEAF },
+    ereport.io.service.degraded@pcibus/pcidev/pcifn { IS_PCI_LEAF };
+
+prop error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ecrccomp-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-ecrccomp-d@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.f-lf-ecrccomp-d@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.f-lf-ecrccomp-d@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.tl.cto@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-lf-ecrccomp-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-nf-ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>; 
+
+prop error.io.pciex.nf-ecrccomp-d@pcibus/pcidev/pcifn (1)->
+    error.io.pciex.nf-ecrccomp-d@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>; 
+
+prop error.io.pciex.nf-ecrccomp-d@pcibus/pcidev/pcifn (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn { IS_PCI_LEAF },
+    error.io.service.restored@pcibus/pcidev/pcifn { IS_PCI_LEAF };
+
+prop error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ecrccomp-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.pciex.tl.cto@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.nf-ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    error.io.service.restored@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.ecrccomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.ecrccomp-d@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn { IS_BDG },
+    error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop error.io.pciex.ecrccomp-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn { IS_SWU || IS_SWD };
+
+/*
+ * upstream poisoned request
+ *
+ * - flt-poisreq-u is just on the pciex node which generated the fault (if the
+ *   fault was generated by a pciex node and not a child pci node).
+ * - source-poisreq-u cascades down to at least one leaf device (pciex or pci),
+ *   whose bdf must match the source-id in the payload of the ereport generated
+ *   from the root complex. Note that pci.esc rules have to generate the
+ *   source-poisreq-u so we limit it to the faulty node or nodes underneath the
+ *   faulty node.
+ * - poisreq-u cascades up to the root complex and any switch ports on
+ *   route will raise a ptlp ereport, while any upstream devices generating
+ *   or forwarding the poisoned packed will raise an mdpe ereport. The root
+ *   complex should also report a ptlp.
+ *
+ * Additionally, as the root complex may treat the request as a ur, which the
+ * leaf/bridge will see (and if hardened report) as an ma (including sending a 
+ * ta onto the child pci bus if this was a delayed write).
+ *
+ * We can always recognize what sort of fault this is from the ptlp (with no
+ * sec-mdpe) at the root complex. Recognizing which originating devices may be
+ * implicated can be done using the mdpe ereport (for a hardened leaf driver),
+ * or for a non-hardened leaf driver by using the source-id payload in the ptlp
+ * ereport to identify the originator of the request.  The ptlp/mdpe ereports
+ * at the intervening switches will narrow the fault down to a single suspect.
+ */
+
+prop error.io.pciex.flt-f-poisreq-u@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pciex.source-f-poisreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-f-poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.f-lf-poisreq-u@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.f-lf-poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn,
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.f-lf-poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-f-poisreq-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (0)->
+    ereport.io.pciex.tl.ptlp@pciexrc<> {
+	BDF_IS_LEAF && SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC },
+    ereport.io.pciex.tl.ur@pciexrc<> {
+	BDF_IS_LEAF && SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-f-poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop error.io.pciex.source-f-poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn,
+    error.io.pci.ta-drw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+
+prop error.io.pci.source-f-dpdata-w-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ptlp@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC },
+    ereport.io.pciex.tl.ur@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pci.source-f-dpdata-w-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-ude@pciexbus/pciexdev/pciexfn { IS_BDG &&
+        BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pciex.flt-nf-poisreq-u@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    error.io.service.restored@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.source-nf-poisreq-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (0)->
+    ereport.io.pciex.tl.ptlp@pciexrc<> {
+	BDF_IS_LEAF && SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC },
+    ereport.io.pciex.tl.ur@pciexrc<> {
+	BDF_IS_LEAF && SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn,
+    error.io.pci.ta-drw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+
+prop error.io.pci.source-nf-dpdata-w-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ptlp@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC },
+    ereport.io.pciex.tl.ur@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pci.source-nf-dpdata-w-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-ude@pciexbus/pciexdev/pciexfn { IS_BDG &&
+        BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn,
+    error.io.pci.ta-drw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+
+prop error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn { IS_SWU },
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+prop error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn { IS_BDG || IS_SWU };
+
+prop error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.poisreq-u@pciexrc/pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.sec-dpe@pciexrc;
+
+/*
+ * upstream poisoned completion
+ *
+ * - flt-poiscomp-u is just on the pciex node which generated the fault (if the
+ *   fault was generated by a pciex node and not a child pci node). There will
+ *   be a target-mdpe downstream from here.
+ * - source-poiscomp-u cascades down to at least one leaf device (pciex or pci),
+ *   whose bdf must match the source-id in the payload of the ereport generated
+ *   from the root complex. Note that pci.esc rules have to generate the
+ *   source-poiscomp-u so we limit it to the faulty node or nodes underneath
+ *   the faulty node.
+ * - poiscomp-u cascades up to the root complex and any switches on
+ *   route will raise ptlp and sec-mdpe ereports. The root complex will also
+ *   raise a sec-mdpe and ptlp.
+ *
+ * We can always recognize what sort of fault this is from the ptlp/sec-mdpe at
+ * the root complex. Recognizing which originating devices may be implicated
+ * can be done using the source-id payload in the ptlp ereport to identify the
+ * originator of the completion. The ptlp/sec-mdpe ereports at the intervening
+ * switches will narrow the fault down to a single suspect.
+ */
+prop error.io.pciex.flt-f-poiscomp-u@pciexbus/pciexdev/pciexfn (3)->
+    error.io.pciex.source-f-poiscomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-f-poiscomp-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.source-f-poiscomp-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (0)->
+    ereport.io.pciex.tl.ptlp@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pci.source-f-dpdata-r-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ptlp@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pci.source-f-dpdata-r-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-ude@pciexbus/pciexdev/pciexfn { IS_BDG &&
+        BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pciex.flt-nf-poiscomp-u@pciexbus/pciexdev/pciexfn (3)->
+    error.io.pciex.source-nf-poiscomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-nf-poiscomp-u@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    error.io.service.restored@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.source-nf-poiscomp-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (0)->
+    ereport.io.pciex.tl.ptlp@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pci.source-nf-dpdata-r-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ptlp@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pci.source-nf-dpdata-r-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-ude@pciexbus/pciexdev/pciexfn { IS_BDG &&
+        BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn { IS_SWD },
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn { IS_SWU },
+    ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn { IS_SWU },
+    ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn { IS_SWU },
+    ereport.io.pciex.tl.ptlp@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+prop error.io.pciex.poiscomp-u@pciexrc/pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.sec-dpe@pciexrc;
+
+prop error.io.pciex.poiscomp-u@pciexrc/pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-mdpe@pciexrc;
+
+/*
+ * upstream request with ecrc error.
+ *
+ * - flt-ecrcreq-u is just on the pciex node which generated the fault.
+ * - source-ecrcreq-u cascades down to at least one leaf device (pciex or pci),
+ *   whose bdf must match the source-id in the payload of the ereport generated
+ *   from the root complex.
+ * - ecrcreq-u cascades up to the root complex which must report it with an ecrc
+ *   ereport and any switches on route can optionally raise an ecrc ereport.
+ *
+ * Additionally, as the root complex will just throw away the packet, we'll
+ * eventually get a cto - so use an nr-d at the pciex leaf or bridge to get
+ * the appropriate behaviour.
+ *
+ * We can always recognize what sort of fault this is from the ecrc (with no
+ * cto) at the root complex. Recognizing which leaf device may be implicated
+ * can be done from the cto ereport (for a hardened leaf driver) or for a
+ * non-hardened leaf using the source-id payload of the ecrc.
+ */
+prop error.io.pciex.flt-f-ecrcreq-u@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ecrcreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.source-f-ecrcreq-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (1)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> {
+	BDF_IS_LEAF && SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-f-ecrcreq-u@pcibus/pcidev/pcifn (0)->
+    ereport.io.service.lost@pcibus/pcidev/pcifn { IS_PCI_LEAF },
+    ereport.io.service.degraded@pcibus/pcidev/pcifn { IS_PCI_LEAF };
+
+prop error.io.pciex.source-f-ecrcreq-u@pciexfn/pcibus[b]/pcidev[d]/pcifn[f] (1)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> { BDF_IS_PCI_IMM_LEAF &&
+	SOURCE_ID_MATCHES_BDF_OR_B && IMM_PCIBDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-f-ecrcreq-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pciex.flt-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ecrcreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    error.io.service.restored@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.source-nf-ecrcreq-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (1)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> {
+	BDF_IS_LEAF && SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-nf-ecrcreq-u@pcibus/pcidev/pcifn (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn { IS_PCI_LEAF },
+    error.io.service.restored@pcibus/pcidev/pcifn { IS_PCI_LEAF };
+
+prop error.io.pciex.source-nf-ecrcreq-u@pciexfn/pcibus[b]/pcidev[d]/pcifn[f] (1)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> { BDF_IS_PCI_IMM_LEAF &&
+	SOURCE_ID_MATCHES_BDF_OR_B && IMM_PCIBDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-nf-ecrcreq-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pciex.ecrcreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ecrcreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.ecrcreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn { IS_SWD || IS_SWU };
+
+/*
+ * upstream completion with ecrc error.
+ *
+ * - flt-ecrccomp-u is just on the pciex node which generated the fault.
+ * - source-ecrccomp-u cascades down to at least one leaf device (pciex or pci),
+ *   whose bdf must match the source-id in the payload of the ereport generated
+ *   from the root complex.
+ * - ecrccomp-u cascades up to the root complex, which should report it with an
+ *   ecrc ereport and any switches on route can optionally raise an ecrc
+ *   ereport.
+ *
+ * Additionally, as the root complex will just throw away the packet, we'll
+ * eventually get a cto - so use an flt-nr-u at the pciex leaf or bridge to get
+ * the appropriate behaviour.
+ *
+ * We can always recognize what sort of fault this from the ecrc/cto from the
+ * root complex. Recognizing which leaf device may be implicated can be done
+ * using either the source-id payload of the ecrc or the target-ma ereport if
+ * available.
+ */
+prop error.io.pciex.flt-f-ecrccomp-u@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ecrccomp-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.service.lost@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.service.degraded@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.source-f-ecrccomp-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (1)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-f-ecrccomp-u@pcibus/pcidev/pcifn (0)->
+    ereport.io.service.lost@pcibus/pcidev/pcifn { IS_PCI_LEAF },
+    ereport.io.service.degraded@pcibus/pcidev/pcifn { IS_PCI_LEAF };
+
+prop error.io.pciex.source-f-ecrccomp-u@pciexfn/pcibus[b]/pcidev[d]/pcifn[f] (1)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> { BDF_IS_PCI_IMM_LEAF &&
+	SOURCE_ID_MATCHES_BDF_OR_B && IMM_PCIBDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-f-ecrccomp-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pciex.flt-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ecrccomp-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.service.unaffected@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    error.io.service.restored@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.source-nf-ecrccomp-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (1)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-nf-ecrccomp-u@pcibus/pcidev/pcifn (1)->
+    ereport.io.service.unaffected@pcibus/pcidev/pcifn { IS_PCI_LEAF },
+    error.io.service.restored@pcibus/pcidev/pcifn { IS_PCI_LEAF };
+
+prop error.io.pciex.source-nf-ecrccomp-u@pciexfn/pcibus[b]/pcidev[d]/pcifn[f] (1)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> { BDF_IS_PCI_IMM_LEAF &&
+	SOURCE_ID_MATCHES_BDF_OR_B && IMM_PCIBDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-nf-ecrccomp-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ecrc@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pciex.ecrccomp-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ecrccomp-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.ecrccomp-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ecrc@pciexbus/pciexdev/pciexfn { IS_SWD || IS_SWU };
+
+/*
+ * no response to downstream requester
+ *
+ * - nr-d will effectively cascade downstream to the requester. The fault here
+ *   is always at the root complex. For a hardened leaf device driver, we will
+ *   always be able to recognize this as the requester will report this as a
+ *   cto. For non-hardened leaf devices, no cto will be reported, and though we
+ *   should still see a nonfatal error reported from the root complex
+ *   identifying the leaf device, we won't actually be informed that the error
+ *   was a cto.
+ */
+prop error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.tl.cto@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.cto@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+/*
+ * no response to upstream requester
+ *
+ * - flt-nr-u is just on the pciex node which generated the fault.
+ * - nr-u will effectively cascade upstream to the root complex which will
+ *   report it as a cto.
+ *
+ * We have to use target-ma to informs us which device failed to respond.
+ */
+prop error.io.pciex.flt-nr-u@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pciex.nr-u@pciexbus/pciexdev/pciexfn,
+    error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nr-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nr-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.nr-u@pciexrc/pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.tl.cto@pciexrc;
+
+prop error.io.pciex.nr-u@pciexrc/pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-ma@pciexrc;
+
+/*
+ * downstream malformed tlp
+ *
+ * This will cascade downstream to the receiver which will report it as an mtlp.
+ * For non-hardened leaf drivers, no mtlp will be reported, and though we should
+ * still see a fatal error reported from the root complex identifying the leaf
+ * device, we won't actually be informed that the error was a mtlp.
+ * Note that sw-mtlp-d is to handle the case where the switch is actually
+ * the target of the packet (config request etc).
+ */
+prop error.io.pciex.mtlp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.sw-mtlp-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.mtlp-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+
+prop error.io.pciex.mtlp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.fatal@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.mtlp-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.tl.mtlp@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop error.io.pciex.mtlp-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.mtlp@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.sw-mtlp-d@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pciex.fatal@pciexbus/pciexdev/pciexfn { IS_SWU },
+    ereport.io.pciex.tl.mtlp@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+/*
+ * upstream malformed tlp
+ *
+ * This will cascade upstream to the receiver which will report it as an mtlp.
+ * The source-id payload could be a pciexpress leaf or a pci leaf behind a 
+ * bridge. Or it could be completely invalid - should we trust it?
+ */
+prop error.io.pciex.mtlp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-mtlp-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-mtlp-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (1)->
+    ereport.io.pciex.tl.mtlp@pciexrc<> {
+	BDF_IS_LEAF && SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC };
+
+prop error.io.pciex.source-mtlp-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.mtlp@pciexrc<> {
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+/*
+ * downstream completer aborts
+ *
+ * This could be the fault of the root complex or a switch reporting an internal
+ * error, or of the leaf device sending an invalid request (the latter is
+ * handled by the badreq-u case below).
+ *
+ * This is reported by the completer or by an intervening downstream switch
+ * port. The completer abort response propagates down to the initiator which
+ * will set the legacy pci bit rta.
+ *
+ * The fault can always be recognized by the ca ereport from the root complex
+ * or downstream switch port. The originator of the request can be recognized
+ * by the rta for a hardened driver or by using the source-id payload of the
+ * ca ereport for a non-hardened driver.
+ *
+ * Note that there is no ur-d (we assume that a ur reported by the root complex
+ * is always due to a badreq-u - see below).
+ */
+prop error.io.pciex.ca-d@pciexrc/pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.sec-sta@pciexrc;
+
+prop error.io.pciex.ca-d@pciexrc/pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ca@pciexrc;
+
+prop error.io.pciex.flt-ca-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.tl.ca@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.flt-ca-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ca-d@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.ca-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ca-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>; 
+
+prop error.io.pciex.ca-d@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.rta@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop error.io.pciex.ca-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.rta@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+/*
+ * upstream unexpected requests
+ *
+ * This could be the fault of a device behind a PCI Express/PCI(X) bridge not
+ * responding, or of the root complex sending an invalid request (the latter
+ * case is handled by badreq-d below).
+ *
+ * This is reported as a ur by the completer, which sets the
+ * appropriate error bit in the completion message to the initiator which will
+ * set the legacy pci bit sec-ma.
+ *
+ * The fault can always be recognized from the sec-ma bit at the root complex.
+ *
+ * If the fault was with the root complex, then we don't care which leaf is
+ * involved.
+ * 
+ * If the fault originated from a pci device behind a PCI Express/PCI(X) bridge
+ * we can identify the leaf device from the target-ma ereport if available or
+ * from the source-id payload of the sec-rma ereport from the bridge.
+ */
+prop error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG };
+
+prop error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pciex.tl.ur@pciexbus/pciexdev/pciexfn { IS_LEAF || IS_BDG };
+
+prop error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.tl.ur@pciexbus/pciexdev/pciexfn { IS_SWU };
+
+prop error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ur-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.ur-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ur-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.ur-u@pciexrc/pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.sec-ma@pciexrc;
+
+/*
+ * upstream completer aborts
+ *
+ * This could be the fault of the leaf device/bridge/upstream switch port
+ * reporting an internal error, or of the root complex sending an invalid
+ * request (the latter case is handled by badreq-d below).
+ *
+ * This is reported as a ca by the completer. The completer sends the
+ * appropriate error bits in the completion message to the initiator which will
+ * set the legacy pci bit sec-rta.
+ *
+ * The fault can always be recognized from the sec-rta bit at the root complex.
+ *
+ * If the fault was with a PCI Express leaf with a hardened driver, then we
+ * will identify the device from the ca ereport.
+ *
+ * If the fault was with a PCI Express leaf with a non-hardened driver, then we
+ * can still identify the leaf device from the source-id payload of the nonfatal
+ * message ereport from the root complex or from the target-rta ereport.
+ *
+ * If the fault originated from a PCI(X) device behind a PCI Express/PCI(X)
+ * bridge, and it's driver is hardened, we can identify the device from the PCI
+ * sta ereport or from the source-id payload of the sec-rta ereport from the
+ * bridge.
+ *
+ * If the fault originated from a PCI(X) device behind a PCI Express/PCI(X)
+ * bridge, and its driver is not hardened we can only identify the leaf device
+ * from the target-rta ereport if available or from the source-id payload of
+ * the sec-rta ereport from the bridge.
+ */
+prop error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn
+	{ IS_SWU || IS_LEAF || IS_BDG };
+
+prop error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sta@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.pciex.tl.ca@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn (2)->
+    ereport.io.pci.sta@pciexbus/pciexdev/pciexfn { IS_SWU || IS_BDG },
+    ereport.io.pciex.tl.ca@pciexbus/pciexdev/pciexfn { IS_SWU || IS_BDG };
+
+prop error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pci.target-rta-d@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ca-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.ca-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.ca-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.ca-u@pciexrc/pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.sec-rta@pciexrc;
+
+/*
+ * upstream bad request
+ *
+ * When detecting bad data on a request the completer (or any switch on the
+ * way to the completer) may report ur or ca. If the switch detects the problem
+ * first then the request doesn't get forwarded on to the completer.
+ *
+ * These are reported as ur/ca ereports. The reporter then sends the appropriate
+ * error bits in the completion message to the initiator which will set the
+ * legacy pci bits ma or rta (oddly there is no equivalent in pcie error
+ * reporting).
+ *
+ * For badreq-u, the ca/ur ereports contain a source-id payload that identifies
+ * the initiator.
+ * - flt-badreq-u represents the initiator that caused the fault. This may
+ *   be a child pci device in which case flt-badreq-u is generated in pci.esc
+ * - badreq-u propagates up to the root complex.
+ *
+ * The fault can always be recognized by the ca/ur ereport from the root
+ * complex or downstream switch port. The originator of the request can be
+ * recognized by the rta/ma for a hardened driver or by using the source-id
+ * payload of the ca/ur ereport for a non-hardened driver.
+ *
+ * Note that handling of badreq-u where source and detector are both pciexfn
+ * has to be handled specially to avoid path name matching.
+ */
+prop error.io.pciex.flt-badreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.badreq-u@pciexrc/pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-sta@pciexrc;
+
+prop error.io.pciex.flt-badreq-u@pciexbus[b]/pciexdev[d]/pciexfn[f] (0)->
+    ereport.io.pciex.tl.ur@pciexrc<> {
+        BDF_IS_LEAF && SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC},
+    ereport.io.pciex.tl.ca@pciexrc<> {
+        BDF_IS_LEAF && SOURCE_ID_MATCHES_BDF && BDF_IS_UNDER_RC};
+
+prop error.io.pci.badreq-pw-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ur@pciexrc<> {
+        SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC },
+    ereport.io.pciex.tl.ca@pciexrc<> {
+        SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pci.badreq-drw-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ur@pciexrc<> {
+        SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC },
+    ereport.io.pciex.tl.ca@pciexrc<> {
+        SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_RC };
+
+prop error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn { IS_SWD };
+
+prop error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn (0)->
+    error.io.pciex.badreq-u@pciexbus/pciexdev { IS_LEAF };
+
+prop error.io.pciex.badreq-u@pciexbus[b]/pciexdev[d] (0)->
+    ereport.io.pciex.tl.ur@pciexfn {
+	(confprop(asru(pciexfn), "EXCAP") == "pciexswd") &&
+	(payloadprop("source-valid") == 0 ||
+	(payloadprop("source-id") & 0xfff8) == ((b << 8) | (d << 3))) },
+    ereport.io.pciex.tl.ca@pciexfn {
+	(confprop(asru(pciexfn), "EXCAP") == "pciexswd") &&
+	(payloadprop("source-valid") == 0 ||
+	(payloadprop("source-id") & 0xfff8) == ((b << 8) | (d << 3))) };
+
+prop error.io.pci.badreq-pw-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ur@pciexbus/pciexdev/pciexfn { IS_SWD &&
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_DEV },
+    ereport.io.pciex.tl.ca@pciexbus/pciexdev/pciexfn { IS_SWD &&
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pci.badreq-drw-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.tl.ur@pciexbus/pciexdev/pciexfn { IS_SWD &&
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_DEV },
+    ereport.io.pciex.tl.ca@pciexbus/pciexdev/pciexfn { IS_SWD &&
+	SOURCE_ID_MATCHES_BDF_OR_B && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pciex.flt-badreq-u@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.pci.rta@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+/*
+ * downstream bad request
+ *
+ * When detecting bad data on a request the completer (or any switch on the
+ * way to the completer) may report ur or ca. If the switch detects the problem
+ * first then the request doesn't get forwarded on to the completer.
+ *
+ * These are reported as ur/ca ereports (except where the completer is a non-
+ * hardened leaf driver when all we get is a nonfatal error from the root
+ * complex identifying the leaf device). The reporter then sends the appropriate
+ * error bits in the completion message to the initiator which will set the
+ * legacy pci bits ma or rta (oddly there is no equivalent in pcie error
+ * reporting).
+ */
+prop error.io.pciex.badreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.badreq-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+
+prop error.io.pciex.badreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop error.io.pciex.badreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.flt-ca-u@pciexbus/pciexdev/pciexfn,
+    error.io.pci.badreq-pw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.badreq-drw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * Stub unused legacy pci ereports at root complex.
+ * Stub tl.uc as we can't do anything useful with it (we should eventually
+ * get a cto which we can do something with - a uc without a cto is a genuinely
+ * spurious completion which is at least harmless).
+ * Stub messages that the root complex sends to itself.
+ * Stub mce/mue/ce/nr/noadverr.
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+
+event error.io.pciex.discard_rc@pciexrc;
+
+event ereport.io.pciex.tl.uc@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.noadverr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.correctable@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.fatal@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.nr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.nr@pciexrc{within(5s)};
+event ereport.io.pci.ma@pciexrc{within(5s)};
+event ereport.io.pci.rta@pciexrc{within(5s)};
+event ereport.io.pci.sta@pciexrc{within(5s)};
+event ereport.io.pci.dpe@pciexrc{within(5s)};
+event ereport.io.pci.mdpe@pciexrc{within(5s)};
+event ereport.io.pci.sserr@pciexrc{within(5s)};
+event ereport.io.pciex.tl.uc@pciexrc{within(5s)};
+event ereport.io.pciex.noadverr@pciexrc{within(5s)};
+event ereport.io.pciex.rc.ce-msg@pciexrc{within(5s)};
+event ereport.io.pciex.rc.mce-msg@pciexrc{within(5s)};
+event ereport.io.pciex.rc.mue-msg@pciexrc{within(5s)};
+
+event upset.io.pciex.discard_uc@pciexbus/pciexdev/pciexfn;
+event upset.io.pciex.discard@pciexbus/pciexdev/pciexfn;
+event upset.io.pciex.discard@pciexrc;
+
+prop upset.io.pciex.discard_uc@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.tl.uc@pciexbus/pciexdev/pciexfn { IS_BDG };
+
+prop upset.io.pciex.discard_uc@pciexbus/pciexdev/pciexfn (2)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn { IS_LEAF },
+    ereport.io.pciex.tl.uc@pciexbus/pciexdev/pciexfn { IS_LEAF };
+
+prop upset.io.pciex.discard@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pci.nr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.noadverr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.correctable@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.fatal@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.discard_rc@pciexrc (1)->
+    ereport.io.pciex.rc.fe-msg@pciexrc { SOURCE_ID_MATCHES_OWN_BDF },
+    ereport.io.pciex.rc.nfe-msg@pciexrc { SOURCE_ID_MATCHES_OWN_BDF },
+    ereport.io.pciex.rc.ce-msg@pciexrc { SOURCE_ID_MATCHES_OWN_BDF };
+
+prop upset.io.pciex.discard@pciexrc (1)->
+    error.io.pciex.discard_rc@pciexrc,
+    ereport.io.pci.nr@pciexrc,
+    ereport.io.pciex.noadverr@pciexrc,
+    ereport.io.pciex.rc.ce-msg@pciexrc,
+    ereport.io.pciex.rc.mce-msg@pciexrc,
+    ereport.io.pciex.rc.mue-msg@pciexrc,
+    ereport.io.pciex.tl.uc@pciexrc,
+    ereport.io.pci.ma@pciexrc,
+    ereport.io.pci.rta@pciexrc,
+    ereport.io.pci.sta@pciexrc,
+    ereport.io.pci.dpe@pciexrc,
+    ereport.io.pci.mdpe@pciexrc,
+    ereport.io.pci.sserr@pciexrc;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * rules for PCI Express to PCI bridge propagations
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+
+event error.io.pci.retry-to-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.badreq-pw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.badreq-drw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.ma-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.ta-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.ape-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.source-ape-u@pcibus/pcidev/pcifn;
+event error.io.pci.source-f-perr-u@pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-perr-u@pcibus/pcidev/pcifn;
+event error.io.pci.target-ma-d@pcibus/pcidev/pcifn;
+event error.io.pci.target-rta-d@pcibus/pcidev/pcifn;
+event error.io.pci.f-dpdata-pw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpdata-pw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.f-dpdata-dw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpdata-dw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.f-dpdata-dr-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.nf-dpdata-dr-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-pw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dr-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.perr-pw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.perr-dw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.perr-dr-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.serr-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pcix.scpe-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pcix.source-scpe-u@pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ma-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ta-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ma-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pcix.spl-comp-ta-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pcix.uscmd@pciexbus/pciexdev/pciexfn;
+
+event ereport.io.pcix.sec-spl-dis@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.uscmd@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-perr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-uadr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-uat@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-serr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-tex@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-rma@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-rta@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-ma-sc@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pciex.bdg.sec-ta-sc@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.dto@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.sec-rta@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.sec-ma@pciexbus/pciexdev/pciexfn{within(5s)};
+
+/*
+ * propagations from pci express onto pci/pci-x
+ */
+
+/*
+ * poisoned tlps propagate as parity/ecc errors.
+ */
+prop error.io.pciex.f-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.f-dpdata-pw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.f-dpdata-dw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pciex.nf-poisreq-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.nf-dpdata-pw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>,
+    error.io.pci.nf-dpdata-dw-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pciex.f-poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.f-dpdata-dr-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pciex.nf-poiscomp-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.nf-dpdata-dr-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+/*
+ * ca-d only propagates on to pci bus if non-posted access
+ */
+prop error.io.pciex.ca-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn,
+    error.io.pci.ta-drw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+
+/*
+ * nr-d only propagates on to pci bus if non-posted access
+ */
+prop error.io.pciex.nr-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn,
+    error.io.pci.nr-drw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn,
+    error.io.pci.ta-drw-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+
+/*
+ * propagations from pci/pci-x onto pci express
+ */
+
+/*
+ * ma-u will only propagate on to pciex bus for non-posted accesses. It
+ * is then represented as an unsupported request.
+ */
+prop error.io.pci.ma-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.tl.ur@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ur-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.ma-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (2)->
+    ereport.io.pci.sec-ma@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.target-ma-d@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-rma@pciexbus/pciexdev/pciexfn { IS_BDG &&
+	BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+/*
+ * ta-u will only propagate on to pciex bus for non-posted accesses. It is
+ * then represented as a completer abort.
+ */
+prop error.io.pci.ta-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sta@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.tl.ca@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ca-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.ta-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (2)->
+    ereport.io.pci.sec-rta@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.target-rta-d@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-rta@pciexbus/pciexdev/pciexfn { IS_BDG &&
+	BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+/*
+ * PERR# on a delayed write is represented as an unsupported request
+ */
+prop error.io.pci.perr-dw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (1)->
+    ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.perr-dw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    error.io.pciex.flt-ur-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.perr-pw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (1)->
+    ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.perr-pw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.source-f-perr-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-perr@pciexbus/pciexdev/pciexfn { IS_BDG &&
+	BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pci.source-nf-perr-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-perr@pciexbus/pciexdev/pciexfn { IS_BDG &&
+	BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pci.perr-dr-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (1)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn;
+
+/*
+ * If the bridge receives data with bad ecc/parity from pci/pci-x, it will
+ * propagate onto pci express as a poisoned tlp
+ */
+prop error.io.pci.dpdata-dr-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (4)->
+    ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-mdpe@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.poiscomp-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.dpdata-dr-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    error.io.pci.source-nf-dpdata-r-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn,
+    error.io.pci.source-f-dpdata-r-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn,
+    error.io.pciex.source-nf-poiscomp-u@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.source-f-poiscomp-u@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.mdpe@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.dpdata-dw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (2)->
+    ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.dpdata-dw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.dpdata-dw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    error.io.pci.source-nf-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn,
+    error.io.pci.source-f-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+
+prop error.io.pci.dpdata-pw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (3)->
+    ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.poisreq-u@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.dpdata-pw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (1)->
+    error.io.pci.source-nf-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn,
+    error.io.pci.source-f-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+
+/*
+ * If the bridge sees an address or attribute parity error it is considered
+ * a fatal error.
+ */
+prop error.io.pci.ape-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (4)->
+    ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-rserr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.bdg.sec-serr@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.fatal@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.source-ape-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-uat@pciexbus/pciexdev/pciexfn { IS_BDG &&
+	BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV },
+    ereport.io.pciex.bdg.sec-uadr@pciexbus/pciexdev/pciexfn { IS_BDG &&
+	BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pci.ape-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn;
+
+/*
+ * If the bridge sees a split completion error (pci-x only) it could
+ * result in a number of things
+ * - unrecovered split completion message data error (uscmd). This would
+ *   happen on a pio write. A completer abort is returned to the initiator.
+ * - for various faults in the split completion (eg address parity error)
+ *   we will respond with a target abort (which the child device will treat
+ *   as a split completion ta)
+ * - for other faults we can't tell who send the split completion and so
+ *   just drop the request (which the child device sees as a split
+ *   completion ma)
+ */
+prop error.io.pcix.scpe-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.sec-dpe@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-rserr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.bdg.sec-serr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.fatal@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pcix.source-scpe-u@pcibus[b]/pcidev[d]/pcifn[f] (0)->
+    ereport.io.pciex.bdg.sec-uat@pciexbus/pciexdev/pciexfn { IS_BDG &&
+	BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV },
+    ereport.io.pciex.bdg.sec-uadr@pciexbus/pciexdev/pciexfn { IS_BDG &&
+	BDF_IS_PCI_LEAF && SOURCE_ID_MATCHES_BDF && PCIBDF_IS_UNDER_DEV };
+
+prop error.io.pcix.scpe-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (1)->
+    error.io.pcix.uscmd@pciexbus/pciexdev/pciexfn,
+    error.io.pcix.spl-comp-ma-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn,
+    error.io.pcix.spl-comp-ta-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+
+prop error.io.pcix.uscmd@pciexbus/pciexdev/pciexfn (5)->
+    error.io.pciex.fatal@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sta@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.tl.ca@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ca-u@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.bdg.uscmd@pciexbus/pciexdev/pciexfn;
+
+/*
+ * Similarly a child device may have responded with a master abort or
+ * target abort to one of our split competions. The hardware just logs these.
+ */
+prop error.io.pcix.spl-comp-ma-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (4)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-spl-dis@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.bdg.sec-ma-sc@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-ma@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pcix.spl-comp-ta-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (4)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-spl-dis@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.bdg.sec-ta-sc@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-rta@pciexbus/pciexdev/pciexfn;
+
+/*
+ * SERR# is considered fatal
+ */
+prop error.io.pci.serr-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (3)->
+    error.io.pciex.fatal@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-rserr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.bdg.sec-serr@pciexbus/pciexdev/pciexfn;
+
+/*
+ * Retry time-out is nonfatal. The initial requester has stopped retrying so
+ * there's nothing else the hardware can do but flag the error.
+ */
+prop error.io.pci.retry-to-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (2)->
+    error.io.pciex.nonfatal@pciexbus/pciexdev/pciexfn,
+    ereport.io.pciex.bdg.sec-tex@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.retry-to-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    ereport.io.pci.sta@pciexbus/pciexdev/pciexfn,
+    error.io.pciex.ca-u@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.dto@pciexbus/pciexdev/pciexfn;
+
+/*
+ * A bad dma request (eg with invalid address) propagates onto pci express
+ * as a bad dma request. The end result may be a master abort or target abort
+ * (depending on whether the child is pci-x or pci).
+ */
+prop error.io.pci.badreq-pw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.rta@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.badreq-drw-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn (0)->
+    error.io.pciex.badreq-u@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.ma@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.rta@pciexbus/pciexdev/pciexfn,
+    ereport.io.pci.sec-sta@pciexbus/pciexdev/pciexfn;
+
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * source- and target- propagations
+ * 
+ * The source- propagations cascade down to a leaf device, which can then have
+ * its bdf matched against the source-id of various ereports. This is necessary
+ * because for a number of cases the source-id represents the original requester
+ * of the packet which may be different from the detector of the error (which
+ * could be a bridge or switch).
+ *
+ * A Root Complex driver may generate "target-" ereports when knowledge of the
+ * physical address associated with a fault allows the target device to be
+ * determined. This is not a requirement of the Diagnosis Engine, but can be
+ * valuable when available.
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+event error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pci.target-rta-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.target-rta-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-f-poiscomp-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-nf-poiscomp-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pci.source-f-dpdata-r-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-r-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.source-f-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pci.source-nf-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-f-ecrcreq-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-nf-ecrcreq-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-f-ecrccomp-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-nf-ecrccomp-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-mtlp-u@pciexbus/pciexdev/pciexfn/pciexbus/pciexdev/pciexfn;
+event error.io.pciex.source-mtlp-u@pciexbus/pciexdev/pciexfn/pcibus/pcidev/pcifn;
+event error.io.pciex.source-mtlp-u@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+
+event ereport.io.pci.target-mdpe@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.target-rta@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pci.target-ma@pciexbus/pciexdev/pciexfn{within(5s)};
+
+prop error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+
+prop error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.target-ma-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.target-ma@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.target-rta-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.target-rta-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+
+prop error.io.pci.target-rta-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.target-rta-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.target-rta-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.target-rta@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+
+prop error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.pci.target-mdpe-d@pciexbus/pciexdev/pciexfn (0)->
+    ereport.io.pci.target-mdpe@pciexbus/pciexdev/pciexfn;
+
+prop error.io.pciex.source-f-poisreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-f-poisreq-u@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+    
+prop error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+    
+prop error.io.pciex.source-f-poisreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.source-f-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-nf-poisreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.source-nf-dpdata-w-u@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-f-poiscomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-f-poiscomp-u@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+    
+prop error.io.pciex.source-nf-poiscomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-nf-poiscomp-u@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+    
+prop error.io.pciex.source-f-poiscomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.source-f-dpdata-r-u@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-nf-poiscomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pci.source-nf-dpdata-r-u@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+    
+prop error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-f-ecrcreq-u@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+    
+prop error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-nf-ecrcreq-u@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-f-ecrcreq-u@pcibus/pcidev/pcifn (1)->
+    error.io.pciex.source-f-ecrcreq-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-nf-ecrcreq-u@pcibus/pcidev/pcifn (1)->
+    error.io.pciex.source-nf-ecrcreq-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+    
+prop error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-f-ecrccomp-u@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+    
+prop error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-nf-ecrccomp-u@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-f-ecrccomp-u@pcibus/pcidev/pcifn (1)->
+    error.io.pciex.source-f-ecrccomp-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-nf-ecrccomp-u@pcibus/pcidev/pcifn (1)->
+    error.io.pciex.source-nf-ecrccomp-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-mtlp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-mtlp-u@pciexbus/pciexdev/pciexfn/pciexbus<>/pciexdev<>/pciexfn<>;
+    
+prop error.io.pciex.source-mtlp-u@pciexbus/pciexdev/pciexfn (1)->
+    error.io.pciex.source-mtlp-u@pciexbus/pciexdev/pciexfn/pcibus<>/pcidev<>/pcifn<>;
+    
+prop error.io.pciex.source-mtlp-u@pcibus/pcidev/pcifn (1)->
+    error.io.pciex.source-mtlp-u@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+    
+/*
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * stub unused pciex-pci bridge ereports
+ * - ignore usc/sec-unex-spl
+ * - ignore sec-spl-or/sec-spl-dly as these aren't really faults (tuning info)
+ * - ignore ecc.ue ereports (we get everything we need from dpe/mdpe)
+ * - ignore ecc.ce ereports for now (could do serd on these)
+ * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ */
+
+event ereport.io.pciex.bdg.usc@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-unex-spl@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-spl-or@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-spl-dly@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-ecc.ce-addr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-ecc.ce-attr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-ecc.ce-data@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-ecc.ue-addr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-ecc.ue-attr@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-ecc.ue-data@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-s-ce@pciexbus/pciexdev/pciexfn{within(5s)};
+event ereport.io.pcix.sec-s-ue@pciexbus/pciexdev/pciexfn{within(5s)};
+
+event upset.io.pciex.discard-bdg@pciexbus/pciexdev/pciexfn;
+
+prop upset.io.pciex.discard-bdg@pciexbus/pciexdev/pciexfn (1)->
+    ereport.io.pciex.bdg.usc@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-unex-spl@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-spl-or@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-spl-dly@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-ecc.ce-addr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-ecc.ce-attr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-ecc.ce-data@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-ecc.ue-addr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-ecc.ue-attr@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-ecc.ue-data@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-s-ce@pciexbus/pciexdev/pciexfn,
+    ereport.io.pcix.sec-s-ue@pciexbus/pciexdev/pciexfn;
--- a/usr/src/cmd/fm/eversholt/files/i386/Makefile	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/eversholt/files/i386/Makefile	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -26,7 +25,7 @@
 #ident	"%Z%%M%	%I%	%E% SMI"
 
 SUBDIRS=i86pc
-EFT_COMMON_FILES= pci.eft sca500.eft sca1000.eft
+EFT_COMMON_FILES= pci.eft pciex.eft sca500.eft sca1000.eft
 
 include ../../../Makefile.subdirs
 
--- a/usr/src/cmd/fm/eversholt/files/sparc/Makefile	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/eversholt/files/sparc/Makefile	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,13 +19,13 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
 
 SUBDIRS=sun4u sun4v SUNW,Sun-Fire-15000
-EFT_COMMON_FILES= pci.eft sca500.eft sca1000.eft
+EFT_COMMON_FILES= pci.eft pciex.eft sca500.eft sca1000.eft
 
 include ../../../Makefile.subdirs
 
--- a/usr/src/cmd/fm/eversholt/files/sparc/sun4u/psycho.esc	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4u/psycho.esc	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -151,14 +150,24 @@
 asru pcibus/pcidev/pcifn;
 fru pcibus/pcidev;
 
-event fault.io.pci.device@hostbridge/pcibus/pcidev/pcifn,
+event fault.io.pci.device-interr@hostbridge/pcibus/pcidev/pcifn,
+    FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
+
+event fault.io.pci.device-interr@pcibus/pcidev/pcifn,
     FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
 
 event error.io.psy.pbm.rl@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.rec-ma@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.rec-mdpe@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.rec-ta@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.serr@hostbridge/pcibus;
+event error.io.psy.pbm.rl@pcibus/pcidev/pcifn;
+event error.io.psy.pbm.rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.psy.pbm.target-rl@pcibus/pcidev/pcifn;
+event error.io.psy.pbm.target-rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.perr-pw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.perr-dw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.retry-to-d@hostbridge/pcibus/pcidev/pcifn;
 event error.psy.cpu.berr@cpu;
 
 event ereport.io.psy.sbh@hostbridge/pcibus/pcidev/pcifn{within(5s)};
@@ -167,7 +176,7 @@
 event ereport.io.psy.pbm.s-ma@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.psy.pbm.s-rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.psy.pbm.s-mdpe@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.psy.pbm.target-rl@hostbridge/pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.psy.pbm.target-rl@pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.pci.rserr@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.cpu.ultraSPARC-II.berr@cpu{within(5s)};
 
@@ -176,48 +185,74 @@
  *
  *  - rl:	it to retry a transaction beyond the specified limit.
  *  - sbh:	it to generate a streaming byte hole.
+ *
+ * For rl, there may be a target-rl ereport on a child device. There may also be
+ * an associated dto - the retry-to-d error propagates into the pci.esc rules
+ * to handle this.
  */
 
-prop fault.io.pci.device@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.psy.pbm.rl@hostbridge/pcibus/pcidev/pcifn,
-    ereport.io.psy.sbh@PCI_HB_DEV_PATH;
+prop fault.io.pci.device-interr@pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.psy.pbm.rl@pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 },
+    error.io.psy.pbm.target-rl@pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 };
+
+prop error.io.psy.pbm.rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    error.io.psy.pbm.rl@pcibus/pcidev/pcifn;
 
 prop error.io.psy.pbm.rl@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.psy.pbm.rl@PCI_HB_DEV_PATH,
     ereport.io.psy.pbm.s-rl@PCI_HB_DEV_PATH;
 
+prop error.io.psy.pbm.target-rl@pcibus/pcidev/pcifn (1)->
+    error.io.psy.pbm.target-rl@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.psy.pbm.target-rl@pcibus/pcidev/pcifn (0)->
+    ereport.io.psy.pbm.target-rl@pcibus/pcidev/pcifn;
+
 prop error.io.psy.pbm.rl@hostbridge/pcibus/pcidev/pcifn (0)->
-    ereport.io.psy.pbm.target-rl@hostbridge/pcibus/pcidev/pcifn;
+    error.io.pci.retry-to-d@hostbridge/pcibus/pcidev/pcifn;
 
 prop error.io.psy.pbm.rl@hostbridge/pcibus/pcidev/pcifn (0)->
     error.psy.cpu.berr@cpu;
 
+prop fault.io.pci.device-interr@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.psy.sbh@PCI_HB_DEV_PATH;
+
 /*
  * Need to add the following psycho specific propagations to complete the PCI
- * fault tree.
+ * fault tree. These are to allow propagations to secondary errors and cpu
+ * bus errors, and to represent the way the chip raises rserr
+ * on detection of SERR#
  */
-prop error.io.pci.rec-ma@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.psy.pbm.s-ma@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-ta@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.psy.pbm.s-rta@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-mdpe@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.perr-pw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.psy.pbm.s-mdpe@PCI_HB_DEV_PATH;
+
+prop error.io.pci.perr-dw-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.psy.pbm.s-mdpe@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-ta@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.psy.pbm.s-mdpe@PCI_HB_DEV_PATH;
+
+prop error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.psy.cpu.berr@cpu;
 
-prop error.io.pci.rec-mdpe@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.psy.cpu.berr@cpu;
 
-prop error.io.pci.rec-ma@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.psy.cpu.berr@cpu;
 
 prop error.psy.cpu.berr@cpu (0)->
     ereport.cpu.ultraSPARC-II.berr@cpu;
 
-prop error.io.pci.serr@hostbridge/pcibus (1)->
+prop error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.pci.rserr@PCI_HB_DEV_PATH;
 
 event ereport.io.psy.nodiag@hostbridge;
--- a/usr/src/cmd/fm/eversholt/files/sparc/sun4u/schizo.esc	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4u/schizo.esc	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -45,16 +44,13 @@
 event fault.io.schizo@hostbridge,
     FITrate=HB_FIT, FRU=hostbridge, ASRU=hostbridge;
 
-event error.io.sch.saf.dstat@hostbridge/pcibus/pcidev/pcifn;
-event error.io.sch.saf.to@hostbridge/pcibus/pcidev/pcifn;
-event error.io.sch.saf.bus@hostbridge/pcibus/pcidev/pcifn;
-event error.io.sch.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
+event error.io.sch.saf.dstat@hostbridge;
+event error.io.sch.saf.to@hostbridge;
+event error.io.sch.saf.bus@hostbridge;
+event error.io.pci.device-ta@hostbridge/pcibus/pcidev/pcifn;
 
 event ereport.io.sch.saf.to@hostbridge{within(5s)};
 event ereport.io.sch.saf.bus@hostbridge{within(5s)};
-event ereport.io.pci.sta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.target-rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.sch.saf.bca@hostbridge{within(5s)};
 event ereport.io.sch.saf.bcb@hostbridge{within(5s)};
 event ereport.io.sch.saf.ciq-to@hostbridge{within(5s)};
@@ -85,6 +81,10 @@
  *  - to:	safari bus timeout.
  *  - bus:	safari bus error.
  *  - dstat:	errant dstat on incoming data.
+ *
+ * The to, bus and dstat errors can cause a target abort to be sent onto the
+ * pci bus in response to a dma request. We represent this using a device-ta
+ * error to propagate into the generic pci.esc rules.
  */
 prop fault.io.schizo@hostbridge (0)->
     ereport.io.sch.saf.bca@hostbridge,
@@ -97,30 +97,23 @@
     ereport.io.sch.ecc.pue@hostbridge,
     ereport.io.sch.ecc.s-pue@hostbridge,
     ereport.io.sch.ecc.thresh@hostbridge,
-    error.io.sch.saf.to@hostbridge/pcibus/pcidev/pcifn,
-    error.io.sch.saf.bus@hostbridge/pcibus/pcidev/pcifn,
-    error.io.sch.saf.dstat@hostbridge/pcibus/pcidev/pcifn;
-
-prop error.io.sch.saf.to@hostbridge/pcibus/pcidev/pcifn (2)->
-    ereport.io.sch.saf.to@hostbridge,
-    error.io.sch.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
+    error.io.sch.saf.to@hostbridge,
+    error.io.sch.saf.bus@hostbridge,
+    error.io.sch.saf.dstat@hostbridge;
 
-prop error.io.sch.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.sta@PCI_HB_DEV_PATH,
-    ereport.io.pci.target-rta@PCI_HB_DEV_PATH;
+prop error.io.sch.saf.to@hostbridge (2)->
+    ereport.io.sch.saf.to@hostbridge,
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
-prop error.io.sch.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.rta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.sch.saf.bus@hostbridge (2)->
+    ereport.io.sch.saf.bus@hostbridge,
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
-prop error.io.sch.saf.bus@hostbridge/pcibus/pcidev/pcifn (2)->
-    ereport.io.sch.saf.bus@hostbridge,
-    error.io.sch.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
-
-prop error.io.sch.saf.dstat@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.sch.saf.dstat@hostbridge (1)->
     ereport.io.sch.saf.dstat@hostbridge;
 
-prop error.io.sch.saf.dstat@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.sch.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.sch.saf.dstat@hostbridge (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
 engine serd.io.schizo.ecc@hostbridge,
     N=3, T=1day, method=persistent,
@@ -180,9 +173,9 @@
  *  - ecc:	multiple PIO CEs.
  */
 prop fault.io.datapath@cpu (0)->
-    error.io.sch.saf.to@hostbridge/pcibus/pcidev/pcifn,
-    error.io.sch.saf.bus@hostbridge/pcibus/pcidev/pcifn,
-    error.io.sch.saf.dstat@hostbridge/pcibus/pcidev/pcifn,
+    error.io.sch.saf.to@hostbridge,
+    error.io.sch.saf.bus@hostbridge,
+    error.io.sch.saf.dstat@hostbridge,
     ereport.io.sch.saf.ssm-dis@hostbridge,
     ereport.io.sch.saf.ape@hostbridge;
 
@@ -249,43 +242,30 @@
 prop upset.io.hbus@hostbridge (0)->
     ereport.io.sch.ecc.pce@hostbridge;
 
-event defect.io.pci.driver@hostbridge/pcibus/pcidev/pcifn;
+/*
+ * A bad request from a downstream device/driver may cause
+ *
+ *  - um:	safari unmapped address error.
+ *  - mmu:	a iommu translation error.
+ */
+event error.io.pci.badreq-pw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.badreq-drw-u@hostbridge/pcibus/pcidev/pcifn;
 
-event error.io.sch.mmu@hostbridge/pcibus/pcidev/pcifn;
-event error.io.sch.saf.unmapped@hostbridge/pcibus/pcidev/pcifn;
-
+event ereport.io.pci.rserr@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.sch.mmu@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.sch.saf.um@hostbridge{within(5s)};
 
-/*
- * A defective PCI driver may cause:
- *
- *  - unmapped:	safari unmapped address error.
- *  - mmu:	a iommu translation error.
- */
-prop defect.io.pci.driver@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.sch.saf.unmapped@hostbridge/pcibus/pcidev/pcifn,
-    error.io.sch.mmu@hostbridge/pcibus/pcidev/pcifn;
-
-prop error.io.sch.saf.unmapped@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.pci.badreq-pw-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.sch.saf.um@hostbridge;
 
-prop error.io.sch.saf.unmapped@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.sch.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
-
-prop error.io.sch.mmu@hostbridge/pcibus/pcidev/pcifn (2)->
-    ereport.io.sch.mmu@PCI_HB_DEV_PATH,
-    error.io.sch.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.pci.badreq-pw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.sch.mmu@PCI_HB_DEV_PATH;
 
-event defect.io.pci.driver@hostbridge;
+prop error.io.pci.badreq-drw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.sch.saf.um@hostbridge;
 
-/*
- * A defective PCI nexus driver may cause:
- *
- *  - unmapped:	safari unmapped address error.
- */
-prop defect.io.pci.driver@hostbridge (0)->
-    error.io.sch.saf.unmapped@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.pci.badreq-drw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.sch.mmu@PCI_HB_DEV_PATH;
 
 fru pcibus;
 asru pcibus;
@@ -309,16 +289,29 @@
 fru pcibus/pcidev;
 asru pcibus/pcidev/pcifn;
 
-event fault.io.pci.device@hostbridge/pcibus/pcidev/pcifn,
+event fault.io.pci.device-interr@hostbridge/pcibus/pcidev/pcifn,
+    FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
+
+event fault.io.pci.device-interr@pcibus/pcidev/pcifn,
     FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
 
 event error.io.sch.pbm.rl@hostbridge/pcibus/pcidev/pcifn;
+event error.io.sch.pbm.rl@pcibus/pcidev/pcifn;
+event error.io.sch.pbm.rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.sch.pbm.target-rl@pcibus/pcidev/pcifn;
+event error.io.sch.pbm.target-rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 event error.io.sch.pbm.tto@hostbridge/pcibus/pcidev/pcifn;
+event error.io.sch.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn;
+event error.io.sch.pbm.target-tto@pcibus/pcidev/pcifn;
+event error.io.sch.pbm.target-tto@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 event error.sch.cpu.berr@cpu;
-event error.io.pci.rec-ma@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.rec-mdpe@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.rec-ta@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.serr@hostbridge/pcibus;
+event error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.perr-pw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.perr-dw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.retry-to-d@hostbridge/pcibus/pcidev/pcifn;
 
 event ereport.io.sch.sbh@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.sch.pbm.rl@hostbridge/pcibus/pcidev/pcifn{within(5s)};
@@ -328,9 +321,8 @@
 event ereport.io.sch.pbm.s-ma@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.sch.pbm.s-rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.sch.pbm.s-mdpe@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.sch.pbm.target-rl@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.sch.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.rserr@hostbridge/pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.sch.pbm.target-rl@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.sch.pbm.target-tto@pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.pci.sserr@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.cpu.ultraSPARC-III.berr@cpu{within(5s)};
 event ereport.cpu.ultraSPARC-IIIplus.berr@cpu{within(5s)};
@@ -343,58 +335,93 @@
  *  - sbh:	a streaming byte hole error.
  *  - rl:	it to exceed the number retriesfor a transaction.
  *  - tto:	it to not assert trdy# within the alloted timeout.
+ *
+ * For rl and tto, there may be a target- ereport on a child device. For rl,
+ * there may also be an associated dto - the retry-to-d error propagates into
+ * the pci.esc rules to handle this.
  */
-prop fault.io.pci.device@hostbridge/pcibus/pcidev/pcifn (0)->
-    ereport.io.sch.sbh@PCI_HB_DEV_PATH,
-    error.io.sch.pbm.rl@hostbridge/pcibus/pcidev/pcifn,
-    error.io.sch.pbm.tto@hostbridge/pcibus/pcidev/pcifn;
+prop fault.io.pci.device-interr@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.sch.sbh@PCI_HB_DEV_PATH;
+
+prop fault.io.pci.device-interr@pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.sch.pbm.rl@pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 },
+    error.io.sch.pbm.target-rl@pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 };
+
+prop error.io.sch.pbm.rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    error.io.sch.pbm.rl@pcibus/pcidev/pcifn;
 
 prop error.io.sch.pbm.rl@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.sch.pbm.rl@PCI_HB_DEV_PATH,
     ereport.io.sch.pbm.s-rl@PCI_HB_DEV_PATH;
 
+prop error.io.sch.pbm.target-rl@pcibus/pcidev/pcifn (1)->
+    error.io.sch.pbm.target-rl@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.sch.pbm.target-rl@pcibus/pcidev/pcifn (0)->
+    ereport.io.sch.pbm.target-rl@pcibus/pcidev/pcifn;
+
 prop error.io.sch.pbm.rl@hostbridge/pcibus/pcidev/pcifn (0)->
-    ereport.io.sch.pbm.target-rl@hostbridge/pcibus/pcidev/pcifn;
+    error.io.pci.retry-to-d@hostbridge/pcibus/pcidev/pcifn;
 
 prop error.io.sch.pbm.rl@hostbridge/pcibus/pcidev/pcifn (0)->
     error.sch.cpu.berr@cpu;
 
+prop fault.io.pci.device-interr@hostbridge/pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.sch.pbm.tto@hostbridge/pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 };
+
 prop error.io.sch.pbm.tto@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.sch.pbm.tto@PCI_HB_DEV_PATH,
     ereport.io.sch.pbm.s-tto@PCI_HB_DEV_PATH;
 
-prop error.io.sch.pbm.tto@hostbridge/pcibus/pcidev/pcifn (0)->
-    ereport.io.sch.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.sch.pbm.tto@hostbridge/pcibus/pcidev/pcifn (1)->
+    error.io.sch.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn;
+
+prop error.io.sch.pbm.target-tto@pcibus/pcidev/pcifn (0)->
+    ereport.io.sch.pbm.target-tto@pcibus/pcidev/pcifn;
+
+prop error.io.sch.pbm.target-tto@pcibus/pcidev/pcifn (1)->
+    error.io.sch.pbm.target-tto@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
 
 prop error.io.sch.pbm.tto@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.sch.bu@PCI_HB_DEV_PATH;
 
 /*
  * Need to add the following schizo specific propagations to complete the PCI
- * fault tree.
+ * fault tree. These are to allow propagations to secondary errors and cpu
+ * bus errors, and to represent the way the chip can raise both rserr and sserr
+ * on detection of SERR#
  */
-prop error.io.pci.rec-ma@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.sch.pbm.s-ma@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-ta@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.sch.pbm.s-rta@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-mdpe@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.perr-pw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.sch.pbm.s-mdpe@PCI_HB_DEV_PATH;
+
+prop error.io.pci.perr-dw-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.sch.pbm.s-mdpe@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-ta@PCI_HB_DEV_PATH (0)->
-    error.sch.cpu.berr@cpu;
+prop error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.sch.pbm.s-mdpe@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-mdpe@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.sch.cpu.berr@cpu;
 
-prop error.io.pci.rec-ma@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.sch.cpu.berr@cpu;
 
-prop error.io.pci.serr@hostbridge/pcibus (1)->
+prop error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    error.sch.cpu.berr@cpu;
+
+prop error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.pci.rserr@PCI_HB_DEV_PATH;
 
-prop error.io.pci.serr@hostbridge/pcibus (0)->
+prop error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.pci.sserr@PCI_HB_DEV_PATH;
 
 prop error.sch.cpu.berr@cpu (1)->
@@ -403,10 +430,16 @@
     ereport.cpu.ultraSPARC-IV.berr@cpu,
     ereport.cpu.ultraSPARC-IVplus.berr@cpu;
 
+event error.io.sch.ecc.drue@hostbridge;
+event ereport.io.sch.ecc.drue@hostbridge{within(5s)};
 event ereport.io.sch.nodiag@hostbridge;
 
 /*
  * Upset used to hide ereports that can not be currently diagnosed.
+ *
+ * The drue error can cause a target abort to be sent onto the
+ * pci bus in response to a dma request. We represent this using a device-ta
+ * error to propagate into the generic pci.esc rules.
  */
 engine serd.io.sch.nodiag@hostbridge,
     N=1000, T=1hour, method=persistent,
@@ -417,4 +450,11 @@
 
 prop upset.io.sch.nodiag@hostbridge (0)->
     ereport.io.sch.ecc.s-pce@hostbridge,
+    error.io.sch.ecc.drue@hostbridge,
     ereport.io.sch.nodiag@hostbridge;
+
+prop error.io.sch.ecc.drue@hostbridge (1)->
+    ereport.io.sch.ecc.drue@hostbridge;
+
+prop error.io.sch.ecc.drue@hostbridge (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
--- a/usr/src/cmd/fm/eversholt/files/sparc/sun4u/tomatillo.esc	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4u/tomatillo.esc	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -43,15 +42,14 @@
     FITrate=HB_FIT, FRU=hostbridge, ASRU=hostbridge;
 
 event error.io.tom.jbus.um@hostbridge;
-event error.io.tom.jbus.to@hostbridge/pcibus/pcidev/pcifn;
-event error.io.tom.jbus.bus@hostbridge/pcibus/pcidev/pcifn;
+event error.io.tom.jbus.to@hostbridge;
+event error.io.tom.jbus.bus@hostbridge;
 event error.io.tom.jbus.iis@hostbridge;
-event error.io.tom.mmu.inval@hostbridge/pcibus/pcidev/pcifn;
-event error.io.tom.mmu.prot@hostbridge/pcibus/pcidev/pcifn;
-event error.io.tom.mmu.bva@hostbridge/pcibus/pcidev/pcifn;
-event error.io.tom.mmu.btt@hostbridge/pcibus/pcidev/pcifn;
-event error.io.tom.pci.txta@hostbridge/pcibus/pcidev/pcifn;
-event error.io.tom.mmu.to@hostbridge;
+event error.io.tom.mmu.inval@hostbridge/pcibus;
+event error.io.tom.mmu.prot@hostbridge/pcibus;
+event error.io.tom.mmu.bva@hostbridge/pcibus;
+event error.io.tom.mmu.btt@hostbridge/pcibus;
+event error.io.pci.device-ta@hostbridge/pcibus/pcidev/pcifn;
 
 event ereport.io.tom.jbus.um@hostbridge{within(5s)};
 event ereport.io.tom.jbus.to@hostbridge{within(5s)};
@@ -66,9 +64,6 @@
 event ereport.io.tom.jbus.srdsa@hostbridge{within(5s)};
 event ereport.io.tom.jbus.sown@hostbridge{within(5s)};
 event ereport.io.tom.jbus.srdo@hostbridge{within(5s)};
-event ereport.io.pci.rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.target-rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.sta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 
 /*
  * A faulty Tomatillo hostbridge may cause:
@@ -85,16 +80,20 @@
  *  - srdsa:	snoop error due to own RDSA hitting cache line in S, O or M.
  *  - sown:	snoop error due to own OWN hitting cache line in S or M.
  *  - srdo:	snoop error due to own RDO hitting cache line in O or M.
+ *
+ * The um, to, bus, btt, inval, prot and bva errors can cause a target abort to
+ * be sent onto the pci bus in response to a dma request. We represent this
+ * using a device-ta error to propagate into the generic pci.esc rules.
  */
 prop fault.io.tomatillo@hostbridge (0)->
     error.io.tom.jbus.um@hostbridge,
-    error.io.tom.jbus.to@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.jbus.bus@hostbridge/pcibus/pcidev/pcifn,
+    error.io.tom.jbus.to@hostbridge,
+    error.io.tom.jbus.bus@hostbridge,
     error.io.tom.jbus.iis@hostbridge,
-    error.io.tom.mmu.inval@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.prot@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.bva@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.btt@hostbridge/pcibus/pcidev/pcifn,
+    error.io.tom.mmu.inval@hostbridge/pcibus,
+    error.io.tom.mmu.prot@hostbridge/pcibus,
+    error.io.tom.mmu.bva@hostbridge/pcibus,
+    error.io.tom.mmu.btt@hostbridge/pcibus,
     ereport.io.tom.jbus.srds@hostbridge,
     ereport.io.tom.jbus.srdsa@hostbridge,
     ereport.io.tom.jbus.sown@hostbridge,
@@ -103,58 +102,55 @@
 prop error.io.tom.jbus.um@hostbridge (1)->
     ereport.io.tom.jbus.um@hostbridge;
 
-prop error.io.tom.jbus.to@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.tom.jbus.um@hostbridge (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
+
+prop error.io.tom.jbus.to@hostbridge (1)->
     ereport.io.tom.jbus.to@hostbridge,
     ereport.io.tom.jbus.to-exp@hostbridge;
 
-prop error.io.tom.jbus.to@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.tom.mmu.to@hostbridge,
-    error.io.tom.pci.txta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.tom.jbus.to@hostbridge (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
-prop error.io.tom.jbus.bus@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.tom.jbus.bus@hostbridge (1)->
     ereport.io.tom.jbus.bus@hostbridge;
 
-prop error.io.tom.jbus.bus@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.tom.pci.txta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.tom.jbus.bus@hostbridge (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
 prop error.io.tom.jbus.iis@hostbridge (1)->
     ereport.io.tom.jbus.iis@hostbridge;
 
-prop error.io.tom.mmu.btt@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.tom.mmu.btt@hostbridge/pcibus (1)->
     ereport.io.tom.mmu.btt@PCI_HB_DEV_PATH;
 
-prop error.io.tom.mmu.btt@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.tom.pci.txta@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.inval@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.tom.mmu.btt@hostbridge/pcibus (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH,
+    error.io.tom.mmu.inval@hostbridge/pcibus;
 
-prop error.io.tom.pci.txta@hostbridge/pcibus/pcidev/pcifn (2)->
-    ereport.io.pci.rta@hostbridge/pcibus/pcidev/pcifn,
-    ereport.io.pci.target-rta@PCI_HB_DEV_PATH,
-    ereport.io.pci.sta@PCI_HB_DEV_PATH;
-
-prop error.io.tom.mmu.inval@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.tom.mmu.inval@hostbridge/pcibus (1)->
     ereport.io.tom.mmu.inval@PCI_HB_DEV_PATH;
 
-prop error.io.tom.mmu.inval@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.tom.pci.txta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.tom.mmu.inval@hostbridge/pcibus (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
-prop error.io.tom.mmu.prot@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.tom.mmu.prot@hostbridge/pcibus (1)->
     ereport.io.tom.mmu.prot@PCI_HB_DEV_PATH;
 
-prop error.io.tom.mmu.prot@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.tom.pci.txta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.tom.mmu.prot@hostbridge/pcibus (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
-prop error.io.tom.mmu.bva@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.tom.mmu.bva@hostbridge/pcibus (1)->
     ereport.io.tom.mmu.bva@PCI_HB_DEV_PATH;
 
-prop error.io.tom.mmu.bva@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.tom.pci.txta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.tom.mmu.bva@hostbridge/pcibus (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
 fru cpu;
 
 event fault.io.datapath@cpu, FITrate=CPU_FIT, FRU=cpu;
 
-event error.io.tom.jbus.ibe@hostbridge/pcibus/pcidev/pcifn;
+event error.io.tom.jbus.ibe@hostbridge;
 
 event ereport.io.tom.jbus.ibe@hostbridge{within(5s)};
 event ereport.io.tom.jbus.srd@hostbridge{within(5s)};
@@ -170,59 +166,88 @@
  *  - um:	jbus unmapped error.
  *  - srd:	foreign RD hitting cache line in S, O or M.
  *  - bc:	bad jbus command.
+ *
+ * The ibe error can cause a target abort to
+ * be sent onto the pci bus in response to a dma request. We represent this
+ * using a device-ta error to propagate into the generic pci.esc rules.
  */
 prop fault.io.datapath@cpu (0)->
-    error.io.tom.jbus.to@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.jbus.bus@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.jbus.ibe@hostbridge/pcibus/pcidev/pcifn,
+    error.io.tom.jbus.to@hostbridge,
+    error.io.tom.jbus.bus@hostbridge,
+    error.io.tom.jbus.ibe@hostbridge,
     error.io.tom.jbus.iis@hostbridge,
     error.io.tom.jbus.um@hostbridge,
     ereport.io.tom.jbus.srd@hostbridge,
     ereport.io.tom.jbus.bc@hostbridge;
 
-prop error.io.tom.jbus.ibe@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.tom.jbus.ibe@hostbridge (1)->
     ereport.io.tom.jbus.ibe@hostbridge;
 
-prop error.io.tom.jbus.ibe@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.tom.pci.txta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.tom.jbus.ibe@hostbridge (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
 event fault.io.hbus@hostbridge,
     FITrate=HBUS_FIT, FRU=hostbridge, ASRU=hostbridge;
 
+event error.io.tom.jbus.drpe@hostbridge;
 event ereport.io.tom.jbus.ape@hostbridge{within(5s)};
 event ereport.io.tom.jbus.pwpe@hostbridge{within(5s)};
 event ereport.io.tom.jbus.drpe@hostbridge{within(5s)};
 event ereport.io.tom.jbus.dwpe@hostbridge{within(5s)};
 event ereport.io.tom.jbus.cpe@hostbridge{within(5s)};
 
-/* A faulty host bus may cause:
+/*
+ * A faulty host bus may cause:
  *
  *  - ape:	jbus address parity error.
  *  - pwpe:	jbus PIO write parity error.
  *  - drpe:	jbus DMA read parity error.
  *  - dwpe:	jbus DMA write parity error.
  *  - cpe:	jbus control parity error.
+ *
+ * The drpe error can cause a target abort to
+ * be sent onto the pci bus in response to a dma request. We represent this
+ * using a device-ta error to propagate into the generic pci.esc rules.
  */
 prop fault.io.hbus@hostbridge(0)->
     ereport.io.tom.jbus.ape@hostbridge,
     ereport.io.tom.jbus.pwpe@hostbridge,
-    ereport.io.tom.jbus.drpe@hostbridge,
+    error.io.tom.jbus.drpe@hostbridge,
     ereport.io.tom.jbus.dwpe@hostbridge,
     ereport.io.tom.jbus.cpe@hostbridge;
 
+prop error.io.tom.jbus.drpe@hostbridge(1)->
+    ereport.io.tom.jbus.drpe@hostbridge;
+
+prop error.io.tom.jbus.drpe@hostbridge(0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
+
 fru pcibus/pcidev;
 asru pcibus/pcidev/pcifn;
 
-event fault.io.pci.device@hostbridge/pcibus/pcidev/pcifn,
+event fault.io.pci.device-interr@hostbridge/pcibus/pcidev/pcifn,
+    FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
+
+event fault.io.pci.device-interr@pcibus/pcidev/pcifn,
     FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
 
 event error.io.tom.pbm.rl@hostbridge/pcibus/pcidev/pcifn;
+event error.io.tom.pbm.rl@pcibus/pcidev/pcifn;
+event error.io.tom.pbm.rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.tom.pbm.target-rl@pcibus/pcidev/pcifn;
+event error.io.tom.pbm.target-rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 event error.io.tom.pbm.tto@hostbridge/pcibus/pcidev/pcifn;
+event error.io.tom.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn;
+event error.io.tom.pbm.target-tto@pcibus/pcidev/pcifn;
+event error.io.tom.pbm.target-tto@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 event error.tom.cpu.berr@cpu;
-event error.io.pci.rec-ma@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.rec-mdpe@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.rec-ta@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.serr@hostbridge/pcibus;
+event error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.perr-pw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.perr-dw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.retry-to-d@hostbridge/pcibus/pcidev/pcifn;
 
 event ereport.io.tom.pbm.tto@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.tom.pbm.rl@hostbridge/pcibus/pcidev/pcifn{within(5s)};
@@ -231,8 +256,8 @@
 event ereport.io.tom.pbm.s-ma@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.tom.pbm.s-rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.tom.pbm.s-mdpe@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.tom.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.tom.pbm.target-rl@hostbridge/pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.tom.pbm.target-tto@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.tom.pbm.target-rl@pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.pci.rserr@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 
 /*
@@ -240,51 +265,84 @@
  *
  *  - rl:	it to exceed the limit on retrying a transaction.
  *  - tto:	it to not assert trdy# within the set timeout.
+ *
+ * For rl and tto, there may be a target- ereport on a child device. For rl,
+ * there may also be an associated dto - the retry-to-d error propagates into
+ * the pci.esc rules to handle this.
  */
-prop fault.io.pci.device@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.tom.pbm.rl@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.pbm.tto@hostbridge/pcibus/pcidev/pcifn;
+prop fault.io.pci.device-interr@pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.tom.pbm.rl@pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 },
+    error.io.tom.pbm.target-rl@pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 };
+
+prop error.io.tom.pbm.rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    error.io.tom.pbm.rl@pcibus/pcidev/pcifn;
 
 prop error.io.tom.pbm.rl@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.tom.pbm.rl@PCI_HB_DEV_PATH,
     ereport.io.tom.pbm.s-rl@PCI_HB_DEV_PATH;
 
-prop error.io.tom.pbm.rl@hostbridge/pcibus/pcidev/pcifn (1)->
-    ereport.io.tom.pbm.target-rl@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.tom.pbm.target-rl@pcibus/pcidev/pcifn (1)->
+    error.io.tom.pbm.target-rl@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.tom.pbm.target-rl@pcibus/pcidev/pcifn (0)->
+    ereport.io.tom.pbm.target-rl@pcibus/pcidev/pcifn;
 
 prop error.io.tom.pbm.rl@hostbridge/pcibus/pcidev/pcifn (0)->
     error.tom.cpu.berr@cpu;
 
+prop error.io.tom.pbm.rl@hostbridge/pcibus/pcidev/pcifn (0)->
+    error.io.pci.retry-to-d@hostbridge/pcibus/pcidev/pcifn;
+
+prop fault.io.pci.device-interr@hostbridge/pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.tom.pbm.tto@hostbridge/pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32};
+
 prop error.io.tom.pbm.tto@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.tom.pbm.tto@PCI_HB_DEV_PATH,
     ereport.io.tom.pbm.s-tto@PCI_HB_DEV_PATH;
 
 prop error.io.tom.pbm.tto@hostbridge/pcibus/pcidev/pcifn (1)->
-    ereport.io.tom.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn;
+    error.io.tom.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn;
+
+prop error.io.tom.pbm.target-tto@pcibus/pcidev/pcifn (0)->
+    ereport.io.tom.pbm.target-tto@pcibus/pcidev/pcifn;
+
+prop error.io.tom.pbm.target-tto@pcibus/pcidev/pcifn (1)->
+    error.io.tom.pbm.target-tto@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
 
 /*
  * Need to add the following tomatillo specific propagations to complete the
- * PCI fault tree.
+ * fault tree. These are to allow propagations to secondary errors and cpu
+ * bus errors, and to represent the way the chip raises rserr
+ * on detection of SERR#
  */
-prop error.io.pci.rec-ma@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.tom.pbm.s-ma@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-ta@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.tom.pbm.s-rta@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-mdpe@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.perr-pw-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.tom.pbm.s-mdpe@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-ta@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.perr-dw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.tom.pbm.s-mdpe@PCI_HB_DEV_PATH;
+
+prop error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.tom.pbm.s-mdpe@PCI_HB_DEV_PATH;
+
+prop error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.tom.cpu.berr@cpu;
 
-prop error.io.pci.rec-mdpe@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.tom.cpu.berr@cpu;
 
-prop error.io.pci.rec-ma@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.tom.cpu.berr@cpu;
 
-prop error.io.pci.serr@hostbridge/pcibus (1)->
+prop error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.pci.rserr@PCI_HB_DEV_PATH;
 
 event ereport.cpu.ultraSPARC-IIIi.berr@cpu{within(5s)};
@@ -292,32 +350,48 @@
 prop error.tom.cpu.berr@cpu (1)->
     ereport.cpu.ultraSPARC-IIIi.berr@cpu;
 
-event defect.io.pci.driver@hostbridge/pcibus/pcidev/pcifn;
-
-prop defect.io.pci.driver@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.tom.mmu.inval@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.prot@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.bva@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.btt@hostbridge/pcibus/pcidev/pcifn;
+/*
+ * A bad request from a downstream device/driver may cause
+ *
+ *  - inval:	iommu invalid entry error.
+ *  - prot:	iommu protection error, attempted to write a read-only page.
+ *  - bva:	iommu bad virtual address, address out of range.
+ *  - btt:	iommu bad tsb size tbw size combination.
+ */
+event error.io.pci.badreq-pw-u@hostbridge/pcibus/pcidev/pcifn;
 
-event defect.io.pci.driver@hostbridge;
+prop error.io.pci.badreq-pw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.tom.mmu.inval@PCI_HB_DEV_PATH,
+    ereport.io.tom.mmu.prot@PCI_HB_DEV_PATH,
+    ereport.io.tom.mmu.bva@PCI_HB_DEV_PATH,
+    ereport.io.tom.mmu.btt@PCI_HB_DEV_PATH;
+
+event error.io.pci.badreq-drw-u@hostbridge/pcibus/pcidev/pcifn;
 
-prop defect.io.pci.driver@hostbridge (0)->
-    error.io.tom.jbus.um@hostbridge,
-    error.io.tom.mmu.inval@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.prot@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.bva@hostbridge/pcibus/pcidev/pcifn,
-    error.io.tom.mmu.btt@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.pci.badreq-drw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.tom.mmu.inval@PCI_HB_DEV_PATH,
+    ereport.io.tom.mmu.prot@PCI_HB_DEV_PATH,
+    ereport.io.tom.mmu.bva@PCI_HB_DEV_PATH,
+    ereport.io.tom.mmu.btt@PCI_HB_DEV_PATH;
 
+event error.io.tom.ecc.drue@hostbridge;
+event error.io.tom.mmu.ue@hostbridge/pcibus;
+event error.io.tom.mmu.to@hostbridge/pcibus;
 event ereport.io.tom.jbus.sgr@hostbridge{within(5s)};
 event ereport.io.tom.jbus.spci@hostbridge{within(5s)};
 event ereport.io.tom.jbus.snp@hostbridge{within(5s)};
+event ereport.io.tom.ecc.drue@hostbridge{within(5s)};
 event ereport.io.tom.mmu.ue@hostbridge/pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.tom.mmu.to@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 
 event ereport.io.tom.nodiag@hostbridge;
 
 /*
  * Upset used to hide ereports that can not be currently diagnosed.
+ *
+ * The ue, to and drue errors can cause a target abort to
+ * be sent onto the pci bus in response to a dma request. We represent this
+ * using a device-ta error to propagate into the generic pci.esc rules.
  */
 engine serd.io.tom.nodiag@hostbridge,
     N=1000, T=1hour, method=persistent,
@@ -330,5 +404,27 @@
     ereport.io.tom.jbus.sgr@hostbridge,
     ereport.io.tom.jbus.spci@hostbridge,
     ereport.io.tom.jbus.snp@hostbridge,
-    ereport.io.tom.mmu.ue@PCI_HB_DEV_PATH,
     ereport.io.tom.nodiag@hostbridge;
+
+prop upset.io.tom.nodiag@hostbridge (0)->
+    error.io.tom.ecc.drue@hostbridge,
+    error.io.tom.mmu.to@hostbridge/pcibus,
+    error.io.tom.mmu.ue@hostbridge/pcibus;
+
+prop error.io.tom.mmu.ue@hostbridge/pcibus (1)->
+    ereport.io.tom.mmu.ue@PCI_HB_DEV_PATH;
+
+prop error.io.tom.mmu.ue@hostbridge/pcibus (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
+
+prop error.io.tom.mmu.to@hostbridge/pcibus (1)->
+    ereport.io.tom.mmu.to@PCI_HB_DEV_PATH;
+
+prop error.io.tom.mmu.to@hostbridge/pcibus (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
+
+prop error.io.tom.ecc.drue@hostbridge (1)->
+    ereport.io.tom.ecc.drue@hostbridge;
+
+prop error.io.tom.ecc.drue@hostbridge (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
--- a/usr/src/cmd/fm/eversholt/files/sparc/sun4u/xmits.esc	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/eversholt/files/sparc/sun4u/xmits.esc	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -45,17 +44,14 @@
 event fault.io.xmits@hostbridge,
     FITrate=HB_FIT, FRU=hostbridge, ASRU=hostbridge;
 
-event error.io.xmits.saf.dstat@hostbridge/pcibus/pcidev/pcifn;
-event error.io.xmits.saf.to@hostbridge/pcibus/pcidev/pcifn;
-event error.io.xmits.saf.bus@hostbridge/pcibus/pcidev/pcifn;
-event error.io.xmits.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
+event error.io.xmits.saf.dstat@hostbridge;
+event error.io.xmits.saf.to@hostbridge;
+event error.io.xmits.saf.bus@hostbridge;
+event error.io.pci.device-ta@hostbridge/pcibus/pcidev/pcifn;
 
 event ereport.io.xmits.saf.ape@hostbridge{within(5s)};
 event ereport.io.xmits.saf.to@hostbridge{within(5s)};
 event ereport.io.xmits.saf.bus@hostbridge{within(5s)};
-event ereport.io.pci.sta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.target-rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.xmits.saf.bca@hostbridge{within(5s)};
 event ereport.io.xmits.saf.bcb@hostbridge{within(5s)};
 event ereport.io.xmits.saf.ciq-to@hostbridge{within(5s)};
@@ -102,6 +98,10 @@
  *  - to:	safari bus timeout.
  *  - bus:	safari bus error.
  *  - dstat:	errant dstat on incoming data.
+ *
+ * The to, bus and dstat errors can cause a target abort to be sent onto the
+ * pci bus in response to a dma request. We represent this using a device-ta
+ * error to propagate into the generic pci.esc rules.
  */
 prop fault.io.xmits@hostbridge (0)->
     ereport.io.xmits.saf.para@hostbridge,
@@ -121,30 +121,23 @@
     ereport.io.xmits.ecc.thresh@hostbridge,
     ereport.io.xmits.pbmx.stdst@PCI_HB_DEV_PATH,
     ereport.io.xmits.pbmx.cndst@PCI_HB_DEV_PATH,
-    error.io.xmits.saf.to@hostbridge/pcibus/pcidev/pcifn,
-    error.io.xmits.saf.bus@hostbridge/pcibus/pcidev/pcifn,
-    error.io.xmits.saf.dstat@hostbridge/pcibus/pcidev/pcifn;
-
-prop error.io.xmits.saf.to@hostbridge/pcibus/pcidev/pcifn (2)->
-    ereport.io.xmits.saf.to@hostbridge,
-    error.io.xmits.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
+    error.io.xmits.saf.to@hostbridge,
+    error.io.xmits.saf.bus@hostbridge,
+    error.io.xmits.saf.dstat@hostbridge;
 
-prop error.io.xmits.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn (1)->
-    ereport.io.pci.sta@PCI_HB_DEV_PATH,
-    ereport.io.pci.target-rta@PCI_HB_DEV_PATH;
+prop error.io.xmits.saf.to@hostbridge (2)->
+    ereport.io.xmits.saf.to@hostbridge,
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
-prop error.io.xmits.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn (0)->
-    ereport.io.pci.rta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.xmits.saf.bus@hostbridge (2)->
+    ereport.io.xmits.saf.bus@hostbridge,
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
-prop error.io.xmits.saf.bus@hostbridge/pcibus/pcidev/pcifn (2)->
-    ereport.io.xmits.saf.bus@hostbridge,
-    error.io.xmits.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
-
-prop error.io.xmits.saf.dstat@hostbridge/pcibus/pcidev/pcifn (1)->
+prop error.io.xmits.saf.dstat@hostbridge (1)->
     ereport.io.xmits.saf.dstat@hostbridge;
 
-prop error.io.xmits.saf.dstat@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.xmits.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.xmits.saf.dstat@hostbridge (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
 
 engine serd.io.xmits.ecc@hostbridge,
     N=3, T=1day, method=persistent,
@@ -180,9 +173,9 @@
  *  - ecc:	multiple PIO CEs.
  */
 prop fault.io.datapath@cpu (0)->
-    error.io.xmits.saf.to@hostbridge/pcibus/pcidev/pcifn,
-    error.io.xmits.saf.bus@hostbridge/pcibus/pcidev/pcifn,
-    error.io.xmits.saf.dstat@hostbridge/pcibus/pcidev/pcifn,
+    error.io.xmits.saf.to@hostbridge,
+    error.io.xmits.saf.bus@hostbridge,
+    error.io.xmits.saf.dstat@hostbridge,
     ereport.io.xmits.saf.ssm-dis@hostbridge,
     ereport.io.xmits.saf.ape@hostbridge;
 
@@ -241,47 +234,42 @@
 prop upset.io.hbus@hostbridge (0)->
     ereport.io.xmits.ecc.pce@hostbridge;
 
-event defect.io.pci.driver@hostbridge/pcibus/pcidev/pcifn;
-
-event error.io.xmits.mmu@hostbridge/pcibus/pcidev/pcifn;
-event error.io.xmits.saf.unmapped@hostbridge/pcibus/pcidev/pcifn;
-
-event ereport.io.xmits.mmu@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.xmits.saf.um@hostbridge{within(5s)};
-
 /*
  * A defective PCI driver may cause:
  *
- *  - unmapped:	safari unmapped address error.
+ *  - um:	safari unmapped address error.
  *  - mmu:	a iommu translation error.
  */
-prop defect.io.pci.driver@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.xmits.saf.unmapped@hostbridge/pcibus/pcidev/pcifn,
-    error.io.xmits.mmu@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.badreq-pw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.badreq-drw-u@hostbridge/pcibus/pcidev/pcifn;
 
-prop error.io.xmits.saf.unmapped@hostbridge/pcibus/pcidev/pcifn (1)->
+event ereport.io.xmits.mmu@hostbridge/pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.xmits.saf.um@hostbridge{within(5s)};
+event ereport.io.pci.rserr@hostbridge/pcibus/pcidev/pcifn{within(5s)};
+
+prop error.io.pci.badreq-pw-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.xmits.saf.um@hostbridge;
 
-prop error.io.xmits.saf.unmapped@hostbridge/pcibus/pcidev/pcifn (0)->
-    error.io.xmits.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.pci.badreq-pw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.xmits.mmu@PCI_HB_DEV_PATH;
 
-prop error.io.xmits.mmu@hostbridge/pcibus/pcidev/pcifn (2)->
-    ereport.io.xmits.mmu@PCI_HB_DEV_PATH,
-    error.io.xmits.saf.tx-ta@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.pci.badreq-drw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.xmits.saf.um@hostbridge;
+
+prop error.io.pci.badreq-drw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.xmits.mmu@PCI_HB_DEV_PATH;
 
 event defect.io.pci.driver@hostbridge;
 
 /*
  * A defective PCI nexus driver may cause:
  *
- *  - unmapped:	safari unmapped address error.
  *  - stmmu:	A streaming DMA split completion transaction
  *		encounters an MMU error.
  *  - cnmmu:	A consistant DMA split completion transaction
  *		encounters an MMU error.
  */
 prop defect.io.pci.driver@hostbridge (0)->
-    error.io.xmits.saf.unmapped@hostbridge/pcibus/pcidev/pcifn,
     ereport.io.xmits.pbmx.stmmu@PCI_HB_DEV_PATH,
     ereport.io.xmits.pbmx.cnmmu@PCI_HB_DEV_PATH;
 
@@ -309,16 +297,29 @@
 fru pcibus/pcidev;
 asru pcibus/pcidev/pcifn;
 
-event fault.io.pci.device@hostbridge/pcibus/pcidev/pcifn,
+event fault.io.pci.device-interr@hostbridge/pcibus/pcidev/pcifn,
+    FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
+
+event fault.io.pci.device-interr@pcibus/pcidev/pcifn,
     FITrate=PCI_DEV_FIT, FRU=pcibus/pcidev, ASRU=pcibus/pcidev/pcifn;
 
 event error.io.xmits.pbm.rl@hostbridge/pcibus/pcidev/pcifn;
+event error.io.xmits.pbm.rl@pcibus/pcidev/pcifn;
+event error.io.xmits.pbm.rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
+event error.io.xmits.pbm.target-rl@pcibus/pcidev/pcifn;
+event error.io.xmits.pbm.target-rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 event error.io.xmits.pbm.tto@hostbridge/pcibus/pcidev/pcifn;
+event error.io.xmits.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn;
+event error.io.xmits.pbm.target-tto@pcibus/pcidev/pcifn;
+event error.io.xmits.pbm.target-tto@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn;
 event error.xmits.cpu.berr@cpu;
-event error.io.pci.rec-ma@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.rec-mdpe@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.rec-ta@hostbridge/pcibus/pcidev/pcifn;
-event error.io.pci.serr@hostbridge/pcibus;
+event error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.perr-pw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.perr-dw-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn;
+event error.io.pci.retry-to-d@hostbridge/pcibus/pcidev/pcifn;
 
 event ereport.io.xmits.sbh@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.xmits.pbm.rl@hostbridge/pcibus/pcidev/pcifn{within(5s)};
@@ -328,9 +329,8 @@
 event ereport.io.xmits.pbm.s-ma@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.xmits.pbm.s-rta@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.xmits.pbm.s-mdpe@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.xmits.pbm.target-rl@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.xmits.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn{within(5s)};
-event ereport.io.pci.rserr@hostbridge/pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.xmits.pbm.target-rl@pcibus/pcidev/pcifn{within(5s)};
+event ereport.io.xmits.pbm.target-tto@pcibus/pcidev/pcifn{within(5s)};
 event ereport.io.pci.sserr@hostbridge/pcibus/pcidev/pcifn{within(5s)};
 event ereport.cpu.ultraSPARC-III.berr@cpu{within(5s)};
 event ereport.cpu.ultraSPARC-IIIplus.berr@cpu{within(5s)};
@@ -343,58 +343,93 @@
  *  - sbh:	a streaming byte hole error.
  *  - rl:	it to exceed the number retriesfor a transaction.
  *  - tto:	it to not assert trdy# within the alloted timeout.
+ *
+ * For rl and tto, there may be a target- ereport on a child device. For rl,
+ * there may also be an associated dto - the retry-to-d error propagates into
+ * the pci.esc rules to handle this.
  */
-prop fault.io.pci.device@hostbridge/pcibus/pcidev/pcifn (0)->
-    ereport.io.xmits.sbh@PCI_HB_DEV_PATH,
-    error.io.xmits.pbm.rl@hostbridge/pcibus/pcidev/pcifn,
-    error.io.xmits.pbm.tto@hostbridge/pcibus/pcidev/pcifn;
+prop fault.io.pci.device-interr@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.xmits.sbh@PCI_HB_DEV_PATH;
+
+prop fault.io.pci.device-interr@pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.xmits.pbm.rl@pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 },
+    error.io.xmits.pbm.target-rl@pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 };
+
+prop error.io.xmits.pbm.rl@pcibus/pcidev/pcifn/pcibus/pcidev/pcifn (1)->
+    error.io.xmits.pbm.rl@pcibus/pcidev/pcifn;
 
 prop error.io.xmits.pbm.rl@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.xmits.pbm.rl@PCI_HB_DEV_PATH,
     ereport.io.xmits.pbm.s-rl@PCI_HB_DEV_PATH;
 
+prop error.io.xmits.pbm.target-rl@pcibus/pcidev/pcifn (1)->
+    error.io.xmits.pbm.target-rl@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
+
+prop error.io.xmits.pbm.target-rl@pcibus/pcidev/pcifn (0)->
+    ereport.io.xmits.pbm.target-rl@pcibus/pcidev/pcifn;
+
 prop error.io.xmits.pbm.rl@hostbridge/pcibus/pcidev/pcifn (0)->
-    ereport.io.xmits.pbm.target-rl@hostbridge/pcibus/pcidev/pcifn;
+    error.io.pci.retry-to-d@hostbridge/pcibus/pcidev/pcifn;
 
 prop error.io.xmits.pbm.rl@hostbridge/pcibus/pcidev/pcifn (0)->
     error.xmits.cpu.berr@cpu;
 
+prop fault.io.pci.device-interr@hostbridge/pcibus/pcidev[fromdev]/pcifn (0)->
+    error.io.xmits.pbm.tto@hostbridge/pcibus/pcidev<todev>/pcifn {
+	fromdev == todev && fromdev != 32 };
+
 prop error.io.xmits.pbm.tto@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.xmits.pbm.tto@PCI_HB_DEV_PATH,
     ereport.io.xmits.pbm.s-tto@PCI_HB_DEV_PATH;
 
-prop error.io.xmits.pbm.tto@hostbridge/pcibus/pcidev/pcifn (0)->
-    ereport.io.xmits.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn;
+prop error.io.xmits.pbm.tto@hostbridge/pcibus/pcidev/pcifn (1)->
+    ereport.io.xmits.bu@PCI_HB_DEV_PATH;
 
 prop error.io.xmits.pbm.tto@hostbridge/pcibus/pcidev/pcifn (1)->
-    ereport.io.xmits.bu@PCI_HB_DEV_PATH;
+    error.io.xmits.pbm.target-tto@hostbridge/pcibus/pcidev/pcifn;
+
+prop error.io.xmits.pbm.target-tto@pcibus/pcidev/pcifn (0)->
+    ereport.io.xmits.pbm.target-tto@pcibus/pcidev/pcifn;
+
+prop error.io.xmits.pbm.target-tto@pcibus/pcidev/pcifn (1)->
+    error.io.xmits.pbm.target-tto@pcibus/pcidev/pcifn/pcibus<>/pcidev<>/pcifn<>;
 
 /*
  * Need to add the following xmits specific propagations to complete the PCI
- * fault tree.
+ * fault tree. These are to allow propagations to secondary errors and cpu
+ * bus errors, and to represent the way the chip can raise both rserr and sserr
+ * on detection of SERR#
  */
-prop error.io.pci.rec-ma@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.xmits.pbm.s-ma@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-ta@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.xmits.pbm.s-rta@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-mdpe@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.perr-dw-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.xmits.pbm.s-mdpe@PCI_HB_DEV_PATH;
+
+prop error.io.pci.perr-pw-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.xmits.pbm.s-mdpe@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-ta@PCI_HB_DEV_PATH (0)->
-    error.xmits.cpu.berr@cpu;
+prop error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    ereport.io.xmits.pbm.s-mdpe@PCI_HB_DEV_PATH;
 
-prop error.io.pci.rec-mdpe@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.ta-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.xmits.cpu.berr@cpu;
 
-prop error.io.pci.rec-ma@PCI_HB_DEV_PATH (0)->
+prop error.io.pci.dpdata-dr-u@hostbridge/pcibus/pcidev/pcifn (0)->
     error.xmits.cpu.berr@cpu;
 
-prop error.io.pci.serr@hostbridge/pcibus (1)->
+prop error.io.pci.ma-u@hostbridge/pcibus/pcidev/pcifn (0)->
+    error.xmits.cpu.berr@cpu;
+
+prop error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn (1)->
     ereport.io.pci.rserr@PCI_HB_DEV_PATH;
 
-prop error.io.pci.serr@hostbridge/pcibus (0)->
+prop error.io.pci.serr-u@hostbridge/pcibus/pcidev/pcifn (0)->
     ereport.io.pci.sserr@PCI_HB_DEV_PATH;
 
 prop error.xmits.cpu.berr@cpu (1)->
@@ -403,10 +438,16 @@
     ereport.cpu.ultraSPARC-IV.berr@cpu,
     ereport.cpu.ultraSPARC-IVplus.berr@cpu;
 
+event error.io.xmits.ecc.drue@hostbridge;
+event ereport.io.xmits.ecc.drue@hostbridge{within(5s)};
 event ereport.io.xmits.nodiag@hostbridge;
 
 /*
  * Upset used to hide ereports that can not be currently diagnosed.
+ *
+ * The drue error can cause a target abort to be sent onto the
+ * pci bus in response to a dma request. We represent this using a device-ta
+ * error to propagate into the generic pci.esc rules.
  */
 engine serd.io.xmits.nodiag@hostbridge,
     N=1000, T=1hour, method=persistent,
@@ -417,4 +458,11 @@
 
 prop upset.io.xmits.nodiag@hostbridge (0)->
     ereport.io.xmits.ecc.s-pce@hostbridge,
+    error.io.xmits.ecc.drue@hostbridge,
     ereport.io.xmits.nodiag@hostbridge;
+
+prop error.io.xmits.ecc.drue@hostbridge (1)->
+    ereport.io.xmits.ecc.drue@hostbridge;
+
+prop error.io.xmits.ecc.drue@hostbridge (0)->
+    error.io.pci.device-ta@PCI_HB_DEV_PATH;
--- a/usr/src/cmd/fm/modules/common/eversholt/fme.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/modules/common/eversholt/fme.c	Sun Apr 23 15:26:28 2006 -0700
@@ -960,7 +960,7 @@
 }
 
 static int mark_arrows(struct fme *fmep, struct event *ep, int mark,
-    unsigned long long at_latest_by, unsigned long long *pdelay);
+    unsigned long long at_latest_by, unsigned long long *pdelay, int keep);
 
 /* ARGSUSED */
 static void
@@ -970,6 +970,7 @@
 	struct arrowlist *ap;
 
 	ep->cached_state = 0;
+	ep->keep_in_tree = 0;
 	for (bp = itree_next_bubble(ep, NULL); bp;
 	    bp = itree_next_bubble(ep, bp)) {
 		if (bp->t != B_FROM)
@@ -2334,7 +2335,7 @@
 	} else {
 		fmep->hesitated = 1;
 	}
-	fme_eval(fmep, NULL);
+	fme_eval(fmep, fmep->e0r);
 }
 
 /*
@@ -2540,6 +2541,7 @@
 			fmd_case_close(fmep->hdl, fmep->fmcase);
 		}
 	}
+	itree_prune(fmep->eventtree);
 }
 
 static void indent(void);
@@ -2625,7 +2627,7 @@
 
 static int
 mark_arrows(struct fme *fmep, struct event *ep, int mark,
-    unsigned long long at_latest_by, unsigned long long *pdelay)
+    unsigned long long at_latest_by, unsigned long long *pdelay, int keep)
 {
 	struct bubble *bp;
 	struct arrowlist *ap;
@@ -2648,9 +2650,13 @@
 			 */
 			if (mark == 0) {
 				ap->arrowp->mark &= ~EFFECTS_COUNTER;
+				if (keep && (ep2->cached_state &
+				    (WAIT_EFFECT|CREDIBLE_EFFECT|PARENT_WAIT)))
+					ep2->keep_in_tree = 1;
 				ep2->cached_state &=
 				    ~(WAIT_EFFECT|CREDIBLE_EFFECT|PARENT_WAIT);
-				(void) mark_arrows(fmep, ep2, mark, 0, NULL);
+				(void) mark_arrows(fmep, ep2, mark, 0, NULL,
+				    keep);
 				continue;
 			}
 			if (ep2->cached_state & REQMNTS_DISPROVED) {
@@ -2687,7 +2693,7 @@
 				continue;
 			}
 			platform_set_payloadnvp(ep2->nvp);
-			if (checkconstraints(fmep, ap->arrowp) != 1) {
+			if (checkconstraints(fmep, ap->arrowp) == 0) {
 				platform_set_payloadnvp(NULL);
 				indent();
 				out(O_ALTFP|O_VERB|O_NONL,
@@ -2721,7 +2727,8 @@
 				out(O_ALTFP|O_VERB, NULL);
 				indent_push("  E");
 				if (mark_arrows(fmep, ep2, PARENT_WAIT,
-				    at_latest_by, &my_delay) == WAIT_EFFECT) {
+				    at_latest_by, &my_delay, 0) ==
+				    WAIT_EFFECT) {
 					retval = WAIT_EFFECT;
 					if (overall_delay > my_delay)
 						overall_delay = my_delay;
@@ -2746,7 +2753,7 @@
 				out(O_ALTFP|O_VERB, NULL);
 				indent_push("  E");
 				if (mark_arrows(fmep, ep2, mark, at_latest_by,
-				    &my_delay) == WAIT_EFFECT) {
+				    &my_delay, 0) == WAIT_EFFECT) {
 					retval = WAIT_EFFECT;
 					if (overall_delay > my_delay)
 						overall_delay = my_delay;
@@ -2777,7 +2784,7 @@
 	out(O_ALTFP|O_VERB, NULL);
 
 	(void) mark_arrows(fmep, fault_event, CREDIBLE_EFFECT, at_latest_by,
-	    &my_delay);
+	    &my_delay, 0);
 	for (error_event = fmep->observations;
 	    error_event; error_event = error_event->observations) {
 		indent();
@@ -2799,7 +2806,12 @@
 			out(O_ALTFP|O_VERB, " triggered");
 		}
 	}
-	(void) mark_arrows(fmep, fault_event, 0, 0, NULL);
+	if (return_value == FME_DISPROVED) {
+		(void) mark_arrows(fmep, fault_event, 0, 0, NULL, 0);
+	} else {
+		fault_event->keep_in_tree = 1;
+		(void) mark_arrows(fmep, fault_event, 0, 0, NULL, 1);
+	}
 
 	indent();
 	out(O_ALTFP|O_VERB|O_NONL, "<-EFFECTS %s ",
@@ -3081,7 +3093,7 @@
 			 * from traversing this arrow
 			 */
 			platform_set_payloadnvp(ep->nvp);
-			if (checkconstraints(fmep, ap->arrowp) != 1)
+			if (checkconstraints(fmep, ap->arrowp) == 0)
 				do_not_follow = 1;
 			platform_set_payloadnvp(NULL);
 			if (do_not_follow) {
--- a/usr/src/cmd/fm/modules/common/eversholt/iexpr.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/modules/common/eversholt/iexpr.c	Sun Apr 23 15:26:28 2006 -0700
@@ -52,6 +52,7 @@
 static struct iexpr {
 	struct node *np;
 	struct iexpr *next;	/* next entry in hash bucket */
+	int count;
 } *Cache[IEXPRSZ];
 
 /*
@@ -238,6 +239,7 @@
 		if (iexpr_cmp(cp->np, np) == 0) {
 			/* found it */
 			tree_free(np);
+			cp->count++;
 			return (cp->np);
 		}
 
@@ -245,6 +247,7 @@
 	cp = MALLOC(sizeof (*cp));
 	cp->np = np;
 	cp->next = bucketp;
+	cp->count = 1;
 	Cache[idx] = cp;
 
 	stats_counter_bump(Niexpr);
@@ -252,6 +255,32 @@
 	return (np);
 }
 
+void
+iexpr_free(struct node *np)
+{
+	unsigned idx = iexpr_hash(np) % IEXPRSZ;
+	struct iexpr *cp;
+	struct iexpr *prevcp = NULL;
+
+	/* search cache */
+	for (cp = Cache[idx]; cp != NULL; cp = cp->next) {
+		if (iexpr_cmp(cp->np, np) == 0) {
+			/* found it */
+			cp->count--;
+			if (cp->count == 0) {
+				tree_free(cp->np);
+				if (prevcp == NULL)
+					Cache[idx] = cp->next;
+				else
+					prevcp->next = cp->next;
+				FREE(cp);
+			}
+			return;
+		}
+		prevcp = cp;
+	}
+}
+
 /*
  * iexpr_cached -- return true if np is in the iexpr cache
  */
--- a/usr/src/cmd/fm/modules/common/eversholt/iexpr.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/modules/common/eversholt/iexpr.h	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -39,6 +38,7 @@
 void iexpr_init(void);
 struct node *iexpr(struct node *np);
 int iexpr_cached(struct node *np);
+void iexpr_free(struct node *np);
 void iexpr_fini(void);
 
 #ifdef	__cplusplus
--- a/usr/src/cmd/fm/modules/common/eversholt/itree.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/modules/common/eversholt/itree.c	Sun Apr 23 15:26:28 2006 -0700
@@ -95,10 +95,12 @@
     struct node *lnp, struct node *anp, struct wildcardinfo **wcproot);
 static void hmatch(struct info *infop, struct node *np, struct node *nextnp);
 static void itree_pbubble(int flags, struct bubble *bp);
+static void itree_pruner(void *left, void *right, void *arg);
 static void itree_destructor(void *left, void *right, void *arg);
 static int itree_set_arrow_traits(struct arrow *ap, struct node *fromev,
     struct node *toev, struct lut *ex);
 static void itree_free_arrowlists(struct bubble *bubp, int arrows_too);
+static void itree_prune_arrowlists(struct bubble *bubp);
 static void arrow_add_within(struct arrow *ap, struct node *xpr);
 static struct arrow *itree_add_arrow(struct bubble *frombubblep,
     struct bubble *tobubblep, struct node *apnode, struct node *fromevent,
@@ -1427,6 +1429,12 @@
 	lut_free(lutp, itree_destructor, NULL);
 }
 
+void
+itree_prune(struct lut *lutp)
+{
+	lut_walk(lutp, itree_pruner, NULL);
+}
+
 int
 itree_nameinstancecmp(struct node *np1, struct node *np2)
 {
@@ -1608,10 +1616,12 @@
 	struct bubble *nextbub, *bub;
 
 	/* Free the properties */
-	lut_free(ep->props, instances_destructor, NULL);
+	if (ep->props)
+		lut_free(ep->props, instances_destructor, NULL);
 
 	/* Free the payload properties */
-	lut_free(ep->payloadprops, payloadprops_destructor, NULL);
+	if (ep->payloadprops)
+		lut_free(ep->payloadprops, payloadprops_destructor, NULL);
 
 	/* Free my bubbles */
 	for (bub = ep->bubbles; bub != NULL; ) {
@@ -1636,6 +1646,38 @@
 	FREE(ep);
 }
 
+/*ARGSUSED*/
+static void
+itree_pruner(void *left, void *right, void *arg)
+{
+	struct event *ep = (struct event *)right;
+	struct bubble *nextbub, *bub;
+
+	if (ep->keep_in_tree)
+		return;
+
+	/* Free the properties */
+	lut_free(ep->props, instances_destructor, NULL);
+
+	/* Free the payload properties */
+	lut_free(ep->payloadprops, payloadprops_destructor, NULL);
+
+	/* Free my bubbles */
+	for (bub = ep->bubbles; bub != NULL; ) {
+		nextbub = bub->next;
+		itree_prune_arrowlists(bub);
+		itree_free_bubble(bub);
+		bub = nextbub;
+	}
+
+	if (ep->nvp != NULL)
+		nvlist_free(ep->nvp);
+	ep->props = NULL;
+	ep->payloadprops = NULL;
+	ep->bubbles = NULL;
+	ep->nvp = NULL;
+}
+
 static void
 itree_free_bubble(struct bubble *freeme)
 {
@@ -1818,8 +1860,11 @@
 	/* handle constraints on the to event in the prop statement */
 	epnames[0] = toev->u.event.epname;
 	epnames[1] = fromev->u.event.epname;
-	if (eval_potential(toev->u.event.eexprlist, ex, epnames, &newc) == 0)
+	if (eval_potential(toev->u.event.eexprlist, ex, epnames, &newc) == 0) {
+		if (newc != NULL)
+			tree_free(newc);
 		return (0);		/* constraint disallows arrow */
+	}
 
 	/* if we came up with any deferred constraints, add them to arrow */
 	if (newc != NULL)
@@ -1904,6 +1949,52 @@
 	}
 }
 
+static void
+itree_delete_arrow(struct bubble *bubp, struct arrow *arrow)
+{
+	struct arrowlist *al, *oal;
+
+	al = bubp->arrows;
+	if (al->arrowp == arrow) {
+		bubp->arrows = al->next;
+		bzero(al, sizeof (*al));
+		FREE(al);
+		return;
+	}
+	while (al != NULL) {
+		oal = al;
+		al = al->next;
+		ASSERT(al != NULL);
+		if (al->arrowp == arrow) {
+			oal->next = al->next;
+			bzero(al, sizeof (*al));
+			FREE(al);
+			return;
+		}
+	}
+}
+
+static void
+itree_prune_arrowlists(struct bubble *bubp)
+{
+	struct arrowlist *al, *nal;
+
+	al = bubp->arrows;
+	while (al != NULL) {
+		nal = al->next;
+		if (bubp->t == B_FROM)
+			itree_delete_arrow(al->arrowp->head, al->arrowp);
+		else
+			itree_delete_arrow(al->arrowp->tail, al->arrowp);
+		itree_free_constraints(al->arrowp);
+		bzero(al->arrowp, sizeof (struct arrow));
+		FREE(al->arrowp);
+		bzero(al, sizeof (*al));
+		FREE(al);
+		al = nal;
+	}
+}
+
 struct arrowlist *
 itree_next_arrow(struct bubble *bubble, struct arrowlist *last)
 {
@@ -1962,6 +2053,8 @@
 		ASSERT(cl->cnode != NULL);
 		if (!iexpr_cached(cl->cnode))
 			tree_free(cl->cnode);
+		else
+			iexpr_free(cl->cnode);
 		bzero(cl, sizeof (*cl));
 		FREE(cl);
 		cl = ncl;
--- a/usr/src/cmd/fm/modules/common/eversholt/itree.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/fm/modules/common/eversholt/itree.h	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -87,6 +86,7 @@
 	struct lut *payloadprops;	/* nvpairs for problem payload */
 	int count;			/* for reports, number seen */
 	int cached_state;
+	int keep_in_tree;
 	unsigned long long cached_delay;
 	struct bubble {
 		struct bubble *next;
@@ -135,6 +135,7 @@
 
 struct lut *itree_create(struct config *croot);
 void itree_free(struct lut *itp);
+void itree_prune(struct lut *itp);
 struct event *itree_lookup(struct lut *itp,
     const char *ename, const struct ipath *ipp);
 
--- a/usr/src/cmd/th_tools/th_script.sh	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/cmd/th_tools/th_script.sh	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
 #
 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 # or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
 # CDDL HEADER END
 #
 #
-# Copyright (c) 2000-2001 by Sun Microsystems, Inc.
-# All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
 #
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
 
@@ -179,9 +178,13 @@
 		if [ "${status[2]}" -gt 0 ]; then
 			res="test not triggered"
 		elif [ "${status[1]}" -eq 0 ]; then
-			res="success (corruption undetected)"
+			res="success (error undetected)"
 		elif [ "${status[1]}" -gt 0 ]; then
-			res="success (corruption reported)"
+			if [ "${status[6]}" -eq 16 ]; then
+				res="failure (no service impact reported)"
+			else
+				res="success (error reported)"
+			fi
 		else
 			res=
 		fi
@@ -200,7 +203,13 @@
 		echo "\tFail Time :\t${status[0]}\tMsg Time  :\t${status[1]}"
 		echo "\tAcc count :\t${status[2]}\tFail count:\t${status[3]}"
 		echo "\tAccess Chk:\t${status[4]}\tEmsg count:\t${status[5]}"
-		echo "\tSeverity  :\t${status[6]}"
+		if [ "${status[6]}" -eq 0 ]; then
+			echo "\tSeverity:\tSERVICE UNAFFECTED"
+		elif [ "${status[6]}" -eq -16 ]; then
+			echo "\tSeverity:\tSERVICE DEGRADED"
+		elif [ "${status[6]}" -eq -32 ]; then
+			echo "\tSeverity:\tSERVICE LOST"
+		fi
 		((edefid += 1))
 	done
 
--- a/usr/src/lib/fm/topo/files/i86pc/hc-topology.xml	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/files/i86pc/hc-topology.xml	Sun Apr 23 15:26:28 2006 -0700
@@ -44,6 +44,11 @@
           path='%r/usr/platform/i86pc/lib/fm/topo/plugins' />
       </range>
 
+      <range name='hostbridge' min='0' max='254'>
+        <enum-method name='hostbridge' version='1'
+          path='%r/usr/platform/i86pc/lib/fm/topo/plugins' />
+      </range>
+
     </dependents>
   </range>
 
--- a/usr/src/lib/fm/topo/modules/common/did.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/modules/common/did.c	Sun Apr 23 15:26:28 2006 -0700
@@ -129,7 +129,7 @@
 	if (*slotnum == -1 && (excap & PCIE_PCIECAP_SLOT_IMPL) != 0) {
 		uint_t slotcap;
 		int e;
-		e = di_uintprop_get(src, SAVED_PCIEX_SLOTCAP_REG, &slotcap);
+		e = di_uintprop_get(src, "pcie-slotcap-reg", &slotcap);
 		if (e == 0)
 			*slotnum = slotcap >> PCIE_SLOTCAP_PHY_SLOT_NUM_SHIFT;
 	}
@@ -248,6 +248,8 @@
 		np->dp_bus = ibus;
 	np->dp_dev = PCI_REG_DEV_G(reg);
 	np->dp_fn = PCI_REG_FUNC_G(reg);
+	np->dp_bdf = (PCI_REG_BUS_G(reg) << 8) | (PCI_REG_DEV_G(reg) << 3) |
+	    PCI_REG_FUNC_G(reg);
 	/*
 	 * There *may* be a class code we can capture.  If there wasn't
 	 * one, capture that fact by setting the class value to -1.
@@ -263,7 +265,7 @@
 	 * If there wasn't one, the capabilities will be the out-of-bounds
 	 * value of zero.
 	 */
-	(void) di_uintprop_get(src, SAVED_PCIEX_CAP_REG, &np->dp_excap);
+	(void) di_uintprop_get(src, "pcie-capid-reg", &np->dp_excap);
 	/*
 	 * There *may* be a physical slot number property we can capture.
 	 */
@@ -431,6 +433,13 @@
 	return ((int)dp->dp_excap);
 }
 
+int
+did_bdf(did_t *dp)
+{
+	assert(dp != NULL);
+	return ((int)dp->dp_bdf);
+}
+
 const char *
 did_label(did_t *dp, int dev)
 {
--- a/usr/src/lib/fm/topo/modules/common/did.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/modules/common/did.h	Sun Apr 23 15:26:28 2006 -0700
@@ -52,6 +52,7 @@
 extern int did_physslot(did_t *);
 extern int did_inherit(tnode_t *, tnode_t *);
 extern int did_excap(did_t *);
+extern int did_bdf(did_t *);
 
 extern did_t *did_create(did_hash_t *, di_node_t, int, int, int, int);
 extern did_t *did_find(did_hash_t *, di_node_t);
--- a/usr/src/lib/fm/topo/modules/common/did_impl.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/modules/common/did_impl.h	Sun Apr 23 15:26:28 2006 -0700
@@ -80,6 +80,7 @@
 	int dp_bus;		/* PCI bus number */
 	int dp_dev;		/* PCI device number on the above bus */
 	int dp_fn;		/* PCI function number of the above device */
+	int dp_bdf;		/* PCI "real" bdf */
 	/*
 	 * There may be some slot name info on devinfo node for a bus or
 	 * hostbridge.  We'll copy or reference it for child nodes of that
--- a/usr/src/lib/fm/topo/modules/common/did_props.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/modules/common/did_props.c	Sun Apr 23 15:26:28 2006 -0700
@@ -54,6 +54,8 @@
     const char *, const char *, const char *);
 static int EXCAP_set(tnode_t *, did_t *,
     const char *, const char *, const char *);
+static int BDF_set(tnode_t *, did_t *,
+    const char *, const char *, const char *);
 static int label_set(tnode_t *, did_t *,
     const char *, const char *, const char *);
 static int maybe_di_chars_copy(tnode_t *, did_t *,
@@ -83,6 +85,8 @@
 	    TOPO_STABILITY_PRIVATE, DRIVERprop_set },
 	{ NULL, TOPO_PGROUP_PCI, TOPO_PROP_EXCAP,
 	    TOPO_STABILITY_PRIVATE, EXCAP_set },
+	{ DI_CLASSPROP, TOPO_PGROUP_PCI, TOPO_PROP_CLASS,
+	    TOPO_STABILITY_PRIVATE, maybe_di_uint_to_str },
 	{ DI_VENDIDPROP, TOPO_PGROUP_PCI, TOPO_PROP_VENDID,
 	    TOPO_STABILITY_PRIVATE, maybe_di_uint_to_str },
 	{ NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL,
@@ -124,6 +128,8 @@
 	    TOPO_STABILITY_PRIVATE, DRIVERprop_set },
 	{ NULL, TOPO_PGROUP_PCI, TOPO_PROP_EXCAP,
 	    TOPO_STABILITY_PRIVATE, EXCAP_set },
+	{ NULL, TOPO_PGROUP_PCI, TOPO_PROP_BDF,
+	    TOPO_STABILITY_PRIVATE, BDF_set },
 	{ NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_LABEL,
 	    TOPO_STABILITY_PRIVATE, label_set },
 	{ NULL, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU,
@@ -678,6 +684,25 @@
 	return (uint_to_strprop(did_mod(pd), v, tn, tpgrp, tpnm));
 }
 
+/*ARGSUSED*/
+static int
+BDF_set(tnode_t *tn, did_t *pd,
+    const char *dpnm, const char *tpgrp, const char *tpnm)
+{
+	int bdf;
+	char str[23]; /* '0x' + sizeof (UINT64_MAX) + '\0' */
+	int e;
+
+	if ((bdf = did_bdf(pd)) <= 0)
+		return (0);
+
+	(void) snprintf(str, 23, "0x%x", bdf);
+	if (topo_prop_set_string(tn,
+	    tpgrp, tpnm, TOPO_PROP_SET_ONCE, str, &e) < 0)
+		return (topo_mod_seterrno(did_mod(pd), e));
+	return (0);
+}
+
 int
 did_props_set(tnode_t *tn, did_t *pd, txprop_t txarray[], int txnum)
 {
--- a/usr/src/lib/fm/topo/modules/common/did_props.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/modules/common/did_props.h	Sun Apr 23 15:26:28 2006 -0700
@@ -67,12 +67,15 @@
 #define	TOPO_PROP_DRIVER	"DRIVER"
 #define	TOPO_PROP_VENDID	"VENDOR-ID"
 #define	TOPO_PROP_DEVID		"DEVICE-ID"
+#define	TOPO_PROP_CLASS		"CLASS-CODE"
 #define	TOPO_PROP_EXCAP		"EXCAP"
+#define	TOPO_PROP_BDF		"BDF"
 #define	TOPO_PROP_DEV		"DEV"
 
 #define	DI_DEVTYPPROP	"device_type"
 #define	DI_VENDIDPROP	"vendor-id"
 #define	DI_DEVIDPROP	"device-id"
+#define	DI_CLASSPROP	"class-code"
 #define	DI_REGPROP	"reg"
 #define	DI_CCPROP	"class-code"
 #define	DI_PHYSPROP	"physical-slot#"
--- a/usr/src/lib/fm/topo/modules/common/hostbridge.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/modules/common/hostbridge.h	Sun Apr 23 15:26:28 2006 -0700
@@ -49,6 +49,8 @@
 #define	SCHIZO "pcisch"
 #define	PSYCHO "pcipsy"
 #define	NPE "npe"
+#define	PCIE_PCI "pcie_pci"
+#define	PCI_PCI "pci_pci"
 #define	PCI "pci"
 #define	PX "px"
 
--- a/usr/src/lib/fm/topo/modules/common/pcibus.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus.c	Sun Apr 23 15:26:28 2006 -0700
@@ -464,8 +464,8 @@
 
 	if (strcmp(name, PCI_BUS) != 0 && strcmp(name, PCIEX_BUS) != 0) {
 		topo_mod_dprintf(PciHdl,
-		    "Currently only know how to enumerate %s or %s.\n",
-		    PCI_BUS, PCIEX_BUS);
+		    "Currently only know how to enumerate %s or %s not %s.\n",
+		    PCI_BUS, PCIEX_BUS, name);
 		return (0);
 	}
 	pname = topo_node_name(troot);
--- a/usr/src/lib/fm/topo/modules/common/pcibus_labels.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/modules/common/pcibus_labels.c	Sun Apr 23 15:26:28 2006 -0700
@@ -165,11 +165,14 @@
 	int err;
 
 	/*
-	 * If it's not a device, just inherit any label from our parent
+	 * If it's not a device or a PCI-express bus (which could potentially
+	 * represent a slot, and therefore we might need to capture its slot
+	 * name information), just inherit any label from our parent
 	 */
 	*out = NULL;
 	nm = topo_node_name(node);
-	if (strcmp(nm, PCI_DEVICE) != 0 && strcmp(nm, PCIEX_DEVICE) != 0) {
+	if (strcmp(nm, PCI_DEVICE) != 0 && strcmp(nm, PCIEX_DEVICE) != 0 &&
+	    strcmp(nm, PCIEX_BUS) != 0) {
 		if (topo_node_label_set(node, NULL, &err) < 0)
 			if (err != ETOPO_PROP_NOENT)
 				return (topo_mod_seterrno(PciHdl, err));
--- a/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/lib/fm/topo/modules/i86pc/hostbridge/hb_i86pc.c	Sun Apr 23 15:26:28 2006 -0700
@@ -28,6 +28,7 @@
 
 #include <fm/topo_mod.h>
 #include <libdevinfo.h>
+#include <strings.h>
 #include "pcibus.h"
 #include "hostbridge.h"
 #include "did.h"
@@ -70,7 +71,7 @@
 {
 	di_node_t devtree;
 	di_node_t pnode;
-	char *eplain;
+	di_node_t cnode;
 	int hbcnt = 0;
 
 	/* Scan for buses, top-level devinfo nodes with the right driver */
@@ -81,29 +82,40 @@
 		return (0);
 	}
 
-	/*
-	 * By default we do not enumerate generic PCI on x86
-	 */
-	eplain = getenv("TOPOENUMPLAINPCI");
-	if (eplain != NULL) {
-		pnode = di_drv_first_node(PCI, devtree);
-		while (pnode != DI_NODE_NIL) {
-			if (hb_process(ptn, hbcnt++, pnode) < 0) {
-				di_fini(devtree);
-				topo_node_range_destroy(ptn, HOSTBRIDGE);
-				return (topo_mod_seterrno(HbHdl,
-				    EMOD_PARTIAL_ENUM));
-			}
-			pnode = di_drv_next_node(pnode);
+	pnode = di_drv_first_node(PCI, devtree);
+	while (pnode != DI_NODE_NIL) {
+		if (hb_process(ptn, hbcnt++, pnode) < 0) {
+			di_fini(devtree);
+			topo_node_range_destroy(ptn, HOSTBRIDGE);
+			return (topo_mod_seterrno(HbHdl, EMOD_PARTIAL_ENUM));
 		}
+		pnode = di_drv_next_node(pnode);
 	}
 
 	pnode = di_drv_first_node(NPE, devtree);
 	while (pnode != DI_NODE_NIL) {
-		if (rc_process(ptn, hbcnt++, pnode) < 0) {
-			di_fini(devtree);
-			topo_node_range_destroy(ptn, HOSTBRIDGE);
-			return (topo_mod_seterrno(HbHdl, EMOD_PARTIAL_ENUM));
+		for (cnode = di_child_node(pnode); cnode != DI_NODE_NIL;
+		    cnode = di_sibling_node(cnode)) {
+			if (di_driver_name(cnode) == NULL)
+				continue;
+			if (strcmp(di_driver_name(cnode), PCI_PCI) == 0) {
+				if (hb_process(ptn, hbcnt++, cnode) < 0) {
+					di_fini(devtree);
+					topo_node_range_destroy(ptn,
+					    HOSTBRIDGE);
+					return (topo_mod_seterrno(HbHdl,
+					    EMOD_PARTIAL_ENUM));
+				}
+			}
+			if (strcmp(di_driver_name(cnode), PCIE_PCI) == 0) {
+				if (rc_process(ptn, hbcnt++, cnode) < 0) {
+					di_fini(devtree);
+					topo_node_range_destroy(ptn,
+					    HOSTBRIDGE);
+					return (topo_mod_seterrno(HbHdl,
+					    EMOD_PARTIAL_ENUM));
+				}
+			}
 		}
 		pnode = di_drv_next_node(pnode);
 	}
--- a/usr/src/pkgdefs/SUNW0on/prototype_com	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/pkgdefs/SUNW0on/prototype_com	Sun Apr 23 15:26:28 2006 -0700
@@ -54,6 +54,7 @@
 f none usr/lib/locale/C/LC_MESSAGES/ZFS.po               644 root bin
 f none usr/lib/locale/C/LC_MESSAGES/SCA500.po            644 root bin
 f none usr/lib/locale/C/LC_MESSAGES/SCA1000.po           644 root bin
+f none usr/lib/locale/C/LC_MESSAGES/PCIEX.po             644 root bin
 f none usr/lib/locale/C/LC_MESSAGES/SUNW_OST_ADMIN.po    644 root sys
 f none usr/lib/locale/C/LC_MESSAGES/SUNW_OST_NETRPC.po   644 root sys
 f none usr/lib/locale/C/LC_MESSAGES/SUNW_OST_OSCMD.po    644 root sys
--- a/usr/src/pkgdefs/SUNWfmd/prototype_com	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/pkgdefs/SUNWfmd/prototype_com	Sun Apr 23 15:26:28 2006 -0700
@@ -49,8 +49,10 @@
 f none usr/lib/fm/dict/SUNOS.dict 444 root bin
 f none usr/lib/fm/dict/PCI.dict 444 root bin
 f none usr/lib/fm/dict/ZFS.dict 444 root bin
+f none usr/lib/fm/dict/PCIEX.dict 444 root bin
 d none usr/lib/fm/eft 755 root bin
 f none usr/lib/fm/eft/pci.eft 444 root bin
+f none usr/lib/fm/eft/pciex.eft 444 root bin
 d none usr/lib/fm/fmd 755 root bin
 f none usr/lib/fm/fmd/fmd 555 root bin
 f none usr/lib/fm/fmd/fminject 555 root bin
@@ -109,6 +111,7 @@
 f none usr/lib/locale/C/LC_MESSAGES/SUNOS.mo 444 root bin
 f none usr/lib/locale/C/LC_MESSAGES/PCI.mo 444 root bin
 f none usr/lib/locale/C/LC_MESSAGES/ZFS.mo 444 root bin
+f none usr/lib/locale/C/LC_MESSAGES/PCIEX.mo 444 root bin
 d none usr/lib/mdb 755 root sys
 d none usr/lib/mdb/proc 755 root sys
 f none usr/lib/mdb/proc/fmd.so 555 root sys
--- a/usr/src/uts/common/Makefile.files	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/Makefile.files	Sun Apr 23 15:26:28 2006 -0700
@@ -204,6 +204,7 @@
 		serializer.o	\
 		pci_intr_lib.o	\
 		pci_cap.o	\
+		pcifm.o		\
 		pgrp.o		\
 		pgrpsys.o	\
 		pid.o		\
--- a/usr/src/uts/common/crypto/io/dca.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/crypto/io/dca.c	Sun Apr 23 15:26:28 2006 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -4840,7 +4840,8 @@
 		/*
 		 * Initialize pci ereport capabilities if ereport capable
 		 */
-		if (DDI_FM_EREPORT_CAP(dca->fm_capabilities))
+		if (DDI_FM_EREPORT_CAP(dca->fm_capabilities) ||
+		    DDI_FM_ERRCB_CAP(dca->fm_capabilities))
 			pci_ereport_setup(dca->dca_dip);
 
 		/*
@@ -4872,7 +4873,8 @@
 		/*
 		 * Release any resources allocated by pci_ereport_setup()
 		 */
-		if (DDI_FM_EREPORT_CAP(dca->fm_capabilities)) {
+		if (DDI_FM_EREPORT_CAP(dca->fm_capabilities) ||
+		    DDI_FM_ERRCB_CAP(dca->fm_capabilities)) {
 			pci_ereport_teardown(dca->dca_dip);
 		}
 
@@ -4895,42 +4897,19 @@
 /*
  * The IO fault service error handling callback function
  */
+/*ARGSUSED*/
 static int
 dca_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
 {
-	int		rv;
 	dca_t		*dca = (dca_t *)impl_data;
-	uint16_t	pci_status;
-	ddi_fm_error_t	dca_err;
-
-	rv = err->fme_status = DDI_FM_OK;
-	if (err->fme_flag == DDI_FM_ERR_EXPECTED) {
-		/*
-		 * dca never perfrom DDI_ACC_CAUTIOUS protected operations
-		 * but if it did. we would handle it here
-		 */
-		return (rv);
-	}
-
-	/*
-	 * See if there is a pci error as well
-	 * The updated pci_ereport_post function requires a reinitialized
-	 * ddi_fm_error_t structure with a zero ena field.
-	 */
-	bzero(&dca_err, sizeof (ddi_fm_error_t));
-	dca_err.fme_version = DDI_FME_VERSION;
-	dca_err.fme_flag = DDI_FM_ERR_UNEXPECTED;
-	pci_ereport_post(dip, &dca_err, &pci_status);
-	if (pci_status != 0) {
+
+	pci_ereport_post(dip, err, NULL);
+	if (err->fme_status == DDI_FM_FATAL) {
 		dca_failure(dca, DDI_DATAPATH_FAULT,
 		    DCA_FM_ECLASS_NONE, dca_ena(0), CRYPTO_DEVICE_ERROR,
 		    "fault PCI in FMA callback.");
-
-		rv = err->fme_status = DDI_FM_FATAL;
-		return (rv);
 	}
-
-	return (rv);
+	return (err->fme_status);
 }
 
 
@@ -4940,17 +4919,13 @@
 {
 	ddi_fm_error_t	de;
 	int		version = 0;
-	uint16_t	pci_status;
-
-	if (DDI_FM_EREPORT_CAP(dca->fm_capabilities)) {
-		ddi_fm_acc_err_get(handle, &de, version);
-		if (de.fme_status != DDI_FM_OK) {
-			pci_ereport_post(dca->dca_dip, &de, &pci_status);
-			dca_failure(dca, DDI_DATAPATH_FAULT,
-			    eclass_index, fm_ena_increment(de.fme_ena),
-			    CRYPTO_DEVICE_ERROR, "");
-			return (DDI_FAILURE);
-		}
+
+	ddi_fm_acc_err_get(handle, &de, version);
+	if (de.fme_status != DDI_FM_OK) {
+		dca_failure(dca, DDI_DATAPATH_FAULT,
+		    eclass_index, fm_ena_increment(de.fme_ena),
+		    CRYPTO_DEVICE_ERROR, "");
+		return (DDI_FAILURE);
 	}
 
 	return (DDI_SUCCESS);
@@ -4962,19 +4937,14 @@
 {
 	ddi_fm_error_t	de;
 	int		version = 0;
-	uint16_t	pci_status;
-
-	if (DDI_FM_EREPORT_CAP(dca->fm_capabilities)) {
-		ddi_fm_dma_err_get(handle, &de, version);
-		if (de.fme_status != DDI_FM_OK) {
-			pci_ereport_post(dca->dca_dip, &de, &pci_status);
-			dca_failure(dca, DDI_DATAPATH_FAULT,
-			    eclass_index, fm_ena_increment(de.fme_ena),
-			    CRYPTO_DEVICE_ERROR, "");
-			return (DDI_FAILURE);
-		}
+
+	ddi_fm_dma_err_get(handle, &de, version);
+	if (de.fme_status != DDI_FM_OK) {
+		dca_failure(dca, DDI_DATAPATH_FAULT,
+		    eclass_index, fm_ena_increment(de.fme_ena),
+		    CRYPTO_DEVICE_ERROR, "");
+		return (DDI_FAILURE);
 	}
-
 	return (DDI_SUCCESS);
 }
 
--- a/usr/src/uts/common/io/bge/bge_chip2.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/bge/bge_chip2.c	Sun Apr 23 15:26:28 2006 -0700
@@ -1062,7 +1062,7 @@
 	 * accesses internally, even with polling OFF.
 	 */
 	regval1 = regval2 = bge_reg_get32(bgep, MI_COMMS_REG);
-	for (timeout = 1000; ; ) {
+	for (timeout = 100; ; ) {
 		if ((regval2 & MI_COMMS_START) == 0) {
 			bge_reg_put32(bgep, MI_COMMS_REG, cmd);
 			break;
@@ -1073,14 +1073,13 @@
 		regval2 = bge_reg_get32(bgep, MI_COMMS_REG);
 	}
 
-	if (timeout != 1000)
+	if (timeout == 0)
+		return ((uint16_t)~0u);
+
+	if (timeout != 100)
 		BGE_REPORT((bgep, "bge_mii_access: cmd 0x%x -- "
 			"MI_COMMS_START set for %d us; 0x%x->0x%x",
-			cmd, 10*(1000-timeout), regval1, regval2));
-
-	ASSERT(timeout != 0);
-	if (timeout == 0)
-		return ((uint16_t)~0u);
+			cmd, 10*(100-timeout), regval1, regval2));
 
 	regval1 = bge_reg_get32(bgep, MI_COMMS_REG);
 	for (timeout = 1000; ; ) {
@@ -1099,7 +1098,6 @@
 	if (regval2 & MI_COMMS_READ_FAILED)
 		return ((uint16_t)~0u);
 
-	ASSERT(timeout != 0);
 	if (timeout == 0)
 		return ((uint16_t)~0u);
 
@@ -1133,11 +1131,9 @@
 		regval2 = regval1;
 	}
 
-	ASSERT((regval2 & MI_COMMS_START) == 0);
 	if (regval2 & MI_COMMS_START)
 		return ((uint16_t)~0u);
 
-	ASSERT((regval2 & MI_COMMS_READ_FAILED) == 0);
 	if (regval2 & MI_COMMS_READ_FAILED)
 		return ((uint16_t)~0u);
 
@@ -1277,7 +1273,6 @@
 		drv_usecwait(1);
 	}
 
-	ASSERT((regval & SEEPROM_ACCESS_START) == 0);
 	if (regval & SEEPROM_ACCESS_COMPLETE) {
 		/*
 		 * All OK; read the SEEPROM data register, then write back
@@ -1438,8 +1433,6 @@
 static void
 bge_nvmem_relinquish(bge_t *bgep)
 {
-	uint32_t regval;
-
 	ASSERT(mutex_owned(bgep->genlock));
 
 	switch (bgep->chipid.nvtype) {
@@ -1464,15 +1457,13 @@
 	/*
 	 * Our own request should be present (whether or not granted) ...
 	 */
-	regval = bge_reg_get32(bgep, NVM_SW_ARBITRATION_REG);
-	ASSERT((regval & NVM_READ_REQ) != 0);
+	(void) bge_reg_get32(bgep, NVM_SW_ARBITRATION_REG);
 
 	/*
 	 * ... this will make it go away.
 	 */
 	bge_reg_put32(bgep, NVM_SW_ARBITRATION_REG, NVM_RESET_REQ);
-	regval = bge_reg_get32(bgep, NVM_SW_ARBITRATION_REG);
-	ASSERT((regval & NVM_READ_REQ) == 0);
+	(void) bge_reg_get32(bgep, NVM_SW_ARBITRATION_REG);
 }
 
 /*
@@ -1547,12 +1538,10 @@
 	 * caller to retry later (hence the choice of return code EAGAIN).
 	 */
 	regval = bge_reg_get32(bgep, NVM_SW_ARBITRATION_REG);
-	ASSERT((regval & NVM_READ_REQ) == 0);
 	bge_reg_put32(bgep, NVM_SW_ARBITRATION_REG, NVM_SET_REQ);
 
 	for (tries = 0; tries < 50; ++tries) {
 		regval = bge_reg_get32(bgep, NVM_SW_ARBITRATION_REG);
-		ASSERT((regval & NVM_READ_REQ) != 0);
 		if (regval & NVM_WON_REQ1)
 			break;
 		drv_usecwait(1);
@@ -1878,10 +1867,10 @@
  * to refer to this chip, the correct settings for various registers, and
  * of course whether the device and/or subsystem are supported!
  */
-void bge_chip_id_init(bge_t *bgep);
+int bge_chip_id_init(bge_t *bgep);
 #pragma	no_inline(bge_chip_id_init)
 
-void
+int
 bge_chip_id_init(bge_t *bgep)
 {
 	char buf[MAXPATHLEN];		/* any risk of stack overflow?	*/
@@ -2201,6 +2190,9 @@
 #endif
 	else
 		cidp->flags |= CHIP_FLAG_SUPPORTED;
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+		return (EIO);
+	return (0);
 }
 
 void
@@ -2254,6 +2246,7 @@
 		drv_usecwait(100);
 	}
 
+	bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE);
 	return (B_FALSE);
 }
 
@@ -2370,7 +2363,7 @@
 	default:
 		bge_reg_put32(bgep, regno, regval);
 		return (bge_chip_poll_engine(bgep, regno,
-			STATE_MACHINE_RESET_BIT, 0));
+		    STATE_MACHINE_RESET_BIT, 0));
 	}
 }
 
@@ -2414,7 +2407,7 @@
 		regval &= ~morebits;
 		bge_reg_put32(bgep, regno, regval);
 		return (bge_chip_poll_engine(bgep, regno,
-			STATE_MACHINE_ENABLE_BIT, 0));
+		    STATE_MACHINE_ENABLE_BIT, 0));
 	}
 }
 
@@ -2458,7 +2451,7 @@
 		regval |= morebits;
 		bge_reg_put32(bgep, regno, regval);
 		return (bge_chip_poll_engine(bgep, regno,
-			STATE_MACHINE_ENABLE_BIT, STATE_MACHINE_ENABLE_BIT));
+		    STATE_MACHINE_ENABLE_BIT, STATE_MACHINE_ENABLE_BIT));
 	}
 }
 
@@ -2537,13 +2530,13 @@
  * the current loopback mode ...
  */
 #ifdef BGE_IPMI_ASF
-void bge_chip_sync(bge_t *bgep, boolean_t asf_keeplive);
+int bge_chip_sync(bge_t *bgep, boolean_t asf_keeplive);
 #else
-void bge_chip_sync(bge_t *bgep);
+int bge_chip_sync(bge_t *bgep);
 #endif
 #pragma	no_inline(bge_chip_sync)
 
-void
+int
 #ifdef BGE_IPMI_ASF
 bge_chip_sync(bge_t *bgep, boolean_t asf_keeplive)
 #else
@@ -2555,6 +2548,7 @@
 	uint64_t macaddr;
 	uint32_t fill;
 	int i;
+	int retval = DDI_SUCCESS;
 
 	BGE_TRACE(("bge_chip_sync($%p)",
 		(void *)bgep));
@@ -2585,19 +2579,24 @@
 	 */
 	if (bge_stop_start_on_sync) {
 #ifdef BGE_IPMI_ASF
-		if (bgep->asf_enabled) {
-			(void) bge_chip_disable_engine(bgep,
-			    RECEIVE_MAC_MODE_REG, 0);
+		if (!bgep->asf_enabled) {
+			if (!bge_chip_disable_engine(bgep,
+			    RECEIVE_MAC_MODE_REG, RECEIVE_MODE_KEEP_VLAN_TAG))
+				retval = DDI_FAILURE;
 		} else {
-			(void) bge_chip_disable_engine(bgep,
-			    RECEIVE_MAC_MODE_REG, RECEIVE_MODE_KEEP_VLAN_TAG);
+			if (!bge_chip_disable_engine(bgep,
+			    RECEIVE_MAC_MODE_REG, 0))
+				retval = DDI_FAILURE;
 		}
 #else
-		(void) bge_chip_disable_engine(bgep, RECEIVE_MAC_MODE_REG,
-		    RECEIVE_MODE_KEEP_VLAN_TAG);
+		if (!bge_chip_disable_engine(bgep, RECEIVE_MAC_MODE_REG,
+		    RECEIVE_MODE_KEEP_VLAN_TAG))
+			retval = DDI_FAILURE;
 #endif
-		(void) bge_chip_disable_engine(bgep, TRANSMIT_MAC_MODE_REG, 0);
-		(void) bge_chip_reset_engine(bgep, RECEIVE_MAC_MODE_REG);
+		if (!bge_chip_disable_engine(bgep, TRANSMIT_MAC_MODE_REG, 0))
+			retval = DDI_FAILURE;
+		if (!bge_chip_reset_engine(bgep, RECEIVE_MAC_MODE_REG))
+			retval = DDI_FAILURE;
 	}
 
 	/*
@@ -2645,20 +2644,25 @@
 	 * Restart RX/TX MAC engines if required ...
 	 */
 	if (bgep->bge_chip_state == BGE_CHIP_RUNNING) {
-		(void) bge_chip_enable_engine(bgep, TRANSMIT_MAC_MODE_REG, 0);
+		if (!bge_chip_enable_engine(bgep, TRANSMIT_MAC_MODE_REG, 0))
+			retval = DDI_FAILURE;
 #ifdef BGE_IPMI_ASF
-		if (bgep->asf_enabled) {
-			(void) bge_chip_enable_engine(bgep,
-			    RECEIVE_MAC_MODE_REG, 0);
+		if (!bgep->asf_enabled) {
+			if (!bge_chip_enable_engine(bgep,
+			    RECEIVE_MAC_MODE_REG, RECEIVE_MODE_KEEP_VLAN_TAG))
+				retval = DDI_FAILURE;
 		} else {
-			(void) bge_chip_enable_engine(bgep,
-			    RECEIVE_MAC_MODE_REG, RECEIVE_MODE_KEEP_VLAN_TAG);
+			if (!bge_chip_enable_engine(bgep,
+			    RECEIVE_MAC_MODE_REG, 0))
+				retval = DDI_FAILURE;
 		}
 #else
-		(void) bge_chip_enable_engine(bgep, RECEIVE_MAC_MODE_REG,
-		    RECEIVE_MODE_KEEP_VLAN_TAG);
+		if (!bge_chip_enable_engine(bgep, RECEIVE_MAC_MODE_REG,
+		    RECEIVE_MODE_KEEP_VLAN_TAG))
+			retval = DDI_FAILURE;
 #endif
 	}
+	return (retval);
 }
 
 /*
@@ -2733,6 +2737,9 @@
 					    regno, 0);
 	}
 
+	if (!ok && !fault)
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
+
 	/*
 	 * Finally, disable (all) MAC events & clear the MAC status
 	 */
@@ -2740,13 +2747,38 @@
 	bge_reg_put32(bgep, ETHERNET_MAC_STATUS_REG, ~0);
 
 	/*
-	 * Do we need to check whether everything completed OK?
-	 * Probably not ... it always works anyway.
+	 * if we're stopping the chip because of a detected fault then do
+	 * appropriate actions
 	 */
-
-	if (fault)
-		bgep->bge_chip_state = BGE_CHIP_FAULT;
-	else
+	if (fault) {
+		if (bgep->bge_chip_state != BGE_CHIP_FAULT) {
+			bgep->bge_chip_state = BGE_CHIP_FAULT;
+			ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+			if (bgep->bge_dma_error) {
+				/*
+				 * need to free buffers in case the fault was
+				 * due to a memory error in a buffer - got to
+				 * do a fair bit of tidying first
+				 */
+				if (bgep->progress & PROGRESS_KSTATS) {
+					bge_fini_kstats(bgep);
+					bgep->progress &= ~PROGRESS_KSTATS;
+				}
+				if (bgep->progress & PROGRESS_INTR) {
+					bge_intr_disable(bgep);
+					rw_enter(bgep->errlock, RW_WRITER);
+					bge_fini_rings(bgep);
+					rw_exit(bgep->errlock);
+					bgep->progress &= ~PROGRESS_INTR;
+				}
+				if (bgep->progress & PROGRESS_BUFS) {
+					bge_free_bufs(bgep);
+					bgep->progress &= ~PROGRESS_BUFS;
+				}
+				bgep->bge_dma_error = B_FALSE;
+			}
+		}
+	} else
 		bgep->bge_chip_state = BGE_CHIP_STOPPED;
 }
 
@@ -2829,13 +2861,13 @@
 }
 
 #ifdef BGE_IPMI_ASF
-void bge_chip_reset(bge_t *bgep, boolean_t enable_dma, uint_t asf_mode);
+int bge_chip_reset(bge_t *bgep, boolean_t enable_dma, uint_t asf_mode);
 #else
-void bge_chip_reset(bge_t *bgep, boolean_t enable_dma);
+int bge_chip_reset(bge_t *bgep, boolean_t enable_dma);
 #endif
 #pragma	no_inline(bge_chip_reset)
 
-void
+int
 #ifdef BGE_IPMI_ASF
 bge_chip_reset(bge_t *bgep, boolean_t enable_dma, uint_t asf_mode)
 #else
@@ -2851,6 +2883,7 @@
 #ifdef BGE_IPMI_ASF
 	uint32_t mailbox;
 #endif
+	int retval = DDI_SUCCESS;
 
 	BGE_TRACE(("bge_chip_reset($%p, %d)",
 		(void *)bgep, enable_dma));
@@ -2865,9 +2898,8 @@
 	 */
 	switch (bgep->bge_chip_state) {
 	default:
-		ASSERT(!"can't get here");
 		_NOTE(NOTREACHED)
-		return;
+		return (DDI_FAILURE);
 
 	case BGE_CHIP_INITIAL:
 	case BGE_CHIP_STOPPED:
@@ -2900,7 +2932,8 @@
 	 * Step 4-5: reset Core clock & wait for completion
 	 * Steps 6-8: are done by bge_chip_cfg_init()
 	 */
-	(void) bge_chip_enable_engine(bgep, MEMORY_ARBITER_MODE_REG, 0);
+	if (!bge_chip_enable_engine(bgep, MEMORY_ARBITER_MODE_REG, 0))
+		retval = DDI_FAILURE;
 
 	mhcr = MHCR_ENABLE_INDIRECT_ACCESS |
 	    MHCR_ENABLE_TAGGED_STATUS_MODE |
@@ -2915,7 +2948,8 @@
 	if (bgep->asf_enabled)
 		bgep->asf_wordswapped = B_FALSE;
 #endif
-	(void) bge_chip_reset_engine(bgep, MISC_CONFIG_REG);
+	if (!bge_chip_reset_engine(bgep, MISC_CONFIG_REG))
+		retval = DDI_FAILURE;
 	bge_chip_cfg_init(bgep, &chipid, enable_dma);
 
 	/*
@@ -2930,7 +2964,8 @@
 	 * Step 9: enable MAC memory arbiter,bit30 and bit31 of 5714/5715 should
 	 * not be changed.
 	 */
-	(void) bge_chip_enable_engine(bgep, MEMORY_ARBITER_MODE_REG, 0);
+	if (!bge_chip_enable_engine(bgep, MEMORY_ARBITER_MODE_REG, 0))
+		retval = DDI_FAILURE;
 
 	/*
 	 * Steps 10-11: configure PIO endianness options and
@@ -3031,13 +3066,14 @@
 	/*
 	 * The SEND INDEX registers should be reset to zero by the
 	 * global chip reset; if they're not, there'll be trouble
-	 * later on -- usually in the form of an ASSERTion failure
-	 * in bge_send.c.  So let's catch it early ...
+	 * later on.
 	 */
 	sx0 = bge_reg_get32(bgep, NIC_DIAG_SEND_INDEX_REG(0));
-	if (sx0 != 0)
-		bge_problem(bgep, "send index %d: device didn't RESET!", sx0);
-	ASSERT(sx0 == 0);
+	if (sx0 != 0) {
+		BGE_REPORT((bgep, "SEND INDEX - device didn't RESET"));
+		bge_fm_ereport(bgep, DDI_FM_DEVICE_INVAL_STATE);
+		return (DDI_FAILURE);
+	}
 
 	/* Enable MSI code */
 	if (bgep->intr_type == DDI_INTR_TYPE_MSI)
@@ -3086,16 +3122,17 @@
 	 */
 	bgep->chip_resets += 1;
 	bgep->bge_chip_state = BGE_CHIP_RESET;
+	return (retval);
 }
 
 /*
  * bge_chip_start() -- start the chip transmitting and/or receiving,
  * including enabling interrupts
  */
-void bge_chip_start(bge_t *bgep, boolean_t reset_phys);
+int bge_chip_start(bge_t *bgep, boolean_t reset_phys);
 #pragma	no_inline(bge_chip_start)
 
-void
+int
 bge_chip_start(bge_t *bgep, boolean_t reset_phys)
 {
 	uint32_t coalmode;
@@ -3103,13 +3140,13 @@
 	uint32_t mtu;
 	uint32_t maxring;
 	uint64_t ring;
+	int retval = DDI_SUCCESS;
 
 	BGE_TRACE(("bge_chip_start($%p)",
 		(void *)bgep));
 
 	ASSERT(mutex_owned(bgep->genlock));
 	ASSERT(bgep->bge_chip_state == BGE_CHIP_RESET);
-	ASSERT(bge_reg_get32(bgep, NIC_DIAG_SEND_INDEX_REG(0)) == 0);
 
 	/*
 	 * Taken from Broadcom document 570X-PG102-R, pp 102-116.
@@ -3208,9 +3245,11 @@
 	/*
 	 * Steps 34-36: enable buffer manager & internal h/w queues
 	 */
-	(void) bge_chip_enable_engine(bgep, BUFFER_MANAGER_MODE_REG,
-		STATE_MACHINE_ATTN_ENABLE_BIT);
-	(void) bge_chip_enable_engine(bgep, FTQ_RESET_REG, 0);
+	if (!bge_chip_enable_engine(bgep, BUFFER_MANAGER_MODE_REG,
+	    STATE_MACHINE_ATTN_ENABLE_BIT))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, FTQ_RESET_REG, 0))
+		retval = DDI_FAILURE;
 
 	/*
 	 * Steps 37-39: initialise Receive Buffer (Producer) RCBs
@@ -3276,10 +3315,11 @@
 	 * Step 96: set up multicast filters
 	 */
 #ifdef BGE_IPMI_ASF
-	bge_chip_sync(bgep, B_FALSE);
+	if (bge_chip_sync(bgep, B_FALSE) == DDI_FAILURE)
 #else
-	bge_chip_sync(bgep);
+	if (bge_chip_sync(bgep) == DDI_FAILURE)
 #endif
+		retval = DDI_FAILURE;
 
 	/*
 	 * Step 49: configure the MTU
@@ -3323,7 +3363,8 @@
 	/*
 	 * Steps 57-58: stop (?) the Host Coalescing Engine
 	 */
-	(void) bge_chip_disable_engine(bgep, HOST_COALESCE_MODE_REG, ~0);
+	if (!bge_chip_disable_engine(bgep, HOST_COALESCE_MODE_REG, ~0))
+		retval = DDI_FAILURE;
 
 	/*
 	 * Steps 59-62: initialise Host Coalescing parameters
@@ -3378,14 +3419,18 @@
 		coalmode = COALESCE_64_BYTE_STATUS;
 	else
 		coalmode = 0;
-	(void) bge_chip_enable_engine(bgep, HOST_COALESCE_MODE_REG, coalmode);
-	(void) bge_chip_enable_engine(bgep, RCV_BD_COMPLETION_MODE_REG,
-	    STATE_MACHINE_ATTN_ENABLE_BIT);
-	(void) bge_chip_enable_engine(bgep, RCV_LIST_PLACEMENT_MODE_REG, 0);
+	if (!bge_chip_enable_engine(bgep, HOST_COALESCE_MODE_REG, coalmode))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, RCV_BD_COMPLETION_MODE_REG,
+	    STATE_MACHINE_ATTN_ENABLE_BIT))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, RCV_LIST_PLACEMENT_MODE_REG, 0))
+		retval = DDI_FAILURE;
 
 	if (DEVICE_5704_SERIES_CHIPSETS(bgep))
-		(void) bge_chip_enable_engine(bgep, RCV_LIST_SELECTOR_MODE_REG,
-		    STATE_MACHINE_ATTN_ENABLE_BIT);
+		if (!bge_chip_enable_engine(bgep, RCV_LIST_SELECTOR_MODE_REG,
+		    STATE_MACHINE_ATTN_ENABLE_BIT))
+			retval = DDI_FAILURE;
 
 	/*
 	 * Step 72: Enable MAC DMA engines
@@ -3423,44 +3468,60 @@
 	 * Beware exhaust fumes?
 	 */
 	if (DEVICE_5704_SERIES_CHIPSETS(bgep))
-		(void) bge_chip_enable_engine(bgep, DMA_COMPLETION_MODE_REG, 0);
-	(void) bge_chip_enable_engine(bgep, WRITE_DMA_MODE_REG,
-		(bge_dma_wrprio << DMA_PRIORITY_SHIFT) | ALL_DMA_ATTN_BITS);
-	(void) bge_chip_enable_engine(bgep, READ_DMA_MODE_REG,
-		(bge_dma_rdprio << DMA_PRIORITY_SHIFT) | ALL_DMA_ATTN_BITS);
-	(void) bge_chip_enable_engine(bgep, RCV_DATA_COMPLETION_MODE_REG,
-		STATE_MACHINE_ATTN_ENABLE_BIT);
+		if (!bge_chip_enable_engine(bgep, DMA_COMPLETION_MODE_REG, 0))
+			retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, WRITE_DMA_MODE_REG,
+	    (bge_dma_wrprio << DMA_PRIORITY_SHIFT) | ALL_DMA_ATTN_BITS))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, READ_DMA_MODE_REG,
+	    (bge_dma_rdprio << DMA_PRIORITY_SHIFT) | ALL_DMA_ATTN_BITS))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, RCV_DATA_COMPLETION_MODE_REG,
+	    STATE_MACHINE_ATTN_ENABLE_BIT))
+		retval = DDI_FAILURE;
 	if (DEVICE_5704_SERIES_CHIPSETS(bgep))
-		(void) bge_chip_enable_engine(bgep,
-		    MBUF_CLUSTER_FREE_MODE_REG, 0);
-	(void) bge_chip_enable_engine(bgep, SEND_DATA_COMPLETION_MODE_REG, 0);
-	(void) bge_chip_enable_engine(bgep, SEND_BD_COMPLETION_MODE_REG,
-		STATE_MACHINE_ATTN_ENABLE_BIT);
-	(void) bge_chip_enable_engine(bgep, RCV_BD_INITIATOR_MODE_REG,
-		RCV_BD_DISABLED_RING_ATTN);
-	(void) bge_chip_enable_engine(bgep, RCV_DATA_BD_INITIATOR_MODE_REG,
-		RCV_DATA_BD_ILL_RING_ATTN);
-	(void) bge_chip_enable_engine(bgep, SEND_DATA_INITIATOR_MODE_REG, 0);
-	(void) bge_chip_enable_engine(bgep, SEND_BD_INITIATOR_MODE_REG,
-		STATE_MACHINE_ATTN_ENABLE_BIT);
-	(void) bge_chip_enable_engine(bgep, SEND_BD_SELECTOR_MODE_REG,
-		STATE_MACHINE_ATTN_ENABLE_BIT);
+		if (!bge_chip_enable_engine(bgep,
+		    MBUF_CLUSTER_FREE_MODE_REG, 0))
+			retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, SEND_DATA_COMPLETION_MODE_REG, 0))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, SEND_BD_COMPLETION_MODE_REG,
+	    STATE_MACHINE_ATTN_ENABLE_BIT))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, RCV_BD_INITIATOR_MODE_REG,
+	    RCV_BD_DISABLED_RING_ATTN))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, RCV_DATA_BD_INITIATOR_MODE_REG,
+	    RCV_DATA_BD_ILL_RING_ATTN))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, SEND_DATA_INITIATOR_MODE_REG, 0))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, SEND_BD_INITIATOR_MODE_REG,
+	    STATE_MACHINE_ATTN_ENABLE_BIT))
+		retval = DDI_FAILURE;
+	if (!bge_chip_enable_engine(bgep, SEND_BD_SELECTOR_MODE_REG,
+	    STATE_MACHINE_ATTN_ENABLE_BIT))
+		retval = DDI_FAILURE;
 
 	/*
 	 * Step 88: download firmware -- doesn't apply
 	 * Steps 89-90: enable Transmit & Receive MAC Engines
 	 */
-	(void) bge_chip_enable_engine(bgep, TRANSMIT_MAC_MODE_REG, 0);
+	if (!bge_chip_enable_engine(bgep, TRANSMIT_MAC_MODE_REG, 0))
+		retval = DDI_FAILURE;
 #ifdef BGE_IPMI_ASF
-	if (bgep->asf_enabled) {
-		(void) bge_chip_enable_engine(bgep, RECEIVE_MAC_MODE_REG, 0);
+	if (!bgep->asf_enabled) {
+		if (!bge_chip_enable_engine(bgep, RECEIVE_MAC_MODE_REG,
+		    RECEIVE_MODE_KEEP_VLAN_TAG))
+			retval = DDI_FAILURE;
 	} else {
-		(void) bge_chip_enable_engine(bgep, RECEIVE_MAC_MODE_REG,
-		    RECEIVE_MODE_KEEP_VLAN_TAG);
+		if (!bge_chip_enable_engine(bgep, RECEIVE_MAC_MODE_REG, 0))
+			retval = DDI_FAILURE;
 	}
 #else
-	(void) bge_chip_enable_engine(bgep, RECEIVE_MAC_MODE_REG,
-	    RECEIVE_MODE_KEEP_VLAN_TAG);
+	if (!bge_chip_enable_engine(bgep, RECEIVE_MAC_MODE_REG,
+	    RECEIVE_MODE_KEEP_VLAN_TAG))
+		retval = DDI_FAILURE;
 #endif
 
 	/*
@@ -3499,7 +3560,8 @@
 	 * restart autoneg (if required)
 	 */
 	if (reset_phys)
-		bge_phys_update(bgep);
+		if (bge_phys_update(bgep) == DDI_FAILURE)
+			retval = DDI_FAILURE;
 
 	/*
 	 * Extra step (DSG): hand over all the Receive Buffers to the chip
@@ -3553,6 +3615,7 @@
 	 * All done!
 	 */
 	bgep->bge_chip_state = BGE_CHIP_RUNNING;
+	return (retval);
 }
 
 
@@ -3569,14 +3632,14 @@
  * the <flags> word of the status block, returning the value of the
  * <tag> and the <flags> before the bits were cleared.
  */
-static uint64_t bge_status_sync(bge_t *bgep, uint64_t bits);
+static int bge_status_sync(bge_t *bgep, uint64_t bits, uint64_t *flags);
 #pragma	inline(bge_status_sync)
 
-static uint64_t
-bge_status_sync(bge_t *bgep, uint64_t bits)
+static int
+bge_status_sync(bge_t *bgep, uint64_t bits, uint64_t *flags)
 {
 	bge_status_t *bsp;
-	uint64_t flags;
+	int retval;
 
 	BGE_TRACE(("bge_status_sync($%p, 0x%llx)",
 		(void *)bgep, bits));
@@ -3584,13 +3647,17 @@
 	ASSERT(bgep->bge_guard == BGE_GUARD);
 
 	DMA_SYNC(bgep->status_block, DDI_DMA_SYNC_FORKERNEL);
+	retval = bge_check_dma_handle(bgep, bgep->status_block.dma_hdl);
+	if (retval != DDI_FM_OK)
+		return (retval);
+
 	bsp = DMA_VPTR(bgep->status_block);
-	flags = bge_atomic_clr64(&bsp->flags_n_tag, bits);
+	*flags = bge_atomic_clr64(&bsp->flags_n_tag, bits);
 
 	BGE_DEBUG(("bge_status_sync($%p, 0x%llx) returning 0x%llx",
-		(void *)bgep, bits, flags));
-
-	return (flags);
+		(void *)bgep, bits, *flags));
+
+	return (retval);
 }
 
 static void bge_wake_factotum(bge_t *bgep);
@@ -3621,6 +3688,7 @@
 	uint64_t flags;
 	uint32_t mlcr = 0;
 	uint_t result;
+	int retval;
 
 	BGE_TRACE(("bge_intr($%p) ($%p)", arg1, arg2));
 
@@ -3652,9 +3720,13 @@
 		 */
 		result = DDI_INTR_CLAIMED;
 
-		if (bgep->intr_type == DDI_INTR_TYPE_FIXED)
+		if (bgep->intr_type == DDI_INTR_TYPE_FIXED) {
 			bge_cfg_set32(bgep, PCI_CONF_BGE_MHCR,
 				MHCR_MASK_PCI_INT_OUTPUT);
+			if (bge_check_acc_handle(bgep, bgep->cfg_handle) !=
+			    DDI_FM_OK)
+				goto chip_stop;
+		}
 
 		/*
 		 * Sync the status block and grab the flags-n-tag from it.
@@ -3665,24 +3737,48 @@
 		 */
 		bgep->missed_dmas += 1;
 		bsp = DMA_VPTR(bgep->status_block);
-		flags = bge_status_sync(bgep, STATUS_FLAG_UPDATED);
-
-		while (flags & STATUS_FLAG_UPDATED) {
+		for (;;) {
+			if (bgep->bge_chip_state != BGE_CHIP_RUNNING) {
+				/*
+				 * bge_chip_stop() may have freed dma area etc
+				 * while we were in this interrupt handler -
+				 * better not call bge_status_sync()
+				 */
+				(void) bge_check_acc_handle(bgep,
+				    bgep->io_handle);
+				mutex_exit(bgep->genlock);
+				return (DDI_INTR_CLAIMED);
+			}
+			retval = bge_status_sync(bgep, STATUS_FLAG_UPDATED,
+			    &flags);
+			if (retval != DDI_FM_OK) {
+				bgep->bge_dma_error = B_TRUE;
+				goto chip_stop;
+			}
+
+			if (!(flags & STATUS_FLAG_UPDATED))
+				break;
+
 			/*
 			 * Tell the chip that we're processing the interrupt
 			 */
 			bge_mbx_put(bgep, INTERRUPT_MBOX_0_REG,
 				INTERRUPT_MBOX_DISABLE(flags));
+			if (bge_check_acc_handle(bgep, bgep->io_handle) !=
+			    DDI_FM_OK)
+				goto chip_stop;
 
 			/*
 			 * Drop the mutex while we:
 			 * 	Receive any newly-arrived packets
 			 *	Recycle any newly-finished send buffers
 			 */
+			bgep->bge_intr_running = B_TRUE;
 			mutex_exit(bgep->genlock);
 			bge_receive(bgep, bsp);
 			bge_recycle(bgep, bsp);
 			mutex_enter(bgep->genlock);
+			bgep->bge_intr_running = B_FALSE;
 
 			/*
 			 * Tell the chip we've finished processing, and
@@ -3698,7 +3794,6 @@
 			bge_mbx_put(bgep, INTERRUPT_MBOX_0_REG,
 				INTERRUPT_MBOX_ENABLE(flags));
 			bgep->missed_dmas = 0;
-			flags = bge_status_sync(bgep, STATUS_FLAG_UPDATED);
 		}
 
 		/*
@@ -3736,25 +3831,9 @@
 				 * over to see whether anything can be done
 				 * about it ...
 				 */
-#ifdef BGE_IPMI_ASF
-				if (bgep->asf_enabled &&
-					(bgep->asf_status == ASF_STAT_RUN)) {
-					/*
-					 * We must stop ASF heart beat before
-					 * bge_chip_stop(), otherwise some
-					 * computers (ex. IBM HS20 blade
-					 * server) may crash.
-					 */
-					bge_asf_update_status(bgep);
-					bge_asf_stop_timer(bgep);
-					bgep->asf_status = ASF_STAT_STOP;
-
-					bge_asf_pre_reset_operations(bgep,
-						BGE_INIT_RESET);
-				}
-#endif
-				bge_chip_stop(bgep, B_TRUE);
-				result = DDI_INTR_UNCLAIMED;
+				bge_fm_ereport(bgep,
+				    DDI_FM_DEVICE_BADINT_LIMIT);
+				goto chip_stop;
 			}
 		}
 
@@ -3762,12 +3841,41 @@
 		 * Reenable assertion of #INTA, unless there's a DMA fault
 		 */
 		if (result == DDI_INTR_CLAIMED) {
-			if (bgep->intr_type == DDI_INTR_TYPE_FIXED)
+			if (bgep->intr_type == DDI_INTR_TYPE_FIXED) {
 				bge_cfg_clr32(bgep, PCI_CONF_BGE_MHCR,
 					MHCR_MASK_PCI_INT_OUTPUT);
+				if (bge_check_acc_handle(bgep,
+				    bgep->cfg_handle) != DDI_FM_OK)
+					goto chip_stop;
+			}
 		}
 	}
 
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+		goto chip_stop;
+
+	mutex_exit(bgep->genlock);
+	return (result);
+
+chip_stop:
+#ifdef BGE_IPMI_ASF
+	if (bgep->asf_enabled && bgep->asf_status == ASF_STAT_RUN) {
+		/*
+		 * We must stop ASF heart beat before
+		 * bge_chip_stop(), otherwise some
+		 * computers (ex. IBM HS20 blade
+		 * server) may crash.
+		 */
+		bge_asf_update_status(bgep);
+		bge_asf_stop_timer(bgep);
+		bgep->asf_status = ASF_STAT_STOP;
+
+		bge_asf_pre_reset_operations(bgep, BGE_INIT_RESET);
+		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
+	}
+#endif
+	bge_chip_stop(bgep, B_TRUE);
+	(void) bge_check_acc_handle(bgep, bgep->io_handle);
 	mutex_exit(bgep->genlock);
 	return (result);
 }
@@ -3877,11 +3985,11 @@
 	(*logfn)(bgep, "link %s%s", bgep->link_mode_msg, msg);
 }
 
-static boolean_t bge_factotum_link_check(bge_t *bgep);
+static boolean_t bge_factotum_link_check(bge_t *bgep, int *dma_state);
 #pragma	no_inline(bge_factotum_link_check)
 
 static boolean_t
-bge_factotum_link_check(bge_t *bgep)
+bge_factotum_link_check(bge_t *bgep, int *dma_state)
 {
 	boolean_t check;
 	uint64_t flags;
@@ -3899,8 +4007,10 @@
 	/*
 	 * Get & clear the ERROR and LINK_CHANGED bits from the status block
 	 */
-	flags = STATUS_FLAG_ERROR | STATUS_FLAG_LINK_CHANGED;
-	flags = bge_status_sync(bgep, flags);
+	*dma_state = bge_status_sync(bgep, STATUS_FLAG_ERROR |
+	    STATUS_FLAG_LINK_CHANGED, &flags);
+	if (*dma_state != DDI_FM_OK)
+		return (B_FALSE);
 
 	/*
 	 * Clear any errors flagged in the status block ...
@@ -3983,6 +4093,7 @@
 		return (B_FALSE);
 
 	BGE_REPORT((bgep, "Tx stall detected, watchdog code 0x%x", dogval));
+	bge_fm_ereport(bgep, DDI_FM_DEVICE_STALL);
 	return (B_TRUE);
 }
 
@@ -4003,6 +4114,7 @@
 	uint_t result;
 	boolean_t error;
 	boolean_t linkchg;
+	int dma_state;
 
 	bgep = (bge_t *)arg;
 
@@ -4026,8 +4138,16 @@
 		break;
 
 	case BGE_CHIP_RUNNING:
-		linkchg = bge_factotum_link_check(bgep);
+		linkchg = bge_factotum_link_check(bgep, &dma_state);
 		error = bge_factotum_stall_check(bgep);
+		if (dma_state != DDI_FM_OK) {
+			bgep->bge_dma_error = B_TRUE;
+			error = B_TRUE;
+		}
+		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+			error = B_TRUE;
+		if (error)
+			bgep->bge_chip_state = BGE_CHIP_ERROR;
 		break;
 
 	case BGE_CHIP_ERROR:
@@ -4039,32 +4159,72 @@
 		 * Fault detected, time to reset ...
 		 */
 		if (bge_autorecover) {
+			if (!(bgep->progress & PROGRESS_BUFS)) {
+				/*
+				 * if we can't allocate the ring buffers,
+				 * try later
+				 */
+				if (bge_alloc_bufs(bgep) != DDI_SUCCESS) {
+					mutex_exit(bgep->genlock);
+					return (result);
+				}
+				bgep->progress |= PROGRESS_BUFS;
+			}
+			if (!(bgep->progress & PROGRESS_INTR)) {
+				bge_init_rings(bgep);
+				bge_intr_enable(bgep);
+				bgep->progress |= PROGRESS_INTR;
+			}
+			if (!(bgep->progress & PROGRESS_KSTATS)) {
+				bge_init_kstats(bgep,
+				    ddi_get_instance(bgep->devinfo));
+				bgep->progress |= PROGRESS_KSTATS;
+			}
+
 			BGE_REPORT((bgep, "automatic recovery activated"));
-			bge_restart(bgep, B_FALSE);
+
+			if (bge_restart(bgep, B_FALSE) != DDI_SUCCESS) {
+				bgep->bge_chip_state = BGE_CHIP_ERROR;
+				error = B_TRUE;
+			}
+			if (bge_check_acc_handle(bgep, bgep->cfg_handle) !=
+			    DDI_FM_OK) {
+				bgep->bge_chip_state = BGE_CHIP_ERROR;
+				error = B_TRUE;
+			}
+			if (bge_check_acc_handle(bgep, bgep->io_handle) !=
+			    DDI_FM_OK) {
+				bgep->bge_chip_state = BGE_CHIP_ERROR;
+				error = B_TRUE;
+			}
+			if (error == B_FALSE) {
 #ifdef BGE_IPMI_ASF
-			/*
-			 * Start our ASF heartbeat counter as soon as possible.
-			 */
-			if (bgep->asf_enabled) {
-				if (bgep->asf_status != ASF_STAT_RUN) {
+				if (bgep->asf_enabled &&
+				    bgep->asf_status != ASF_STAT_RUN) {
 					bgep->asf_timeout_id = timeout(
-						bge_asf_heartbeat,
-						(void *)bgep,
-						drv_usectohz(
-						BGE_ASF_HEARTBEAT_INTERVAL));
+					    bge_asf_heartbeat, (void *)bgep,
+					    drv_usectohz(
+					    BGE_ASF_HEARTBEAT_INTERVAL));
 					bgep->asf_status = ASF_STAT_RUN;
 				}
+#endif
+				ddi_fm_service_impact(bgep->devinfo,
+				    DDI_SERVICE_RESTORED);
 			}
-#endif
 		}
 		break;
 	}
 
+
 	/*
 	 * If an error is detected, stop the chip now, marking it as
 	 * faulty, so that it will be reset next time through ...
+	 *
+	 * Note that if intr_running is set, then bge_intr() has dropped
+	 * genlock to call bge_receive/bge_recycle. Can't stop the chip at
+	 * this point so have to wait until the next time the factotum runs.
 	 */
-	if (error) {
+	if (error && !bgep->bge_intr_running) {
 #ifdef BGE_IPMI_ASF
 		if (bgep->asf_enabled && (bgep->asf_status == ASF_STAT_RUN)) {
 			/*
@@ -4077,9 +4237,11 @@
 			bgep->asf_status = ASF_STAT_STOP;
 
 			bge_asf_pre_reset_operations(bgep, BGE_INIT_RESET);
+			(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
 		}
 #endif
 		bge_chip_stop(bgep, B_TRUE);
+		(void) bge_check_acc_handle(bgep, bgep->io_handle);
 	}
 	mutex_exit(bgep->genlock);
 
@@ -4116,6 +4278,9 @@
 
 	case BGE_CHIP_RUNNING:
 		bge_reg_set32(bgep, HOST_COALESCE_MODE_REG, COALESCE_NOW);
+		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_UNAFFECTED);
 		break;
 
 	case BGE_CHIP_FAULT:
@@ -4757,7 +4922,7 @@
 		/*
 		 * Reset and reinitialise the 570x hardware
 		 */
-		bge_restart(bgep, cmd == BGE_HARD_RESET);
+		(void) bge_restart(bgep, cmd == BGE_HARD_RESET);
 		return (IOC_ACK);
 	}
 
@@ -4954,8 +5119,12 @@
 {
 	bge_t *bgep = arg;
 
+	mutex_enter(bgep->genlock);
 	bge_reg_put32(bgep, RCV_COALESCE_TICKS_REG, ticks);
 	bge_reg_put32(bgep, RCV_COALESCE_MAX_BD_REG, count);
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
+	mutex_exit(bgep->genlock);
 }
 
 #ifdef BGE_IPMI_ASF
@@ -5006,9 +5175,17 @@
  * of the required value.
  */
 void
-bge_asf_heartbeat(void *bgep)
+bge_asf_heartbeat(void *arg)
 {
+	bge_t *bgep = (bge_t *)arg;
+
+	mutex_enter(bgep->genlock);
 	bge_asf_update_status((bge_t *)bgep);
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK)
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+	mutex_exit(bgep->genlock);
 	((bge_t *)bgep)->asf_timeout_id = timeout(bge_asf_heartbeat, bgep,
 		drv_usectohz(BGE_ASF_HEARTBEAT_INTERVAL));
 }
--- a/usr/src/uts/common/io/bge/bge_kstats.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/bge/bge_kstats.c	Sun Apr 23 15:26:28 2006 -0700
@@ -430,6 +430,9 @@
 		return (EACCES);
 
 	bgep = ksp->ks_private;
+	if (bgep->bge_chip_state == BGE_CHIP_FAULT)
+		return (EIO);
+
 	knp = ksp->ks_data;
 
 	(knp++)->value.ui64 = bgep->rx_buff[0].cookie.dmac_laddress;
@@ -452,9 +455,19 @@
 	(knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_MHCR);
 	(knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PDRWCR);
 	(knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PCISTATE);
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 
 	(knp++)->value.ui64 = bge_reg_get32(bgep, BUFFER_MANAGER_STATUS_REG);
 	(knp++)->value.ui64 = bge_reg_get32(bgep, RCV_INITIATOR_STATUS_REG);
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	mutex_exit(bgep->genlock);
 
 	return (0);
@@ -528,6 +541,9 @@
 		return (EACCES);
 
 	bgep = ksp->ks_private;
+	if (bgep->bge_chip_state == BGE_CHIP_FAULT)
+		return (EIO);
+
 	knp = ksp->ks_data;
 
 	/*
@@ -543,6 +559,11 @@
 	xcvr_id = bge_mii_get16(bgep, MII_PHYIDH);
 	xcvr_id <<= 16;
 	xcvr_id |= bge_mii_get16(bgep, MII_PHYIDL);
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	mutex_exit(bgep->genlock);
 
 	switch (bgep->param_link_speed) {
@@ -695,6 +716,9 @@
 		return (EACCES);
 
 	bgep = ksp->ks_private;
+	if (bgep->bge_chip_state == BGE_CHIP_FAULT)
+		return (EIO);
+
 	knp = ksp->ks_data;
 
 	/*
@@ -722,6 +746,12 @@
 			knp->value.ui64 = bge_mii_get16(bgep, ksip->index);
 			break;
 		}
+		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_DEGRADED);
+			mutex_exit(bgep->genlock);
+			return (EIO);
+		}
 		mutex_exit(bgep->genlock);
 	}
 
@@ -866,6 +896,12 @@
 	bge_statistics_t *bstp;
 	uint64_t val;
 
+	mutex_enter(bgep->genlock);
+	if (bgep->bge_chip_state == BGE_CHIP_FAULT) {
+		mutex_exit(bgep->genlock);
+		return (0);
+	}
+
 	if (bgep->chipid.statistic_type == BGE_STAT_BLK)
 		bstp = DMA_VPTR(bgep->statistics);
 	else {
@@ -924,7 +960,11 @@
 			bge_reg_get32(bgep, STAT_ETHER_JABBERS_REG);
 		bgep->stat_val.etherStatsUndersizePkts +=
 			bge_reg_get32(bgep, STAT_ETHER_UNDERSIZE_REG);
+		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_UNAFFECTED);
 		}
+	}
 
 	switch (stat) {
 	case MAC_STAT_IFSPEED:
@@ -1113,11 +1153,13 @@
 		break;
 
 	case MAC_STAT_XCVR_ID:
-		mutex_enter(bgep->genlock);
 		val = bge_mii_get16(bgep, MII_PHYIDH);
 		val <<= 16;
 		val |= bge_mii_get16(bgep, MII_PHYIDL);
-		mutex_exit(bgep->genlock);
+		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_UNAFFECTED);
+		}
 		break;
 
 	case MAC_STAT_XCVR_INUSE:
@@ -1261,5 +1303,6 @@
 #endif
 	}
 
+	mutex_exit(bgep->genlock);
 	return (val);
 }
--- a/usr/src/uts/common/io/bge/bge_log.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/bge/bge_log.c	Sun Apr 23 15:26:28 2006 -0700
@@ -143,6 +143,20 @@
 	mutex_exit(bge_log_mutex);
 }
 
+void
+bge_fm_ereport(bge_t *bgep, char *detail)
+{
+	uint64_t ena;
+	char buf[FM_MAX_CLASS];
+
+	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
+	ena = fm_ena_generate(0, FM_ENA_FMT1);
+	if (DDI_FM_EREPORT_CAP(bgep->fm_capabilities)) {
+		ddi_fm_ereport_post(bgep->devinfo, buf, ena, DDI_NOSLEEP,
+		    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL);
+	}
+}
+
 #if	BGE_DEBUGGING
 
 static void
--- a/usr/src/uts/common/io/bge/bge_main2.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/bge/bge_main2.c	Sun Apr 23 15:26:28 2006 -0700
@@ -48,6 +48,7 @@
 static char subven_propname[] = "subsystem-vendor-id";
 static char rxrings_propname[] = "bge-rx-rings";
 static char txrings_propname[] = "bge-tx-rings";
+static char fm_cap[] = "fm-capable";
 static char default_mtu[] = "default-mtu";
 
 static int bge_add_intrs(bge_t *, int);
@@ -68,7 +69,7 @@
 	0xFFFFFFFFFFFFFFFFull,		/* dma_attr_seg		*/
 	1,				/* dma_attr_sgllen 	*/
 	0x00000001,			/* dma_attr_granular 	*/
-	0				/* dma_attr_flags 	*/
+	DDI_DMA_FLAGERR			/* dma_attr_flags */
 };
 
 /*
@@ -77,7 +78,8 @@
 static ddi_device_acc_attr_t bge_reg_accattr = {
 	DDI_DEVICE_ATTR_V0,
 	DDI_NEVERSWAP_ACC,
-	DDI_STRICTORDER_ACC
+	DDI_STRICTORDER_ACC,
+	DDI_FLAGERR_ACC
 };
 
 /*
@@ -86,7 +88,8 @@
 static ddi_device_acc_attr_t bge_desc_accattr = {
 	DDI_DEVICE_ATTR_V0,
 	DDI_NEVERSWAP_ACC,
-	DDI_STRICTORDER_ACC
+	DDI_STRICTORDER_ACC,
+	DDI_FLAGERR_ACC
 };
 
 /*
@@ -244,7 +247,7 @@
 /*
  *	bge_reset() -- reset h/w & rings to initial state
  */
-static void
+static int
 #ifdef BGE_IPMI_ASF
 bge_reset(bge_t *bgep, uint_t asf_mode)
 #else
@@ -252,6 +255,7 @@
 #endif
 {
 	uint64_t	ring;
+	int retval;
 
 	BGE_TRACE(("bge_reset($%p)", (void *)bgep));
 
@@ -270,9 +274,9 @@
 		mutex_enter(bgep->send[ring].tc_lock);
 
 #ifdef BGE_IPMI_ASF
-	bge_chip_reset(bgep, B_TRUE, asf_mode);
+	retval = bge_chip_reset(bgep, B_TRUE, asf_mode);
 #else
-	bge_chip_reset(bgep, B_TRUE);
+	retval = bge_chip_reset(bgep, B_TRUE);
 #endif
 	bge_reinit_rings(bgep);
 
@@ -288,6 +292,7 @@
 		mutex_exit(bgep->recv[ring].rx_lock);
 
 	BGE_DEBUG(("bge_reset($%p) done", (void *)bgep));
+	return (retval);
 }
 
 /*
@@ -316,9 +321,11 @@
 /*
  *	bge_start() -- start transmitting/receiving
  */
-static void
+static int
 bge_start(bge_t *bgep, boolean_t reset_phys)
 {
+	int retval;
+
 	BGE_TRACE(("bge_start($%p, %d)", (void *)bgep, reset_phys));
 
 	ASSERT(mutex_owned(bgep->genlock));
@@ -326,34 +333,41 @@
 	/*
 	 * Start chip processing, including enabling interrupts
 	 */
-	bge_chip_start(bgep, reset_phys);
+	retval = bge_chip_start(bgep, reset_phys);
 
 	BGE_DEBUG(("bge_start($%p, %d) done", (void *)bgep, reset_phys));
+	return (retval);
 }
 
 /*
  * bge_restart - restart transmitting/receiving after error or suspend
  */
-void
+int
 bge_restart(bge_t *bgep, boolean_t reset_phys)
 {
+	int retval = DDI_SUCCESS;
 	ASSERT(mutex_owned(bgep->genlock));
 
 #ifdef BGE_IPMI_ASF
 	if (bgep->asf_enabled) {
-		bge_reset(bgep, ASF_MODE_POST_INIT);
+		if (bge_reset(bgep, ASF_MODE_POST_INIT) != DDI_SUCCESS)
+			retval = DDI_FAILURE;
 	} else
-		bge_reset(bgep, ASF_MODE_NONE);
+		if (bge_reset(bgep, ASF_MODE_NONE) != DDI_SUCCESS)
+			retval = DDI_FAILURE;
 #else
-	bge_reset(bgep);
+	if (bge_reset(bgep) != DDI_SUCCESS)
+		retval = DDI_FAILURE;
 #endif
 	if (bgep->bge_mac_state == BGE_MAC_STARTED) {
-		bge_start(bgep, reset_phys);
+		if (bge_start(bgep, reset_phys) != DDI_SUCCESS)
+			retval = DDI_FAILURE;
 		bgep->watchdog = 0;
 		ddi_trigger_softintr(bgep->resched_id);
 	}
 
 	BGE_DEBUG(("bge_restart($%p, %d) done", (void *)bgep, reset_phys));
+	return (retval);
 }
 
 
@@ -378,10 +392,18 @@
 	 * Just stop processing, then record new GLD state
 	 */
 	mutex_enter(bgep->genlock);
+	if (!(bgep->progress & PROGRESS_INTR)) {
+		/* can happen during autorecovery */
+		mutex_exit(bgep->genlock);
+		return;
+	}
+
 	bgep->link_up_msg = bgep->link_down_msg = " (stopped)";
 	bge_stop(bgep);
 	bgep->bge_mac_state = BGE_MAC_STOPPED;
 	BGE_DEBUG(("bge_m_stop($%p) done", arg));
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
 	mutex_exit(bgep->genlock);
 }
 
@@ -399,6 +421,12 @@
 	 * Start processing and record new GLD state
 	 */
 	mutex_enter(bgep->genlock);
+	if (!(bgep->progress & PROGRESS_INTR)) {
+		/* can happen during autorecovery */
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 #ifdef BGE_IPMI_ASF
 	if (bgep->asf_enabled) {
 		if ((bgep->asf_status == ASF_STAT_RUN) &&
@@ -411,15 +439,37 @@
 			return (0);
 		}
 	}
-	bge_reset(bgep, ASF_MODE_INIT);
+	if (bge_reset(bgep, ASF_MODE_INIT) != DDI_SUCCESS) {
 #else
-	bge_reset(bgep);
+	if (bge_reset(bgep) != DDI_SUCCESS) {
 #endif
+		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
+		(void) bge_check_acc_handle(bgep, bgep->io_handle);
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	bgep->link_up_msg = bgep->link_down_msg = " (initialized)";
-	bge_start(bgep, B_TRUE);
+	if (bge_start(bgep, B_TRUE) != DDI_SUCCESS) {
+		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
+		(void) bge_check_acc_handle(bgep, bgep->io_handle);
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	bgep->bge_mac_state = BGE_MAC_STARTED;
 	BGE_DEBUG(("bge_m_start($%p) done", arg));
 
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 #ifdef BGE_IPMI_ASF
 	if (bgep->asf_enabled) {
 		if (bgep->asf_status != ASF_STAT_RUN) {
@@ -452,9 +502,25 @@
 	 * Sync the chip's idea of the address too ...
 	 */
 	mutex_enter(bgep->genlock);
+	if (!(bgep->progress & PROGRESS_INTR)) {
+		/* can happen during autorecovery */
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	ethaddr_copy(macaddr, bgep->curr_addr.addr);
 #ifdef BGE_IPMI_ASF
-	bge_chip_sync(bgep, B_FALSE);
+	if (bge_chip_sync(bgep, B_FALSE) == DDI_FAILURE) {
+#else
+	if (bge_chip_sync(bgep) == DDI_FAILURE) {
+#endif
+		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
+		(void) bge_check_acc_handle(bgep, bgep->io_handle);
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
+#ifdef BGE_IPMI_ASF
 	if (bgep->asf_enabled) {
 		/*
 		 * The above bge_chip_sync() function wrote the ethernet MAC
@@ -473,9 +539,17 @@
 
 			bge_asf_pre_reset_operations(bgep, BGE_INIT_RESET);
 		}
-		bge_chip_stop(bgep, B_TRUE);
+		bge_chip_stop(bgep, B_FALSE);
 
-		bge_restart(bgep, B_FALSE);
+		if (bge_restart(bgep, B_FALSE) == DDI_FAILURE) {
+			(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
+			(void) bge_check_acc_handle(bgep, bgep->io_handle);
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_DEGRADED);
+			mutex_exit(bgep->genlock);
+			return (EIO);
+		}
+
 		/*
 		 * Start our ASF heartbeat counter as soon as possible.
 		 */
@@ -487,10 +561,18 @@
 			bgep->asf_status = ASF_STAT_RUN;
 		}
 	}
-#else
-	bge_chip_sync(bgep);
 #endif
 	BGE_DEBUG(("bge_m_unicst_set($%p) done", arg));
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	mutex_exit(bgep->genlock);
 
 	return (0);
@@ -547,26 +629,60 @@
 	 * must also update the chip's hardware map registers.
 	 */
 	mutex_enter(bgep->genlock);
+	if (!(bgep->progress & PROGRESS_INTR)) {
+		/* can happen during autorecovery */
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	if (add) {
 		if ((*refp)++ == 0) {
 			bgep->mcast_hash[word] |= bit;
 #ifdef BGE_IPMI_ASF
-			bge_chip_sync(bgep, B_TRUE);
+			if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
 #else
-			bge_chip_sync(bgep);
+			if (bge_chip_sync(bgep) == DDI_FAILURE) {
 #endif
+				(void) bge_check_acc_handle(bgep,
+				    bgep->cfg_handle);
+				(void) bge_check_acc_handle(bgep,
+				    bgep->io_handle);
+				ddi_fm_service_impact(bgep->devinfo,
+				    DDI_SERVICE_DEGRADED);
+				mutex_exit(bgep->genlock);
+				return (EIO);
+			}
 		}
 	} else {
 		if (--(*refp) == 0) {
 			bgep->mcast_hash[word] &= ~bit;
 #ifdef BGE_IPMI_ASF
-			bge_chip_sync(bgep, B_TRUE);
+			if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
 #else
-			bge_chip_sync(bgep);
+			if (bge_chip_sync(bgep) == DDI_FAILURE) {
 #endif
+				(void) bge_check_acc_handle(bgep,
+				    bgep->cfg_handle);
+				(void) bge_check_acc_handle(bgep,
+				    bgep->io_handle);
+				ddi_fm_service_impact(bgep->devinfo,
+				    DDI_SERVICE_DEGRADED);
+				mutex_exit(bgep->genlock);
+				return (EIO);
+			}
 		}
 	}
 	BGE_DEBUG(("bge_m_multicst($%p) done", arg));
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	mutex_exit(bgep->genlock);
 
 	return (0);
@@ -589,13 +705,35 @@
 	 * Store MAC layer specified mode and pass to chip layer to update h/w
 	 */
 	mutex_enter(bgep->genlock);
+	if (!(bgep->progress & PROGRESS_INTR)) {
+		/* can happen during autorecovery */
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	bgep->promisc = on;
 #ifdef BGE_IPMI_ASF
-	bge_chip_sync(bgep, B_TRUE);
+	if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
 #else
-	bge_chip_sync(bgep);
+	if (bge_chip_sync(bgep) == DDI_FAILURE) {
 #endif
+		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
+		(void) bge_check_acc_handle(bgep, bgep->io_handle);
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	BGE_DEBUG(("bge_m_promisc_set($%p) done", arg));
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	mutex_exit(bgep->genlock);
 	return (0);
 }
@@ -781,6 +919,12 @@
 	}
 
 	mutex_enter(bgep->genlock);
+	if (!(bgep->progress & PROGRESS_INTR)) {
+		/* can happen during autorecovery */
+		mutex_exit(bgep->genlock);
+		miocnak(wq, mp, 0, EIO);
+		return;
+	}
 
 	switch (cmd) {
 	default:
@@ -824,17 +968,33 @@
 	switch (status) {
 	case IOC_RESTART_REPLY:
 	case IOC_RESTART_ACK:
-		bge_phys_update(bgep);
+		if (bge_phys_update(bgep) != DDI_SUCCESS) {
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_DEGRADED);
+			status = IOC_INVAL;
+		}
 #ifdef BGE_IPMI_ASF
-		bge_chip_sync(bgep, B_FALSE);
+		if (bge_chip_sync(bgep, B_FALSE) == DDI_FAILURE) {
 #else
-		bge_chip_sync(bgep);
+		if (bge_chip_sync(bgep) == DDI_FAILURE) {
 #endif
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_DEGRADED);
+			status = IOC_INVAL;
+		}
 		if (bgep->intr_type == DDI_INTR_TYPE_MSI)
 			bge_chip_msi_trig(bgep);
 		break;
 	}
 
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		status = IOC_INVAL;
+	}
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		status = IOC_INVAL;
+	}
 	mutex_exit(bgep->genlock);
 
 	/*
@@ -1196,24 +1356,14 @@
 
 /*
  * Initialise all transmit, receive, and buffer rings.
- * (also a few top-level mutexen that can't be done until
- * the h/w interrupt handler has been registered 'cos we
- * need the cookie).
  */
-static void
+void
 bge_init_rings(bge_t *bgep)
 {
 	uint64_t ring;
 
 	BGE_TRACE(("bge_init_rings($%p)", (void *)bgep));
 
-	mutex_init(bgep->genlock, NULL, MUTEX_DRIVER,
-	    DDI_INTR_PRI(bgep->intr_pri));
-	mutex_init(bgep->softintrlock, NULL, MUTEX_DRIVER,
-		DDI_INTR_PRI(bgep->intr_pri));
-	rw_init(bgep->errlock, NULL, RW_DRIVER,
-	    DDI_INTR_PRI(bgep->intr_pri));
-
 	/*
 	 * Perform one-off initialisation of each ring ...
 	 */
@@ -1228,7 +1378,7 @@
 /*
  * Undo the work of bge_init_rings() above before the memory is freed
  */
-static void
+void
 bge_fini_rings(bge_t *bgep)
 {
 	uint64_t ring;
@@ -1241,10 +1391,6 @@
 		bge_fini_recv_ring(bgep, ring);
 	for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
 		bge_fini_send_ring(bgep, ring);
-
-	rw_destroy(bgep->errlock);
-	mutex_destroy(bgep->softintrlock);
-	mutex_destroy(bgep->genlock);
 }
 
 /*
@@ -1323,7 +1469,7 @@
  * This function allocates all the transmit and receive buffers
  * and descriptors, in four chunks (or one, if MONOLITHIC).
  */
-static int
+int
 bge_alloc_bufs(bge_t *bgep)
 {
 	dma_area_t area;
@@ -1502,7 +1648,7 @@
  * This routine frees the transmit and receive buffers and descriptors.
  * Make sure the chip is stopped before calling it!
  */
-static void
+void
 bge_free_bufs(bge_t *bgep)
 {
 	int split;
@@ -1638,6 +1784,106 @@
 		cidp->vendor_addr.set ? "" : "not "));
 }
 
+
+/*ARGSUSED*/
+int
+bge_check_acc_handle(bge_t *bgep, ddi_acc_handle_t handle)
+{
+	ddi_fm_error_t de;
+
+	ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
+	ddi_fm_acc_err_clear(handle, DDI_FME_VERSION);
+	return (de.fme_status);
+}
+
+/*ARGSUSED*/
+int
+bge_check_dma_handle(bge_t *bgep, ddi_dma_handle_t handle)
+{
+	ddi_fm_error_t de;
+
+	ASSERT(bgep->progress & PROGRESS_BUFS);
+	ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
+	return (de.fme_status);
+}
+
+/*
+ * The IO fault service error handling callback function
+ */
+/*ARGSUSED*/
+static int
+bge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
+{
+	/*
+	 * as the driver can always deal with an error in any dma or
+	 * access handle, we can just return the fme_status value.
+	 */
+	pci_ereport_post(dip, err, NULL);
+	return (err->fme_status);
+}
+
+static void
+bge_fm_init(bge_t *bgep)
+{
+	ddi_iblock_cookie_t iblk;
+
+	/* Only register with IO Fault Services if we have some capability */
+	if (bgep->fm_capabilities) {
+		bge_reg_accattr.devacc_attr_access = DDI_FLAGERR_ACC;
+		bge_desc_accattr.devacc_attr_access = DDI_FLAGERR_ACC;
+		dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
+
+		/* Register capabilities with IO Fault Services */
+		ddi_fm_init(bgep->devinfo, &bgep->fm_capabilities, &iblk);
+
+		/*
+		 * Initialize pci ereport capabilities if ereport capable
+		 */
+		if (DDI_FM_EREPORT_CAP(bgep->fm_capabilities) ||
+		    DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
+			pci_ereport_setup(bgep->devinfo);
+
+		/*
+		 * Register error callback if error callback capable
+		 */
+		if (DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
+			ddi_fm_handler_register(bgep->devinfo,
+			bge_fm_error_cb, (void*) bgep);
+	} else {
+		/*
+		 * These fields have to be cleared of FMA if there are no
+		 * FMA capabilities at runtime.
+		 */
+		bge_reg_accattr.devacc_attr_access = DDI_DEFAULT_ACC;
+		bge_desc_accattr.devacc_attr_access = DDI_DEFAULT_ACC;
+		dma_attr.dma_attr_flags = 0;
+	}
+}
+
+static void
+bge_fm_fini(bge_t *bgep)
+{
+	/* Only unregister FMA capabilities if we registered some */
+	if (bgep->fm_capabilities) {
+
+		/*
+		 * Release any resources allocated by pci_ereport_setup()
+		 */
+		if (DDI_FM_EREPORT_CAP(bgep->fm_capabilities) ||
+		    DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
+			pci_ereport_teardown(bgep->devinfo);
+
+		/*
+		 * Un-register error callback if error callback capable
+		 */
+		if (DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
+			ddi_fm_handler_unregister(bgep->devinfo);
+
+		/* Unregister from IO Fault Services */
+		ddi_fm_fini(bgep->devinfo);
+	}
+}
+
 static void
 #ifdef BGE_IPMI_ASF
 bge_unattach(bge_t *bgep, uint_t asf_mode)
@@ -1673,7 +1919,13 @@
 	if (bgep->progress & PROGRESS_HWINT) {
 		mutex_enter(bgep->genlock);
 #ifdef BGE_IPMI_ASF
-		bge_chip_reset(bgep, B_FALSE, asf_mode);
+		if (bge_chip_reset(bgep, B_FALSE, asf_mode) != DDI_SUCCESS)
+#else
+		if (bge_chip_reset(bgep, B_FALSE) != DDI_SUCCESS)
+#endif
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_UNAFFECTED);
+#ifdef BGE_IPMI_ASF
 		if (bgep->asf_enabled) {
 			/*
 			 * This register has been overlaid. We restore its
@@ -1682,27 +1934,38 @@
 			bge_nic_put32(bgep, BGE_NIC_DATA_SIG_ADDR,
 			    BGE_NIC_DATA_SIG);
 		}
-#else
-		bge_chip_reset(bgep, B_FALSE);
 #endif
+		if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK)
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_UNAFFECTED);
+		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_UNAFFECTED);
 		mutex_exit(bgep->genlock);
 	}
-
 	if (bgep->progress & PROGRESS_INTR) {
-		bge_rem_intrs(bgep);
+		bge_intr_disable(bgep);
 		bge_fini_rings(bgep);
 	}
-
+	if (bgep->progress & PROGRESS_HWINT) {
+		bge_rem_intrs(bgep);
+		rw_destroy(bgep->errlock);
+		mutex_destroy(bgep->softintrlock);
+		mutex_destroy(bgep->genlock);
+	}
 	if (bgep->progress & PROGRESS_FACTOTUM)
 		ddi_remove_softintr(bgep->factotum_id);
 	if (bgep->progress & PROGRESS_RESCHED)
 		ddi_remove_softintr(bgep->resched_id);
-	bge_free_bufs(bgep);
+	if (bgep->progress & PROGRESS_BUFS)
+		bge_free_bufs(bgep);
 	if (bgep->progress & PROGRESS_REGS)
 		ddi_regs_map_free(&bgep->io_handle);
 	if (bgep->progress & PROGRESS_CFG)
 		pci_config_teardown(&bgep->cfg_handle);
 
+	bge_fm_fini(bgep);
+
 	ddi_remove_minor_node(bgep->devinfo, NULL);
 	macp = bgep->macp;
 	kmem_free(macp, sizeof (*macp));
@@ -1740,7 +2003,14 @@
 	 * Refuse to resume if the chip has changed its identity!
 	 */
 	cidp = &bgep->chipid;
+	mutex_enter(bgep->genlock);
 	bge_chip_cfg_init(bgep, &chipid, B_FALSE);
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		mutex_exit(bgep->genlock);
+		return (DDI_FAILURE);
+	}
+	mutex_exit(bgep->genlock);
 	if (chipid.vendor != cidp->vendor)
 		return (DDI_FAILURE);
 	if (chipid.device != cidp->device)
@@ -1754,7 +2024,23 @@
 	 * All OK, reinitialise h/w & kick off GLD scheduling
 	 */
 	mutex_enter(bgep->genlock);
-	bge_restart(bgep, B_TRUE);
+	if (bge_restart(bgep, B_TRUE) != DDI_SUCCESS) {
+		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
+		(void) bge_check_acc_handle(bgep, bgep->io_handle);
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		mutex_exit(bgep->genlock);
+		return (DDI_FAILURE);
+	}
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		mutex_exit(bgep->genlock);
+		return (DDI_FAILURE);
+	}
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		mutex_exit(bgep->genlock);
+		return (DDI_FAILURE);
+	}
 	mutex_exit(bgep->genlock);
 	return (DDI_SUCCESS);
 }
@@ -1779,7 +2065,6 @@
 	int err;
 	mac_info_t *mip;
 	int intr_types;
-	int i;
 #ifdef BGE_IPMI_ASF
 	uint32_t mhcrValue;
 #endif
@@ -1823,6 +2108,16 @@
 		BGE_DRIVER_NAME, instance);
 
 	/*
+	 * Initialize for fma support
+	 */
+	bgep->fm_capabilities = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
+	    DDI_PROP_DONTPASS, fm_cap,
+	    DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
+	    DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
+	BGE_DEBUG(("bgep->fm_capabilities = %d", bgep->fm_capabilities));
+	bge_fm_init(bgep);
+
+	/*
 	 * Look up the IOMMU's page size for DVMA mappings (must be
 	 * a power of 2) and convert to a mask.  This can be used to
 	 * determine whether a message buffer crosses a page boundary.
@@ -1862,6 +2157,10 @@
 	cidp = &bgep->chipid;
 	bzero(cidp, sizeof (*cidp));
 	bge_chip_cfg_init(bgep, cidp, B_FALSE);
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		goto attach_fail;
+	}
 
 #ifdef BGE_IPMI_ASF
 	if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
@@ -1914,12 +2213,16 @@
 	 * Characterise the device, so we know its requirements.
 	 * Then allocate the appropriate TX and RX descriptors & buffers.
 	 */
-	bge_chip_id_init(bgep);
+	if (bge_chip_id_init(bgep) == EIO) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		goto attach_fail;
+	}
 	err = bge_alloc_bufs(bgep);
 	if (err != DDI_SUCCESS) {
 		bge_problem(bgep, "DMA buffer allocation failed");
 		goto attach_fail;
 	}
+	bgep->progress |= PROGRESS_BUFS;
 
 	/*
 	 * Add the softint handlers:
@@ -1976,11 +2279,11 @@
 			bge_log(bgep, "Using MSI interrupt type\n");
 
 			bgep->intr_type = DDI_INTR_TYPE_MSI;
-			bgep->progress |= PROGRESS_INTR;
+			bgep->progress |= PROGRESS_HWINT;
 		}
 	}
 
-	if (!(bgep->progress & PROGRESS_INTR) &&
+	if (!(bgep->progress & PROGRESS_HWINT) &&
 	    (intr_types & DDI_INTR_TYPE_FIXED)) {
 		if (bge_add_intrs(bgep, DDI_INTR_TYPE_FIXED) != DDI_SUCCESS) {
 			bge_error(bgep, "FIXED interrupt "
@@ -1991,34 +2294,35 @@
 		bge_log(bgep, "Using FIXED interrupt type\n");
 
 		bgep->intr_type = DDI_INTR_TYPE_FIXED;
-		bgep->progress |= PROGRESS_INTR;
+		bgep->progress |= PROGRESS_HWINT;
 	}
 
-	if (!(bgep->progress & PROGRESS_INTR)) {
+	if (!(bgep->progress & PROGRESS_HWINT)) {
 		bge_error(bgep, "No interrupts registered\n");
 		goto attach_fail;
 	}
 
 	/*
 	 * Note that interrupts are not enabled yet as
-	 * mutex locks are not initialized.
-	 * Initialize rings and mutex locks.
+	 * mutex locks are not initialized. Initialize mutex locks.
+	 */
+	mutex_init(bgep->genlock, NULL, MUTEX_DRIVER,
+	    DDI_INTR_PRI(bgep->intr_pri));
+	mutex_init(bgep->softintrlock, NULL, MUTEX_DRIVER,
+	    DDI_INTR_PRI(bgep->intr_pri));
+	rw_init(bgep->errlock, NULL, RW_DRIVER,
+	    DDI_INTR_PRI(bgep->intr_pri));
+
+	/*
+	 * Initialize rings.
 	 */
 	bge_init_rings(bgep);
-	bgep->progress |= PROGRESS_HWINT;
 
 	/*
 	 * Now that mutex locks are initialized, enable interrupts.
 	 */
-	if (bgep->intr_cap & DDI_INTR_FLAG_BLOCK) {
-		/* Call ddi_intr_block_enable() for MSI interrupts */
-		(void) ddi_intr_block_enable(bgep->htable, bgep->intr_cnt);
-	} else {
-		/* Call ddi_intr_enable for MSI or FIXED interrupts */
-		for (i = 0; i < bgep->intr_cnt; i++) {
-			(void) ddi_intr_enable(bgep->htable[i]);
-		}
-	}
+	bge_intr_enable(bgep);
+	bgep->progress |= PROGRESS_INTR;
 
 	/*
 	 * Initialise link state variables
@@ -2035,19 +2339,38 @@
 	 * filtering, promiscuity, loopback mode.
 	 */
 #ifdef BGE_IPMI_ASF
-	bge_reset(bgep, ASF_MODE_SHUTDOWN);
+	if (bge_reset(bgep, ASF_MODE_SHUTDOWN) != DDI_SUCCESS) {
 #else
-	bge_reset(bgep);
+	if (bge_reset(bgep) != DDI_SUCCESS) {
 #endif
+		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
+		(void) bge_check_acc_handle(bgep, bgep->io_handle);
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		mutex_exit(bgep->genlock);
+		goto attach_fail;
+	}
 
 	bzero(bgep->mcast_hash, sizeof (bgep->mcast_hash));
 	bzero(bgep->mcast_refs, sizeof (bgep->mcast_refs));
 	bgep->promisc = B_FALSE;
 	bgep->param_loop_mode = BGE_LOOP_NONE;
+	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		mutex_exit(bgep->genlock);
+		goto attach_fail;
+	}
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		mutex_exit(bgep->genlock);
+		goto attach_fail;
+	}
 
 	mutex_exit(bgep->genlock);
 
-	bge_phys_init(bgep);
+	if (bge_phys_init(bgep) == EIO) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+		goto attach_fail;
+	}
 	bgep->progress |= PROGRESS_PHY;
 
 	/*
@@ -2163,7 +2486,17 @@
 	 */
 #endif
 	bge_stop(bgep);
-	bge_phys_idle(bgep);
+	if (bge_phys_idle(bgep) != DDI_SUCCESS) {
+		(void) bge_check_acc_handle(bgep, bgep->io_handle);
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (DDI_FAILURE);
+	}
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+		mutex_exit(bgep->genlock);
+		return (DDI_FAILURE);
+	}
 	mutex_exit(bgep->genlock);
 
 	return (DDI_SUCCESS);
@@ -2214,6 +2547,13 @@
 		}
 
 		asf_mode = ASF_MODE_POST_SHUTDOWN;
+
+		if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK)
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_UNAFFECTED);
+		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+			ddi_fm_service_impact(bgep->devinfo,
+			    DDI_SERVICE_UNAFFECTED);
 	}
 	mutex_exit(bgep->genlock);
 #endif
@@ -2424,7 +2764,38 @@
 
 	bge_log(bgep, "bge_rem_intrs\n");
 
-	/* Disable all interrupts */
+	/* Call ddi_intr_remove_handler() */
+	for (i = 0; i < bgep->intr_cnt; i++) {
+		(void) ddi_intr_remove_handler(bgep->htable[i]);
+		(void) ddi_intr_free(bgep->htable[i]);
+	}
+
+	kmem_free(bgep->htable, bgep->intr_cnt * sizeof (ddi_intr_handle_t));
+}
+
+
+void
+bge_intr_enable(bge_t *bgep)
+{
+	int i;
+
+	if (bgep->intr_cap & DDI_INTR_FLAG_BLOCK) {
+		/* Call ddi_intr_block_enable() for MSI interrupts */
+		(void) ddi_intr_block_enable(bgep->htable, bgep->intr_cnt);
+	} else {
+		/* Call ddi_intr_enable for MSI or FIXED interrupts */
+		for (i = 0; i < bgep->intr_cnt; i++) {
+			(void) ddi_intr_enable(bgep->htable[i]);
+		}
+	}
+}
+
+
+void
+bge_intr_disable(bge_t *bgep)
+{
+	int i;
+
 	if (bgep->intr_cap & DDI_INTR_FLAG_BLOCK) {
 		/* Call ddi_intr_block_disable() */
 		(void) ddi_intr_block_disable(bgep->htable, bgep->intr_cnt);
@@ -2433,12 +2804,4 @@
 			(void) ddi_intr_disable(bgep->htable[i]);
 		}
 	}
-
-	/* Call ddi_intr_remove_handler() */
-	for (i = 0; i < bgep->intr_cnt; i++) {
-		(void) ddi_intr_remove_handler(bgep->htable[i]);
-		(void) ddi_intr_free(bgep->htable[i]);
-	}
-
-	kmem_free(bgep->htable, bgep->intr_cnt * sizeof (ddi_intr_handle_t));
 }
--- a/usr/src/uts/common/io/bge/bge_mii.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/bge/bge_mii.c	Sun Apr 23 15:26:28 2006 -0700
@@ -457,6 +457,10 @@
 	extctrl = bge_mii_get16(bgep, 0x10);
 	bge_mii_put16(bgep, 0x10, extctrl & ~0x3000);
 
+	if (!reset_success)
+		bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE);
+	else if (phy_locked)
+		bge_fm_ereport(bgep, DDI_FM_DEVICE_INVAL_STATE);
 	return (reset_success && !phy_locked);
 }
 
@@ -472,7 +476,7 @@
  * End of Broadcom-derived workaround code				*
  */
 
-static void
+static int
 bge_restart_copper(bge_t *bgep, boolean_t powerdown)
 {
 	uint16_t phy_status;
@@ -503,10 +507,14 @@
 		 * Just a plain reset; the "check" code breaks these chips
 		 */
 		reset_ok = bge_phy_reset(bgep);
+		if (!reset_ok)
+			bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE);
 		break;
 	}
-	if (!reset_ok)
-		bge_problem(bgep, "PHY failed to reset correctly");
+	if (!reset_ok) {
+		BGE_REPORT((bgep, "PHY failed to reset correctly"));
+		return (DDI_FAILURE);
+	}
 
 	/*
 	 * Step 5: disable WOL (not required after RESET)
@@ -546,6 +554,7 @@
 	 */
 	if (powerdown)
 		bge_phy_powerdown(bgep);
+	return (DDI_SUCCESS);
 }
 
 /*
@@ -561,7 +570,7 @@
  *
  * NOTE: <genlock> must already be held by the caller
  */
-static void
+static int
 bge_update_copper(bge_t *bgep)
 {
 	boolean_t adv_autoneg;
@@ -740,7 +749,8 @@
 	 * changes can be attributed to our reprogramming the PHY
 	 */
 	bgep->phys_write_time = gethrtime();
-	(*bgep->physops->phys_restart)(bgep, B_FALSE);
+	if ((*bgep->physops->phys_restart)(bgep, B_FALSE) == DDI_FAILURE)
+		return (DDI_FAILURE);
 	bge_mii_put16(bgep, MII_AN_ADVERT, anar);
 	bge_mii_put16(bgep, MII_CONTROL, control);
 	bge_mii_put16(bgep, MII_AUX_CONTROL, auxctrl);
@@ -778,6 +788,7 @@
 		break;
 	}
 #endif	/* BGE_COPPER_WIRESPEED */
+	return (DDI_SUCCESS);
 }
 
 static boolean_t
@@ -937,7 +948,7 @@
  * Reinitialise the SerDes interface.  Note that it normally powers
  * up in the disabled state, so we need to explicitly activate it.
  */
-static void
+static int
 bge_restart_serdes(bge_t *bgep, boolean_t powerdown)
 {
 	uint32_t macmode;
@@ -965,7 +976,7 @@
 	bge_reg_set32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_COMMA_DETECT);
 	bge_reg_set32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TX_DISABLE);
 	if (powerdown)
-		return;
+		return (DDI_SUCCESS);
 
 	/*
 	 * Otherwise, pause, (re-)enable the SerDes output, and send
@@ -981,6 +992,7 @@
 	bge_reg_clr32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_SEND_CFGS);
 	bgep->serdes_lpadv = AUTONEG_CODE_FAULT_ANEG_ERR;
 	bgep->serdes_status = ~0U;
+	return (DDI_SUCCESS);
 }
 
 /*
@@ -998,7 +1010,7 @@
  *
  * NOTE: <genlock> must already be held by the caller
  */
-static void
+static int
 bge_update_serdes(bge_t *bgep)
 {
 	boolean_t adv_autoneg;
@@ -1112,11 +1124,12 @@
 	 */
 	bgep->serdes_advert = advert;
 	bgep->phys_write_time = gethrtime();
-	bge_restart_serdes(bgep, B_FALSE);
+	(void) bge_restart_serdes(bgep, B_FALSE);
 	bge_reg_set32(bgep, SERDES_CONTROL_REG, serdes);
 
 	BGE_DEBUG(("bge_update_serdes: serdes |= 0x%x, advert 0x%x",
 		serdes, advert));
+	return (DDI_SUCCESS);
 }
 
 /*
@@ -1359,7 +1372,7 @@
  * Here we have to determine which media we're using (copper or serdes).
  * Once that's done, we can initialise the physical layer appropriately.
  */
-void
+int
 bge_phys_init(bge_t *bgep)
 {
 	BGE_TRACE(("bge_phys_init($%p)", (void *)bgep));
@@ -1383,8 +1396,16 @@
 		bgep->physops = &serdes_ops;
 	}
 
-	(*bgep->physops->phys_restart)(bgep, B_FALSE);
+	if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS) {
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
+		mutex_exit(bgep->genlock);
+		return (EIO);
+	}
 	mutex_exit(bgep->genlock);
+	return (0);
 }
 
 /*
@@ -1396,7 +1417,10 @@
 	BGE_TRACE(("bge_phys_reset($%p)", (void *)bgep));
 
 	mutex_enter(bgep->genlock);
-	(*bgep->physops->phys_restart)(bgep, B_FALSE);
+	if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS)
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
 	mutex_exit(bgep->genlock);
 }
 
@@ -1406,13 +1430,13 @@
  * Another RESET should get it back to working, but it may take a few
  * seconds it may take a few moments to return to normal operation ...
  */
-void
+int
 bge_phys_idle(bge_t *bgep)
 {
 	BGE_TRACE(("bge_phys_idle($%p)", (void *)bgep));
 
 	ASSERT(mutex_owned(bgep->genlock));
-	(*bgep->physops->phys_restart)(bgep, B_TRUE);
+	return ((*bgep->physops->phys_restart)(bgep, B_TRUE));
 }
 
 /*
@@ -1427,13 +1451,13 @@
  *
  * NOTE: <genlock> must already be held by the caller
  */
-void
+int
 bge_phys_update(bge_t *bgep)
 {
 	BGE_TRACE(("bge_phys_update($%p)", (void *)bgep));
 
 	ASSERT(mutex_owned(bgep->genlock));
-	(*bgep->physops->phys_update)(bgep);
+	return ((*bgep->physops->phys_update)(bgep));
 }
 
 #undef	BGE_DBG
--- a/usr/src/uts/common/io/bge/bge_recv2.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/bge/bge_recv2.c	Sun Apr 23 15:26:28 2006 -0700
@@ -193,6 +193,11 @@
 	 * Sync the data and copy it to the STREAMS buffer.
 	 */
 	DMA_SYNC(srbdp->pbuf, DDI_DMA_SYNC_FORKERNEL);
+	if (bge_check_dma_handle(bgep, srbdp->pbuf.dma_hdl) != DDI_FM_OK) {
+		bgep->bge_dma_error = B_TRUE;
+		bgep->bge_chip_state = BGE_CHIP_ERROR;
+		return (NULL);
+	}
 #ifdef BGE_IPMI_ASF
 	if (bgep->asf_enabled && (hw_rbd.flags & RBD_FLAG_VLAN_TAG)) {
 		/*
@@ -252,9 +257,8 @@
 	 * (rather than merely packet data) appears corrupted.
 	 * The factotum will attempt to reset-and-recover.
 	 */
-	mutex_enter(bgep->genlock);
 	bgep->bge_chip_state = BGE_CHIP_ERROR;
-	mutex_exit(bgep->genlock);
+	bge_fm_ereport(bgep, DDI_FM_DEVICE_INVAL_STATE);
 	return (NULL);
 }
 
@@ -288,6 +292,19 @@
 	 * before accepting the packets they describe
 	 */
 	DMA_SYNC(rrp->desc, DDI_DMA_SYNC_FORKERNEL);
+	if (*rrp->prod_index_p >= rrp->desc.nslots) {
+		bgep->bge_chip_state = BGE_CHIP_ERROR;
+		bge_fm_ereport(bgep, DDI_FM_DEVICE_INVAL_STATE);
+		return (NULL);
+	}
+	if (bge_check_dma_handle(bgep, rrp->desc.dma_hdl) != DDI_FM_OK) {
+		rrp->rx_next = *rrp->prod_index_p;
+		bge_mbx_put(bgep, rrp->chip_mbx_reg, rrp->rx_next);
+		bgep->bge_dma_error = B_TRUE;
+		bgep->bge_chip_state = BGE_CHIP_ERROR;
+		return (NULL);
+	}
+
 	hw_rbd_p = DMA_VPTR(rrp->desc);
 	head = NULL;
 	tail = &head;
@@ -302,6 +319,8 @@
 	}
 
 	bge_mbx_put(bgep, rrp->chip_mbx_reg, rrp->rx_next);
+	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+		bgep->bge_chip_state = BGE_CHIP_ERROR;
 	return (head);
 }
 
--- a/usr/src/uts/common/io/bge/bge_send.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/bge/bge_send.c	Sun Apr 23 15:26:28 2006 -0700
@@ -113,8 +113,6 @@
 	 *	we're not about to free more places than were claimed!
 	 */
 	ASSERT(srp->tx_free > 0);
-	ASSERT(srp->tx_free < srp->desc.nslots);
-	ASSERT(srp->tx_free + n <= srp->desc.nslots);
 
 	srp->tc_next = slot;
 	bge_atomic_renounce(&srp->tx_free, n);
@@ -412,7 +410,6 @@
 	 *	there must be at least one place NOT free (ours!)
 	 */
 	ASSERT(srp->tx_free > 0);
-	ASSERT(srp->tx_free < srp->desc.nslots);
 
 	if ((status = bge_send_copy(bgep, mp, srp, tci)) == SEND_FAIL) {
 		/*
@@ -437,6 +434,8 @@
 	if (--srp->tx_flow == 0) {
 		DMA_SYNC(srp->desc, DDI_DMA_SYNC_FORDEV);
 		bge_mbx_put(bgep, srp->chip_mbx_reg, srp->tx_next);
+		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
+			bgep->bge_chip_state = BGE_CHIP_ERROR;
 	}
 	mutex_exit(srp->tx_lock);
 
--- a/usr/src/uts/common/io/bofi.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/bofi.c	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -38,6 +37,10 @@
 #include <sys/cpuvar.h>
 #include <sys/ddi_impldefs.h>
 #include <sys/ddi.h>
+#include <sys/fm/protocol.h>
+#include <sys/fm/util.h>
+#include <sys/fm/io/ddi.h>
+#include <sys/sysevent/eventdefs.h>
 #include <sys/sunddi.h>
 #include <sys/sunndi.h>
 #include <sys/debug.h>
@@ -180,6 +183,12 @@
 static int	bofi_intr_ops(dev_info_t *dip, dev_info_t *rdip,
 		    ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp,
 		    void *result);
+static int	bofi_fm_ereport_callback(sysevent_t *ev, void *cookie);
+
+evchan_t *bofi_error_chan;
+
+#define	FM_SIMULATED_DMA "simulated.dma"
+#define	FM_SIMULATED_PIO "simulated.pio"
 
 #if defined(__sparc)
 static void	bofi_dvma_kaddr_load(ddi_dma_handle_t, caddr_t, uint_t,
@@ -725,6 +734,10 @@
 			mutex_destroy(&bofi_low_mutex);
 			return (DDI_FAILURE);
 		}
+		if (sysevent_evc_bind(FM_ERROR_CHAN, &bofi_error_chan, 0) == 0)
+			(void) sysevent_evc_subscribe(bofi_error_chan, "bofi",
+			    EC_FM, bofi_fm_ereport_callback, NULL, 0);
+
 		/*
 		 * save dip for getinfo
 		 */
@@ -768,6 +781,8 @@
 	if (reset_bus_ops(nexus_name, &save_bus_ops) == 0)
 		return (DDI_FAILURE);
 
+	sysevent_evc_unbind(bofi_error_chan);
+
 	mutex_destroy(&clone_tab_mutex);
 	mutex_destroy(&bofi_mutex);
 	mutex_destroy(&bofi_low_mutex);
@@ -1724,6 +1739,7 @@
 	ep->errdef = *errdefp;
 	ep->name = namep;
 	ep->errdef.errdef_handle = (uint64_t)(uintptr_t)ep;
+	ep->errstate.severity = DDI_SERVICE_RESTORED;
 	ep->errstate.errdef_handle = (uint64_t)(uintptr_t)ep;
 	cv_init(&ep->cv, NULL, CV_DRIVER, NULL);
 	/*
@@ -2164,8 +2180,10 @@
 	 */
 	if (rval == 0 && !(ep->state & BOFI_NEW_MESSAGE)) {
 		ep->state |= BOFI_MESSAGE_WAIT;
-		if (cv_wait_sig(&ep->cv, &bofi_low_mutex) == 0)
-			rval = EINTR;
+		if (cv_wait_sig(&ep->cv, &bofi_low_mutex) == 0) {
+			if (!(ep->state & BOFI_NEW_MESSAGE))
+				rval = EINTR;
+		}
 		goto retry;
 	}
 	ep->state &= ~BOFI_NEW_MESSAGE;
@@ -2277,6 +2295,8 @@
 	caddr_t logaddr;
 	uint64_t *addr;
 	uint64_t *endaddr;
+	ddi_dma_impl_t *hdlp;
+	ndi_err_t *errp;
 
 	ASSERT(MUTEX_HELD(&bofi_mutex));
 	if ((ep->errdef.access_count ||
@@ -2325,6 +2345,19 @@
 		    ep->errdef.offset + ep->errdef.len)) & ~LLSZMASK);
 		len = endaddr - addr;
 		operand = ep->errdef.operand;
+		hdlp = (ddi_dma_impl_t *)(hp->hdl.dma_handle);
+		errp = &hdlp->dmai_error;
+		if (ep->errdef.acc_chk & 2) {
+			uint64_t ena;
+			char buf[FM_MAX_CLASS];
+
+			errp->err_status = DDI_FM_NONFATAL;
+			(void) snprintf(buf, FM_MAX_CLASS, FM_SIMULATED_DMA);
+			ena = fm_ena_generate(0, FM_ENA_FMT1);
+			ddi_fm_ereport_post(hp->dip, buf, ena,
+			    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8,
+			    FM_EREPORT_VERS0, NULL);
+		}
 		switch (ep->errdef.optype) {
 		case BOFI_EQUAL :
 			for (i = 0; i < len; i++)
@@ -2377,6 +2410,8 @@
 	intptr_t base;
 	int done_get = 0;
 	uint64_t get_val, gv;
+	ddi_acc_impl_t *hdlp;
+	ndi_err_t *errp;
 
 	ASSERT(MUTEX_HELD(&bofi_mutex));
 	/*
@@ -2431,6 +2466,21 @@
 					    addr - hp->addr,
 					    accsize, repcount, &gv);
 				}
+				hdlp = (ddi_acc_impl_t *)(hp->hdl.acc_handle);
+				errp = hdlp->ahi_err;
+				if (ep->errdef.acc_chk & 1) {
+					uint64_t ena;
+					char buf[FM_MAX_CLASS];
+
+					errp->err_status = DDI_FM_NONFATAL;
+					(void) snprintf(buf, FM_MAX_CLASS,
+					    FM_SIMULATED_PIO);
+					ena = fm_ena_generate(0, FM_ENA_FMT1);
+					ddi_fm_ereport_post(hp->dip, buf, ena,
+					    DDI_NOSLEEP, FM_VERSION,
+					    DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+					    NULL);
+				}
 				switch (ep->errdef.optype) {
 				case BOFI_EQUAL :
 					get_val = operand;
@@ -2476,6 +2526,8 @@
 	uintptr_t minlen;
 	intptr_t base;
 	uint64_t v = *valuep;
+	ddi_acc_impl_t *hdlp;
+	ndi_err_t *errp;
 
 	ASSERT(MUTEX_HELD(&bofi_mutex));
 	/*
@@ -2513,6 +2565,21 @@
 				 */
 				if (ep->errstate.fail_time == 0)
 					ep->errstate.fail_time = bofi_gettime();
+				hdlp = (ddi_acc_impl_t *)(hp->hdl.acc_handle);
+				errp = hdlp->ahi_err;
+				if (ep->errdef.acc_chk & 1) {
+					uint64_t ena;
+					char buf[FM_MAX_CLASS];
+
+					errp->err_status = DDI_FM_NONFATAL;
+					(void) snprintf(buf, FM_MAX_CLASS,
+					    FM_SIMULATED_PIO);
+					ena = fm_ena_generate(0, FM_ENA_FMT1);
+					ddi_fm_ereport_post(hp->dip, buf, ena,
+					    DDI_NOSLEEP, FM_VERSION,
+					    DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+					    NULL);
+				}
 				switch (ep->errdef.optype) {
 				case BOFI_EQUAL :
 					*valuep = ep->errdef.operand;
@@ -4624,6 +4691,79 @@
 	return (save_bus_ops.bus_post_event(dip, rdip, eventhdl, impl_data));
 }
 
+/*ARGSUSED*/
+static int
+bofi_fm_ereport_callback(sysevent_t *ev, void *cookie)
+{
+	char *class = "";
+	char *path = "";
+	char *ptr;
+	nvlist_t *nvlist;
+	nvlist_t *detector;
+	ddi_fault_impact_t impact;
+	struct bofi_errent *ep;
+	struct bofi_shadow *hp;
+	struct bofi_link   *lp;
+	char service_class[FM_MAX_CLASS];
+	char hppath[MAXPATHLEN];
+	int service_ereport = 0;
+
+	(void) sysevent_get_attr_list(ev, &nvlist);
+	(void) nvlist_lookup_string(nvlist, FM_CLASS, &class);
+	if (nvlist_lookup_nvlist(nvlist, FM_EREPORT_DETECTOR, &detector) == 0)
+		(void) nvlist_lookup_string(detector, FM_FMRI_DEV_PATH, &path);
+
+	(void) snprintf(service_class, FM_MAX_CLASS, "%s.%s.%s.",
+	    FM_EREPORT_CLASS, DDI_IO_CLASS, DDI_FM_SERVICE_IMPACT);
+	if (strncmp(class, service_class, strlen(service_class) - 1) == 0)
+		service_ereport = 1;
+
+	mutex_enter(&bofi_mutex);
+	/*
+	 * find shadow handles with appropriate dev_infos
+	 * and set error reported on all associated errdef structures
+	 */
+	for (hp = shadow_list.next; hp != &shadow_list; hp = hp->next) {
+		(void) ddi_pathname(hp->dip, hppath);
+		if (strcmp(path, hppath) != 0)
+			continue;
+		for (lp = hp->link; lp != NULL; lp = lp->link) {
+			ep = lp->errentp;
+			ep->errstate.errmsg_count++;
+			if (!(ep->state & BOFI_DEV_ACTIVE))
+				continue;
+			if (ep->errstate.msg_time != NULL)
+				continue;
+			if (service_ereport) {
+				ptr = class + strlen(service_class);
+				if (strcmp(ptr, DDI_FM_SERVICE_LOST) == 0)
+					impact = DDI_SERVICE_LOST;
+				else if (strcmp(ptr,
+				    DDI_FM_SERVICE_DEGRADED) == 0)
+					impact = DDI_SERVICE_DEGRADED;
+				else if (strcmp(ptr,
+				    DDI_FM_SERVICE_RESTORED) == 0)
+					impact = DDI_SERVICE_RESTORED;
+				else
+					impact = DDI_SERVICE_UNAFFECTED;
+				if (ep->errstate.severity > impact)
+					ep->errstate.severity = impact;
+			} else if (ep->errstate.buffer[0] == '\0') {
+				(void) strncpy(ep->errstate.buffer, class,
+				    ERRMSGSIZE);
+			}
+			if (ep->errstate.buffer[0] != '\0' &&
+			    ep->errstate.severity < DDI_SERVICE_RESTORED) {
+				ep->errstate.msg_time = bofi_gettime();
+				ddi_trigger_softintr(ep->softintr_id);
+			}
+		}
+	}
+	nvlist_free(nvlist);
+	mutex_exit(&bofi_mutex);
+	return (0);
+}
+
 /*
  * our intr_ops routine
  */
--- a/usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c	Sun Apr 23 15:26:28 2006 -0700
@@ -106,30 +106,6 @@
 static int pcicfg_sec_reset_delay = 3000000;
 static int pcicfg_do_legacy_props = 1;	/* create legacy compatible prop */
 
-/*
- * The following typedef is used to represent a
- * 1275 "bus-range" property of a PCI Bus node.
- * DAF - should be in generic include file...
- */
-
-typedef struct pcicfg_bus_range {
-	uint32_t lo;
-	uint32_t hi;
-} pcicfg_bus_range_t;
-
-typedef struct pcicfg_range {
-
-	uint32_t child_hi;
-	uint32_t child_mid;
-	uint32_t child_lo;
-	uint32_t parent_hi;
-	uint32_t parent_mid;
-	uint32_t parent_lo;
-	uint32_t size_hi;
-	uint32_t size_lo;
-
-} pcicfg_range_t;
-
 typedef struct hole hole_t;
 
 struct hole {
@@ -289,7 +265,7 @@
 static void pcicfg_get_mem(pcicfg_phdl_t *, uint32_t, uint64_t *);
 static void pcicfg_get_pf_mem(pcicfg_phdl_t *, uint32_t, uint64_t *);
 static void pcicfg_get_io(pcicfg_phdl_t *, uint32_t, uint32_t *);
-static int pcicfg_update_ranges_prop(dev_info_t *, pcicfg_range_t *);
+static int pcicfg_update_ranges_prop(dev_info_t *, ppb_ranges_t *);
 static int pcicfg_configure_ntbridge(dev_info_t *, uint_t, uint_t);
 static uint_t pcicfg_ntbridge_child(dev_info_t *);
 static int pcicfg_indirect_map(dev_info_t *dip);
@@ -604,7 +580,7 @@
 	int func;
 	dev_info_t *new_device;
 	dev_info_t *attach_point;
-	pcicfg_bus_range_t pci_bus_range;
+	pci_bus_range_t pci_bus_range;
 	int rv;
 	int circ;
 	uint_t highest_bus;
@@ -613,7 +589,7 @@
 	 * Start probing at the device specified in "device" on the
 	 * "bus" specified.
 	 */
-	len = sizeof (pcicfg_bus_range_t);
+	len = sizeof (pci_bus_range_t);
 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, devi, 0, "bus-range",
 	    (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
 		DEBUG0("no bus-range property\n");
@@ -1062,10 +1038,10 @@
 static int
 pcicfg_ntbridge_configure_done(dev_info_t *dip)
 {
-	pcicfg_range_t range[PCICFG_RANGE_LEN];
+	ppb_ranges_t range[PCICFG_RANGE_LEN];
 	pcicfg_phdl_t		*entry;
 	uint_t			len;
-	pcicfg_bus_range_t	bus_range;
+	pci_bus_range_t		bus_range;
 	int			new_bus_range[2];
 
 	DEBUG1("Configuring children for %p\n", dip);
@@ -1074,21 +1050,21 @@
 	ASSERT(entry);
 
 	bzero((caddr_t)range,
-		sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
-	range[1].child_hi = range[1].parent_hi |=
+		sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
+	range[1].child_high = range[1].parent_high |=
 		(PCI_REG_REL_M | PCI_ADDR_MEM32);
-	range[1].child_lo = range[1].parent_lo = (uint32_t)entry->memory_base;
-
-	range[0].child_hi = range[0].parent_hi |=
+	range[1].child_low = range[1].parent_low = (uint32_t)entry->memory_base;
+
+	range[0].child_high = range[0].parent_high |=
 		(PCI_REG_REL_M | PCI_ADDR_IO);
-	range[0].child_lo = range[0].parent_lo = (uint32_t)entry->io_base;
-
-	range[2].child_hi = range[2].parent_hi |=
+	range[0].child_low = range[0].parent_low = (uint32_t)entry->io_base;
+
+	range[2].child_high = range[2].parent_high |=
 		(PCI_REG_REL_M | PCI_ADDR_MEM32 | PCI_REG_PF_M);
-	range[2].child_lo = range[2].parent_lo =
+	range[2].child_low = range[2].parent_low =
 		(uint32_t)entry->pf_memory_base;
 
-	len = sizeof (pcicfg_bus_range_t);
+	len = sizeof (pci_bus_range_t);
 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 		"bus-range", (caddr_t)&bus_range, (int *)&len) != DDI_SUCCESS) {
 		DEBUG0("no bus-range property\n");
@@ -1128,7 +1104,7 @@
 	}
 #endif
 
-	range[0].size_lo = entry->io_len;
+	range[0].size_low = entry->io_len;
 	if (pcicfg_update_ranges_prop(dip, &range[0])) {
 		DEBUG0("Failed to update ranges (i/o)\n");
 		entry->error = PCICFG_FAILURE;
@@ -1144,7 +1120,7 @@
 	}
 #endif
 
-	range[1].size_lo = entry->memory_len;
+	range[1].size_low = entry->memory_len;
 	if (pcicfg_update_ranges_prop(dip, &range[1])) {
 		DEBUG0("Failed to update ranges (memory)\n");
 		entry->error = PCICFG_FAILURE;
@@ -1160,7 +1136,7 @@
 	}
 #endif
 
-	range[2].size_lo = entry->pf_memory_len;
+	range[2].size_low = entry->pf_memory_len;
 	if (pcicfg_update_ranges_prop(dip, &range[2])) {
 		DEBUG0("Failed to update ranges (PF memory)\n");
 		entry->error = PCICFG_FAILURE;
@@ -1207,9 +1183,9 @@
 	int 		len, bus;
 	uint16_t	vid;
 	ddi_acc_handle_t	config_handle;
-	pcicfg_bus_range_t pci_bus_range;
-
-	len = sizeof (pcicfg_bus_range_t);
+	pci_bus_range_t pci_bus_range;
+
+	len = sizeof (pci_bus_range_t);
 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, new_device, DDI_PROP_DONTPASS,
 		"bus-range", (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
 		DEBUG0("no bus-range property\n");
@@ -1657,7 +1633,7 @@
 	uint32_t io_answer;
 	int count;
 	uint8_t header_type;
-	pcicfg_range_t range[PCICFG_RANGE_LEN];
+	ppb_ranges_t range[PCICFG_RANGE_LEN];
 	int bus_range[2];
 	uint64_t mem_residual;
 	uint64_t pf_mem_residual;
@@ -1688,21 +1664,21 @@
 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
 
 		bzero((caddr_t)range,
-			sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
+			sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
 
 		(void) pcicfg_setup_bridge(entry, handle);
 
-		range[0].child_hi = range[0].parent_hi |=
+		range[0].child_high = range[0].parent_high |=
 			(PCI_REG_REL_M | PCI_ADDR_IO);
-		range[0].child_lo = range[0].parent_lo =
+		range[0].child_low = range[0].parent_low =
 			entry->io_last;
-		range[1].child_hi = range[1].parent_hi |=
+		range[1].child_high = range[1].parent_high |=
 			(PCI_REG_REL_M | PCI_ADDR_MEM32);
-		range[1].child_lo = range[1].parent_lo =
+		range[1].child_low = range[1].parent_low =
 			entry->memory_last;
-		range[2].child_hi = range[2].parent_hi |=
+		range[2].child_high = range[2].parent_high |=
 			(PCI_REG_REL_M | PCI_ADDR_MEM32 | PCI_REG_PF_M);
-		range[2].child_lo = range[2].parent_lo =
+		range[2].child_low = range[2].parent_low =
 			entry->pf_memory_last;
 
 		ndi_devi_enter(dip, &count);
@@ -1754,7 +1730,7 @@
 		}
 
 		if (entry->io_len > 0) {
-			range[0].size_lo = entry->io_last - entry->io_base;
+			range[0].size_low = entry->io_last - entry->io_base;
 			if (pcicfg_update_ranges_prop(dip, &range[0])) {
 				DEBUG0("Failed to update ranges (i/o)\n");
 				entry->error = PCICFG_FAILURE;
@@ -1762,7 +1738,7 @@
 			}
 		}
 		if (entry->memory_len > 0) {
-			range[1].size_lo =
+			range[1].size_low =
 				entry->memory_last - entry->memory_base;
 			if (pcicfg_update_ranges_prop(dip, &range[1])) {
 				DEBUG0("Failed to update ranges (memory)\n");
@@ -1771,7 +1747,7 @@
 			}
 		}
 		if (entry->pf_memory_len > 0) {
-			range[2].size_lo =
+			range[2].size_low =
 				entry->pf_memory_last - entry->pf_memory_base;
 			if (pcicfg_update_ranges_prop(dip, &range[2])) {
 				DEBUG0("Failed to update ranges (PF memory)\n");
@@ -2377,7 +2353,7 @@
 static int
 pcicfg_free_bridge_resources(dev_info_t *dip)
 {
-	pcicfg_range_t		*ranges;
+	ppb_ranges_t		*ranges;
 	uint_t			*bus;
 	int			k;
 	int			length;
@@ -2403,20 +2379,20 @@
 		length = 0;
 	}
 
-	for (i = 0; i < length / sizeof (pcicfg_range_t); i++) {
+	for (i = 0; i < length / sizeof (ppb_ranges_t); i++) {
 		char *mem_type;
 
-		if (ranges[i].size_lo != 0 ||
-			ranges[i].size_hi != 0) {
-			switch (ranges[i].parent_hi & PCI_REG_ADDR_M) {
+		if (ranges[i].size_low != 0 ||
+			ranges[i].size_high != 0) {
+			switch (ranges[i].parent_high & PCI_REG_ADDR_M) {
 				case PCI_ADDR_IO:
 					DEBUG2("Free I/O    "
 					"base/length = [0x%x]/[0x%x]\n",
-						ranges[i].child_lo,
-						ranges[i].size_lo);
+						ranges[i].child_low,
+						ranges[i].size_low);
 					if (ndi_ra_free(ddi_get_parent(dip),
-						(uint64_t)ranges[i].child_lo,
-						(uint64_t)ranges[i].size_lo,
+						(uint64_t)ranges[i].child_low,
+						(uint64_t)ranges[i].size_low,
 						NDI_RA_TYPE_IO, NDI_RA_PASS)
 						!= NDI_SUCCESS) {
 						DEBUG0("Trouble freeing "
@@ -2427,29 +2403,30 @@
 				break;
 				case PCI_ADDR_MEM32:
 				case PCI_ADDR_MEM64:
-				    if (ranges[i].parent_hi & PCI_REG_PF_M) {
+				    if (ranges[i].parent_high & PCI_REG_PF_M) {
 					DEBUG3("Free PF Memory base/length"
 					" = [0x%x.0x%x]/[0x%x]\n",
 					ranges[i].child_mid,
-					ranges[i].child_lo,
-					ranges[i].size_lo)
+					ranges[i].child_low,
+					ranges[i].size_low)
 					mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
 				    } else {
 					DEBUG3("Free Memory base/length"
 					" = [0x%x.0x%x]/[0x%x]\n",
 					ranges[i].child_mid,
-					ranges[i].child_lo,
-					ranges[i].size_lo)
+					ranges[i].child_low,
+					ranges[i].size_low)
 					mem_type = NDI_RA_TYPE_MEM;
 				    }
 				    if (ndi_ra_free(ddi_get_parent(dip),
-						PCICFG_LADDR(ranges[i].child_lo,
+						PCICFG_LADDR(
+						ranges[i].child_low,
 						ranges[i].child_mid),
-						(uint64_t)ranges[i].size_lo,
+						(uint64_t)ranges[i].size_low,
 						mem_type,
 						NDI_RA_PASS) != NDI_SUCCESS) {
 						DEBUG0("Trouble freeing "
-						"PCI memory space\n");
+						    "PCI memory space\n");
 						kmem_free(ranges, length);
 						return (PCICFG_FAILURE);
 				    }
@@ -2750,10 +2727,10 @@
 }
 
 static int
-pcicfg_update_ranges_prop(dev_info_t *dip, pcicfg_range_t *addition)
+pcicfg_update_ranges_prop(dev_info_t *dip, ppb_ranges_t *addition)
 {
 	int		rlen;
-	pcicfg_range_t	*ranges;
+	ppb_ranges_t	*ranges;
 	caddr_t		newreg;
 	uint_t		status;
 
@@ -2771,7 +2748,7 @@
 			DEBUG0("no ranges property - creating one\n");
 			if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
 				dip, "ranges", (int *)addition,
-				sizeof (pcicfg_range_t)/sizeof (int))
+				sizeof (ppb_ranges_t)/sizeof (int))
 				!= DDI_SUCCESS) {
 				DEBUG0("Did'nt create ranges property\n");
 				return (PCICFG_FAILURE);
@@ -2783,22 +2760,22 @@
 	 * Allocate memory for the existing ranges plus one and then
 	 * build it.
 	 */
-	newreg = kmem_zalloc(rlen+sizeof (pcicfg_range_t), KM_SLEEP);
+	newreg = kmem_zalloc(rlen+sizeof (ppb_ranges_t), KM_SLEEP);
 
 	bcopy(ranges, newreg, rlen);
-	bcopy(addition, newreg + rlen, sizeof (pcicfg_range_t));
+	bcopy(addition, newreg + rlen, sizeof (ppb_ranges_t));
 
 	/*
 	 * Write out the new "ranges" property
 	 */
 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
 		dip, "ranges", (int *)newreg,
-		(rlen + sizeof (pcicfg_range_t))/sizeof (int));
+		(rlen + sizeof (ppb_ranges_t))/sizeof (int));
 
 	DEBUG1("Updating ranges property for %d entries",
-			rlen / sizeof (pcicfg_range_t) + 1);
-
-	kmem_free((caddr_t)newreg, rlen+sizeof (pcicfg_range_t));
+			rlen / sizeof (ppb_ranges_t) + 1);
+
+	kmem_free((caddr_t)newreg, rlen+sizeof (ppb_ranges_t));
 
 	kmem_free((caddr_t)ranges, rlen);
 
@@ -3042,20 +3019,32 @@
 			return (ret);
 		}
 	}
+	if ((cap_id_loc = pcicfg_get_cap(config_handle, PCI_CAP_ID_PCIX)) > 0) {
+		/* create the pcix-capid-pointer property */
+		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
+		    "pcix-capid-pointer", cap_id_loc)) != DDI_SUCCESS)
+			return (ret);
+	}
 	if (pcie_dev && (cap_id_loc = pcicfg_get_cap(config_handle,
 					PCI_CAP_ID_PCI_E)) > 0) {
+		/* create the pcie-capid-pointer property */
+		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
+		    "pcie-capid-pointer", cap_id_loc)) != DDI_SUCCESS)
+			return (ret);
 		val = pci_config_get16(config_handle, cap_id_loc +
 				PCIE_PCIECAP) & PCIE_PCIECAP_SLOT_IMPL;
 		/* if slot implemented, get physical slot number */
 		if (val) {
-			wordval = (pci_config_get32(config_handle, cap_id_loc +
-					PCIE_SLOTCAP) >>
-					PCIE_SLOTCAP_PHY_SLOT_NUM_SHIFT) &
-					PCIE_SLOTCAP_PHY_SLOT_NUM_MASK;
+			wordval = pci_config_get32(config_handle, cap_id_loc +
+					PCIE_SLOTCAP);
+			/* create the slotcap-reg property */
+			if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE,
+			    dip, "pcie-slotcap-reg", wordval)) != DDI_SUCCESS)
+				return (ret);
 			/* create the property only if slotnum set correctly? */
-			if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE,
-					dip, "physical-slot#", wordval))
-						!= DDI_SUCCESS) {
+			if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
+			    "physical-slot#", PCIE_SLOTCAP_PHY_SLOT_NUM(
+			    wordval))) != DDI_SUCCESS) {
 				return (ret);
 			}
 		}
@@ -3637,7 +3626,7 @@
 	uint64_t mem_size, io_size, pf_mem_size;
 	uint64_t mem_end, pf_mem_end, io_end;
 	uint64_t round_answer, round_len;
-	pcicfg_range_t range[PCICFG_RANGE_LEN];
+	ppb_ranges_t range[PCICFG_RANGE_LEN];
 	int bus_range[2];
 	pcicfg_phdl_t phdl;
 	int count;
@@ -4273,27 +4262,28 @@
 	DEBUG2("                         - PF Mem address %lx PF Mem Size %x\n",
 	    pf_mem_base, pf_mem_size);
 
-	bzero((caddr_t)range, sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
-
-	range[0].child_hi = range[0].parent_hi |= (PCI_REG_REL_M | PCI_ADDR_IO);
-	range[0].child_lo = range[0].parent_lo = io_base;
-	range[1].child_hi = range[1].parent_hi |=
+	bzero((caddr_t)range, sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
+
+	range[0].child_high = range[0].parent_high |= (PCI_REG_REL_M |
+	    PCI_ADDR_IO);
+	range[0].child_low = range[0].parent_low = io_base;
+	range[1].child_high = range[1].parent_high |=
 	    (PCI_REG_REL_M | PCI_ADDR_MEM32);
-	range[1].child_lo = range[1].parent_lo = mem_base;
-	range[2].child_hi = range[2].parent_hi |=
+	range[1].child_low = range[1].parent_low = mem_base;
+	range[2].child_high = range[2].parent_high |=
 	    (PCI_REG_REL_M | PCI_ADDR_MEM64 | PCI_REG_PF_M);
-	range[2].child_lo = range[2].parent_lo = pf_mem_base;
+	range[2].child_low = range[2].parent_low = pf_mem_base;
 
 	if (io_size > 0) {
-		range[0].size_lo = io_size;
+		range[0].size_low = io_size;
 		(void) pcicfg_update_ranges_prop(new_child, &range[0]);
 	}
 	if (mem_size > 0) {
-		range[1].size_lo = mem_size;
+		range[1].size_low = mem_size;
 		(void) pcicfg_update_ranges_prop(new_child, &range[1]);
 	}
 	if (pf_mem_size > 0) {
-		range[2].size_lo = pf_mem_size;
+		range[2].size_low = pf_mem_size;
 		(void) pcicfg_update_ranges_prop(new_child, &range[2]);
 	}
 
--- a/usr/src/uts/common/io/hotplug/pcihp/pcihp.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/hotplug/pcihp/pcihp.c	Sun Apr 23 15:26:28 2006 -0700
@@ -3609,10 +3609,7 @@
 	struct pcihp_slotinfo *slotinfop;
 	hpc_slot_state_t rstate;
 	ddi_acc_hdl_t *hp;
-	struct bus_range {
-		uint32_t lo;
-		uint32_t hi;
-	} pci_bus_range;
+	pci_bus_range_t pci_bus_range;
 
 	slotinfop = &pcihp_p->slotinfo[pci_dev];
 
@@ -3645,7 +3642,7 @@
 	 * If there is no dip then we need to see if an
 	 * adapter has just been hot plugged.
 	 */
-	len = sizeof (struct bus_range);
+	len = sizeof (pci_bus_range_t);
 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, pdip,
 	    0, "bus-range",
 	    (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
--- a/usr/src/uts/common/io/pci_pci/pci_pci.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/io/pci_pci/pci_pci.c	Sun Apr 23 15:26:28 2006 -0700
@@ -39,6 +39,9 @@
 #include <sys/ddi.h>
 #include <sys/sunddi.h>
 #include <sys/sunndi.h>
+#include <sys/ddifm.h>
+#include <sys/ndifm.h>
+#include <sys/fm/protocol.h>
 #include <sys/hotplug/pci/pcihp.h>
 #if defined(__i386) || defined(__amd64)
 #include <sys/pci_intr_lib.h>
@@ -73,6 +76,11 @@
 	off_t, off_t, caddr_t *);
 static int ppb_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
 	void *, void *);
+static int	ppb_fm_init(dev_info_t *, dev_info_t *, int,
+		    ddi_iblock_cookie_t *);
+
+static int	ppb_fm_callback(dev_info_t *, ddi_fm_error_t *, const void *);
+
 #if defined(__i386) || defined(__amd64)
 static int ppb_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t,
 	ddi_intr_handle_impl_t *, void *);
@@ -112,7 +120,7 @@
 	0,		/* (*bus_intr_ctl)();		*/
 	0,		/* (*bus_config)(); 		*/
 	0,		/* (*bus_unconfig)(); 		*/
-	NULL,		/* (*bus_fm_init)(); 		*/
+	ppb_fm_init,	/* (*bus_fm_init)(); 		*/
 	NULL,		/* (*bus_fm_fini)(); 		*/
 	NULL,		/* (*bus_fm_access_enter)(); 	*/
 	NULL,		/* (*bus_fm_access_exit)(); 	*/
@@ -198,6 +206,10 @@
 typedef struct {
 
 	dev_info_t *dip;
+	int ppb_fmcap;
+	ddi_iblock_cookie_t ppb_fm_ibc;
+	kmutex_t ppb_peek_poke_mutex;
+	kmutex_t ppb_err_mutex;
 
 #if defined(__sparc)
 	/*
@@ -323,7 +335,37 @@
 			return (DDI_FAILURE);
 		ppb = ddi_get_soft_state(ppb_state, instance);
 		ppb->dip = devi;
+
+		/*
+		 * don't enable ereports if immediate child of npe
+		 */
+		if (strcmp(ddi_driver_name(ddi_get_parent(devi)), "npe") == 0)
+			ppb->ppb_fmcap = DDI_FM_ERRCB_CAPABLE |
+			    DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
+		else
+			ppb->ppb_fmcap = DDI_FM_EREPORT_CAPABLE |
+			    DDI_FM_ERRCB_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
+			    DDI_FM_DMACHK_CAPABLE;
+
+		ddi_fm_init(devi, &ppb->ppb_fmcap, &ppb->ppb_fm_ibc);
+		mutex_init(&ppb->ppb_err_mutex, NULL, MUTEX_DRIVER,
+		    (void *)ppb->ppb_fm_ibc);
+		mutex_init(&ppb->ppb_peek_poke_mutex, NULL, MUTEX_DRIVER,
+		    (void *)ppb->ppb_fm_ibc);
+
+		if (ppb->ppb_fmcap & (DDI_FM_ERRCB_CAPABLE |
+		    DDI_FM_EREPORT_CAPABLE))
+			pci_ereport_setup(devi);
+		if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE)
+		    ddi_fm_handler_register(devi, ppb_fm_callback, NULL);
+
 		if (pci_config_setup(devi, &config_handle) != DDI_SUCCESS) {
+			if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE)
+				ddi_fm_handler_unregister(devi);
+			if (ppb->ppb_fmcap & (DDI_FM_ERRCB_CAPABLE |
+			    DDI_FM_EREPORT_CAPABLE))
+				pci_ereport_teardown(devi);
+			ddi_fm_fini(devi);
 			ddi_soft_state_free(ppb_state, instance);
 			return (DDI_FAILURE);
 		}
@@ -371,6 +413,17 @@
 	switch (cmd) {
 	case DDI_DETACH:
 		(void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "device_type");
+
+		ppb = ddi_get_soft_state(ppb_state, ddi_get_instance(devi));
+		if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE)
+			ddi_fm_handler_unregister(devi);
+		if (ppb->ppb_fmcap & (DDI_FM_ERRCB_CAPABLE |
+		    DDI_FM_EREPORT_CAPABLE))
+			pci_ereport_teardown(devi);
+		mutex_destroy(&ppb->ppb_peek_poke_mutex);
+		mutex_destroy(&ppb->ppb_err_mutex);
+		ddi_fm_fini(devi);
+
 		/*
 		 * And finally free the per-pci soft state.
 		 */
@@ -414,6 +467,7 @@
 	int	reglen;
 	int	rn;
 	int	totreg;
+	ppb_devstate_t *ppb;
 
 	switch (ctlop) {
 	case DDI_CTLOPS_REPORTDEV:
@@ -441,6 +495,15 @@
 			return (DDI_FAILURE);
 		break;
 
+	case DDI_CTLOPS_PEEK:
+	case DDI_CTLOPS_POKE:
+		ppb = ddi_get_soft_state(ppb_state, ddi_get_instance(dip));
+		if (strcmp(ddi_driver_name(ddi_get_parent(dip)), "npe") != 0)
+			return (ddi_ctlops(dip, rdip, ctlop, arg, result));
+		return (pci_peekpoke_check(dip, rdip, ctlop, arg, result,
+		    ddi_ctlops, &ppb->ppb_err_mutex,
+		    &ppb->ppb_peek_poke_mutex));
+
 	default:
 		return (ddi_ctlops(dip, rdip, ctlop, arg, result));
 	}
@@ -985,3 +1048,30 @@
 {
 	return (pcihp_info(dip, cmd, arg, result));
 }
+
+/*ARGSUSED*/
+static int
+ppb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
+    ddi_iblock_cookie_t *ibc)
+{
+	ppb_devstate_t  *ppb = ddi_get_soft_state(ppb_state,
+	    ddi_get_instance(dip));
+
+	ASSERT(ibc != NULL);
+	*ibc = ppb->ppb_fm_ibc;
+
+	return (ppb->ppb_fmcap);
+}
+
+/*ARGSUSED*/
+static int
+ppb_fm_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *no_used)
+{
+	ppb_devstate_t  *ppb = ddi_get_soft_state(ppb_state,
+	    ddi_get_instance(dip));
+
+	mutex_enter(&ppb->ppb_err_mutex);
+	pci_ereport_post(dip, derr, NULL);
+	mutex_exit(&ppb->ppb_err_mutex);
+	return (derr->fme_status);
+}
--- a/usr/src/uts/common/os/ddifm.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/os/ddifm.c	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -158,19 +157,54 @@
 void
 ddi_fm_service_impact(dev_info_t *dip, int svc_impact)
 {
+	uint64_t ena;
+	char buf[FM_MAX_CLASS];
+
+	ena = fm_ena_generate(0, FM_ENA_FMT1);
 	mutex_enter(&(DEVI(dip)->devi_lock));
 	if (!DEVI_IS_DEVICE_OFFLINE(dip)) {
 		switch (svc_impact) {
 		case DDI_SERVICE_LOST:
 			DEVI_SET_DEVICE_DOWN(dip);
+			(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+			    DDI_FM_SERVICE_IMPACT, DDI_FM_SERVICE_LOST);
+			ddi_fm_ereport_post(dip, buf, ena, DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    NULL);
 			break;
 		case DDI_SERVICE_DEGRADED:
 			DEVI_SET_DEVICE_DEGRADED(dip);
+			if (DEVI_IS_DEVICE_DEGRADED(dip)) {
+				(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+				    DDI_FM_SERVICE_IMPACT,
+				    DDI_FM_SERVICE_DEGRADED);
+				ddi_fm_ereport_post(dip, buf, ena, DDI_NOSLEEP,
+				    FM_VERSION, DATA_TYPE_UINT8,
+				    FM_EREPORT_VERS0, NULL);
+			} else if (DEVI_IS_DEVICE_DOWN(dip)) {
+				(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+				    DDI_FM_SERVICE_IMPACT,
+				    DDI_FM_SERVICE_LOST);
+				ddi_fm_ereport_post(dip, buf, ena, DDI_NOSLEEP,
+				    FM_VERSION, DATA_TYPE_UINT8,
+				    FM_EREPORT_VERS0, NULL);
+			}
 			break;
 		case DDI_SERVICE_RESTORED:
 			DEVI_SET_DEVICE_UP(dip);
+			(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+			    DDI_FM_SERVICE_IMPACT, DDI_FM_SERVICE_RESTORED);
+			ddi_fm_ereport_post(dip, buf, ena, DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    NULL);
 			break;
 		case DDI_SERVICE_UNAFFECTED:
+			(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+			    DDI_FM_SERVICE_IMPACT, DDI_FM_SERVICE_UNAFFECTED);
+			ddi_fm_ereport_post(dip, buf, ena, DDI_NOSLEEP,
+			    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0,
+			    NULL);
+			break;
 		default:
 			break;
 		}
@@ -210,7 +244,7 @@
 		(void) ddi_pathname(dip, device_path);
 	}
 
-	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
+	if (ddi_prop_lookup_string(DDI_DEV_T_NONE, dip,
 		DDI_PROP_DONTPASS, DEVID_PROP_NAME, &devid) == DDI_SUCCESS) {
 		fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL,
 		    device_path, devid);
@@ -391,10 +425,8 @@
 	va_list ap;
 	struct i_ddi_fmhdl *fmhdl = DEVI(dip)->devi_fmhdl;
 
-	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip))) {
-		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, sflag);
+	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip)))
 		return;
-	}
 
 	ASSERT(fmhdl);
 
@@ -651,12 +683,11 @@
 	/*
 	 * Initialize support for ereport generation
 	 */
-	if (DDI_FM_EREPORT_CAP(*fmcap) &&
-	    DDI_FM_EREPORT_CAP(ddi_system_fmcap)) {
+	if (DDI_FM_EREPORT_CAP(*fmcap) && DDI_FM_EREPORT_CAP(pcap)) {
 		fmhdl->fh_errorq = ereport_errorq;
-		if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+		if (ddi_getprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
 		    "fm-ereport-capable", 0) == 0)
-			(void) ddi_prop_create(DDI_DEV_T_ANY, dip,
+			(void) ddi_prop_create(DDI_DEV_T_NONE, dip,
 			    DDI_PROP_CANSLEEP, "fm-ereport-capable", NULL, 0);
 
 		newcap |= DDI_FM_EREPORT_CAPABLE;
@@ -667,9 +698,9 @@
 	 */
 
 	if (DDI_FM_ERRCB_CAP(*fmcap) && DDI_FM_ERRCB_CAP(pcap)) {
-		if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+		if (ddi_getprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
 		    "fm-errcb-capable", 0) == 0)
-			(void) ddi_prop_create(DDI_DEV_T_ANY, dip,
+			(void) ddi_prop_create(DDI_DEV_T_NONE, dip,
 			    DDI_PROP_CANSLEEP, "fm-errcb-capable", NULL, 0);
 
 		newcap |= DDI_FM_ERRCB_CAPABLE;
@@ -683,9 +714,9 @@
 		i_ndi_fmc_create(&fmhdl->fh_dma_cache, 2, ibc);
 
 		/* Set-up dma chk capability prop */
-		if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+		if (ddi_getprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
 		    "fm-dmachk-capable", 0) == 0)
-			(void) ddi_prop_create(DDI_DEV_T_ANY, dip,
+			(void) ddi_prop_create(DDI_DEV_T_NONE, dip,
 			    DDI_PROP_CANSLEEP, "fm-dmachk-capable", NULL, 0);
 
 		newcap |= DDI_FM_DMACHK_CAPABLE;
@@ -694,9 +725,9 @@
 	if (DDI_FM_ACC_ERR_CAP(*fmcap) && DDI_FM_ACC_ERR_CAP(pcap)) {
 		i_ndi_fmc_create(&fmhdl->fh_acc_cache, 2, ibc);
 		/* Set-up dma chk capability prop */
-		if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+		if (ddi_getprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
 		    "fm-accchk-capable", 0) == 0)
-			(void) ddi_prop_create(DDI_DEV_T_ANY, dip,
+			(void) ddi_prop_create(DDI_DEV_T_NONE, dip,
 			    DDI_PROP_CANSLEEP, "fm-accchk-capable", NULL, 0);
 
 		newcap |= DDI_FM_ACCCHK_CAPABLE;
@@ -726,20 +757,17 @@
 {
 	struct i_ddi_fmhdl *fmhdl = DEVI(dip)->devi_fmhdl;
 
+	ASSERT(fmhdl);
+
 	if (!(DEVI_IS_DETACHING(dip) || DEVI_IS_ATTACHING(dip))) {
 		i_ddi_drv_ereport_post(dip, DVR_ECONTEXT, NULL, DDI_NOSLEEP);
 		return;
 	}
 
-	if (DDI_FM_DEFAULT_CAP(fmhdl->fh_cap))
-		return;
-
-	ASSERT(fmhdl);
-
 	kstat_delete(fmhdl->fh_ksp);
 
 	if (DDI_FM_EREPORT_CAP(fmhdl->fh_cap)) {
-		(void) ddi_prop_remove(DDI_DEV_T_ANY, dip,
+		(void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
 		    "fm-ereport-capable");
 	}
 
@@ -750,12 +778,12 @@
 		    DDI_FM_ACC_ERR_CAP(fmhdl->fh_cap)) {
 			if (fmhdl->fh_dma_cache != NULL) {
 				i_ndi_fmc_destroy(fmhdl->fh_dma_cache);
-				(void) ddi_prop_remove(DDI_DEV_T_ANY, dip,
+				(void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
 				    "fm-dmachk-capable");
 			}
 			if (fmhdl->fh_acc_cache != NULL) {
 				i_ndi_fmc_destroy(fmhdl->fh_acc_cache);
-				(void) ddi_prop_remove(DDI_DEV_T_ANY, dip,
+				(void) ddi_prop_remove(DDI_DEV_T_NONE, dip,
 				    "fm-accachk-capable");
 			}
 		}
@@ -791,16 +819,20 @@
 void
 ddi_fm_acc_err_get(ddi_acc_handle_t handle, ddi_fm_error_t *de, int version)
 {
-	ndi_err_t *errp = ((ddi_acc_impl_t *)handle)->ahi_err;
+	ndi_err_t *errp;
+
+	if (handle == NULL)
+		return;
 
 	if (version != DDI_FME_VER0) {
 		ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
 
 		i_ddi_drv_ereport_post(hp->ah_dip, DVR_EVER, NULL, DDI_NOSLEEP);
-		cmn_err(CE_PANIC, "ddi_fm_dma_err_get: "
+		cmn_err(CE_PANIC, "ddi_fm_acc_err_get: "
 		    "Invalid driver version\n");
 	}
 
+	errp = ((ddi_acc_impl_t *)handle)->ahi_err;
 	de->fme_status = errp->err_status;
 	de->fme_ena = errp->err_ena;
 	de->fme_flag = errp->err_expected;
@@ -810,7 +842,10 @@
 void
 ddi_fm_dma_err_get(ddi_dma_handle_t handle, ddi_fm_error_t *de, int version)
 {
-	ndi_err_t *errp = &((ddi_dma_impl_t *)handle)->dmai_error;
+	ndi_err_t *errp;
+
+	if (handle == NULL)
+		return;
 
 	if (version != DDI_FME_VER0) {
 		i_ddi_drv_ereport_post(((ddi_dma_impl_t *)handle)->dmai_rdip,
@@ -819,6 +854,8 @@
 		    "Invalid driver version\n");
 	}
 
+	errp = &((ddi_dma_impl_t *)handle)->dmai_error;
+
 	de->fme_status = errp->err_status;
 	de->fme_ena = errp->err_ena;
 	de->fme_flag = errp->err_expected;
@@ -826,6 +863,50 @@
 }
 
 void
+ddi_fm_acc_err_clear(ddi_acc_handle_t handle, int version)
+{
+	ndi_err_t *errp;
+
+	if (handle == NULL)
+		return;
+
+	if (version != DDI_FME_VER0) {
+		ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
+
+		i_ddi_drv_ereport_post(hp->ah_dip, DVR_EVER, NULL, DDI_NOSLEEP);
+		cmn_err(CE_PANIC, "ddi_fm_acc_err_clear: "
+		    "Invalid driver version\n");
+	}
+
+	errp = ((ddi_acc_impl_t *)handle)->ahi_err;
+	errp->err_status = DDI_FM_OK;
+	errp->err_ena = 0;
+	errp->err_expected = DDI_FM_ERR_UNEXPECTED;
+}
+
+void
+ddi_fm_dma_err_clear(ddi_dma_handle_t handle, int version)
+{
+	ndi_err_t *errp;
+
+	if (handle == NULL)
+		return;
+
+	if (version != DDI_FME_VER0) {
+		i_ddi_drv_ereport_post(((ddi_dma_impl_t *)handle)->dmai_rdip,
+		    DVR_EVER, NULL, DDI_NOSLEEP);
+		cmn_err(CE_PANIC, "ddi_fm_dma_err_clear: "
+		    "Invalid driver version\n");
+	}
+
+	errp = &((ddi_dma_impl_t *)handle)->dmai_error;
+
+	errp->err_status = DDI_FM_OK;
+	errp->err_ena = 0;
+	errp->err_expected = DDI_FM_ERR_UNEXPECTED;
+}
+
+void
 i_ddi_fm_acc_err_set(ddi_acc_handle_t handle, uint64_t ena, int status,
     int flag)
 {
@@ -851,3 +932,19 @@
 	hdlp->dmai_error.err_expected = flag;
 	atomic_add_64(&fmhdl->fh_kstat.fek_dma_err.value.ui64, 1);
 }
+
+ddi_fmcompare_t
+i_ddi_fm_acc_err_cf_get(ddi_acc_handle_t handle)
+{
+	ddi_acc_impl_t *i_hdlp = (ddi_acc_impl_t *)handle;
+
+	return (i_hdlp->ahi_err->err_cf);
+}
+
+ddi_fmcompare_t
+i_ddi_fm_dma_err_cf_get(ddi_dma_handle_t handle)
+{
+	ddi_dma_impl_t *hdlp = (ddi_dma_impl_t *)handle;
+
+	return (hdlp->dmai_error.err_cf);
+}
--- a/usr/src/uts/common/os/ndifm.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/os/ndifm.c	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -443,6 +442,84 @@
 	mutex_exit(&fcp->fc_lock);
 }
 
+int
+ndi_fmc_entry_error(dev_info_t *dip, int flag, ddi_fm_error_t *derr,
+    const void *bus_err_state)
+{
+	int status, fatal = 0, nonfatal = 0;
+	ndi_fmc_t *fcp = NULL;
+	ndi_fmcentry_t *fep;
+	struct i_ddi_fmhdl *fmhdl;
+
+	ASSERT(flag == DMA_HANDLE || flag == ACC_HANDLE);
+
+	fmhdl = DEVI(dip)->devi_fmhdl;
+	ASSERT(fmhdl);
+	status = DDI_FM_UNKNOWN;
+
+	if (flag == DMA_HANDLE && DDI_FM_DMA_ERR_CAP(fmhdl->fh_cap)) {
+		fcp = fmhdl->fh_dma_cache;
+		ASSERT(fcp);
+	} else if (flag == ACC_HANDLE && DDI_FM_ACC_ERR_CAP(fmhdl->fh_cap)) {
+		fcp = fmhdl->fh_acc_cache;
+		ASSERT(fcp);
+	}
+
+	if (fcp != NULL) {
+
+		/*
+		 * Check active resource entries
+		 */
+		mutex_enter(&fcp->fc_lock);
+		for (fep = fcp->fc_active->fce_next; fep != NULL;
+		    fep = fep->fce_next) {
+			ddi_fmcompare_t compare_func;
+
+			/*
+			 * Compare captured error state with handle
+			 * resources.  During the comparison and
+			 * subsequent error handling, we block
+			 * attempts to free the cache entry.
+			 */
+			compare_func = (flag == ACC_HANDLE) ?
+			    i_ddi_fm_acc_err_cf_get((ddi_acc_handle_t)
+				fep->fce_resource) :
+			    i_ddi_fm_dma_err_cf_get((ddi_dma_handle_t)
+				fep->fce_resource);
+
+			status = compare_func(dip, fep->fce_resource,
+			    bus_err_state, fep->fce_bus_specific);
+			if (status == DDI_FM_UNKNOWN || status == DDI_FM_OK)
+				continue;
+
+			if (status == DDI_FM_FATAL)
+				++fatal;
+			else if (status == DDI_FM_NONFATAL)
+				++nonfatal;
+
+			/* Set the error for this resource handle */
+			if (flag == ACC_HANDLE) {
+				ddi_acc_handle_t ap = fep->fce_resource;
+
+				i_ddi_fm_acc_err_set(ap, derr->fme_ena, status,
+				    DDI_FM_ERR_UNEXPECTED);
+				ddi_fm_acc_err_get(ap, derr, DDI_FME_VERSION);
+				derr->fme_acc_handle = ap;
+			} else {
+				ddi_dma_handle_t dp = fep->fce_resource;
+
+				i_ddi_fm_dma_err_set(dp, derr->fme_ena, status,
+				    DDI_FM_ERR_UNEXPECTED);
+				ddi_fm_dma_err_get(dp, derr, DDI_FME_VERSION);
+				derr->fme_dma_handle = dp;
+			}
+			break;
+		}
+		mutex_exit(&fcp->fc_lock);
+	}
+	return (fatal ? DDI_FM_FATAL : nonfatal ? DDI_FM_NONFATAL :
+	    DDI_FM_UNKNOWN);
+}
 
 /*
  * Check error state against the handle resource stored in the specified
@@ -466,13 +543,11 @@
  *
  */
 int
-ndi_fmc_error(dev_info_t *dip, dev_info_t *tdip, int flag,
-    ndi_fmcompare_t compare_func, uint64_t ena, const void *bus_err_state)
+ndi_fmc_error(dev_info_t *dip, dev_info_t *tdip, int flag, uint64_t ena,
+    const void *bus_err_state)
 {
 	int status, fatal = 0, nonfatal = 0;
-	ndi_fmc_t *fcp;
 	ddi_fm_error_t derr;
-	ndi_fmcentry_t *fep;
 	struct i_ddi_fmhdl *fmhdl;
 	struct i_ddi_fmtgt *tgt;
 
@@ -481,88 +556,42 @@
 	i_ddi_fm_handler_enter(dip);
 	fmhdl = DEVI(dip)->devi_fmhdl;
 	ASSERT(fmhdl);
+
+	bzero(&derr, sizeof (ddi_fm_error_t));
+	derr.fme_version = DDI_FME_VERSION;
+	derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
+	derr.fme_ena = ena;
+
 	for (tgt = fmhdl->fh_tgts; tgt != NULL; tgt = tgt->ft_next) {
 
 		if (tdip != NULL && tdip != tgt->ft_dip)
 			continue;
 
-		fmhdl = DEVI(tgt->ft_dip)->devi_fmhdl;
-		fcp = NULL;
-		bzero(&derr, sizeof (ddi_fm_error_t));
-		derr.fme_version = DDI_FME_VERSION;
-		derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
-		status = DDI_FM_UNKNOWN;
-
-		if (flag == DMA_HANDLE && DDI_FM_DMA_ERR_CAP(fmhdl->fh_cap)) {
-			fcp = fmhdl->fh_dma_cache;
-			ASSERT(fcp);
-		} else if (flag == ACC_HANDLE &&
-		    DDI_FM_ACC_ERR_CAP(fmhdl->fh_cap)) {
-			fcp = fmhdl->fh_acc_cache;
-			ASSERT(fcp);
-		}
-
-		if (fcp != NULL) {
+		/*
+		 * Attempt to find the entry in this childs handle cache
+		 */
+		status = ndi_fmc_entry_error(tgt->ft_dip, flag, &derr,
+		    bus_err_state);
 
-			/*
-			 * Check active resource entries
-			 */
-			mutex_enter(&fcp->fc_lock);
-			for (fep = fcp->fc_active->fce_next; fep != NULL;
-			    fep = fep->fce_next) {
-
-				/*
-				 * Compare captured error state with handle
-				 * resources.  During the comparison and
-				 * subsequent error handling, we block
-				 * attempts to free the cache entry.
-				 */
-				status = compare_func(dip, fep->fce_resource,
-				    bus_err_state, fep->fce_bus_specific);
-				if (status == DDI_FM_UNKNOWN ||
-				    status == DDI_FM_OK)
-					continue;
+		if (status == DDI_FM_FATAL)
+			++fatal;
+		else if (status == DDI_FM_NONFATAL)
+			++nonfatal;
+		else
+			continue;
 
-				if (status == DDI_FM_FATAL)
-					++fatal;
-				else if (status == DDI_FM_NONFATAL)
-					++nonfatal;
-
-				/* Set the error for this resource handle */
-				if (flag == ACC_HANDLE) {
-					ddi_acc_handle_t ap = fep->fce_resource;
-
-					i_ddi_fm_acc_err_set(ap, ena, status,
-					    DDI_FM_ERR_UNEXPECTED);
-					ddi_fm_acc_err_get(ap, &derr,
-					    DDI_FME_VERSION);
-					derr.fme_acc_handle = ap;
-				} else {
-					ddi_dma_handle_t dp = fep->fce_resource;
+		/*
+		 * Call our child to process this error.
+		 */
+		status = tgt->ft_errhdl->eh_func(tgt->ft_dip, &derr,
+		    tgt->ft_errhdl->eh_impl);
 
-					i_ddi_fm_dma_err_set(dp, ena, status,
-					    DDI_FM_ERR_UNEXPECTED);
-					ddi_fm_dma_err_get(dp, &derr,
-					    DDI_FME_VERSION);
-					derr.fme_dma_handle = dp;
-				}
+		if (status == DDI_FM_FATAL)
+			++fatal;
+		else if (status == DDI_FM_NONFATAL)
+			++nonfatal;
+	}
 
-				/*
-				 * Call our child to process this error.
-				 */
-				derr.fme_bus_specific = (void *)bus_err_state;
-				status = tgt->ft_errhdl->eh_func(tgt->ft_dip,
-				    &derr, tgt->ft_errhdl->eh_impl);
-
-				if (status == DDI_FM_FATAL)
-					++fatal;
-				else if (status == DDI_FM_NONFATAL)
-					++nonfatal;
-			}
-			mutex_exit(&fcp->fc_lock);
-		}
-
-	}
 	i_ddi_fm_handler_exit(dip);
 
 	if (fatal)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/os/pcifm.c	Sun Apr 23 15:26:28 2006 -0700
@@ -0,0 +1,2524 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <sys/types.h>
+#include <sys/sunndi.h>
+#include <sys/sysmacros.h>
+#include <sys/ddifm_impl.h>
+#include <sys/fm/util.h>
+#include <sys/fm/protocol.h>
+#include <sys/fm/io/pci.h>
+#include <sys/fm/io/ddi.h>
+#include <sys/pci.h>
+#include <sys/pcie.h>
+#include <sys/pci_impl.h>
+#include <sys/epm.h>
+#include <sys/pcifm.h>
+
+#define	PCIX_ECC_VER_CHECK(x)	(((x) == PCI_PCIX_VER_1) ||\
+				((x) == PCI_PCIX_VER_2))
+
+/*
+ * Expected PCI Express error mask values
+ */
+uint32_t pcie_expected_ce_mask = PCIE_AER_CE_AD_NFE;
+uint32_t pcie_expected_ue_mask = 0x0;
+uint32_t pcie_expected_sue_mask = 0x0;
+
+errorq_t *pci_target_queue = NULL;
+
+pci_fm_err_t pci_err_tbl[] = {
+	PCI_DET_PERR,	PCI_STAT_PERROR,	NULL,		DDI_FM_UNKNOWN,
+	PCI_MDPE,	PCI_STAT_S_PERROR,	PCI_TARG_MDPE,	DDI_FM_UNKNOWN,
+	PCI_SIG_SERR,	PCI_STAT_S_SYSERR,	NULL,		DDI_FM_FATAL,
+	PCI_MA,		PCI_STAT_R_MAST_AB,	PCI_TARG_MA,	DDI_FM_UNKNOWN,
+	PCI_REC_TA,	PCI_STAT_R_TARG_AB,	PCI_TARG_REC_TA, DDI_FM_UNKNOWN,
+	PCI_SIG_TA,	PCI_STAT_S_TARG_AB,	NULL,		DDI_FM_UNKNOWN,
+	NULL, NULL, NULL, NULL,
+};
+
+pci_fm_err_t pci_bdg_err_tbl[] = {
+	PCI_DET_PERR,	PCI_STAT_PERROR,	NULL,		DDI_FM_UNKNOWN,
+	PCI_MDPE,	PCI_STAT_S_PERROR,	PCI_TARG_MDPE,	DDI_FM_UNKNOWN,
+	PCI_REC_SERR,	PCI_STAT_S_SYSERR,	NULL,		DDI_FM_UNKNOWN,
+	PCI_MA,		PCI_STAT_R_MAST_AB,	PCI_TARG_MA,	DDI_FM_UNKNOWN,
+	PCI_REC_TA,	PCI_STAT_R_TARG_AB,	PCI_TARG_REC_TA, DDI_FM_UNKNOWN,
+	PCI_SIG_TA,	PCI_STAT_S_TARG_AB,	NULL,		DDI_FM_UNKNOWN,
+	NULL, NULL, NULL, NULL,
+};
+
+static pci_fm_err_t pciex_ce_err_tbl[] = {
+	PCIEX_RE,	PCIE_AER_CE_RECEIVER_ERR,	NULL,	DDI_FM_NONFATAL,
+	PCIEX_RNR,	PCIE_AER_CE_REPLAY_ROLLOVER,	NULL,	DDI_FM_NONFATAL,
+	PCIEX_RTO,	PCIE_AER_CE_REPLAY_TO,		NULL,	DDI_FM_NONFATAL,
+	PCIEX_BDP,	PCIE_AER_CE_BAD_DLLP,		NULL,	DDI_FM_NONFATAL,
+	PCIEX_BTP,	PCIE_AER_CE_BAD_TLP,		NULL,	DDI_FM_NONFATAL,
+	PCIEX_ANFE,	PCIE_AER_CE_AD_NFE,		NULL,	DDI_FM_NONFATAL,
+	NULL, NULL, NULL, NULL,
+};
+
+static pci_fm_err_t pciex_ue_err_tbl[] = {
+	PCIEX_TE,	PCIE_AER_UCE_TRAINING,		NULL,	DDI_FM_FATAL,
+	PCIEX_DLP,	PCIE_AER_UCE_DLP,		NULL,	DDI_FM_FATAL,
+	PCIEX_SD,	PCIE_AER_UCE_SD,		NULL,   DDI_FM_FATAL,
+	PCIEX_ROF,	PCIE_AER_UCE_RO,		NULL,	DDI_FM_FATAL,
+	PCIEX_FCP,	PCIE_AER_UCE_FCP,		NULL,	DDI_FM_FATAL,
+	PCIEX_MFP,	PCIE_AER_UCE_MTLP,		NULL,	DDI_FM_FATAL,
+	PCIEX_CTO,	PCIE_AER_UCE_TO,		NULL,	DDI_FM_NONFATAL,
+	PCIEX_UC,	PCIE_AER_UCE_UC,		NULL,	DDI_FM_NONFATAL,
+	PCIEX_ECRC,	PCIE_AER_UCE_ECRC,		NULL,	DDI_FM_UNKNOWN,
+	PCIEX_CA,	PCIE_AER_UCE_CA,		NULL,	DDI_FM_UNKNOWN,
+	PCIEX_UR,	PCIE_AER_UCE_UR,		NULL,	DDI_FM_NONFATAL,
+	PCIEX_POIS,	PCIE_AER_UCE_PTLP,		NULL,	DDI_FM_UNKNOWN,
+	NULL, NULL, NULL, NULL,
+};
+
+static pci_fm_err_t pcie_sue_err_tbl[] = {
+	PCIEX_S_TA_SC,	PCIE_AER_SUCE_TA_ON_SC,		NULL,	DDI_FM_UNKNOWN,
+	PCIEX_S_MA_SC,	PCIE_AER_SUCE_MA_ON_SC,		NULL,	DDI_FM_UNKNOWN,
+	PCIEX_S_RTA,	PCIE_AER_SUCE_RCVD_TA,		NULL,	DDI_FM_UNKNOWN,
+	PCIEX_S_RMA,	PCIE_AER_SUCE_RCVD_MA,		NULL,	DDI_FM_UNKNOWN,
+	PCIEX_S_USC,	PCIE_AER_SUCE_USC_ERR,		NULL,	DDI_FM_UNKNOWN,
+	PCIEX_S_USCMD,	PCIE_AER_SUCE_USC_MSG_DATA_ERR,	NULL,	DDI_FM_FATAL,
+	PCIEX_S_UDE,	PCIE_AER_SUCE_UC_DATA_ERR,	NULL,	DDI_FM_UNKNOWN,
+	PCIEX_S_UAT,	PCIE_AER_SUCE_UC_ATTR_ERR,	NULL,	DDI_FM_FATAL,
+	PCIEX_S_UADR,	PCIE_AER_SUCE_UC_ADDR_ERR,	NULL,	DDI_FM_FATAL,
+	PCIEX_S_TEX,	PCIE_AER_SUCE_TIMER_EXPIRED,	NULL,	DDI_FM_FATAL,
+	PCIEX_S_PERR,	PCIE_AER_SUCE_PERR_ASSERT,	NULL,	DDI_FM_UNKNOWN,
+	PCIEX_S_SERR,	PCIE_AER_SUCE_SERR_ASSERT,	NULL,	DDI_FM_FATAL,
+	PCIEX_INTERR,	PCIE_AER_SUCE_INTERNAL_ERR,	NULL,	DDI_FM_FATAL,
+	NULL, NULL, NULL, NULL,
+};
+
+static pci_fm_err_t pcix_err_tbl[] = {
+	PCIX_SPL_DIS,		PCI_PCIX_SPL_DSCD,	NULL,	DDI_FM_UNKNOWN,
+	PCIX_UNEX_SPL,		PCI_PCIX_UNEX_SPL,	NULL,	DDI_FM_UNKNOWN,
+	PCIX_RX_SPL_MSG,	PCI_PCIX_RX_SPL_MSG,	NULL,   DDI_FM_UNKNOWN,
+	NULL, NULL, NULL, NULL,
+};
+
+static pci_fm_err_t pcix_sec_err_tbl[] = {
+	PCIX_SPL_DIS,		PCI_PCIX_BSS_SPL_DSCD,	NULL,	DDI_FM_UNKNOWN,
+	PCIX_UNEX_SPL,		PCI_PCIX_BSS_UNEX_SPL,	NULL,	DDI_FM_UNKNOWN,
+	PCIX_BSS_SPL_OR,	PCI_PCIX_BSS_SPL_OR,	NULL,	DDI_FM_NONFATAL,
+	PCIX_BSS_SPL_DLY,	PCI_PCIX_BSS_SPL_DLY,	NULL,	DDI_FM_NONFATAL,
+	NULL, NULL, NULL, NULL,
+};
+
+static pci_fm_err_t pciex_nadv_err_tbl[] = {
+	PCIEX_UR,	PCIE_DEVSTS_UR_DETECTED,	NULL,	DDI_FM_UNKNOWN,
+	PCIEX_FAT,	PCIE_DEVSTS_FE_DETECTED,	NULL,	DDI_FM_FATAL,
+	PCIEX_NONFAT,	PCIE_DEVSTS_NFE_DETECTED,	NULL,	DDI_FM_UNKNOWN,
+	PCIEX_CORR,	PCIE_DEVSTS_CE_DETECTED,	NULL,	DDI_FM_NONFATAL,
+	NULL, NULL, NULL, NULL,
+};
+
+static int
+pci_config_check(ddi_acc_handle_t handle)
+{
+	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
+	ddi_fm_error_t de;
+
+	if (!(DDI_FM_ACC_ERR_CAP(ddi_fm_capable(hp->ah_dip))))
+		return (DDI_FM_OK);
+
+	de.fme_version = DDI_FME_VERSION;
+
+	ddi_fm_acc_err_get(handle, &de, de.fme_version);
+	if (de.fme_status != DDI_FM_OK) {
+		char buf[FM_MAX_CLASS];
+
+		(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", PCI_ERROR_SUBCLASS,
+		    PCI_NR);
+		ddi_fm_ereport_post(hp->ah_dip, buf, de.fme_ena, DDI_NOSLEEP,
+		    FM_VERSION, DATA_TYPE_UINT8, 0, NULL);
+		ddi_fm_acc_err_clear(handle, de.fme_version);
+	}
+	return (de.fme_status);
+}
+
+static void
+pcix_ecc_regs_gather(pci_erpt_t *erpt_p, pcix_ecc_regs_t *pcix_ecc_regs,
+    uint8_t pcix_cap_ptr)
+{
+	int bdg = erpt_p->pe_dflags & PCI_BRIDGE_DEV;
+
+	pcix_ecc_regs->pcix_ecc_ctlstat = pci_config_get32(erpt_p->pe_hdl,
+	    (pcix_cap_ptr + (bdg ? PCI_PCIX_BDG_ECC_STATUS :
+	    PCI_PCIX_ECC_STATUS)));
+	if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+		pcix_ecc_regs->pcix_ecc_vflags |= PCIX_ERR_ECC_STS_VALID;
+	else
+		return;
+	pcix_ecc_regs->pcix_ecc_fstaddr = pci_config_get32(erpt_p->pe_hdl,
+	    (pcix_cap_ptr + (bdg ? PCI_PCIX_BDG_ECC_FST_AD :
+	    PCI_PCIX_ECC_FST_AD)));
+	pcix_ecc_regs->pcix_ecc_secaddr = pci_config_get32(erpt_p->pe_hdl,
+	    (pcix_cap_ptr + (bdg ? PCI_PCIX_BDG_ECC_SEC_AD :
+	    PCI_PCIX_ECC_SEC_AD)));
+	pcix_ecc_regs->pcix_ecc_attr = pci_config_get32((
+	    ddi_acc_handle_t)erpt_p->pe_hdl,
+	    (pcix_cap_ptr + (bdg ? PCI_PCIX_BDG_ECC_ATTR : PCI_PCIX_ECC_ATTR)));
+}
+
+static void
+pcix_regs_gather(pci_erpt_t *erpt_p, void *pe_regs)
+{
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
+		pcix_bdg_error_regs_t *pcix_bdg_regs =
+		    (pcix_bdg_error_regs_t *)pe_regs;
+		uint8_t pcix_bdg_cap_ptr;
+		int i;
+
+		pcix_bdg_cap_ptr = pcix_bdg_regs->pcix_bdg_cap_ptr;
+		pcix_bdg_regs->pcix_bdg_sec_stat = pci_config_get16(
+		    erpt_p->pe_hdl, (pcix_bdg_cap_ptr + PCI_PCIX_SEC_STATUS));
+		if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+			pcix_bdg_regs->pcix_bdg_vflags |=
+			    PCIX_BDG_SEC_STATUS_VALID;
+		else
+			return;
+		pcix_bdg_regs->pcix_bdg_stat = pci_config_get32(erpt_p->pe_hdl,
+		    (pcix_bdg_cap_ptr + PCI_PCIX_BDG_STATUS));
+		if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+			pcix_bdg_regs->pcix_bdg_vflags |= PCIX_BDG_STATUS_VALID;
+		else
+			return;
+		if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) {
+			pcix_ecc_regs_t *pcix_bdg_ecc_regs;
+			/*
+			 * PCI Express to PCI-X bridges only implement the
+			 * secondary side of the PCI-X ECC registers, bit one is
+			 * read-only so we make sure we do not write to it.
+			 */
+			if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) {
+				pcix_bdg_ecc_regs =
+				    pcix_bdg_regs->pcix_bdg_ecc_regs[1];
+				pcix_ecc_regs_gather(erpt_p, pcix_bdg_ecc_regs,
+				    pcix_bdg_cap_ptr);
+			} else {
+				for (i = 0; i < 2; i++) {
+					pcix_bdg_ecc_regs =
+					    pcix_bdg_regs->pcix_bdg_ecc_regs[i];
+					pci_config_put32(erpt_p->pe_hdl,
+					    (pcix_bdg_cap_ptr +
+					    PCI_PCIX_BDG_ECC_STATUS), i);
+					pcix_ecc_regs_gather(erpt_p,
+					    pcix_bdg_ecc_regs,
+					    pcix_bdg_cap_ptr);
+				}
+			}
+		}
+	} else {
+		pcix_error_regs_t *pcix_regs = (pcix_error_regs_t *)pe_regs;
+		uint8_t pcix_cap_ptr;
+
+		pcix_cap_ptr = pcix_regs->pcix_cap_ptr;
+
+		pcix_regs->pcix_command = pci_config_get16(erpt_p->pe_hdl,
+		    (pcix_cap_ptr + PCI_PCIX_COMMAND));
+		pcix_regs->pcix_status = pci_config_get32(erpt_p->pe_hdl,
+		    (pcix_cap_ptr + PCI_PCIX_STATUS));
+		if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+			pcix_regs->pcix_vflags |= PCIX_ERR_STATUS_VALID;
+		else
+			return;
+		if (PCIX_ECC_VER_CHECK(pcix_regs->pcix_ver)) {
+			pcix_ecc_regs_t *pcix_ecc_regs =
+			    pcix_regs->pcix_ecc_regs;
+
+			pcix_ecc_regs_gather(erpt_p, pcix_ecc_regs,
+			    pcix_cap_ptr);
+		}
+	}
+}
+
+static void
+pcie_regs_gather(pci_erpt_t *erpt_p)
+{
+	pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
+	uint8_t pcie_cap_ptr;
+	pcie_adv_error_regs_t *pcie_adv_regs;
+	uint16_t pcie_ecap_ptr;
+
+	pcie_cap_ptr = pcie_regs->pcie_cap_ptr;
+
+	pcie_regs->pcie_err_status = pci_config_get16(erpt_p->pe_hdl,
+	    pcie_cap_ptr + PCIE_DEVSTS);
+	if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+		pcie_regs->pcie_vflags |= PCIE_ERR_STATUS_VALID;
+	else
+		return;
+
+	pcie_regs->pcie_err_ctl = pci_config_get16(erpt_p->pe_hdl,
+	    (pcie_cap_ptr + PCIE_DEVCTL));
+
+	if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && (erpt_p->pe_dflags &
+	    PCIX_DEV))
+		pcix_regs_gather(erpt_p, pcie_regs->pcix_bdg_regs);
+
+	if (erpt_p->pe_dflags & PCIEX_RC_DEV) {
+		pcie_rc_error_regs_t *pcie_rc_regs = pcie_regs->pcie_rc_regs;
+
+		pcie_rc_regs->pcie_rc_status = pci_config_get32(erpt_p->pe_hdl,
+		    (pcie_cap_ptr + PCIE_ROOTSTS));
+		pcie_rc_regs->pcie_rc_ctl = pci_config_get16(erpt_p->pe_hdl,
+		    (pcie_cap_ptr + PCIE_ROOTCTL));
+	}
+
+	if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV))
+		return;
+
+	pcie_adv_regs = pcie_regs->pcie_adv_regs;
+
+	pcie_ecap_ptr = pcie_adv_regs->pcie_adv_cap_ptr;
+
+	pcie_adv_regs->pcie_ue_status = pci_config_get32(erpt_p->pe_hdl,
+	    pcie_ecap_ptr + PCIE_AER_UCE_STS);
+	if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+		pcie_adv_regs->pcie_adv_vflags |= PCIE_UE_STATUS_VALID;
+
+	pcie_adv_regs->pcie_ue_mask = pci_config_get32(erpt_p->pe_hdl,
+	    pcie_ecap_ptr + PCIE_AER_UCE_MASK);
+	pcie_adv_regs->pcie_ue_sev = pci_config_get32(erpt_p->pe_hdl,
+	    pcie_ecap_ptr + PCIE_AER_UCE_SERV);
+	pcie_adv_regs->pcie_adv_ctl = pci_config_get32(erpt_p->pe_hdl,
+	    pcie_ecap_ptr + PCIE_AER_CTL);
+	pcie_adv_regs->pcie_ue_hdr0 = pci_config_get32(erpt_p->pe_hdl,
+	    pcie_ecap_ptr + PCIE_AER_HDR_LOG);
+	if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) {
+		int i;
+		pcie_adv_regs->pcie_adv_vflags |= PCIE_UE_HDR_VALID;
+
+		for (i = 0; i < 3; i++) {
+			pcie_adv_regs->pcie_ue_hdr[i] = pci_config_get32(
+			    erpt_p->pe_hdl, pcie_ecap_ptr + PCIE_AER_HDR_LOG +
+			    (4 * (i + 1)));
+		}
+	}
+
+	pcie_adv_regs->pcie_ce_status = pci_config_get32(erpt_p->pe_hdl,
+	    pcie_ecap_ptr + PCIE_AER_CE_STS);
+	if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+		pcie_adv_regs->pcie_adv_vflags |= PCIE_CE_STATUS_VALID;
+
+	pcie_adv_regs->pcie_ce_mask = pci_config_get32(erpt_p->pe_hdl,
+	    pcie_ecap_ptr + PCIE_AER_CE_MASK);
+
+	/*
+	 * If pci express to pci bridge then grab the bridge
+	 * error registers.
+	 */
+	if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) {
+		pcie_adv_bdg_error_regs_t *pcie_bdg_regs =
+		    pcie_adv_regs->pcie_adv_bdg_regs;
+
+		pcie_bdg_regs->pcie_sue_status =
+		    pci_config_get32(erpt_p->pe_hdl,
+		    pcie_ecap_ptr + PCIE_AER_SUCE_STS);
+		if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+			pcie_adv_regs->pcie_adv_vflags |= PCIE_SUE_STATUS_VALID;
+		pcie_bdg_regs->pcie_sue_hdr0 = pci_config_get32(erpt_p->pe_hdl,
+		    (pcie_ecap_ptr + PCIE_AER_SHDR_LOG));
+
+		if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) {
+			int i;
+
+			pcie_adv_regs->pcie_adv_vflags |= PCIE_SUE_HDR_VALID;
+
+			for (i = 0; i < 3; i++) {
+				pcie_bdg_regs->pcie_sue_hdr[i] =
+				    pci_config_get32(erpt_p->pe_hdl,
+					pcie_ecap_ptr + PCIE_AER_SHDR_LOG +
+					(4 * (i + 1)));
+			}
+		}
+	}
+	/*
+	 * If PCI Express root complex then grab the root complex
+	 * error registers.
+	 */
+	if (erpt_p->pe_dflags & PCIEX_RC_DEV) {
+		pcie_adv_rc_error_regs_t *pcie_rc_regs =
+		    pcie_adv_regs->pcie_adv_rc_regs;
+
+		pcie_rc_regs->pcie_rc_err_cmd = pci_config_get32(erpt_p->pe_hdl,
+		    (pcie_ecap_ptr + PCIE_AER_RE_CMD));
+		pcie_rc_regs->pcie_rc_err_status =
+		    pci_config_get32(erpt_p->pe_hdl,
+			(pcie_ecap_ptr + PCIE_AER_RE_STS));
+		if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+			pcie_adv_regs->pcie_adv_vflags |=
+			    PCIE_RC_ERR_STATUS_VALID;
+		pcie_rc_regs->pcie_rc_ce_src_id =
+		    pci_config_get16(erpt_p->pe_hdl,
+			(pcie_ecap_ptr + PCIE_AER_CE_SRC_ID));
+		pcie_rc_regs->pcie_rc_ue_src_id =
+		    pci_config_get16(erpt_p->pe_hdl,
+			(pcie_ecap_ptr + PCIE_AER_ERR_SRC_ID));
+		if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+			pcie_adv_regs->pcie_adv_vflags |= PCIE_SRC_ID_VALID;
+	}
+}
+
+/*ARGSUSED*/
+static void
+pci_regs_gather(dev_info_t *dip, pci_erpt_t *erpt_p)
+{
+	pci_error_regs_t *pci_regs = erpt_p->pe_pci_regs;
+
+	/*
+	 * Start by reading all the error registers that are available for
+	 * pci and pci express and for leaf devices and bridges/switches
+	 */
+	pci_regs->pci_err_status = pci_config_get16(erpt_p->pe_hdl,
+	    PCI_CONF_STAT);
+	if (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK)
+		return;
+	pci_regs->pci_vflags |= PCI_ERR_STATUS_VALID;
+	pci_regs->pci_cfg_comm = pci_config_get16(erpt_p->pe_hdl,
+	    PCI_CONF_COMM);
+	if (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK)
+		return;
+
+	/*
+	 * If pci-pci bridge grab PCI bridge specific error registers.
+	 */
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
+		pci_regs->pci_bdg_regs->pci_bdg_sec_stat =
+		    pci_config_get16(erpt_p->pe_hdl, PCI_BCNF_SEC_STATUS);
+		if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+			pci_regs->pci_bdg_regs->pci_bdg_vflags |=
+			    PCI_BDG_SEC_STAT_VALID;
+		pci_regs->pci_bdg_regs->pci_bdg_ctrl =
+		    pci_config_get16(erpt_p->pe_hdl, PCI_BCNF_BCNTRL);
+		if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK)
+			pci_regs->pci_bdg_regs->pci_bdg_vflags |=
+			    PCI_BDG_CTRL_VALID;
+	}
+
+	/*
+	 * If pci express device grab pci express error registers and
+	 * check for advanced error reporting features and grab them if
+	 * available.
+	 */
+	if (erpt_p->pe_dflags & PCIEX_DEV)
+		pcie_regs_gather(erpt_p);
+	else if (erpt_p->pe_dflags & PCIX_DEV)
+		pcix_regs_gather(erpt_p, erpt_p->pe_regs);
+
+}
+
+static void
+pcix_regs_clear(pci_erpt_t *erpt_p, void *pe_regs)
+{
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
+		pcix_bdg_error_regs_t *pcix_bdg_regs =
+		    (pcix_bdg_error_regs_t *)pe_regs;
+		uint8_t pcix_bdg_cap_ptr;
+		int i;
+
+		pcix_bdg_cap_ptr = pcix_bdg_regs->pcix_bdg_cap_ptr;
+
+		if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_SEC_STATUS_VALID)
+			pci_config_put16(erpt_p->pe_hdl,
+			    (pcix_bdg_cap_ptr + PCI_PCIX_SEC_STATUS),
+			    pcix_bdg_regs->pcix_bdg_sec_stat);
+
+		if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_STATUS_VALID)
+			pci_config_put32(erpt_p->pe_hdl,
+			    (pcix_bdg_cap_ptr + PCI_PCIX_BDG_STATUS),
+			    pcix_bdg_regs->pcix_bdg_stat);
+
+		pcix_bdg_regs->pcix_bdg_vflags = 0x0;
+
+		if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) {
+			pcix_ecc_regs_t *pcix_bdg_ecc_regs;
+			/*
+			 * PCI Express to PCI-X bridges only implement the
+			 * secondary side of the PCI-X ECC registers, bit one is
+			 * read-only so we make sure we do not write to it.
+			 */
+			if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) {
+				pcix_bdg_ecc_regs =
+				    pcix_bdg_regs->pcix_bdg_ecc_regs[1];
+
+				if (pcix_bdg_ecc_regs->pcix_ecc_vflags &
+				    PCIX_ERR_ECC_STS_VALID) {
+
+					pci_config_put32(erpt_p->pe_hdl,
+					    (pcix_bdg_cap_ptr +
+					    PCI_PCIX_BDG_ECC_STATUS),
+					    pcix_bdg_ecc_regs->
+					    pcix_ecc_ctlstat);
+				}
+				pcix_bdg_ecc_regs->pcix_ecc_vflags = 0x0;
+			} else {
+				for (i = 0; i < 2; i++) {
+					pcix_bdg_ecc_regs =
+					    pcix_bdg_regs->pcix_bdg_ecc_regs[i];
+
+
+					if (pcix_bdg_ecc_regs->pcix_ecc_vflags &
+					    PCIX_ERR_ECC_STS_VALID) {
+						pci_config_put32(erpt_p->pe_hdl,
+						    (pcix_bdg_cap_ptr +
+						    PCI_PCIX_BDG_ECC_STATUS),
+						    i);
+
+						pci_config_put32(erpt_p->pe_hdl,
+						    (pcix_bdg_cap_ptr +
+						    PCI_PCIX_BDG_ECC_STATUS),
+						    pcix_bdg_ecc_regs->
+						    pcix_ecc_ctlstat);
+					}
+					pcix_bdg_ecc_regs->pcix_ecc_vflags =
+					    0x0;
+				}
+			}
+		}
+	} else {
+		pcix_error_regs_t *pcix_regs = (pcix_error_regs_t *)pe_regs;
+		uint8_t pcix_cap_ptr;
+
+		pcix_cap_ptr = pcix_regs->pcix_cap_ptr;
+
+		if (pcix_regs->pcix_vflags & PCIX_ERR_STATUS_VALID)
+			pci_config_put32(erpt_p->pe_hdl,
+			    (pcix_cap_ptr + PCI_PCIX_STATUS),
+			    pcix_regs->pcix_status);
+
+		pcix_regs->pcix_vflags = 0x0;
+
+		if (PCIX_ECC_VER_CHECK(pcix_regs->pcix_ver)) {
+			pcix_ecc_regs_t *pcix_ecc_regs =
+			    pcix_regs->pcix_ecc_regs;
+
+			if (pcix_ecc_regs->pcix_ecc_vflags &
+			    PCIX_ERR_ECC_STS_VALID)
+				pci_config_put32(erpt_p->pe_hdl,
+				    (pcix_cap_ptr + PCI_PCIX_ECC_STATUS),
+				    pcix_ecc_regs->pcix_ecc_ctlstat);
+
+			pcix_ecc_regs->pcix_ecc_vflags = 0x0;
+		}
+	}
+}
+
+static void
+pcie_regs_clear(pci_erpt_t *erpt_p)
+{
+	pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
+	uint8_t pcie_cap_ptr;
+	pcie_adv_error_regs_t *pcie_adv_regs;
+	uint16_t pcie_ecap_ptr;
+
+	pcie_cap_ptr = pcie_regs->pcie_cap_ptr;
+
+	if (pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID)
+		pci_config_put16(erpt_p->pe_hdl, pcie_cap_ptr + PCIE_DEVSTS,
+		    pcie_regs->pcie_err_status);
+
+	pcie_regs->pcie_vflags = 0x0;
+
+	if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) &&
+	    (erpt_p->pe_dflags & PCIX_DEV))
+		pcix_regs_clear(erpt_p, pcie_regs->pcix_bdg_regs);
+
+	if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV))
+		return;
+
+	pcie_adv_regs = pcie_regs->pcie_adv_regs;
+
+	pcie_ecap_ptr = pcie_adv_regs->pcie_adv_cap_ptr;
+
+	if (pcie_adv_regs->pcie_adv_vflags & PCIE_UE_STATUS_VALID)
+		pci_config_put32(erpt_p->pe_hdl,
+		    pcie_ecap_ptr + PCIE_AER_UCE_STS,
+		    pcie_adv_regs->pcie_ue_status);
+
+	if (pcie_adv_regs->pcie_adv_vflags & PCIE_CE_STATUS_VALID)
+		pci_config_put32(erpt_p->pe_hdl,
+		    pcie_ecap_ptr + PCIE_AER_CE_STS,
+		    pcie_adv_regs->pcie_ce_status);
+
+
+	if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) {
+		pcie_adv_bdg_error_regs_t *pcie_bdg_regs =
+		    pcie_adv_regs->pcie_adv_bdg_regs;
+
+
+		if (pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_STATUS_VALID)
+			pci_config_put32(erpt_p->pe_hdl,
+			    pcie_ecap_ptr + PCIE_AER_SUCE_STS,
+			    pcie_bdg_regs->pcie_sue_status);
+	}
+	/*
+	 * If PCI Express root complex then clear the root complex
+	 * error registers.
+	 */
+	if (erpt_p->pe_dflags & PCIEX_RC_DEV) {
+		pcie_adv_rc_error_regs_t *pcie_rc_regs =
+		    pcie_adv_regs->pcie_adv_rc_regs;
+
+
+		if (pcie_adv_regs->pcie_adv_vflags & PCIE_RC_ERR_STATUS_VALID)
+			pci_config_put32(erpt_p->pe_hdl,
+			    (pcie_ecap_ptr + PCIE_AER_RE_STS),
+			    pcie_rc_regs->pcie_rc_err_status);
+	}
+	pcie_adv_regs->pcie_adv_vflags = 0x0;
+}
+
+static void
+pci_regs_clear(pci_erpt_t *erpt_p)
+{
+	/*
+	 * Finally clear the error bits
+	 */
+	if (erpt_p->pe_dflags & PCIEX_DEV)
+		pcie_regs_clear(erpt_p);
+	else if (erpt_p->pe_dflags & PCIX_DEV)
+		pcix_regs_clear(erpt_p, erpt_p->pe_regs);
+
+	if (erpt_p->pe_pci_regs->pci_vflags & PCI_ERR_STATUS_VALID)
+		pci_config_put16(erpt_p->pe_hdl, PCI_CONF_STAT,
+		    erpt_p->pe_pci_regs->pci_err_status);
+
+	erpt_p->pe_pci_regs->pci_vflags = 0x0;
+
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
+		if (erpt_p->pe_pci_regs->pci_bdg_regs->pci_bdg_vflags &
+		    PCI_BDG_SEC_STAT_VALID)
+			pci_config_put16(erpt_p->pe_hdl, PCI_BCNF_SEC_STATUS,
+			    erpt_p->pe_pci_regs->pci_bdg_regs->
+			    pci_bdg_sec_stat);
+		if (erpt_p->pe_pci_regs->pci_bdg_regs->pci_bdg_vflags &
+		    PCI_BDG_CTRL_VALID)
+			pci_config_put16(erpt_p->pe_hdl, PCI_BCNF_BCNTRL,
+			    erpt_p->pe_pci_regs->pci_bdg_regs->pci_bdg_ctrl);
+
+		erpt_p->pe_pci_regs->pci_bdg_regs->pci_bdg_vflags = 0x0;
+	}
+}
+
+/*
+ * pcix_ereport_setup: Allocate structures for PCI-X error handling and ereport
+ * generation.
+ */
+/* ARGSUSED */
+static void
+pcix_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p)
+{
+	uint8_t pcix_cap_ptr;
+	int i;
+
+	pcix_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+	    "pcix-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
+
+	if (pcix_cap_ptr != PCI_CAP_NEXT_PTR_NULL)
+		erpt_p->pe_dflags |= PCIX_DEV;
+	else
+		return;
+
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
+		pcix_bdg_error_regs_t *pcix_bdg_regs;
+
+		erpt_p->pe_regs = kmem_zalloc(sizeof (pcix_bdg_error_regs_t),
+		    KM_SLEEP);
+		pcix_bdg_regs = (pcix_bdg_error_regs_t *)erpt_p->pe_regs;
+		pcix_bdg_regs->pcix_bdg_cap_ptr = pcix_cap_ptr;
+		pcix_bdg_regs->pcix_bdg_ver = pci_config_get16(erpt_p->pe_hdl,
+		    pcix_cap_ptr + PCI_PCIX_SEC_STATUS) & PCI_PCIX_VER_MASK;
+		if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) {
+			for (i = 0; i < 2; i++) {
+				pcix_bdg_regs->pcix_bdg_ecc_regs[i] =
+				    kmem_zalloc(sizeof (pcix_ecc_regs_t),
+					KM_SLEEP);
+			}
+		}
+	} else {
+		pcix_error_regs_t *pcix_regs;
+
+		erpt_p->pe_regs = kmem_zalloc(sizeof (pcix_error_regs_t),
+		    KM_SLEEP);
+		pcix_regs = (pcix_error_regs_t *)erpt_p->pe_regs;
+		pcix_regs->pcix_cap_ptr = pcix_cap_ptr;
+		pcix_regs->pcix_ver = pci_config_get16(erpt_p->pe_hdl,
+		    pcix_cap_ptr + PCI_PCIX_COMMAND) & PCI_PCIX_VER_MASK;
+		if (PCIX_ECC_VER_CHECK(pcix_regs->pcix_ver)) {
+			pcix_regs->pcix_ecc_regs = kmem_zalloc(
+			    sizeof (pcix_ecc_regs_t), KM_SLEEP);
+		}
+	}
+}
+
+static void
+pcie_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p)
+{
+	pcie_error_regs_t *pcie_regs;
+	pcie_adv_error_regs_t *pcie_adv_regs;
+	char buf[FM_MAX_CLASS];
+	uint8_t pcix_cap_ptr;
+	uint8_t pcie_cap_ptr;
+	uint16_t pcie_ecap_ptr;
+	uint16_t dev_type = 0;
+	uint32_t mask = pcie_expected_ue_mask;
+
+	/*
+	 * The following sparc specific code should be removed once the pci_cap
+	 * interfaces create the necessary properties for us.
+	 */
+#if defined(__sparc)
+	ushort_t status;
+	uint32_t slot_cap;
+	uint8_t cap_ptr = 0;
+	uint8_t cap_id = 0;
+	uint32_t hdr, hdr_next_ptr, hdr_cap_id;
+	uint16_t offset = P2ALIGN(PCIE_EXT_CAP, 4);
+	uint16_t aer_ptr = 0;
+
+	cap_ptr = pci_config_get8(erpt_p->pe_hdl, PCI_CONF_CAP_PTR);
+	if (pci_config_check(erpt_p->pe_hdl) == DDI_FM_OK) {
+		while ((cap_id = pci_config_get8(erpt_p->pe_hdl, cap_ptr)) !=
+		    0xff) {
+			if (cap_id == PCI_CAP_ID_PCIX) {
+				(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
+				    "pcix-capid-pointer", cap_ptr);
+			}
+		if (cap_id == PCI_CAP_ID_PCI_E) {
+			status = pci_config_get16(erpt_p->pe_hdl, cap_ptr + 2);
+			if (status & PCIE_PCIECAP_SLOT_IMPL) {
+				/* offset 14h is Slot Cap Register */
+				slot_cap = pci_config_get32(erpt_p->pe_hdl,
+				    cap_ptr + PCIE_SLOTCAP);
+				(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
+				    "pcie-slotcap-reg", slot_cap);
+			}
+			(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
+			    "pcie-capid-reg", pci_config_get16(erpt_p->pe_hdl,
+			    cap_ptr + PCIE_PCIECAP));
+			(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
+			    "pcie-capid-pointer", cap_ptr);
+
+		}
+			if ((cap_ptr = pci_config_get8(erpt_p->pe_hdl,
+			    cap_ptr + 1)) == 0xff || cap_ptr == 0 ||
+			    (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK))
+				break;
+		}
+	}
+
+#endif
+
+	pcix_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+	    "pcix-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
+
+	if (pcix_cap_ptr != PCI_CAP_NEXT_PTR_NULL)
+		erpt_p->pe_dflags |= PCIX_DEV;
+
+	pcie_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
+	    DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
+
+	if (pcie_cap_ptr != PCI_CAP_NEXT_PTR_NULL) {
+		erpt_p->pe_dflags |= PCIEX_DEV;
+		erpt_p->pe_regs = kmem_zalloc(sizeof (pcie_error_regs_t),
+		    KM_SLEEP);
+		pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
+		pcie_regs->pcie_cap_ptr = pcie_cap_ptr;
+	}
+
+	if (!(erpt_p->pe_dflags & PCIEX_DEV))
+		return;
+
+	/*
+	 * Don't currently need to check for version here because we are
+	 * compliant with PCIE 1.0a which is version 0 and is guaranteed
+	 * software compatibility with future versions.  We will need to
+	 * add errors for new detectors/features which are added in newer
+	 * revisions [sec 7.8.2].
+	 */
+	pcie_regs->pcie_cap = pci_config_get16(erpt_p->pe_hdl,
+	    pcie_regs->pcie_cap_ptr + PCIE_PCIECAP);
+
+	dev_type = pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK;
+
+	if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) &&
+	    (erpt_p->pe_dflags & PCIX_DEV)) {
+		int i;
+
+		pcie_regs->pcix_bdg_regs =
+		    kmem_zalloc(sizeof (pcix_bdg_error_regs_t), KM_SLEEP);
+
+		pcie_regs->pcix_bdg_regs->pcix_bdg_cap_ptr = pcix_cap_ptr;
+		pcie_regs->pcix_bdg_regs->pcix_bdg_ver =
+		    pci_config_get16(erpt_p->pe_hdl,
+			pcix_cap_ptr + PCI_PCIX_SEC_STATUS) & PCI_PCIX_VER_MASK;
+
+		if (PCIX_ECC_VER_CHECK(pcie_regs->pcix_bdg_regs->pcix_bdg_ver))
+			for (i = 0; i < 2; i++)
+				pcie_regs->pcix_bdg_regs->pcix_bdg_ecc_regs[i] =
+				    kmem_zalloc(sizeof (pcix_ecc_regs_t),
+					KM_SLEEP);
+	}
+
+	if (dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT) {
+		erpt_p->pe_dflags |= PCIEX_RC_DEV;
+		pcie_regs->pcie_rc_regs = kmem_zalloc(
+		    sizeof (pcie_rc_error_regs_t), KM_SLEEP);
+	}
+	/*
+	 * The following sparc specific code should be removed once the pci_cap
+	 * interfaces create the necessary properties for us.
+	 */
+#if defined(__sparc)
+
+	hdr = pci_config_get32(erpt_p->pe_hdl, offset);
+	hdr_next_ptr = (hdr >> PCIE_EXT_CAP_NEXT_PTR_SHIFT) &
+	    PCIE_EXT_CAP_NEXT_PTR_MASK;
+	hdr_cap_id = (hdr >> PCIE_EXT_CAP_ID_SHIFT) & PCIE_EXT_CAP_ID_MASK;
+
+	while ((hdr_next_ptr != PCIE_EXT_CAP_NEXT_PTR_NULL) &&
+	    (hdr_cap_id != PCIE_EXT_CAP_ID_AER)) {
+		offset = P2ALIGN(hdr_next_ptr, 4);
+		hdr = pci_config_get32(erpt_p->pe_hdl, offset);
+		hdr_next_ptr = (hdr >> PCIE_EXT_CAP_NEXT_PTR_SHIFT) &
+		    PCIE_EXT_CAP_NEXT_PTR_MASK;
+		hdr_cap_id = (hdr >> PCIE_EXT_CAP_ID_SHIFT) &
+		    PCIE_EXT_CAP_ID_MASK;
+	}
+
+	if (hdr_cap_id == PCIE_EXT_CAP_ID_AER)
+		aer_ptr = P2ALIGN(offset, 4);
+	if (aer_ptr != PCI_CAP_NEXT_PTR_NULL)
+		(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
+		    "pcie-aer-pointer", aer_ptr);
+#endif
+
+	/*
+	 * Find and store if this device is capable of pci express
+	 * advanced errors, if not report an error against the device.
+	 */
+	pcie_ecap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+	    "pcie-aer-pointer", PCI_CAP_NEXT_PTR_NULL);
+	if (pcie_ecap_ptr != PCI_CAP_NEXT_PTR_NULL) {
+		erpt_p->pe_dflags |= PCIEX_ADV_DEV;
+		pcie_regs->pcie_adv_regs = kmem_zalloc(
+		    sizeof (pcie_adv_error_regs_t), KM_SLEEP);
+		pcie_regs->pcie_adv_regs->pcie_adv_cap_ptr = pcie_ecap_ptr;
+	}
+
+	if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) {
+		(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+		    PCIEX_ERROR_SUBCLASS, PCIEX_NADV);
+		ddi_fm_ereport_post(dip, buf, NULL, DDI_NOSLEEP,
+		    FM_VERSION, DATA_TYPE_UINT8, 0, NULL);
+		return;
+	}
+
+	pcie_adv_regs = pcie_regs->pcie_adv_regs;
+
+	if (pcie_adv_regs == NULL)
+		return;
+	/*
+	 * Initialize structures for advanced PCI Express devices.
+	 */
+
+	/*
+	 * Advanced error registers exist for PCI Express to PCI(X) Bridges and
+	 * may also exist for PCI(X) to PCI Express Bridges, the latter is not
+	 * well explained in the PCI Express to PCI/PCI-X Bridge Specification
+	 * 1.0 and will be left out of the current gathering of these registers.
+	 */
+	if (dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
+		erpt_p->pe_dflags |= PCIEX_2PCI_DEV;
+		pcie_adv_regs->pcie_adv_bdg_regs = kmem_zalloc(
+		    sizeof (pcie_adv_bdg_error_regs_t), KM_SLEEP);
+	}
+
+	if (erpt_p->pe_dflags & PCIEX_RC_DEV)
+		pcie_adv_regs->pcie_adv_rc_regs = kmem_zalloc(
+		    sizeof (pcie_adv_rc_error_regs_t), KM_SLEEP);
+
+	/*
+	 * Check that mask values are as expected, if not
+	 * change them to what we desire.
+	 */
+	pci_regs_gather(dip, erpt_p);
+	pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
+	if (pcie_regs->pcie_adv_regs->pcie_ce_mask != pcie_expected_ce_mask) {
+		pci_config_put32(erpt_p->pe_hdl,
+		    pcie_ecap_ptr + PCIE_AER_CE_MASK, pcie_expected_ce_mask);
+	}
+
+	/* Disable PTLP/ECRC (or mask these two) for Switches */
+	if (dev_type == PCIE_PCIECAP_DEV_TYPE_UP ||
+	    dev_type == PCIE_PCIECAP_DEV_TYPE_DOWN)
+		mask |= PCIE_AER_UCE_PTLP | PCIE_AER_UCE_ECRC;
+
+	if (pcie_regs->pcie_adv_regs->pcie_ue_mask != mask) {
+		pci_config_put32(erpt_p->pe_hdl,
+		    pcie_ecap_ptr + PCIE_AER_UCE_MASK, mask);
+	}
+	if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) {
+		if (pcie_regs->pcie_adv_regs->pcie_adv_bdg_regs->pcie_sue_mask
+		    != pcie_expected_sue_mask) {
+			pci_config_put32(erpt_p->pe_hdl,
+			    pcie_ecap_ptr + PCIE_AER_SUCE_MASK,
+			    pcie_expected_sue_mask);
+		}
+	}
+}
+
+/*
+ * pci_ereport_setup: Detect PCI device type and initialize structures to be
+ * used to generate ereports based on detected generic device errors.
+ */
+void
+pci_ereport_setup(dev_info_t *dip)
+{
+	struct dev_info *devi = DEVI(dip);
+	struct i_ddi_fmhdl *fmhdl = devi->devi_fmhdl;
+	pci_erpt_t *erpt_p;
+	uint8_t pci_hdr_type;
+	uint16_t pci_status;
+	pci_regspec_t *pci_rp;
+	int32_t len;
+	uint32_t phys_hi;
+
+	/*
+	 * If device is not ereport capbable then report an error against the
+	 * driver for using this interface,
+	 */
+	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip)) &&
+	    !DDI_FM_ERRCB_CAP(ddi_fm_capable(dip))) {
+		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_SLEEP);
+		return;
+	}
+
+	/*
+	 * ASSERT fmhdl exists and fh_bus_specific is NULL.
+	 */
+	ASSERT(fmhdl && (fmhdl->fh_bus_specific == NULL));
+
+	erpt_p = kmem_zalloc(sizeof (pci_erpt_t), KM_SLEEP);
+
+	if (pci_config_setup(dip, &erpt_p->pe_hdl) != DDI_SUCCESS)
+		goto error;
+
+	erpt_p->pe_pci_regs = kmem_zalloc(sizeof (pci_error_regs_t), KM_SLEEP);
+
+	pci_status = pci_config_get16(erpt_p->pe_hdl, PCI_CONF_STAT);
+	if (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK)
+		goto error;
+
+	/*
+	 * Get header type and record if device is a bridge.
+	 */
+	pci_hdr_type = pci_config_get8(erpt_p->pe_hdl, PCI_CONF_HEADER);
+	if (pci_config_check(erpt_p->pe_hdl) != DDI_FM_OK)
+		goto error;
+
+	/*
+	 * Check to see if PCI device is a bridge, if so allocate pci bridge
+	 * error register structure.
+	 */
+	if ((pci_hdr_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
+		erpt_p->pe_dflags |= PCI_BRIDGE_DEV;
+		erpt_p->pe_pci_regs->pci_bdg_regs = kmem_zalloc(
+		    sizeof (pci_bdg_error_regs_t), KM_SLEEP);
+	}
+
+	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
+	    (caddr_t)&pci_rp, &len) == DDI_SUCCESS) {
+		phys_hi = pci_rp->pci_phys_hi;
+		kmem_free(pci_rp, len);
+
+		erpt_p->pe_bdf = (uint16_t)(PCI_REG_BDFR_G(phys_hi) >>
+		    PCI_REG_FUNC_SHIFT);
+	}
+
+
+	if (!(pci_status & PCI_STAT_CAP)) {
+		goto done;
+	}
+
+	/*
+	 * Initialize structures for PCI Express and PCI-X devices.
+	 * Order matters below and pcie_ereport_setup should preceed
+	 * pcix_ereport_setup.
+	 */
+	pcie_ereport_setup(dip, erpt_p);
+
+	if (!(erpt_p->pe_dflags & PCIEX_DEV)) {
+		pcix_ereport_setup(dip, erpt_p);
+	}
+
+done:
+	pci_regs_gather(dip, erpt_p);
+	pci_regs_clear(erpt_p);
+
+	/*
+	 * Before returning set fh_bus_specific to completed pci_erpt_t
+	 * structure
+	 */
+	fmhdl->fh_bus_specific = (void *)erpt_p;
+
+	return;
+error:
+	if (erpt_p->pe_pci_regs)
+		kmem_free(erpt_p->pe_pci_regs, sizeof (pci_error_regs_t));
+	kmem_free(erpt_p, sizeof (pci_erpt_t));
+	erpt_p = NULL;
+}
+
+static void
+pcix_ereport_teardown(pci_erpt_t *erpt_p)
+{
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
+		pcix_bdg_error_regs_t *pcix_bdg_regs;
+		uint16_t pcix_ver;
+
+		pcix_bdg_regs = (pcix_bdg_error_regs_t *)erpt_p->pe_regs;
+		pcix_ver = pcix_bdg_regs->pcix_bdg_ver;
+		if (PCIX_ECC_VER_CHECK(pcix_ver)) {
+			int i;
+			for (i = 0; i < 2; i++)
+				kmem_free(pcix_bdg_regs->pcix_bdg_ecc_regs[i],
+				    sizeof (pcix_ecc_regs_t));
+		}
+		kmem_free(erpt_p->pe_regs, sizeof (pcix_bdg_error_regs_t));
+	} else {
+		pcix_error_regs_t *pcix_regs;
+		uint16_t pcix_ver;
+
+		pcix_regs = (pcix_error_regs_t *)erpt_p->pe_regs;
+		pcix_ver = pcix_regs->pcix_ver;
+		if (PCIX_ECC_VER_CHECK(pcix_ver)) {
+			kmem_free(pcix_regs->pcix_ecc_regs,
+			    sizeof (pcix_ecc_regs_t));
+		}
+		kmem_free(erpt_p->pe_regs, sizeof (pcix_error_regs_t));
+	}
+}
+
+static void
+pcie_ereport_teardown(pci_erpt_t *erpt_p)
+{
+	pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
+
+	if (erpt_p->pe_dflags & PCIEX_ADV_DEV) {
+		pcie_adv_error_regs_t *pcie_adv = pcie_regs->pcie_adv_regs;
+
+		if (erpt_p->pe_dflags & PCIEX_2PCI_DEV)
+			kmem_free(pcie_adv->pcie_adv_bdg_regs,
+			    sizeof (pcie_adv_bdg_error_regs_t));
+		if (erpt_p->pe_dflags & PCIEX_RC_DEV)
+			kmem_free(pcie_adv->pcie_adv_rc_regs,
+			    sizeof (pcie_adv_rc_error_regs_t));
+		kmem_free(pcie_adv, sizeof (pcie_adv_error_regs_t));
+	}
+
+	if (erpt_p->pe_dflags & PCIEX_RC_DEV)
+		kmem_free(pcie_regs->pcie_rc_regs,
+		    sizeof (pcie_rc_error_regs_t));
+
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
+		if (erpt_p->pe_dflags & PCIX_DEV) {
+			uint16_t pcix_ver = pcie_regs->pcix_bdg_regs->
+			    pcix_bdg_ver;
+
+			if (PCIX_ECC_VER_CHECK(pcix_ver)) {
+				int i;
+				for (i = 0; i < 2; i++)
+					kmem_free(pcie_regs->pcix_bdg_regs->
+					    pcix_bdg_ecc_regs[i],
+					    sizeof (pcix_ecc_regs_t));
+			}
+			kmem_free(pcie_regs->pcix_bdg_regs,
+			    sizeof (pcix_bdg_error_regs_t));
+		}
+	}
+	kmem_free(erpt_p->pe_regs, sizeof (pcie_error_regs_t));
+}
+
+void
+pci_ereport_teardown(dev_info_t *dip)
+{
+	struct i_ddi_fmhdl *fmhdl = DEVI(dip)->devi_fmhdl;
+	pci_erpt_t *erpt_p;
+
+	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip)) &&
+	    !DDI_FM_ERRCB_CAP(ddi_fm_capable(dip))) {
+		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_SLEEP);
+	}
+
+	ASSERT(fmhdl);
+
+	erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific;
+	if (erpt_p == NULL)
+		return;
+
+	if (erpt_p->pe_dflags & PCIEX_DEV)
+		pcie_ereport_teardown(erpt_p);
+	else if (erpt_p->pe_dflags & PCIX_DEV)
+		pcix_ereport_teardown(erpt_p);
+	pci_config_teardown((ddi_acc_handle_t *)&erpt_p->pe_hdl);
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV)
+		kmem_free(erpt_p->pe_pci_regs->pci_bdg_regs,
+		    sizeof (pci_bdg_error_regs_t));
+	kmem_free(erpt_p->pe_pci_regs, sizeof (pci_error_regs_t));
+	kmem_free(erpt_p, sizeof (pci_erpt_t));
+	fmhdl->fh_bus_specific = NULL;
+	/*
+	 * The following sparc specific code should be removed once the pci_cap
+	 * interfaces create the necessary properties for us.
+	 */
+#if defined(__sparc)
+	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcix-capid-pointer");
+	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-slotcap-reg");
+	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-capid-reg");
+	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-capid-pointer");
+	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-aer-pointer");
+#endif
+}
+
+/*
+ * Function used by PCI device and nexus error handlers to check if a
+ * captured address resides in their DMA or ACC handle caches or the caches of
+ * their children devices, respectively.
+ */
+static int
+pci_dev_hdl_lookup(dev_info_t *dip, int type, ddi_fm_error_t *derr,
+    void *addr)
+{
+	struct i_ddi_fmhdl *fmhdl = DEVI(dip)->devi_fmhdl;
+	pci_erpt_t *erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific;
+
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV)
+		return (ndi_fmc_error(dip, NULL, type, derr->fme_ena, addr));
+	else
+		return (ndi_fmc_entry_error(dip, type, derr, addr));
+}
+
+static void
+pcie_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p,
+    char *buf, int errtype)
+{
+	pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
+	pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs;
+	pcie_adv_rc_error_regs_t *pcie_adv_rc_regs =
+	    pcie_adv_regs->pcie_adv_rc_regs;
+
+	switch (errtype) {
+	    case PCIEX_TYPE_CE:
+		ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+		    PCIEX_DEVSTS_REG, DATA_TYPE_UINT16,
+		    pcie_regs->pcie_err_status,
+		    PCIEX_CE_STATUS_REG, DATA_TYPE_UINT32,
+		    pcie_adv_regs->pcie_ce_status, NULL);
+		break;
+	    case PCIEX_TYPE_UE:
+		ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+		    PCIEX_DEVSTS_REG, DATA_TYPE_UINT16,
+		    pcie_regs->pcie_err_status,
+		    PCIEX_UE_STATUS_REG, DATA_TYPE_UINT32,
+		    pcie_adv_regs->pcie_ue_status, PCIEX_UE_SEV_REG,
+		    DATA_TYPE_UINT32, pcie_adv_regs->pcie_ue_sev,
+		    PCIEX_ADV_CTL, DATA_TYPE_UINT32,
+		    pcie_adv_regs->pcie_adv_ctl,
+		    PCIEX_SRC_ID, DATA_TYPE_UINT16,
+		    pcie_adv_regs->pcie_adv_bdf,
+		    PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE,
+		    (pcie_adv_regs->pcie_adv_bdf != NULL) ?
+		    1 : NULL,
+#ifdef DEBUG
+		    PCIEX_UE_HDR0, DATA_TYPE_UINT32,
+		    pcie_adv_regs->pcie_ue_hdr0,
+		    PCIEX_UE_HDR1, DATA_TYPE_UINT32,
+		    pcie_adv_regs->pcie_ue_hdr[0],
+		    PCIEX_UE_HDR2, DATA_TYPE_UINT32,
+		    pcie_adv_regs->pcie_ue_hdr[1],
+		    PCIEX_UE_HDR3, DATA_TYPE_UINT32,
+		    pcie_adv_regs->pcie_ue_hdr[2],
+#endif
+		    NULL);
+		break;
+	    case PCIEX_TYPE_GEN:
+		ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8,
+		    0, PCIEX_DEVSTS_REG, DATA_TYPE_UINT16,
+		    pcie_regs->pcie_err_status, NULL);
+		break;
+	    case PCIEX_TYPE_RC_UE_MSG:
+	    case PCIEX_TYPE_RC_CE_MSG:
+		ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+		    PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32,
+		    pcie_adv_rc_regs->pcie_rc_err_status,
+		    PCIEX_SRC_ID, DATA_TYPE_UINT16,
+		    (errtype == PCIEX_TYPE_RC_UE_MSG) ?
+		    pcie_adv_rc_regs->pcie_rc_ue_src_id :
+		    pcie_adv_rc_regs->pcie_rc_ce_src_id,
+		    PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE,
+		    (errtype == PCIEX_TYPE_RC_UE_MSG) ?
+		    (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID &&
+		    pcie_adv_rc_regs->pcie_rc_ue_src_id != 0) :
+		    (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID &&
+		    pcie_adv_rc_regs->pcie_rc_ce_src_id != 0), NULL);
+		break;
+	    case PCIEX_TYPE_RC_MULT_MSG:
+		ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+		    PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32,
+		    pcie_adv_rc_regs->pcie_rc_err_status, NULL);
+		break;
+	    default:
+		break;
+	}
+}
+
+static void
+pcie_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *eprt_p)
+{
+	pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)eprt_p->pe_regs;
+	pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs;
+	pcie_tlp_hdr_t *ue_hdr0;
+	uint32_t *ue_hdr;
+	uint64_t addr = NULL;
+
+	if (!(pcie_adv_regs->pcie_adv_vflags & PCIE_UE_HDR_VALID)) {
+		derr->fme_status = DDI_FM_UNKNOWN;
+		return;
+	}
+	ue_hdr0 = (pcie_tlp_hdr_t *)&pcie_adv_regs->pcie_ue_hdr0;
+	ue_hdr = pcie_adv_regs->pcie_ue_hdr;
+
+	switch (ue_hdr0->type) {
+	    case PCIE_TLP_TYPE_MEM:
+	    case PCIE_TLP_TYPE_MEMLK:
+		if ((ue_hdr0->fmt & 0x1) == 0x1) {
+			pcie_mem64_t *mem64_tlp = (pcie_mem64_t *)ue_hdr;
+
+			addr = (uint64_t)mem64_tlp->addr1 << 32 |
+			    (uint32_t)mem64_tlp->addr0 << 2;
+			pcie_adv_regs->pcie_adv_bdf = mem64_tlp->rid;
+		} else {
+			pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr;
+
+			addr = (uint32_t)memio32_tlp->addr0 << 2;
+			pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid;
+		}
+
+		derr->fme_status = pci_dev_hdl_lookup(dip, DMA_HANDLE, derr,
+		    (void *) &addr);
+		/*
+		 * If DMA handle is not found error could have been a memory
+		 * mapped IO address so check in the access cache
+		 */
+		if (derr->fme_status == DDI_FM_UNKNOWN)
+			derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE,
+			    derr, (void *) &addr);
+		break;
+
+	    case PCIE_TLP_TYPE_IO:
+		{
+			pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr;
+
+			addr = (uint32_t)memio32_tlp->addr0 << 2;
+			pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid;
+			derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE,
+			    derr, (void *) &addr);
+			break;
+		}
+	    case PCIE_TLP_TYPE_CFG0:
+	    case PCIE_TLP_TYPE_CFG1:
+		{
+			pcie_cfg_t *cfg_tlp = (pcie_cfg_t *)ue_hdr;
+
+			pcie_adv_regs->pcie_adv_bdf =
+			    (uint16_t)cfg_tlp->bus << 8 |
+			    (uint16_t)cfg_tlp->dev << 3 | cfg_tlp->func;
+
+			derr->fme_status = DDI_FM_UNKNOWN;
+			break;
+		}
+	    case PCIE_TLP_TYPE_MSG:
+		{
+			pcie_msg_t *msg_tlp = (pcie_msg_t *)ue_hdr;
+
+			pcie_adv_regs->pcie_adv_bdf = msg_tlp->rid;
+			derr->fme_status = DDI_FM_UNKNOWN;
+			break;
+		}
+	    case PCIE_TLP_TYPE_CPL:
+	    case PCIE_TLP_TYPE_CPLLK:
+		{
+			pcie_cpl_t *cpl_tlp = (pcie_cpl_t *)ue_hdr;
+
+			pcie_adv_regs->pcie_adv_bdf = cpl_tlp->cid;
+			derr->fme_status = DDI_FM_UNKNOWN;
+			break;
+		}
+	    case PCIE_TLP_TYPE_MSI:
+	    default:
+		derr->fme_status = DDI_FM_UNKNOWN;
+	}
+
+	/*
+	 * If no handle was found in the children caches and their is no
+	 * address infomation already stored and we have a captured address
+	 * then we need to store it away so that intermediate bridges can
+	 * check if the address exists in their handle caches.
+	 */
+	if (derr->fme_status == DDI_FM_UNKNOWN &&
+	    derr->fme_bus_specific == NULL &&
+	    addr != NULL)
+		derr->fme_bus_specific = (void *)(uintptr_t)addr;
+}
+
+static void
+pcie_pci_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *eprt_p)
+{
+	pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)eprt_p->pe_regs;
+	pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs;
+	pcie_adv_bdg_error_regs_t *pcie_bdg_regs =
+	    pcie_adv_regs->pcie_adv_bdg_regs;
+	uint64_t addr = NULL;
+	pcix_attr_t *pcie_pci_sue_attr;
+	int cmd;
+	int dual_addr = 0;
+
+	if (!(pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_HDR_VALID)) {
+		derr->fme_status = DDI_FM_UNKNOWN;
+		return;
+	}
+
+	pcie_pci_sue_attr = (pcix_attr_t *)&pcie_bdg_regs->pcie_sue_hdr0;
+	cmd = (pcie_bdg_regs->pcie_sue_hdr[0] >>
+	    PCIE_AER_SUCE_HDR_CMD_LWR_SHIFT) & PCIE_AER_SUCE_HDR_CMD_LWR_MASK;
+cmd_switch:
+	switch (cmd) {
+	    case PCI_PCIX_CMD_IORD:
+	    case PCI_PCIX_CMD_IOWR:
+		pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid;
+
+		addr = pcie_bdg_regs->pcie_sue_hdr[2];
+		addr = (addr << PCIE_AER_SUCE_HDR_ADDR_SHIFT) |
+		    pcie_bdg_regs->pcie_sue_hdr[1];
+
+		derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE,
+		    derr, (void *) &addr);
+		break;
+	    case PCI_PCIX_CMD_MEMRD_DW:
+	    case PCI_PCIX_CMD_MEMWR:
+	    case PCI_PCIX_CMD_MEMRD_BL:
+	    case PCI_PCIX_CMD_MEMWR_BL:
+	    case PCI_PCIX_CMD_MEMRDBL:
+	    case PCI_PCIX_CMD_MEMWRBL:
+		pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid;
+
+		addr = pcie_bdg_regs->pcie_sue_hdr[2];
+		addr = (addr << PCIE_AER_SUCE_HDR_ADDR_SHIFT) |
+		    pcie_bdg_regs->pcie_sue_hdr[1];
+
+		derr->fme_status = pci_dev_hdl_lookup(dip, DMA_HANDLE,
+		    derr, (void *) &addr);
+		if (derr->fme_status == DDI_FM_UNKNOWN)
+			derr->fme_status = pci_dev_hdl_lookup(dip, ACC_HANDLE,
+			    derr, (void *) &addr);
+		break;
+	    case PCI_PCIX_CMD_CFRD:
+	    case PCI_PCIX_CMD_CFWR:
+		/*
+		 * If we want to store the bdf of the device being addressed we
+		 * will need to do some surgery
+		 */
+		derr->fme_status = DDI_FM_UNKNOWN;
+		break;
+	    case PCI_PCIX_CMD_DADR:
+		cmd = (pcie_bdg_regs->pcie_sue_hdr[0] >>
+		    PCIE_AER_SUCE_HDR_CMD_UP_SHIFT) &
+		    PCIE_AER_SUCE_HDR_CMD_UP_MASK;
+		if (dual_addr)
+			break;
+		++dual_addr;
+		goto cmd_switch;
+	    default:
+		derr->fme_status = DDI_FM_UNKNOWN;
+	}
+
+	/*
+	 * If no handle was found in the children caches and their is no
+	 * address infomation already stored and we have a captured address
+	 * then we need to store it away so that intermediate bridges can
+	 * check if the address exists in their handle caches.
+	 */
+	if (derr->fme_status == DDI_FM_UNKNOWN &&
+	    derr->fme_bus_specific == NULL &&
+	    addr != NULL)
+		derr->fme_bus_specific = (void *)(uintptr_t)addr;
+}
+
+static int
+pcix_check_addr(dev_info_t *dip, ddi_fm_error_t *derr,
+    pcix_ecc_regs_t *pcix_ecc_regs)
+{
+	int cmd = (pcix_ecc_regs->pcix_ecc_ctlstat >> 16) & 0xf;
+	uint64_t addr;
+
+	addr = pcix_ecc_regs->pcix_ecc_secaddr;
+	addr = addr << 32;
+	addr |= pcix_ecc_regs->pcix_ecc_fstaddr;
+
+	switch (cmd) {
+	    case PCI_PCIX_CMD_INTR:
+	    case PCI_PCIX_CMD_SPEC:
+		return (DDI_FM_FATAL);
+	    case PCI_PCIX_CMD_IORD:
+	    case PCI_PCIX_CMD_IOWR:
+		return (pci_dev_hdl_lookup(dip, ACC_HANDLE, derr,
+		    (void *) &addr));
+	    case PCI_PCIX_CMD_DEVID:
+		return (DDI_FM_FATAL);
+	    case PCI_PCIX_CMD_MEMRD_DW:
+	    case PCI_PCIX_CMD_MEMWR:
+	    case PCI_PCIX_CMD_MEMRD_BL:
+	    case PCI_PCIX_CMD_MEMWR_BL:
+		return (pci_dev_hdl_lookup(dip, DMA_HANDLE, derr,
+		    (void *) &addr));
+	    case PCI_PCIX_CMD_CFRD:
+	    case PCI_PCIX_CMD_CFWR:
+		return (pci_dev_hdl_lookup(dip, ACC_HANDLE, derr,
+		    (void *) &addr));
+	    case PCI_PCIX_CMD_SPL:
+	    case PCI_PCIX_CMD_DADR:
+		return (DDI_FM_FATAL);
+	    case PCI_PCIX_CMD_MEMRDBL:
+	    case PCI_PCIX_CMD_MEMWRBL:
+		return (pci_dev_hdl_lookup(dip, DMA_HANDLE, derr,
+		    (void *) &addr));
+	    default:
+		return (DDI_FM_FATAL);
+	}
+}
+
+/*ARGSUSED*/
+static int
+pci_bdg_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
+{
+	pci_bdg_error_regs_t *pci_bdg_regs = erpt_p->pe_pci_regs->pci_bdg_regs;
+	int fatal = 0;
+	int nonfatal = 0;
+	int unknown = 0;
+	int ok = 0;
+	int ret = DDI_FM_OK;
+	char buf[FM_MAX_CLASS];
+	int i;
+
+	if (derr->fme_flag != DDI_FM_ERR_UNEXPECTED)
+		goto done;
+
+	if ((pci_bdg_regs->pci_bdg_vflags & PCI_BDG_CTRL_VALID) &&
+	    (pci_bdg_regs->pci_bdg_ctrl & PCI_BCNF_BCNTRL_DTO_STAT)) {
+		(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+		    PCI_ERROR_SUBCLASS, PCI_DTO);
+		ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+		    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+		    PCI_SEC_CONFIG_STATUS, DATA_TYPE_UINT16,
+		    pci_bdg_regs->pci_bdg_sec_stat, PCI_BCNTRL,
+		    DATA_TYPE_UINT16, pci_bdg_regs->pci_bdg_ctrl, NULL);
+		unknown++;
+	}
+
+	if (pci_bdg_regs->pci_bdg_vflags & PCI_BDG_SEC_STAT_VALID) {
+		for (i = 0; pci_bdg_err_tbl[i].err_class != NULL; i++) {
+			if (pci_bdg_regs->pci_bdg_sec_stat &
+			    pci_bdg_err_tbl[i].reg_bit) {
+				(void) snprintf(buf, FM_MAX_CLASS, "%s.%s-%s",
+				    PCI_ERROR_SUBCLASS, PCI_SEC_ERROR_SUBCLASS,
+				    pci_bdg_err_tbl[i].err_class);
+				ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+				    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+				    PCI_SEC_CONFIG_STATUS, DATA_TYPE_UINT16,
+				    pci_bdg_regs->pci_bdg_sec_stat, PCI_BCNTRL,
+				    DATA_TYPE_UINT16,
+				    pci_bdg_regs->pci_bdg_ctrl, NULL);
+				/*
+				 * Increment severity based on flag if bridge
+				 * is PCI or PCI-X, if PCI Express and this is a
+				 * master abort then treat as nonfatal.
+				 * XXFM May need to check if all other errors
+				 * are related to MA?
+				 */
+				if (!(erpt_p->pe_dflags & PCIEX_DEV)) {
+					PCI_FM_SEV_INC(
+					    pci_bdg_err_tbl[i].flags);
+				} else if (pci_bdg_err_tbl[i].reg_bit ==
+				    PCI_STAT_R_MAST_AB) {
+					nonfatal++;
+				}
+
+				if (derr->fme_bus_specific &&
+				    pci_bdg_err_tbl[i].terr_class)
+					pci_target_enqueue(derr->fme_ena,
+					    pci_bdg_err_tbl[i].terr_class,
+					    PCI_ERROR_SUBCLASS,
+					    (uintptr_t)derr->fme_bus_specific);
+			}
+		}
+	}
+
+done:
+
+	/*
+	 * Need to check for poke and cautious put. We already know peek
+	 * and cautious get errors occurred (as we got a trap) and we know
+	 * they are nonfatal.
+	 */
+	if (derr->fme_flag == DDI_FM_ERR_EXPECTED) {
+		/*
+		 * for cautious puts we treat all errors as nonfatal. Actually
+		 * we set nonfatal for cautious gets as well - doesn't do any
+		 * harm
+		 */
+		if (pci_bdg_regs->pci_bdg_sec_stat & (PCI_STAT_R_TARG_AB |
+		    PCI_STAT_R_MAST_AB | PCI_STAT_S_PERROR | PCI_STAT_S_SYSERR))
+			nonfatal++;
+
+		/*
+		 * for cautious accesses we already have the acc_handle. Just
+		 * need to call children to clear their error bits
+		 */
+		ret = ndi_fm_handler_dispatch(dip, NULL, derr);
+		PCI_FM_SEV_INC(ret);
+		return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
+		    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
+	}
+	if (derr->fme_flag == DDI_FM_ERR_POKE) {
+		/*
+		 * special case for pokes - we only consider master abort
+		 * and target abort as nonfatal. Sserr with no master abort is
+		 * fatal, but master/target abort can come in on separate
+		 * instance, so return unknown and parent will determine if
+		 * nonfatal (if another child returned nonfatal - ie master
+		 * or target abort) or fatal otherwise
+		 */
+		if (pci_bdg_regs->pci_bdg_sec_stat & (PCI_STAT_R_TARG_AB |
+		    PCI_STAT_R_MAST_AB))
+			nonfatal++;
+		if (erpt_p->pe_pci_regs->pci_err_status & PCI_STAT_S_SYSERR)
+			unknown++;
+	}
+
+	/*
+	 * If errant address is passed in then attempt to find
+	 * ACC/DMA handle in caches.
+	 */
+	if (derr->fme_bus_specific) {
+		int i;
+
+		for (i = 0; i < 2; i++) {
+			ret = ndi_fmc_error(dip, NULL, i ? ACC_HANDLE :
+			    DMA_HANDLE, derr->fme_ena,
+			    (void *)&derr->fme_bus_specific);
+			PCI_FM_SEV_INC(ret);
+		}
+	}
+
+	/*
+	 * now check children below the bridge, only if errant handle was not
+	 * found
+	 */
+	if (!derr->fme_acc_handle && !derr->fme_dma_handle) {
+		ret = ndi_fm_handler_dispatch(dip, NULL, derr);
+		PCI_FM_SEV_INC(ret);
+	}
+
+	return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
+	    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
+}
+
+static int
+pcix_ecc_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p,
+    void *pe_regs)
+{
+	pcix_error_regs_t *pcix_regs;
+	pcix_bdg_error_regs_t *pcix_bdg_regs;
+	pcix_ecc_regs_t *pcix_ecc_regs;
+	int bridge;
+	int i;
+	int ecc_phase;
+	int ecc_corr;
+	int sec_ue;
+	int sec_ce;
+	int fatal = 0;
+	int nonfatal = 0;
+	int unknown = 0;
+	int ok = 0;
+	char buf[FM_MAX_CLASS];
+
+	if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
+		pcix_bdg_regs = (pcix_bdg_error_regs_t *)pe_regs;
+		bridge = 1;
+	} else {
+		pcix_regs = (pcix_error_regs_t *)pe_regs;
+		bridge = 0;
+	}
+
+	for (i = 0; i < (bridge ? 2 : 1); i++) {
+		int ret = DDI_FM_OK;
+		pcix_ecc_regs = bridge ? pcix_bdg_regs->pcix_bdg_ecc_regs[i] :
+		    pcix_regs->pcix_ecc_regs;
+		if (pcix_ecc_regs->pcix_ecc_vflags & PCIX_ERR_ECC_STS_VALID) {
+			ecc_phase = (pcix_ecc_regs->pcix_ecc_ctlstat &
+			    PCI_PCIX_ECC_PHASE) >> 0x4;
+			ecc_corr = (pcix_ecc_regs->pcix_ecc_ctlstat &
+			    PCI_PCIX_ECC_CORR);
+			sec_ue = (pcix_ecc_regs->pcix_ecc_ctlstat &
+			    PCI_PCIX_ECC_S_UE);
+			sec_ce = (pcix_ecc_regs->pcix_ecc_ctlstat &
+			    PCI_PCIX_ECC_S_CE);
+
+			switch (ecc_phase) {
+			    case PCI_PCIX_ECC_PHASE_NOERR:
+				break;
+			    case PCI_PCIX_ECC_PHASE_FADDR:
+			    case PCI_PCIX_ECC_PHASE_SADDR:
+				PCI_FM_SEV_INC(ecc_corr ?  DDI_FM_NONFATAL :
+				    DDI_FM_FATAL);
+				(void) snprintf(buf, FM_MAX_CLASS,
+				    "%s.%s%s", PCIX_ERROR_SUBCLASS,
+				    i ? PCIX_SEC_ERROR_SUBCLASS : "",
+				    ecc_corr ? PCIX_ECC_CE_ADDR :
+				    PCIX_ECC_UE_ADDR);
+				break;
+			    case PCI_PCIX_ECC_PHASE_ATTR:
+				PCI_FM_SEV_INC(ecc_corr ?
+				    DDI_FM_NONFATAL : DDI_FM_FATAL);
+				(void) snprintf(buf, FM_MAX_CLASS,
+				    "%s.%s%s", PCIX_ERROR_SUBCLASS,
+				    i ? PCIX_SEC_ERROR_SUBCLASS : "",
+				    ecc_corr ? PCIX_ECC_CE_ATTR :
+				    PCIX_ECC_UE_ATTR);
+				break;
+			    case PCI_PCIX_ECC_PHASE_DATA32:
+			    case PCI_PCIX_ECC_PHASE_DATA64:
+				if (ecc_corr)
+					ret = DDI_FM_NONFATAL;
+				else
+					ret = pcix_check_addr(dip, derr,
+					    pcix_ecc_regs);
+				PCI_FM_SEV_INC(ret);
+
+				(void) snprintf(buf, FM_MAX_CLASS,
+				    "%s.%s%s", PCIX_ERROR_SUBCLASS,
+				    i ? PCIX_SEC_ERROR_SUBCLASS : "",
+				    ecc_corr ? PCIX_ECC_CE_DATA :
+				    PCIX_ECC_UE_DATA);
+				break;
+			}
+			if (ecc_phase)
+				if (bridge)
+					ddi_fm_ereport_post(dip, buf,
+					    derr->fme_ena,
+					    DDI_NOSLEEP, FM_VERSION,
+					    DATA_TYPE_UINT8, 0,
+					    PCIX_SEC_STATUS, DATA_TYPE_UINT16,
+					    pcix_bdg_regs->pcix_bdg_sec_stat,
+					    PCIX_BDG_STAT, DATA_TYPE_UINT32,
+					    pcix_bdg_regs->pcix_bdg_stat,
+					    PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32,
+					    pcix_ecc_regs->pcix_ecc_ctlstat,
+					    PCIX_ECC_ATTR, DATA_TYPE_UINT32,
+					    pcix_ecc_regs->pcix_ecc_attr, NULL);
+				else
+					ddi_fm_ereport_post(dip, buf,
+					    derr->fme_ena,
+					    DDI_NOSLEEP, FM_VERSION,
+					    DATA_TYPE_UINT8, 0,
+					    PCIX_COMMAND, DATA_TYPE_UINT16,
+					    pcix_regs->pcix_command,
+					    PCIX_STATUS, DATA_TYPE_UINT32,
+					    pcix_regs->pcix_status,
+					    PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32,
+					    pcix_ecc_regs->pcix_ecc_ctlstat,
+					    PCIX_ECC_ATTR, DATA_TYPE_UINT32,
+					    pcix_ecc_regs->pcix_ecc_attr, NULL);
+			if (sec_ce || sec_ue) {
+				(void) snprintf(buf, FM_MAX_CLASS,
+				    "%s.%s%s", PCIX_ERROR_SUBCLASS,
+				    i ? PCIX_SEC_ERROR_SUBCLASS : "",
+				    sec_ce ? PCIX_ECC_S_CE : PCIX_ECC_S_UE);
+				if (bridge)
+					ddi_fm_ereport_post(dip, buf,
+					    derr->fme_ena,
+					    DDI_NOSLEEP, FM_VERSION,
+					    DATA_TYPE_UINT8, 0,
+					    PCIX_SEC_STATUS, DATA_TYPE_UINT16,
+					    pcix_bdg_regs->pcix_bdg_sec_stat,
+					    PCIX_BDG_STAT, DATA_TYPE_UINT32,
+					    pcix_bdg_regs->pcix_bdg_stat,
+					    PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32,
+					    pcix_ecc_regs->pcix_ecc_ctlstat,
+					    PCIX_ECC_ATTR, DATA_TYPE_UINT32,
+					    pcix_ecc_regs->pcix_ecc_attr, NULL);
+				else
+					ddi_fm_ereport_post(dip, buf,
+					    derr->fme_ena,
+					    DDI_NOSLEEP, FM_VERSION,
+					    DATA_TYPE_UINT8, 0,
+					    PCIX_COMMAND, DATA_TYPE_UINT16,
+					    pcix_regs->pcix_command,
+					    PCIX_STATUS, DATA_TYPE_UINT32,
+					    pcix_regs->pcix_status,
+					    PCIX_ECC_CTLSTAT, DATA_TYPE_UINT32,
+					    pcix_ecc_regs->pcix_ecc_ctlstat,
+					    PCIX_ECC_ATTR, DATA_TYPE_UINT32,
+					    pcix_ecc_regs->pcix_ecc_attr, NULL);
+				PCI_FM_SEV_INC(sec_ue ? DDI_FM_FATAL :
+				    DDI_FM_NONFATAL);
+			}
+		}
+	}
+	return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
+	    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
+}
+
+static int
+pcix_bdg_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p,
+    void *pe_regs)
+{
+	pcix_bdg_error_regs_t *pcix_bdg_regs = (pcix_bdg_error_regs_t *)pe_regs;
+	int fatal = 0;
+	int nonfatal = 0;
+	int unknown = 0;
+	int ok = 0;
+	char buf[FM_MAX_CLASS];
+	int i;
+
+	if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_STATUS_VALID) {
+		for (i = 0; pcix_err_tbl[i].err_class != NULL; i++) {
+			if ((pcix_bdg_regs->pcix_bdg_stat &
+			    pcix_err_tbl[i].reg_bit)) {
+				(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+				    PCIX_ERROR_SUBCLASS,
+				    pcix_err_tbl[i].err_class);
+				ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+				    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+				    PCIX_SEC_STATUS, DATA_TYPE_UINT16,
+				    pcix_bdg_regs->pcix_bdg_sec_stat,
+				    PCIX_BDG_STAT, DATA_TYPE_UINT32,
+				    pcix_bdg_regs->pcix_bdg_stat, NULL);
+				PCI_FM_SEV_INC(pcix_err_tbl[i].flags);
+			}
+		}
+	}
+
+	if (pcix_bdg_regs->pcix_bdg_vflags & PCIX_BDG_SEC_STATUS_VALID) {
+		for (i = 0; pcix_sec_err_tbl[i].err_class != NULL; i++) {
+			if ((pcix_bdg_regs->pcix_bdg_sec_stat &
+			    pcix_sec_err_tbl[i].reg_bit)) {
+				(void) snprintf(buf, FM_MAX_CLASS, "%s.%s%s",
+				    PCIX_ERROR_SUBCLASS,
+				    PCIX_SEC_ERROR_SUBCLASS,
+				    pcix_sec_err_tbl[i].err_class);
+				ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+				    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+				    PCIX_SEC_STATUS, DATA_TYPE_UINT16,
+				    pcix_bdg_regs->pcix_bdg_sec_stat,
+				    PCIX_BDG_STAT, DATA_TYPE_UINT32,
+				    pcix_bdg_regs->pcix_bdg_stat, NULL);
+				PCI_FM_SEV_INC(pcix_sec_err_tbl[i].flags);
+			}
+		}
+	}
+
+	/* Log/Handle ECC errors */
+	if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) {
+		int ret;
+
+		ret = pcix_ecc_error_report(dip, derr, erpt_p,
+		    (void *)pcix_bdg_regs);
+		PCI_FM_SEV_INC(ret);
+	}
+	return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
+	    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
+}
+
+static int
+pcix_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
+{
+	pcix_error_regs_t *pcix_regs = (pcix_error_regs_t *)erpt_p->pe_regs;
+	int fatal = 0;
+	int nonfatal = 0;
+	int unknown = 0;
+	int ok = 0;
+	char buf[FM_MAX_CLASS];
+	int i;
+
+	if (pcix_regs->pcix_vflags & PCIX_ERR_STATUS_VALID) {
+		for (i = 0; pcix_err_tbl[i].err_class != NULL; i++) {
+			if (!(pcix_regs->pcix_status & pcix_err_tbl[i].reg_bit))
+				continue;
+
+			(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+			    PCIX_ERROR_SUBCLASS, pcix_err_tbl[i].err_class);
+			ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+			    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+			    PCIX_COMMAND, DATA_TYPE_UINT16,
+			    pcix_regs->pcix_command, PCIX_STATUS,
+			    DATA_TYPE_UINT32, pcix_regs->pcix_status,
+			    NULL);
+			PCI_FM_SEV_INC(pcix_err_tbl[i].flags);
+		}
+	}
+	/* Log/Handle ECC errors */
+	if (PCIX_ECC_VER_CHECK(pcix_regs->pcix_ver)) {
+		int ret = pcix_ecc_error_report(dip, derr, erpt_p,
+		    (void *)pcix_regs);
+		PCI_FM_SEV_INC(ret);
+	}
+
+	return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
+	    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
+}
+
+static int
+pcie_rc_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p,
+    void *pe_regs)
+{
+	pcie_adv_error_regs_t *pcie_adv_regs = (pcie_adv_error_regs_t *)pe_regs;
+	int fatal = 0;
+	int nonfatal = 0;
+	int unknown = 0;
+	char buf[FM_MAX_CLASS];
+
+	if (pcie_adv_regs->pcie_adv_vflags & PCIE_RC_ERR_STATUS_VALID) {
+		pcie_adv_rc_error_regs_t *pcie_rc_regs =
+		    pcie_adv_regs->pcie_adv_rc_regs;
+		int ce, ue, mult_ce, mult_ue, first_ue_fatal, nfe, fe;
+
+		ce = pcie_rc_regs->pcie_rc_err_status &
+		    PCIE_AER_RE_STS_CE_RCVD;
+		ue = pcie_rc_regs->pcie_rc_err_status &
+		    PCIE_AER_RE_STS_FE_NFE_RCVD;
+		mult_ce = pcie_rc_regs->pcie_rc_err_status &
+		    PCIE_AER_RE_STS_MUL_CE_RCVD;
+		mult_ue = pcie_rc_regs->pcie_rc_err_status &
+		    PCIE_AER_RE_STS_MUL_FE_NFE_RCVD;
+		first_ue_fatal = pcie_rc_regs->pcie_rc_err_status &
+		    PCIE_AER_RE_STS_FIRST_UC_FATAL;
+		nfe = pcie_rc_regs->pcie_rc_err_status &
+		    PCIE_AER_RE_STS_NFE_MSGS_RCVD;
+		fe = pcie_rc_regs->pcie_rc_err_status &
+		    PCIE_AER_RE_STS_FE_MSGS_RCVD;
+		/*
+		 * log fatal/nonfatal/corrected messages
+		 * recieved by root complex
+		 */
+		if (ue && fe)
+			fatal++;
+		else if (ce && !ue)
+			nonfatal++;
+
+		if (fe && first_ue_fatal) {
+			(void) snprintf(buf, FM_MAX_CLASS,
+			    "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_FE_MSG);
+			pcie_ereport_post(dip, derr, erpt_p, buf,
+			    PCIEX_TYPE_RC_UE_MSG);
+		}
+		if (nfe && !first_ue_fatal) {
+			(void) snprintf(buf, FM_MAX_CLASS,
+			    "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_NFE_MSG);
+			pcie_ereport_post(dip, derr, erpt_p, buf,
+			    PCIEX_TYPE_RC_UE_MSG);
+		}
+		if (ce) {
+			(void) snprintf(buf, FM_MAX_CLASS,
+			    "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_CE_MSG);
+			pcie_ereport_post(dip, derr, erpt_p, buf,
+			    PCIEX_TYPE_RC_CE_MSG);
+		}
+		if (mult_ce) {
+			(void) snprintf(buf, FM_MAX_CLASS,
+			    "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MCE_MSG);
+			pcie_ereport_post(dip, derr, erpt_p, buf,
+			    PCIEX_TYPE_RC_MULT_MSG);
+		}
+		if (mult_ue) {
+			(void) snprintf(buf, FM_MAX_CLASS,
+			    "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MUE_MSG);
+			pcie_ereport_post(dip, derr, erpt_p, buf,
+			    PCIEX_TYPE_RC_MULT_MSG);
+		}
+	}
+	return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
+	    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
+}
+
+static int
+pcie_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
+{
+	int fatal = 0;
+	int nonfatal = 0;
+	int unknown = 0;
+	int ok = 0;
+	char buf[FM_MAX_CLASS];
+	int i;
+	pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
+	pcie_adv_error_regs_t *pcie_adv_regs;
+	pcie_adv_bdg_error_regs_t *pcie_bdg_regs;
+
+	if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) &&
+	    (erpt_p->pe_dflags & PCIX_DEV)) {
+		int ret = pcix_bdg_error_report(dip, derr, erpt_p,
+		    (void *)pcie_regs->pcix_bdg_regs);
+		PCI_FM_SEV_INC(ret);
+	}
+
+	if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) {
+		if (!(pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID))
+			goto done;
+		for (i = 0; pciex_nadv_err_tbl[i].err_class != NULL; i++) {
+			if (!(pcie_regs->pcie_err_status &
+			    pciex_nadv_err_tbl[i].reg_bit))
+				continue;
+
+			(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+			    PCIEX_ERROR_SUBCLASS,
+			    pciex_nadv_err_tbl[i].err_class);
+			pcie_ereport_post(dip, derr, erpt_p, buf,
+			    PCIEX_TYPE_GEN);
+			PCI_FM_SEV_INC(pciex_nadv_err_tbl[i].flags);
+		}
+		goto done;
+	}
+
+	pcie_adv_regs = pcie_regs->pcie_adv_regs;
+
+	/*
+	 * Log PCI Express uncorrectable errors
+	 */
+	if (pcie_adv_regs->pcie_adv_vflags & PCIE_UE_STATUS_VALID) {
+		for (i = 0; pciex_ue_err_tbl[i].err_class != NULL; i++) {
+			if (!(pcie_adv_regs->pcie_ue_status &
+			    pciex_ue_err_tbl[i].reg_bit))
+				continue;
+
+			(void) snprintf(buf, FM_MAX_CLASS,
+			    "%s.%s", PCIEX_ERROR_SUBCLASS,
+			    pciex_ue_err_tbl[i].err_class);
+
+			pcie_adv_regs->pcie_adv_bdf = 0;
+			if ((pcie_adv_regs->pcie_ue_status &
+			    PCIE_AER_UCE_LOG_BITS) !=
+			    pciex_ue_err_tbl[i].reg_bit) {
+				PCI_FM_SEV_INC(pciex_ue_err_tbl[i].flags);
+				pcie_ereport_post(dip, derr, erpt_p, buf,
+				    PCIEX_TYPE_UE);
+			} else {
+				pcie_check_addr(dip, derr, erpt_p);
+				/*
+				 * fatal/nonfatal errors are fatal/nonfatal
+				 * regardless of if we find a handle
+				 */
+				if (pciex_ue_err_tbl[i].flags == DDI_FM_FATAL)
+					derr->fme_status = DDI_FM_FATAL;
+				else if (pciex_ue_err_tbl[i].flags ==
+				    DDI_FM_NONFATAL)
+					derr->fme_status = DDI_FM_NONFATAL;
+				pcie_ereport_post(dip, derr, erpt_p, buf,
+				    PCIEX_TYPE_UE);
+				PCI_FM_SEV_INC(derr->fme_status);
+			}
+		}
+	}
+
+	/*
+	 * Log PCI Express correctable errors
+	 */
+	if (pcie_adv_regs->pcie_adv_vflags & PCIE_CE_STATUS_VALID) {
+		for (i = 0; pciex_ce_err_tbl[i].err_class != NULL; i++) {
+			if (!(pcie_adv_regs->pcie_ce_status &
+			    pciex_ce_err_tbl[i].reg_bit))
+				continue;
+
+			(void) snprintf(buf, FM_MAX_CLASS,
+			    "%s.%s", PCIEX_ERROR_SUBCLASS,
+			    pciex_ce_err_tbl[i].err_class);
+			pcie_ereport_post(dip, derr, erpt_p, buf,
+			    PCIEX_TYPE_CE);
+			if (!fatal && !unknown)
+				PCI_FM_SEV_INC(pciex_ce_err_tbl[i].flags);
+		}
+	}
+
+	if (!(erpt_p->pe_dflags & PCI_BRIDGE_DEV))
+		goto done;
+
+	if (erpt_p->pe_dflags & PCIEX_RC_DEV) {
+		int ret = pcie_rc_error_report(dip, derr, erpt_p,
+		    (void *)pcie_adv_regs);
+		PCI_FM_SEV_INC(ret);
+	}
+
+	if (!((erpt_p->pe_dflags & PCIEX_2PCI_DEV) &&
+	    (pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_STATUS_VALID)))
+		goto done;
+
+	pcie_bdg_regs = pcie_adv_regs->pcie_adv_bdg_regs;
+
+	for (i = 0; pcie_sue_err_tbl[i].err_class != NULL; i++) {
+		if ((pcie_bdg_regs->pcie_sue_status &
+		    pcie_sue_err_tbl[i].reg_bit)) {
+			(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+			    PCIEX_ERROR_SUBCLASS,
+			    pcie_sue_err_tbl[i].err_class);
+
+			if ((pcie_bdg_regs->pcie_sue_status &
+			    PCIE_AER_SUCE_LOG_BITS) !=
+			    pcie_sue_err_tbl[i].reg_bit) {
+				PCI_FM_SEV_INC(pcie_sue_err_tbl[i].flags);
+				ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+				    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+				    PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_status,
+#ifdef DEBUG
+				    PCIEX_SUE_HDR0, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_hdr0,
+				    PCIEX_SUE_HDR1, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_hdr[0],
+				    PCIEX_SUE_HDR2, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_hdr[1],
+				    PCIEX_SUE_HDR3, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_hdr[2],
+#endif
+				    NULL);
+			} else {
+				pcie_adv_regs->pcie_adv_bdf = 0;
+				pcie_pci_check_addr(dip, derr, erpt_p);
+				/*
+				 * fatal/nonfatal errors are fatal/nonfatal
+				 * regardless of if we find a handle
+				 */
+				if (pcie_sue_err_tbl[i].flags == DDI_FM_FATAL)
+					derr->fme_status = DDI_FM_FATAL;
+				else if (pcie_sue_err_tbl[i].flags ==
+				    DDI_FM_NONFATAL)
+					derr->fme_status = DDI_FM_NONFATAL;
+
+				ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+				    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+				    PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_status,
+				    PCIEX_SRC_ID, DATA_TYPE_UINT16,
+				    pcie_adv_regs->pcie_adv_bdf,
+				    PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE,
+				    (pcie_adv_regs->pcie_adv_bdf != NULL) ?
+				    1 : NULL,
+#ifdef DEBUG
+				    PCIEX_SUE_HDR0, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_hdr0,
+				    PCIEX_SUE_HDR1, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_hdr[0],
+				    PCIEX_SUE_HDR2, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_hdr[1],
+				    PCIEX_SUE_HDR3, DATA_TYPE_UINT32,
+				    pcie_bdg_regs->pcie_sue_hdr[2],
+#endif
+				    NULL);
+				PCI_FM_SEV_INC(derr->fme_status);
+			}
+		}
+	}
+done:
+	return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
+	    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
+}
+
+static void
+pci_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
+{
+	int fatal = 0;
+	int nonfatal = 0;
+	int unknown = 0;
+	int ok = 0;
+	char buf[FM_MAX_CLASS];
+	int i;
+
+	if (derr->fme_flag == DDI_FM_ERR_UNEXPECTED) {
+		/*
+		 * Log generic PCI errors.
+		 */
+		for (i = 0; pci_err_tbl[i].err_class != NULL; i++) {
+			if (!(erpt_p->pe_pci_regs->pci_err_status &
+			    pci_err_tbl[i].reg_bit) ||
+			    !(erpt_p->pe_pci_regs->pci_vflags &
+			    PCI_ERR_STATUS_VALID))
+				continue;
+			/*
+			 * Generate an ereport for this error bit.
+			 */
+			(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+			    PCI_ERROR_SUBCLASS, pci_err_tbl[i].err_class);
+			ddi_fm_ereport_post(dip, buf, derr->fme_ena,
+			    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
+			    PCI_CONFIG_STATUS, DATA_TYPE_UINT16,
+			    erpt_p->pe_pci_regs->pci_err_status,
+			    PCI_CONFIG_COMMAND, DATA_TYPE_UINT16,
+			    erpt_p->pe_pci_regs->pci_cfg_comm, NULL);
+
+			if (!(erpt_p->pe_dflags & PCIEX_DEV))
+				PCI_FM_SEV_INC(pci_err_tbl[i].flags);
+		}
+		if (erpt_p->pe_dflags & PCIEX_DEV) {
+			int ret = pcie_error_report(dip, derr, erpt_p);
+			PCI_FM_SEV_INC(ret);
+		} else if (erpt_p->pe_dflags & PCIX_DEV) {
+			if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
+				int ret = pcix_bdg_error_report(dip, derr,
+				    erpt_p, erpt_p->pe_regs);
+				PCI_FM_SEV_INC(ret);
+			} else {
+				int ret = pcix_error_report(dip, derr, erpt_p);
+				PCI_FM_SEV_INC(ret);
+			}
+		}
+	}
+
+	if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV)) {
+		int ret = pci_bdg_error_report(dip, derr, erpt_p);
+		PCI_FM_SEV_INC(ret);
+	}
+
+	derr->fme_status = (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
+	    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
+}
+
+void
+pci_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, uint16_t *xx_status)
+{
+	struct i_ddi_fmhdl *fmhdl;
+	pci_erpt_t *erpt_p;
+
+	fmhdl = DEVI(dip)->devi_fmhdl;
+	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip)) &&
+	    !DDI_FM_ERRCB_CAP(ddi_fm_capable(dip))) {
+		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_NOSLEEP);
+		return;
+	}
+
+	ASSERT(fmhdl);
+
+	if (derr->fme_ena == NULL)
+		derr->fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
+
+	erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific;
+	if (erpt_p == NULL) {
+		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_NOSLEEP);
+		return;
+	}
+
+	pci_regs_gather(dip, erpt_p);
+	pci_error_report(dip, derr, erpt_p);
+	pci_regs_clear(erpt_p);
+
+	if (xx_status != NULL)
+		*xx_status = erpt_p->pe_pci_regs->pci_err_status;
+}
+
+/*
+ * private version of walk_devs() that can be used during panic. No
+ * sleeping or locking required.
+ */
+static int
+pci_fm_walk_devs(dev_info_t *dip, int (*f)(dev_info_t *, void *), void *arg)
+{
+	while (dip) {
+		switch ((*f)(dip, arg)) {
+		case DDI_WALK_TERMINATE:
+			return (DDI_WALK_TERMINATE);
+		case DDI_WALK_CONTINUE:
+			if (pci_fm_walk_devs(ddi_get_child(dip), f,
+			    arg) == DDI_WALK_TERMINATE)
+				return (DDI_WALK_TERMINATE);
+			break;
+		case DDI_WALK_PRUNECHILD:
+			break;
+		}
+		dip = ddi_get_next_sibling(dip);
+	}
+	return (DDI_WALK_CONTINUE);
+}
+
+/*
+ * need special version of ddi_fm_ereport_post() as the leaf driver may
+ * not be hardened.
+ */
+static void
+pci_fm_ereport_post(dev_info_t *dip, const char *error_class, uint64_t ena,
+    uint8_t version, ...)
+{
+	char *name;
+	char device_path[MAXPATHLEN];
+	char ddi_error_class[FM_MAX_CLASS];
+	nvlist_t *ereport, *detector;
+	nv_alloc_t *nva;
+	errorq_elem_t *eqep;
+	va_list ap;
+
+	if (panicstr) {
+		eqep = errorq_reserve(ereport_errorq);
+		if (eqep == NULL)
+			return;
+		ereport = errorq_elem_nvl(ereport_errorq, eqep);
+		nva = errorq_elem_nva(ereport_errorq, eqep);
+		detector = fm_nvlist_create(nva);
+	} else {
+		ereport = fm_nvlist_create(NULL);
+		detector = fm_nvlist_create(NULL);
+	}
+
+	(void) ddi_pathname(dip, device_path);
+	fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL,
+	    device_path, NULL);
+	(void) snprintf(ddi_error_class, FM_MAX_CLASS, "%s.%s",
+	    DDI_IO_CLASS, error_class);
+	fm_ereport_set(ereport, version, ddi_error_class, ena, detector, NULL);
+
+	va_start(ap, version);
+	name = va_arg(ap, char *);
+	(void) i_fm_payload_set(ereport, name, ap);
+	va_end(ap);
+
+	if (panicstr) {
+		errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC);
+	} else {
+		(void) fm_ereport_post(ereport, EVCH_TRYHARD);
+		fm_nvlist_destroy(ereport, FM_NVA_FREE);
+		fm_nvlist_destroy(detector, FM_NVA_FREE);
+	}
+}
+
+static int
+pci_check_regs(dev_info_t *dip, void *arg)
+{
+	int reglen;
+	int rn;
+	int totreg;
+	pci_regspec_t *drv_regp;
+	pci_target_err_t *tgt_err = (pci_target_err_t *)arg;
+
+	if (tgt_err->tgt_pci_space == PCI_REG_ADDR_G(PCI_ADDR_CONFIG)) {
+		/*
+		 * for config space, we need to check if the given address
+		 * is a valid config space address for this device - based
+		 * on pci_phys_hi of the config space entry in reg property.
+		 */
+		if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
+		    "reg", (caddr_t)&drv_regp, &reglen) != DDI_SUCCESS)
+			return (DDI_WALK_CONTINUE);
+
+		totreg = reglen / sizeof (pci_regspec_t);
+		for (rn = 0; rn < totreg; rn++) {
+			if (tgt_err->tgt_pci_space ==
+			    PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi) &&
+			    (tgt_err->tgt_pci_addr & (PCI_REG_BUS_M |
+			    PCI_REG_DEV_M | PCI_REG_FUNC_M)) ==
+			    (drv_regp[rn].pci_phys_hi & (PCI_REG_BUS_M |
+			    PCI_REG_DEV_M | PCI_REG_FUNC_M))) {
+				tgt_err->tgt_dip = dip;
+				kmem_free(drv_regp, reglen);
+				return (DDI_WALK_TERMINATE);
+			}
+		}
+		kmem_free(drv_regp, reglen);
+	} else {
+		/*
+		 * for non config space, need to check reg to look
+		 * for any non-relocable mapping, otherwise check
+		 * assigned-addresses.
+		 */
+		if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
+		    "reg", (caddr_t)&drv_regp, &reglen) != DDI_SUCCESS)
+			return (DDI_WALK_CONTINUE);
+
+		totreg = reglen / sizeof (pci_regspec_t);
+		for (rn = 0; rn < totreg; rn++) {
+			if ((drv_regp[rn].pci_phys_hi & PCI_RELOCAT_B) &&
+			    (tgt_err->tgt_pci_space == TGT_PCI_SPACE_UNKNOWN ||
+			    tgt_err->tgt_pci_space ==
+			    PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi)) &&
+			    (tgt_err->tgt_pci_addr >=
+			    (uint64_t)drv_regp[rn].pci_phys_low +
+			    ((uint64_t)drv_regp[rn].pci_phys_mid << 32)) &&
+			    (tgt_err->tgt_pci_addr <
+			    (uint64_t)drv_regp[rn].pci_phys_low +
+			    ((uint64_t)drv_regp[rn].pci_phys_mid << 32) +
+			    (uint64_t)drv_regp[rn].pci_size_low +
+			    ((uint64_t)drv_regp[rn].pci_size_hi << 32))) {
+				tgt_err->tgt_dip = dip;
+				kmem_free(drv_regp, reglen);
+				return (DDI_WALK_TERMINATE);
+			}
+		}
+		kmem_free(drv_regp, reglen);
+
+		if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
+		    "assigned-addresses", (caddr_t)&drv_regp, &reglen) !=
+		    DDI_SUCCESS)
+			return (DDI_WALK_CONTINUE);
+
+		totreg = reglen / sizeof (pci_regspec_t);
+		for (rn = 0; rn < totreg; rn++) {
+			if ((tgt_err->tgt_pci_space == TGT_PCI_SPACE_UNKNOWN ||
+			    tgt_err->tgt_pci_space ==
+			    PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi)) &&
+			    (tgt_err->tgt_pci_addr >=
+			    (uint64_t)drv_regp[rn].pci_phys_low +
+			    ((uint64_t)drv_regp[rn].pci_phys_mid << 32)) &&
+			    (tgt_err->tgt_pci_addr <
+			    (uint64_t)drv_regp[rn].pci_phys_low +
+			    ((uint64_t)drv_regp[rn].pci_phys_mid << 32) +
+			    (uint64_t)drv_regp[rn].pci_size_low +
+			    ((uint64_t)drv_regp[rn].pci_size_hi << 32))) {
+				tgt_err->tgt_dip = dip;
+				kmem_free(drv_regp, reglen);
+				return (DDI_WALK_TERMINATE);
+			}
+		}
+		kmem_free(drv_regp, reglen);
+	}
+	return (DDI_WALK_CONTINUE);
+}
+
+/*
+ * impl_fix_ranges - fixes the config space entry of the "ranges"
+ * property on psycho+ platforms.  (if changing this function please make sure
+ * to change the pci_fix_ranges function in pcipsy.c)
+ */
+/*ARGSUSED*/
+static void
+pci_fix_ranges(dev_info_t *dip, pci_ranges_t *pci_ranges, int nrange)
+{
+#if defined(__sparc)
+	char *name = ddi_binding_name(dip);
+
+	if ((strcmp(name, "pci108e,8000") == 0) ||
+	    (strcmp(name, "pci108e,a000") == 0) ||
+	    (strcmp(name, "pci108e,a001") == 0)) {
+		int i;
+		for (i = 0; i < nrange; i++, pci_ranges++)
+			if ((pci_ranges->child_high & PCI_REG_ADDR_M) ==
+			    PCI_ADDR_CONFIG)
+				pci_ranges->parent_low |=
+				    pci_ranges->child_high;
+	}
+#endif
+}
+
+static int
+pci_check_ranges(dev_info_t *dip, void *arg)
+{
+	uint64_t range_parent_begin;
+	uint64_t range_parent_size;
+	uint64_t range_parent_end;
+	uint32_t space_type;
+	uint32_t bus_num;
+	uint32_t range_offset;
+	pci_ranges_t *pci_ranges, *rangep;
+	pci_bus_range_t *pci_bus_rangep;
+	int pci_ranges_length;
+	int nrange;
+	pci_target_err_t *tgt_err = (pci_target_err_t *)arg;
+	int i, size;
+	if (strcmp(ddi_node_name(dip), "pci") != 0 &&
+	    strcmp(ddi_node_name(dip), "pciex") != 0)
+		return (DDI_WALK_CONTINUE);
+
+	/*
+	 * Get the ranges property. Note we only look at the top level pci
+	 * node (hostbridge) which has a ranges property of type pci_ranges_t
+	 * not at pci-pci bridges.
+	 */
+	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "ranges",
+	    (caddr_t)&pci_ranges, &pci_ranges_length) != DDI_SUCCESS) {
+		/*
+		 * no ranges property - no translation needed
+		 */
+		tgt_err->tgt_pci_addr = tgt_err->tgt_err_addr;
+		tgt_err->tgt_pci_space = TGT_PCI_SPACE_UNKNOWN;
+		if (panicstr)
+			(void) pci_fm_walk_devs(ddi_get_child(dip),
+			    pci_check_regs, (void *)tgt_err);
+		else {
+			int circ = 0;
+			ndi_devi_enter(dip, &circ);
+			ddi_walk_devs(ddi_get_child(dip), pci_check_regs,
+			    (void *)tgt_err);
+			ndi_devi_exit(dip, circ);
+		}
+		if (tgt_err->tgt_dip != NULL)
+			return (DDI_WALK_TERMINATE);
+		return (DDI_WALK_PRUNECHILD);
+	}
+	nrange = pci_ranges_length / sizeof (pci_ranges_t);
+	rangep = pci_ranges;
+
+	/* Need to fix the pci ranges property for psycho based systems */
+	pci_fix_ranges(dip, pci_ranges, nrange);
+
+	for (i = 0; i < nrange; i++, rangep++) {
+		range_parent_begin = ((uint64_t)rangep->parent_high << 32) +
+		    rangep->parent_low;
+		range_parent_size = ((uint64_t)rangep->size_high << 32) +
+		    rangep->size_low;
+		range_parent_end = range_parent_begin + range_parent_size - 1;
+
+		if ((tgt_err->tgt_err_addr < range_parent_begin) ||
+		    (tgt_err->tgt_err_addr > range_parent_end)) {
+			/* Not in range */
+			continue;
+		}
+		space_type = PCI_REG_ADDR_G(rangep->child_high);
+		if (space_type == PCI_REG_ADDR_G(PCI_ADDR_CONFIG)) {
+			/* Config space address - check bus range */
+			range_offset = tgt_err->tgt_err_addr -
+			    range_parent_begin;
+			bus_num = PCI_REG_BUS_G(range_offset);
+			if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
+			    DDI_PROP_DONTPASS, "bus-range",
+			    (caddr_t)&pci_bus_rangep, &size) != DDI_SUCCESS) {
+				continue;
+			}
+			if ((bus_num < pci_bus_rangep->lo) ||
+			    (bus_num > pci_bus_rangep->hi)) {
+				/*
+				 * Bus number not appropriate for this
+				 * pci nexus.
+				 */
+				kmem_free(pci_bus_rangep, size);
+				continue;
+			}
+			kmem_free(pci_bus_rangep, size);
+		}
+
+		/* We have a match if we get here - compute pci address */
+		tgt_err->tgt_pci_addr = tgt_err->tgt_err_addr -
+		    range_parent_begin;
+		tgt_err->tgt_pci_addr += (((uint64_t)rangep->child_mid << 32) +
+		    rangep->child_low);
+		tgt_err->tgt_pci_space = space_type;
+		if (panicstr)
+			(void) pci_fm_walk_devs(ddi_get_child(dip),
+			    pci_check_regs, (void *)tgt_err);
+		else {
+			int circ = 0;
+			ndi_devi_enter(dip, &circ);
+			ddi_walk_devs(ddi_get_child(dip), pci_check_regs,
+			    (void *)tgt_err);
+			ndi_devi_exit(dip, circ);
+		}
+		if (tgt_err->tgt_dip != NULL) {
+			kmem_free(pci_ranges, pci_ranges_length);
+			return (DDI_WALK_TERMINATE);
+		}
+	}
+	kmem_free(pci_ranges, pci_ranges_length);
+	return (DDI_WALK_PRUNECHILD);
+}
+
+/*
+ * Function used to drain pci_target_queue, either during panic or after softint
+ * is generated, to generate target device ereports based on captured physical
+ * addresses
+ */
+/*ARGSUSED*/
+static void
+pci_target_drain(void *private_p, pci_target_err_t *tgt_err)
+{
+	char buf[FM_MAX_CLASS];
+
+	/*
+	 * The following assumes that all pci_pci bridge devices
+	 * are configured as transparant. Find the top-level pci
+	 * nexus which has tgt_err_addr in one of its ranges, converting this
+	 * to a pci address in the process. Then starting at this node do
+	 * another tree walk to find a device with the pci address we've
+	 * found within range of one of it's assigned-addresses properties.
+	 */
+	tgt_err->tgt_dip = NULL;
+	if (panicstr)
+		(void) pci_fm_walk_devs(ddi_root_node(), pci_check_ranges,
+		    (void *)tgt_err);
+	else
+		ddi_walk_devs(ddi_root_node(), pci_check_ranges,
+		    (void *)tgt_err);
+	if (tgt_err->tgt_dip == NULL)
+		return;
+
+	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", tgt_err->tgt_bridge_type,
+	    tgt_err->tgt_err_class);
+	pci_fm_ereport_post(tgt_err->tgt_dip, buf, tgt_err->tgt_err_ena, 0,
+	    PCI_PA, DATA_TYPE_UINT64, tgt_err->tgt_err_addr, NULL);
+}
+
+void
+pci_target_enqueue(uint64_t ena, char *class, char *bridge_type, uint64_t addr)
+{
+	pci_target_err_t tgt_err;
+
+	tgt_err.tgt_err_ena = ena;
+	tgt_err.tgt_err_class = class;
+	tgt_err.tgt_bridge_type = bridge_type;
+	tgt_err.tgt_err_addr = addr;
+	errorq_dispatch(pci_target_queue, (void *)&tgt_err,
+	    sizeof (pci_target_err_t), ERRORQ_ASYNC);
+}
+
+void
+pci_targetq_init(void)
+{
+	/*
+	 * PCI target errorq, to schedule async handling of generation of
+	 * target device ereports based on captured physical address.
+	 * The errorq is created here but destroyed when _fini is called
+	 * for the pci module.
+	 */
+	if (pci_target_queue == NULL) {
+		pci_target_queue = errorq_create("pci_target_queue",
+		    (errorq_func_t)pci_target_drain, (void *)NULL,
+		    TARGET_MAX_ERRS, sizeof (pci_target_err_t), FM_ERR_PIL,
+		    ERRORQ_VITAL);
+		if (pci_target_queue == NULL)
+			panic("failed to create required system error queue");
+	}
+}
--- a/usr/src/uts/common/os/sunpci.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/os/sunpci.c	Sun Apr 23 15:26:28 2006 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -28,17 +28,12 @@
 
 #include <sys/types.h>
 #include <sys/sunndi.h>
-#include <sys/ddifm_impl.h>
-#include <sys/fm/util.h>
-#include <sys/fm/protocol.h>
-#include <sys/fm/io/pci.h>
-#include <sys/fm/io/ddi.h>
+#include <sys/sysmacros.h>
 #include <sys/pci.h>
 #include <sys/pcie.h>
 #include <sys/pci_impl.h>
 #include <sys/epm.h>
 
-
 int
 pci_config_setup(dev_info_t *dip, ddi_acc_handle_t *handle)
 {
@@ -50,8 +45,10 @@
 	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
 
 	/* Check for fault management capabilities */
-	if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(dip)))
+	if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(dip))) {
+		attr.devacc_attr_version = DDI_DEVICE_ATTR_V1;
 		attr.devacc_attr_access = DDI_FLAGERR_ACC;
+	}
 
 	return (ddi_regs_map_setup(dip, 0, &cfgaddr, 0, 0, &attr, handle));
 }
@@ -62,404 +59,6 @@
 	ddi_regs_map_free(handle);
 }
 
-/*
- * pci_ereport_setup, pci_ereport_teardown, pci_ereport_post:
- * Interfaces to be used by ereport capable PCI device drivers to setup,
- * teardown, and post generic PCI error reports. This is to guarantee a
- * consistant error report model for all PCI devices. Please see
- * PSARC/2004/391.
- */
-
-typedef struct pci_erpt {
-	caddr_t pci_cfg_addr;		/* Config space address */
-	ddi_acc_handle_t pci_cfg_hdl;	/* Config space access handle */
-} pci_erpt_t;
-
-pci_fm_err_t pci_err_tbl[] = {
-	PCI_DET_PERR,	PCI_STAT_PERROR,	NULL,
-	PCI_MDPE,	PCI_STAT_S_PERROR,	PCI_TARG_MDPE,
-	PCI_SIG_SERR,	PCI_STAT_S_SYSERR,	NULL,
-	PCI_MA,		PCI_STAT_R_MAST_AB,	PCI_TARG_MA,
-	PCI_REC_TA,	PCI_STAT_R_TARG_AB,	PCI_TARG_REC_TA,
-	PCI_SIG_TA,	PCI_STAT_S_TARG_AB,	NULL,
-	NULL, NULL,
-};
-
-pci_fm_err_t pci_bdg_err_tbl[] = {
-	PCI_DET_PERR,	PCI_STAT_PERROR,	NULL,
-	PCI_MDPE,	PCI_STAT_S_PERROR,	NULL,
-	PCI_REC_SERR,	PCI_STAT_S_SYSERR,	NULL,
-	PCI_MA,		PCI_STAT_R_MAST_AB,	NULL,
-	PCI_REC_TA,	PCI_STAT_R_TARG_AB,	NULL,
-	PCI_SIG_TA,	PCI_STAT_S_TARG_AB,	NULL,
-	NULL, NULL,
-};
-
-void
-pci_ereport_setup(dev_info_t *dip)
-{
-	struct dev_info *devi = DEVI(dip);
-	struct i_ddi_fmhdl *fmhdl = devi->devi_fmhdl;
-	pci_erpt_t *erpt_p;
-	ddi_acc_hdl_t *hp;
-	uint16_t pci_devstat = 0;
-	uint16_t pcie_cap = 0;
-	uint8_t ecap_ptr = 0;
-	uint8_t cap_ptr = 0;
-	uint8_t cap_id = 0;
-	int have_pciex;
-
-	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip))) {
-		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_SLEEP);
-		return;
-	}
-
-	ASSERT(fmhdl);
-	ASSERT(fmhdl->fh_bus_specific == NULL);
-
-	if ((erpt_p = kmem_zalloc(sizeof (pci_erpt_t), KM_SLEEP)) == NULL)
-		return;
-
-	/*
-	 * Setup config space and store config address
-	 * in pci_erpt struct.
-	 */
-	if (pci_config_setup(dip, &erpt_p->pci_cfg_hdl) == DDI_SUCCESS) {
-		hp = impl_acc_hdl_get(erpt_p->pci_cfg_hdl);
-		erpt_p->pci_cfg_addr = (caddr_t)hp->ah_addr;
-		fmhdl->fh_bus_specific = (void *)erpt_p;
-	} else {
-		return;
-	}
-
-	/*
-	 * Determine if this device supports a capabilities list.  We
-	 * do so by looking at a bit in the status register. If we are
-	 * unable to retrieve the status register, something is horribly
-	 * wrong and we should just bail.
-	 */
-	if ((pci_devstat = ddi_get16(erpt_p->pci_cfg_hdl,
-	    (uint16_t *)(erpt_p->pci_cfg_addr + PCI_CONF_STAT))) == 0xff)
-		return;
-	if ((pci_devstat & PCI_STAT_CAP) == 0)
-		return;
-
-	/*
-	 * Determine if we are on a machine with pci express.  We do so
-	 * by looping through the capabilities of the device and looking
-	 * to see if one of those capabilities is support of PCI
-	 * express.
-	 */
-	have_pciex = 0;
-	if ((cap_ptr = ddi_get8(erpt_p->pci_cfg_hdl,
-	    (uint8_t *)(erpt_p->pci_cfg_addr + PCI_CONF_CAP_PTR))) !=
-	    0xff) {
-		while ((cap_id = ddi_get8(erpt_p->pci_cfg_hdl,
-		    (uint8_t *)(erpt_p->pci_cfg_addr + cap_ptr))) !=
-		    0xff) {
-			if (cap_id == PCI_CAP_ID_PCI_E) {
-				ecap_ptr = cap_ptr;
-				have_pciex = 1;
-				break;
-			}
-			if ((cap_ptr = ddi_get8(erpt_p->pci_cfg_hdl,
-			    (uint8_t *)(erpt_p->pci_cfg_addr +
-			    cap_ptr + 1))) == 0xff || cap_ptr == 0)
-				break;
-		}
-	}
-
-	/*
-	 * If not pci express, we're done
-	 */
-	if (have_pciex == 0)
-		return;
-
-	/*
-	 * Save and export the pci express capabilities reg.
-	 */
-	pcie_cap = ddi_get16(erpt_p->pci_cfg_hdl,
-	    (uint16_t *)(erpt_p->pci_cfg_addr + ecap_ptr + PCIE_PCIECAP));
-	(void) ndi_prop_update_int(DDI_DEV_T_NONE,
-	    dip, SAVED_PCIEX_CAP_REG, pcie_cap);
-
-	/*
-	 * Find and export any slot capabilities register
-	 */
-	if (pcie_cap & PCIE_PCIECAP_SLOT_IMPL) {
-		int sltcap = ddi_get32(erpt_p->pci_cfg_hdl,
-		    (uint32_t *)
-		    (erpt_p->pci_cfg_addr + ecap_ptr + PCIE_SLOTCAP));
-		(void) ndi_prop_update_int(DDI_DEV_T_NONE,
-		    dip, SAVED_PCIEX_SLOTCAP_REG, sltcap);
-	}
-}
-
-void
-pci_ereport_teardown(dev_info_t *dip)
-{
-	struct i_ddi_fmhdl *fmhdl = DEVI(dip)->devi_fmhdl;
-	pci_erpt_t *erpt_p;
-
-	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip))) {
-		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_SLEEP);
-	}
-
-	ASSERT(fmhdl);
-
-	erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific;
-	if (erpt_p == NULL)
-		return;
-
-	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, SAVED_PCIEX_CAP_REG);
-	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, SAVED_PCIEX_SLOTCAP_REG);
-	pci_config_teardown(&erpt_p->pci_cfg_hdl);
-	kmem_free(erpt_p, sizeof (pci_erpt_t));
-	fmhdl->fh_bus_specific = NULL;
-}
-
-void
-pci_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, uint16_t *status)
-{
-	struct i_ddi_fmhdl *fmhdl;
-	pci_erpt_t *erpt_p;
-	char buf[FM_MAX_CLASS];
-	uint16_t cfg_comm = 0xffff;
-	uint16_t cfg_stat = 0xffff;
-	int i;
-	fmhdl = DEVI(dip)->devi_fmhdl;
-
-	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip))) {
-		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_NOSLEEP);
-		return;
-	}
-
-	ASSERT(fmhdl);
-
-	derr->fme_ena = derr->fme_ena ? derr->fme_ena : fm_ena_generate(0,
-	    FM_ENA_FMT1);
-
-	erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific;
-	if (erpt_p == NULL) {
-		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_NOSLEEP);
-		return;
-	}
-
-	if ((cfg_stat = ddi_get16(erpt_p->pci_cfg_hdl,
-	    (uint16_t *)(erpt_p->pci_cfg_addr + PCI_CONF_STAT))) == 0xffff) {
-		(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
-		    PCI_ERROR_SUBCLASS, PCI_NR);
-		ddi_fm_ereport_post(dip, buf, derr->fme_ena, DDI_NOSLEEP,
-		    FM_VERSION, DATA_TYPE_UINT8, 0, NULL);
-		goto done;
-	}
-	if ((cfg_comm = ddi_get16(erpt_p->pci_cfg_hdl,
-	    (uint16_t *)(erpt_p->pci_cfg_addr + PCI_CONF_COMM))) == 0xffff) {
-		(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
-		    PCI_ERROR_SUBCLASS, PCI_NR);
-		ddi_fm_ereport_post(dip, buf, derr->fme_ena, DDI_NOSLEEP,
-		    FM_VERSION, DATA_TYPE_UINT8, 0, NULL);
-		goto done;
-	}
-
-	if (derr->fme_flag == DDI_FM_ERR_UNEXPECTED) {
-		for (i = 0; pci_err_tbl[i].err_class != NULL; i++) {
-			if (cfg_stat & pci_err_tbl[i].reg_bit) {
-
-				/*
-				 * Generate an ereport for this error bit.
-				 */
-				(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
-				    PCI_ERROR_SUBCLASS,
-				    pci_err_tbl[i].err_class);
-				ddi_fm_ereport_post(dip, buf, derr->fme_ena,
-				    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
-				    PCI_CONFIG_STATUS, DATA_TYPE_UINT16,
-				    cfg_stat, PCI_CONFIG_COMMAND,
-				    DATA_TYPE_UINT16, cfg_comm, NULL);
-
-				/*
-				 * Generate a corresponding ereport on behalf
-				 * of the target (the parent dip) of the
-				 * transaction.
-				 */
-				if (pci_err_tbl[i].terr_class != NULL &&
-				    DDI_FM_EREPORT_CAP(ddi_fm_capable(
-				    (dev_info_t *)DEVI(dip)->devi_parent))) {
-					(void) snprintf(buf, FM_MAX_CLASS,
-					    "%s.%s", PCI_ERROR_SUBCLASS,
-					    pci_err_tbl[i].terr_class);
-					ddi_fm_ereport_post((dev_info_t *)
-					    DEVI(dip)->devi_parent, buf,
-					    derr->fme_ena, DDI_NOSLEEP,
-					    FM_VERSION, DATA_TYPE_UINT8, 0,
-					    NULL);
-				}
-			}
-		}
-	}
-
-	/*
-	 * Clear error bits
-	 */
-	ddi_put16(erpt_p->pci_cfg_hdl,
-	    (uint16_t *)(erpt_p->pci_cfg_addr + PCI_CONF_STAT),
-	    (uint16_t)cfg_stat);
-done:
-	if (status != NULL)
-		*status = cfg_stat;
-}
-
-/*
- * Generic pci-pci bridge error report function
- */
-void
-pci_bdg_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, uint16_t *status)
-{
-	struct i_ddi_fmhdl *fmhdl;
-	pci_erpt_t *erpt_p;
-	char buf[FM_MAX_CLASS];
-	uint16_t bdg_ctrl = 0xffff;
-	uint16_t cfg_sec_stat = 0xffff;
-	int i;
-
-	if (!DDI_FM_EREPORT_CAP(ddi_fm_capable(dip))) {
-		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_NOSLEEP);
-		return;
-	}
-
-	fmhdl = DEVI(dip)->devi_fmhdl;
-
-	ASSERT(fmhdl);
-
-	derr->fme_ena = derr->fme_ena ? derr->fme_ena : fm_ena_generate(0,
-	    FM_ENA_FMT1);
-
-	erpt_p = (pci_erpt_t *)fmhdl->fh_bus_specific;
-	if (erpt_p == NULL) {
-		i_ddi_drv_ereport_post(dip, DVR_EFMCAP, NULL, DDI_NOSLEEP);
-		return;
-	}
-
-	if ((cfg_sec_stat = ddi_get16(erpt_p->pci_cfg_hdl,
-	    (uint16_t *)(erpt_p->pci_cfg_addr + PCI_BCNF_SEC_STATUS)))
-	    == 0xffff) {
-		(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", PCI_ERROR_SUBCLASS,
-		    PCI_NR);
-		ddi_fm_ereport_post(dip, buf, derr->fme_ena, DDI_NOSLEEP,
-		    FM_VERSION, DATA_TYPE_UINT8, 0, NULL);
-		goto done;
-	}
-
-	if ((bdg_ctrl = ddi_get16(erpt_p->pci_cfg_hdl,
-	    (uint16_t *)(erpt_p->pci_cfg_addr + PCI_BCNF_BCNTRL))) == 0xffff) {
-		(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", PCI_ERROR_SUBCLASS,
-		    PCI_NR);
-		ddi_fm_ereport_post(dip, buf, derr->fme_ena, DDI_NOSLEEP,
-		    FM_VERSION, DATA_TYPE_UINT8, 0, NULL);
-		goto done;
-	}
-
-	if (derr->fme_flag == DDI_FM_ERR_UNEXPECTED) {
-		if (bdg_ctrl & PCI_BCNF_BCNTRL_DTO_STAT) {
-			(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
-			    PCI_ERROR_SUBCLASS, PCI_DTO);
-			ddi_fm_ereport_post(dip, buf, derr->fme_ena,
-			    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
-			    PCI_SEC_CONFIG_STATUS, DATA_TYPE_UINT16,
-			    cfg_sec_stat, PCI_BCNTRL, DATA_TYPE_UINT16,
-			    bdg_ctrl, NULL);
-		}
-
-		for (i = 0; pci_bdg_err_tbl[i].err_class != NULL; i++) {
-			if (cfg_sec_stat & pci_bdg_err_tbl[i].reg_bit) {
-				(void) snprintf(buf, FM_MAX_CLASS, "%s.%s-%s",
-				    PCI_ERROR_SUBCLASS, PCI_SEC_ERROR_SUBCLASS,
-				    pci_bdg_err_tbl[i].err_class);
-				ddi_fm_ereport_post(dip, buf, derr->fme_ena,
-				    DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
-				    PCI_SEC_CONFIG_STATUS, DATA_TYPE_UINT16,
-				    cfg_sec_stat, PCI_BCNTRL, DATA_TYPE_UINT16,
-				    bdg_ctrl, NULL);
-			}
-		}
-	}
-
-	/*
-	 * Clear error bits
-	 */
-	ddi_put16(erpt_p->pci_cfg_hdl, (uint16_t *)
-	    (erpt_p->pci_cfg_addr + PCI_BCNF_SEC_STATUS),
-	    (uint16_t)cfg_sec_stat);
-	ddi_put16(erpt_p->pci_cfg_hdl, (uint16_t *)
-	    (erpt_p->pci_cfg_addr + PCI_BCNF_BCNTRL),
-	    (uint16_t)bdg_ctrl);
-
-done:
-	if (status != NULL)
-		*status = cfg_sec_stat;
-}
-
-/*
- * Generic pci-pci bridge error analysis function
- */
-int
-pci_bdg_check_status(dev_info_t *dip, ddi_fm_error_t *derr,
-    uint16_t pci_cfg_stat, uint16_t pci_cfg_sec_stat)
-{
-	int ret;
-	int fatal = 0;
-	int nonfatal = 0;
-	int unknown = 0;
-
-	if (derr->fme_flag == DDI_FM_ERR_POKE) {
-		/*
-		 * special case for pokes - we only consider master abort
-		 * and target abort as nonfatal. Sserr with no master abort is
-		 * fatal, but master/target abort can come in on separate
-		 * instance, so return unknown and parent will determine if
-		 * nonfatal (if another child returned nonfatal - ie master
-		 * or target abort) or fatal otherwise
-		 */
-		if (pci_cfg_sec_stat & (PCI_STAT_R_TARG_AB |
-		    PCI_STAT_R_MAST_AB))
-			nonfatal++;
-		if (pci_cfg_stat & PCI_STAT_S_SYSERR)
-			unknown++;
-	} else if (derr->fme_flag == DDI_FM_ERR_UNEXPECTED) {
-		/*
-		 * Only sserr on primary bus is considered fatal.
-		 * In all other conditions, the bridge has been able to notify
-		 * the initiator of the error condition, so let the initiator
-		 * (be it the host for PIO or the leaf device for DMA) handle it
-		 */
-		if (pci_cfg_stat & PCI_STAT_S_SYSERR)
-			fatal++;
-		if (pci_cfg_stat & (PCI_STAT_PERROR |
-		    PCI_STAT_R_MAST_AB | PCI_STAT_S_PERROR |
-		    PCI_STAT_R_TARG_AB | PCI_STAT_S_TARG_AB))
-			nonfatal++;
-		if (pci_cfg_sec_stat & (PCI_STAT_R_TARG_AB |
-		    PCI_STAT_S_SYSERR | PCI_STAT_R_MAST_AB | PCI_STAT_S_PERROR |
-		    PCI_STAT_PERROR | PCI_STAT_S_TARG_AB))
-			nonfatal++;
-	}
-
-	/*
-	 * now check children below the bridge
-	 */
-	ret = ndi_fm_handler_dispatch(dip, NULL, derr);
-	if (ret == DDI_FM_FATAL)
-		fatal++;
-	else if (ret == DDI_FM_NONFATAL)
-		nonfatal++;
-	else if (ret == DDI_FM_UNKNOWN)
-		unknown++;
-
-	return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
-	    (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
-}
-
 uint8_t
 pci_config_get8(ddi_acc_handle_t handle, off_t offset)
 {
--- a/usr/src/uts/common/sys/bge_impl2.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/bge_impl2.h	Sun Apr 23 15:26:28 2006 -0700
@@ -67,6 +67,11 @@
 #include <sys/ddi.h>
 #include <sys/sunddi.h>
 
+#include <sys/ddifm.h>
+#include <sys/fm/protocol.h>
+#include <sys/fm/util.h>
+#include <sys/fm/io/ddi.h>
+
 #include <sys/mac.h>
 
 #ifdef __amd64
@@ -600,8 +605,8 @@
  *	check for link status change
  */
 typedef struct {
-	void			(*phys_restart)(struct bge *, boolean_t);
-	void			(*phys_update)(struct bge *);
+	int			(*phys_restart)(struct bge *, boolean_t);
+	int			(*phys_update)(struct bge *);
 	boolean_t		(*phys_check)(struct bge *, boolean_t);
 } phys_ops_t;
 
@@ -754,6 +759,8 @@
 	const phys_ops_t	*physops;
 	char			ifname[8];	/* "bge0" ... "bge999"	*/
 
+	int			fm_capabilities;	/* FMA capabilities */
+
 	/*
 	 * These structures describe the blocks of memory allocated during
 	 * attach().  They remain unchanged thereafter, although the memory
@@ -896,6 +903,8 @@
 	 * Miscellaneous operating variables (not synchronised)
 	 */
 	uint32_t		watchdog;	/* watches for Tx stall	*/
+	boolean_t		bge_intr_running;
+	boolean_t		bge_dma_error;
 	boolean_t		resched_needed;
 	boolean_t		resched_running;
 	uint32_t		factotum_flag;	/* softint pending	*/
@@ -936,6 +945,7 @@
  */
 #define	PROGRESS_CFG		0x0001	/* config space mapped		*/
 #define	PROGRESS_REGS		0x0002	/* registers mapped		*/
+#define	PROGRESS_BUFS		0x0004	/* ring buffers allocated	*/
 #define	PROGRESS_RESCHED	0x0010	/* resched softint registered	*/
 #define	PROGRESS_FACTOTUM	0x0020	/* factotum softint registered	*/
 #define	PROGRESS_HWINT		0x0040	/* h/w interrupt registered	*/
@@ -1157,8 +1167,8 @@
 void bge_reg_clr32(bge_t *bgep, bge_regno_t regno, uint32_t bits);
 void bge_mbx_put(bge_t *bgep, bge_regno_t regno, uint64_t value);
 void bge_chip_cfg_init(bge_t *bgep, chip_id_t *cidp, boolean_t enable_dma);
-void bge_chip_id_init(bge_t *bgep);
-void bge_chip_start(bge_t *bgep, boolean_t reset_phy);
+int bge_chip_id_init(bge_t *bgep);
+int bge_chip_start(bge_t *bgep, boolean_t reset_phy);
 void bge_chip_stop(bge_t *bgep, boolean_t fault);
 #ifdef BGE_IPMI_ASF
 void bge_nic_put32(bge_t *bgep, bge_regno_t addr, uint32_t data);
@@ -1171,11 +1181,11 @@
 void bge_asf_pre_reset_operations(bge_t *bgep, uint32_t mode);
 void bge_asf_post_reset_old_mode(bge_t *bgep, uint32_t mode);
 void bge_asf_post_reset_new_mode(bge_t *bgep, uint32_t mode);
-void bge_chip_reset(bge_t *bgep, boolean_t enable_dma, uint_t asf_mode);
-void bge_chip_sync(bge_t *bgep, boolean_t asf_keeplive);
+int bge_chip_reset(bge_t *bgep, boolean_t enable_dma, uint_t asf_mode);
+int bge_chip_sync(bge_t *bgep, boolean_t asf_keeplive);
 #else
-void bge_chip_reset(bge_t *bgep, boolean_t enable_dma);
-void bge_chip_sync(bge_t *bgep);
+int bge_chip_reset(bge_t *bgep, boolean_t enable_dma);
+int bge_chip_sync(bge_t *bgep);
 #endif
 void bge_chip_blank(void *arg, time_t ticks, uint_t count);
 uint_t bge_chip_factotum(caddr_t arg);
@@ -1206,17 +1216,26 @@
 void bge_notice(bge_t *bgep, const char *fmt, ...);
 void bge_log(bge_t *bgep, const char *fmt, ...);
 void bge_error(bge_t *bgep, const char *fmt, ...);
+void bge_fm_ereport(bge_t *bgep, char *detail);
 extern kmutex_t bge_log_mutex[1];
 extern uint32_t bge_debug;
 
 /* bge_main.c */
-void bge_restart(bge_t *bgep, boolean_t reset_phy);
+int bge_restart(bge_t *bgep, boolean_t reset_phy);
+int bge_check_acc_handle(bge_t *bgep, ddi_acc_handle_t handle);
+int bge_check_dma_handle(bge_t *bgep, ddi_dma_handle_t handle);
+void bge_init_rings(bge_t *bgep);
+void bge_fini_rings(bge_t *bgep);
+int bge_alloc_bufs(bge_t *bgep);
+void bge_free_bufs(bge_t *bgep);
+void bge_intr_enable(bge_t *bgep);
+void bge_intr_disable(bge_t *bgep);
 
 /* bge_phys.c */
-void bge_phys_init(bge_t *bgep);
+int bge_phys_init(bge_t *bgep);
 void bge_phys_reset(bge_t *bgep);
-void bge_phys_idle(bge_t *bgep);
-void bge_phys_update(bge_t *bgep);
+int bge_phys_idle(bge_t *bgep);
+int bge_phys_update(bge_t *bgep);
 boolean_t bge_phys_check(bge_t *bgep);
 
 /* bge_ndd.c */
--- a/usr/src/uts/common/sys/ddi_implfuncs.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/ddi_implfuncs.h	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -165,6 +164,8 @@
 
 /* access error handling support */
 extern void impl_acc_err_init(ddi_acc_hdl_t *);
+extern int impl_dma_check(dev_info_t *, const void *, const void *,
+    const void *);
 extern int i_ddi_ontrap(ddi_acc_handle_t);
 extern void i_ddi_notrap(ddi_acc_handle_t);
 extern int i_ddi_prot_trampoline();
--- a/usr/src/uts/common/sys/ddifm.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/ddifm.h	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -87,6 +86,13 @@
 
 /* ereporting and service changes */
 extern void ddi_fm_ereport_post(dev_info_t *, const char *, uint64_t, int, ...);
+
+/*
+ * After a hardened driver raises an ereport (or after pci_ereport_post() has
+ * raised an ereport for an event which implecated one of a driver's access or
+ * dma handles), the driver should always determine the service impact and
+ * report it.
+ */
 extern void ddi_fm_service_impact(dev_info_t *, int);
 
 /* error handling */
@@ -101,6 +107,8 @@
 /* access and dma handle error protection */
 extern void ddi_fm_dma_err_get(ddi_dma_handle_t, ddi_fm_error_t *, int);
 extern void ddi_fm_acc_err_get(ddi_acc_handle_t, ddi_fm_error_t *, int);
+extern void ddi_fm_dma_err_clear(ddi_dma_handle_t, int);
+extern void ddi_fm_acc_err_clear(ddi_acc_handle_t, int);
 
 #endif /* _KERNEL */
 
--- a/usr/src/uts/common/sys/ddifm_impl.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/ddifm_impl.h	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -97,13 +96,16 @@
 
 typedef struct pci_fm_err {
 	char *err_class;
-	uint16_t reg_bit;
+	uint32_t reg_bit;
 	char *terr_class;
+	int flags;
 } pci_fm_err_t;
 
 extern pci_fm_err_t pci_err_tbl[];
 
 #ifdef _KERNEL
+typedef int (*ddi_fmcompare_t)(dev_info_t *, const void *, const void *,
+    const void *);
 
 /* driver defect error reporting */
 void i_ddi_drv_ereport_post(dev_info_t *, const char *, nvlist_t *, int);
@@ -115,6 +117,8 @@
 /* access and dma handle protection support */
 extern void i_ddi_fm_acc_err_set(ddi_acc_handle_t, uint64_t, int, int);
 extern void i_ddi_fm_dma_err_set(ddi_dma_handle_t, uint64_t, int, int);
+extern ddi_fmcompare_t i_ddi_fm_acc_err_cf_get(ddi_acc_handle_t);
+extern ddi_fmcompare_t i_ddi_fm_dma_err_cf_get(ddi_dma_handle_t);
 
 /* fm busop support */
 extern void i_ndi_busop_access_enter(dev_info_t *, ddi_acc_handle_t);
--- a/usr/src/uts/common/sys/fm/io/ddi.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/fm/io/ddi.h	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -38,6 +37,22 @@
 /* IO-specific FMA ereport class defintions */
 #define	DDI_IO_CLASS			"io"
 
+/* leaf driver detected ereport definitions */
+#define	DDI_FM_DEVICE			"device"
+#define	DDI_FM_DEVICE_INVAL_STATE	"inval_state"
+#define	DDI_FM_DEVICE_NO_RESPONSE	"no_response"
+#define	DDI_FM_DEVICE_STALL		"stall"
+#define	DDI_FM_DEVICE_BADINT_LIMIT	"badint_limit"
+#define	DDI_FM_DEVICE_INTERN_CORR	"intern_corr"
+#define	DDI_FM_DEVICE_INTERN_UNCORR	"intern_uncorr"
+
+/* service impact ereport definitions */
+#define	DDI_FM_SERVICE_IMPACT		"service"
+#define	DDI_FM_SERVICE_LOST		"lost"
+#define	DDI_FM_SERVICE_DEGRADED		"degraded"
+#define	DDI_FM_SERVICE_RESTORED		"restored"
+#define	DDI_FM_SERVICE_UNAFFECTED	"unaffected"
+
 /* Driver defect ereport specifications */
 #define	DVR_ERPT		"ddi."
 #define	DVR_ECONTEXT		"context"	/* Invalid calling context */
--- a/usr/src/uts/common/sys/fm/io/pci.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/fm/io/pci.h	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -57,6 +56,106 @@
 #define	PCI_BCNTRL		"pci-bdg-ctrl"
 #define	PCI_PA			"pci-pa"
 
+/*
+ * PCI-X extensions
+ */
+#define	PCIX_ERROR_SUBCLASS	"pcix"
+#define	PCIX_SEC_ERROR_SUBCLASS "sec-"
+
+/* Common PCI-X ereport classes */
+#define	PCIX_ECC_CE_ADDR	"ecc.ce-addr"
+#define	PCIX_ECC_CE_ATTR	"ecc.ce-attr"
+#define	PCIX_ECC_CE_DATA	"ecc.ce-data"
+#define	PCIX_ECC_UE_ADDR	"ecc.ue-addr"
+#define	PCIX_ECC_UE_ATTR	"ecc.ue-attr"
+#define	PCIX_ECC_UE_DATA	"ecc.ue-data"
+#define	PCIX_RX_SPL_MSG		"rx-spl"
+#define	PCIX_ECC_S_CE		"s-ce"
+#define	PCIX_ECC_S_UE		"s-ue"
+#define	PCIX_SPL_DIS		"spl-dis"
+#define	PCIX_BSS_SPL_DLY	"spl-dly"
+#define	PCIX_BSS_SPL_OR		"spl-or"
+#define	PCIX_UNEX_SPL		"unex-spl"
+
+#define	PCIX_SEC_STATUS		"pcix-sec-status"
+#define	PCIX_BDG_STAT		"pcix-bdg-stat"
+#define	PCIX_COMMAND		"pcix-command"
+#define	PCIX_STATUS		"pcix-status"
+#define	PCIX_ECC_CTLSTAT	"pcix-ecc-ctlstat"
+#define	PCIX_ECC_ATTR		"pcix-ecc-attr"
+
+/*
+ * PCI Express extensions
+ */
+#define	PCIEX_ERROR_SUBCLASS		"pciex"
+
+/* Common PCI Express ereport classes */
+#define	PCIEX_RE		"pl.re"
+#define	PCIEX_TE		"pl.te"
+
+#define	PCIEX_SD		"dl.sd"
+#define	PCIEX_BDP		"dl.bdllp"
+#define	PCIEX_BTP		"dl.btlp"
+#define	PCIEX_DLP		"dl.dllp"
+#define	PCIEX_RNR		"dl.rnr"
+#define	PCIEX_RTO		"dl.rto"
+
+#define	PCIEX_CA		"tl.ca"
+#define	PCIEX_CTO		"tl.cto"
+#define	PCIEX_ECRC		"tl.ecrc"
+#define	PCIEX_FCP		"tl.fcp"
+#define	PCIEX_MFP		"tl.mtlp"
+#define	PCIEX_POIS		"tl.ptlp"
+#define	PCIEX_ROF		"tl.rof"
+#define	PCIEX_UC		"tl.uc"
+#define	PCIEX_UR		"tl.ur"
+
+#define	PCIEX_INTERR		"bdg.sec-interr"
+#define	PCIEX_S_MA_SC		"bdg.sec-ma-sc"
+#define	PCIEX_S_PERR		"bdg.sec-perr"
+#define	PCIEX_S_RMA		"bdg.sec-rma"
+#define	PCIEX_S_RTA		"bdg.sec-rta"
+#define	PCIEX_S_SERR		"bdg.sec-serr"
+#define	PCIEX_S_TA_SC		"bdg.sec-ta-sc"
+#define	PCIEX_S_TEX		"bdg.sec-tex"
+#define	PCIEX_S_UADR		"bdg.sec-uadr"
+#define	PCIEX_S_UAT		"bdg.sec-uat"
+#define	PCIEX_S_UDE		"bdg.sec-ude"
+#define	PCIEX_S_USC		"bdg.usc"
+#define	PCIEX_S_USCMD		"bdg.uscmd"
+
+#define	PCIEX_RC_FE_MSG		"rc.fe-msg"
+#define	PCIEX_RC_NFE_MSG	"rc.nfe-msg"
+#define	PCIEX_RC_CE_MSG		"rc.ce-msg"
+#define	PCIEX_RC_MCE_MSG	"rc.mce-msg"
+#define	PCIEX_RC_MUE_MSG	"rc.mue-msg"
+
+#define	PCIEX_CORR		"correctable"
+#define	PCIEX_FAT		"fatal"
+#define	PCIEX_NONFAT		"nonfatal"
+#define	PCIEX_NADV		"noadverr"
+#define	PCIEX_ANFE		"a-nonfatal"
+
+/* PCI Express payload name fields */
+#define	PCIEX_DEVSTS_REG	"dev-status"
+#define	PCIEX_LINKSTS_REG	"link-status"
+#define	PCIEX_ROOT_ERRSTS_REG	"rc-status"
+#define	PCIEX_CE_STATUS_REG	"ce-status"
+#define	PCIEX_UE_STATUS_REG	"ue-status"
+#define	PCIEX_UE_SEV_REG	"ue-severity"
+#define	PCIEX_SEC_UE_STATUS	"sue-status"
+#define	PCIEX_SRC_ID		"source-id"
+#define	PCIEX_SRC_VALID		"source-valid"
+#define	PCIEX_ADV_CTL		"adv-ctl"
+#define	PCIEX_UE_HDR0		"ue_hdr0"
+#define	PCIEX_UE_HDR1		"ue_hdr1"
+#define	PCIEX_UE_HDR2		"ue_hdr2"
+#define	PCIEX_UE_HDR3		"ue_hdr3"
+#define	PCIEX_SUE_HDR0		"sue_hdr0"
+#define	PCIEX_SUE_HDR1		"sue_hdr1"
+#define	PCIEX_SUE_HDR2		"sue_hdr2"
+#define	PCIEX_SUE_HDR3		"sue_hdr3"
+
 #ifdef	__cplusplus
 }
 #endif
--- a/usr/src/uts/common/sys/ndifm.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/ndifm.h	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -58,18 +57,17 @@
 	int err_expected;			/* was this error expected? */
 	void *err_ontrap;			/* ontrap protection, if any */
 	struct i_ddi_fmc_entry *err_fep;	/* FM cache link */
+	int (*err_cf)();			/* compare function */
 } ndi_err_t;
 
-
-typedef int (ndi_fmcompare_t)(dev_info_t *, const void *, const void *,
-    const void *);
-
 #ifdef	_KERNEL
 
 extern void ndi_fmc_insert(dev_info_t *, int, void *, void *);
 extern void ndi_fmc_remove(dev_info_t *, int, const void *);
-extern int ndi_fmc_error(dev_info_t *, dev_info_t *, int, ndi_fmcompare_t,
-    uint64_t, const void *);
+extern int ndi_fmc_error(dev_info_t *, dev_info_t *, int, uint64_t,
+    const void *);
+extern int ndi_fmc_entry_error(dev_info_t *, int, ddi_fm_error_t *,
+    const void *);
 
 extern int ndi_fm_handler_dispatch(dev_info_t *, dev_info_t *,
     const ddi_fm_error_t *);
--- a/usr/src/uts/common/sys/pci.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/pci.h	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -641,12 +640,103 @@
  * PCI-X capability related definitions
  */
 #define	PCI_PCIX_COMMAND	0x2	/* Command register offset */
+#define	PCI_PCIX_STATUS		0x4	/* Status register offset */
+#define	PCI_PCIX_ECC_STATUS	0x8	/* ECC Status register offset */
+#define	PCI_PCIX_ECC_FST_AD	0xC	/* ECC First address register offset */
+#define	PCI_PCIX_ECC_SEC_AD	0x10	/* ECC Second address register offset */
+#define	PCI_PCIX_ECC_ATTR	0x14	/* ECC Attribute register offset */
 
+/*
+ * PCI-X bridge capability related definitions
+ */
+#define	PCI_PCIX_SEC_STATUS	0x2	/* Secondary status register offset */
+#define	PCI_PCIX_BDG_STATUS	0x4	/* Bridge Status register offset */
+#define	PCI_PCIX_UP_SPL_CTL	0x8	/* Upstream split ctrl reg offset */
+#define	PCI_PCIX_DOWN_SPL_CTL	0xC	/* Downstream split ctrl reg offset */
+#define	PCI_PCIX_BDG_ECC_STATUS	0x10	/* ECC Status register offset */
+#define	PCI_PCIX_BDG_ECC_FST_AD	0x14	/* ECC First address register offset */
+#define	PCI_PCIX_BDG_ECC_SEC_AD	0x18	/* ECC Second address register offset */
+#define	PCI_PCIX_BDG_ECC_ATTR	0x1C	/* ECC Attribute register offset */
+
+/*
+ * PCIX capabilities values
+ */
 #define	PCI_PCIX_VER_MASK	0x3000	/* Bits 12 and 13 */
 #define	PCI_PCIX_VER_0		0x0000	/* PCIX cap list item version 0 */
 #define	PCI_PCIX_VER_1		0x1000	/* PCIX cap list item version 1 */
 #define	PCI_PCIX_VER_2		0x2000	/* PCIX cap list item version 2 */
 
+#define	PCI_PCIX_SPL_DSCD	0x40000 /* Split Completion Discarded */
+#define	PCI_PCIX_UNEX_SPL	0x80000	/* Unexpected Split Completion */
+#define	PCI_PCIX_RX_SPL_MSG	0x20000000 /* Recieved Spl Comp Error Message */
+
+#define	PCI_PCIX_ECC_SEL	0x1	/* Secondary ECC register select */
+#define	PCI_PCIX_ECC_EP		0x2	/* Error Present on other side */
+#define	PCI_PCIX_ECC_S_CE	0x4	/* Addl Correctable ECC Error */
+#define	PCI_PCIX_ECC_S_UE	0x8	/* Addl Uncorrectable ECC Error */
+#define	PCI_PCIX_ECC_PHASE	0x70	/* ECC Error Phase */
+#define	PCI_PCIX_ECC_CORR	0x80	/* ECC Error Corrected */
+#define	PCI_PCIX_ECC_SYN	0xff00	/* ECC Error Syndrome */
+#define	PCI_PCIX_ECC_FST_CMD	0xf0000	 /* ECC Error First Command */
+#define	PCI_PCIX_ECC_SEC_CMD	0xf00000 /* ECC Error Second Command */
+#define	PCI_PCIX_ECC_UP_ATTR	0xf000000 /* ECC Error Upper Attributes */
+
+/*
+ * PCIX ECC Phase Values
+ */
+#define	PCI_PCIX_ECC_PHASE_NOERR	0x0
+#define	PCI_PCIX_ECC_PHASE_FADDR	0x1
+#define	PCI_PCIX_ECC_PHASE_SADDR	0x2
+#define	PCI_PCIX_ECC_PHASE_ATTR		0x3
+#define	PCI_PCIX_ECC_PHASE_DATA32	0x4
+#define	PCI_PCIX_ECC_PHASE_DATA64	0x5
+
+/*
+ * PCI-X Command Encoding
+ */
+#define	PCI_PCIX_CMD_INTR		0x0
+#define	PCI_PCIX_CMD_SPEC		0x1
+#define	PCI_PCIX_CMD_IORD		0x2
+#define	PCI_PCIX_CMD_IOWR		0x3
+#define	PCI_PCIX_CMD_DEVID		0x5
+#define	PCI_PCIX_CMD_MEMRD_DW		0x6
+#define	PCI_PCIX_CMD_MEMWR		0x7
+#define	PCI_PCIX_CMD_MEMRD_BL		0x8
+#define	PCI_PCIX_CMD_MEMWR_BL		0x9
+#define	PCI_PCIX_CMD_CFRD		0xA
+#define	PCI_PCIX_CMD_CFWR		0xB
+#define	PCI_PCIX_CMD_SPL		0xC
+#define	PCI_PCIX_CMD_DADR		0xD
+#define	PCI_PCIX_CMD_MEMRDBL		0xE
+#define	PCI_PCIX_CMD_MEMWRBL		0xF
+
+#if defined(_BIT_FIELDS_LTOH)
+typedef struct pcix_attr {
+	uint32_t	lbc	:8,
+			rid	:16,
+			tag	:5,
+			ro	:1,
+			ns	:1,
+			r	:1;
+} pcix_attr_t;
+#elif defined(_BIT_FIELDS_HTOL)
+typedef struct pcix_attr {
+	uint32_t	r	:1,
+			ns	:1,
+			ro	:1,
+			tag	:5,
+			rid	:16,
+			lbc	:8;
+} pcix_attr_t;
+#else
+#error "bit field not defined"
+#endif
+
+#define	PCI_PCIX_BSS_SPL_DSCD	0x4	/* Secondary split comp discarded */
+#define	PCI_PCIX_BSS_UNEX_SPL	0x8	/* Secondary unexpected split comp */
+#define	PCI_PCIX_BSS_SPL_OR	0x10	/* Secondary split comp overrun */
+#define	PCI_PCIX_BSS_SPL_DLY	0x20	/* Secondary split comp delayed */
+
 /*
  * PCI Message Signalled Interrupts (MSI) capability entry offsets for 32-bit
  */
@@ -725,6 +815,43 @@
 #define	PCI_CLK_133MHZ	(133 * 1000 * 1000)	/* 133MHz clock speed */
 
 /*
+ * pci bus range definition
+ */
+typedef struct pci_bus_range {
+	uint32_t lo;
+	uint32_t hi;
+} pci_bus_range_t;
+
+/*
+ * The following typedef is used to represent an entry in the "ranges"
+ * property of a pci hostbridge device node.
+ */
+typedef struct pci_ranges {
+	uint32_t child_high;
+	uint32_t child_mid;
+	uint32_t child_low;
+	uint32_t parent_high;
+	uint32_t parent_low;
+	uint32_t size_high;
+	uint32_t size_low;
+} pci_ranges_t;
+
+/*
+ * The following typedef is used to represent an entry in the "ranges"
+ * property of a pci-pci bridge device node.
+ */
+typedef struct {
+	uint32_t child_high;
+	uint32_t child_mid;
+	uint32_t child_low;
+	uint32_t parent_high;
+	uint32_t parent_mid;
+	uint32_t parent_low;
+	uint32_t size_high;
+	uint32_t size_low;
+} ppb_ranges_t;
+
+/*
  * This structure represents one entry of the 1275 "reg" property and
  * "assigned-addresses" property for a PCI node.  For the "reg" property, it
  * may be one of an arbitrary length array for devices with multiple address
--- a/usr/src/uts/common/sys/pcie.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/pcie.h	Sun Apr 23 15:26:28 2006 -0700
@@ -395,8 +395,9 @@
 /*
  * AER Uncorrectable Error Status/Mask/Severity Register
  */
-#define	PCIE_AER_UCE_TRAINING		0x0	/* Training Error Status */
+#define	PCIE_AER_UCE_TRAINING		0x1	/* Training Error Status */
 #define	PCIE_AER_UCE_DLP		0x10	/* Data Link Protocol Error */
+#define	PCIE_AER_UCE_SD			0x20	/* Link Surprise down */
 #define	PCIE_AER_UCE_PTLP		0x1000	/* Poisoned TLP Status */
 #define	PCIE_AER_UCE_FCP		0x2000	/* Flow Control Protocol Sts */
 #define	PCIE_AER_UCE_TO			0x4000	/* Completion Timeout Status */
@@ -405,11 +406,14 @@
 #define	PCIE_AER_UCE_RO			0x20000	/* Receiver Overflow Status */
 #define	PCIE_AER_UCE_MTLP		0x40000	/* Malformed TLP Status */
 #define	PCIE_AER_UCE_ECRC		0x80000	/* ECRC Error Status */
-#define	PCIE_AER_UCE_UR		0x100000	/* Unsupported Req */
+#define	PCIE_AER_UCE_UR			0x100000 /* Unsupported Req */
 #define	PCIE_AER_UCE_BITS		(PCIE_AER_UCE_TRAINING | \
-    PCIE_AER_UCE_DLP | PCIE_AER_UCE_PTLP | PCIE_AER_UCE_FCP | \
-    PCIE_AER_UCE_TO | PCIE_AER_UCE_CA | PCIE_AER_UCE_UC | PCIE_AER_UCE_RO | \
-    PCIE_AER_UCE_MTLP | PCIE_AER_UCE_ECRC | PCIE_AER_UCE_UR)
+    PCIE_AER_UCE_DLP | PCIE_AER_UCE_SD | PCIE_AER_UCE_PTLP | \
+    PCIE_AER_UCE_FCP | PCIE_AER_UCE_TO | PCIE_AER_UCE_CA | \
+    PCIE_AER_UCE_UC | PCIE_AER_UCE_RO | PCIE_AER_UCE_MTLP | \
+    PCIE_AER_UCE_ECRC | PCIE_AER_UCE_UR)
+#define	PCIE_AER_UCE_LOG_BITS		(PCIE_AER_UCE_PTLP | PCIE_AER_UCE_CA | \
+    PCIE_AER_UCE_UC | PCIE_AER_UCE_MTLP | PCIE_AER_UCE_ECRC | PCIE_AER_UCE_UR)
 
 /*
  * AER Correctable Error Status/Mask Register
@@ -419,6 +423,7 @@
 #define	PCIE_AER_CE_BAD_DLLP		0x80	/* Bad DLLP Status */
 #define	PCIE_AER_CE_REPLAY_ROLLOVER	0x100	/* REPLAY_NUM Rollover Status */
 #define	PCIE_AER_CE_REPLAY_TO		0x1000	/* Replay Timer Timeout Sts */
+#define	PCIE_AER_CE_AD_NFE		0x2000	/* Advisory Non-Fatal Status */
 #define	PCIE_AER_CE_BITS		(PCIE_AER_CE_RECEIVER_ERR | \
     PCIE_AER_CE_BAD_TLP | PCIE_AER_CE_BAD_DLLP | PCIE_AER_CE_REPLAY_ROLLOVER | \
     PCIE_AER_CE_REPLAY_TO)
@@ -477,6 +482,13 @@
 #define	PCIE_AER_SUCE_PERR_ASSERT	0x800	/* PERR Assertion Detected */
 #define	PCIE_AER_SUCE_SERR_ASSERT	0x1000	/* SERR Assertion Detected */
 #define	PCIE_AER_SUCE_INTERNAL_ERR	0x2000	/* Internal Bridge Err Detect */
+
+#define	PCIE_AER_SUCE_HDR_CMD_LWR_MASK	0xF	/* Lower Command Mask */
+#define	PCIE_AER_SUCE_HDR_CMD_LWR_SHIFT	4	/* Lower Command Shift */
+#define	PCIE_AER_SUCE_HDR_CMD_UP_MASK	0xF	/* Upper Command Mask */
+#define	PCIE_AER_SUCE_HDR_CMD_UP_SHIFT	8	/* Upper Command Shift */
+#define	PCIE_AER_SUCE_HDR_ADDR_SHIFT	32	/* Upper Command Shift */
+
 #define	PCIE_AER_SUCE_BITS		(PCIE_AER_SUCE_TA_ON_SC | \
     PCIE_AER_SUCE_MA_ON_SC | PCIE_AER_SUCE_RCVD_TA | PCIE_AER_SUCE_RCVD_MA | \
     PCIE_AER_SUCE_USC_ERR | PCIE_AER_SUCE_USC_MSG_DATA_ERR | \
@@ -484,6 +496,11 @@
     PCIE_AER_SUCE_UC_ADDR_ERR |	PCIE_AER_SUCE_TIMER_EXPIRED | \
     PCIE_AER_SUCE_PERR_ASSERT |	PCIE_AER_SUCE_SERR_ASSERT | \
     PCIE_AER_SUCE_INTERNAL_ERR)
+#define	PCIE_AER_SUCE_LOG_BITS		(PCIE_AER_SUCE_TA_ON_SC | \
+    PCIE_AER_SUCE_MA_ON_SC | PCIE_AER_SUCE_RCVD_TA | PCIE_AER_SUCE_RCVD_MA | \
+    PCIE_AER_SUCE_USC_ERR | PCIE_AER_SUCE_USC_MSG_DATA_ERR | \
+    PCIE_AER_SUCE_UC_DATA_ERR | PCIE_AER_SUCE_UC_ATTR_ERR | \
+    PCIE_AER_SUCE_UC_ADDR_ERR |	PCIE_AER_SUCE_PERR_ASSERT)
 
 /*
  * AER Secondary Capability & Control
@@ -507,17 +524,17 @@
 /*
  * PCI-E Common TLP Header Fields
  */
-#define	PCIE_TLP_FMT_3DW 	0x00
+#define	PCIE_TLP_FMT_3DW	0x00
 #define	PCIE_TLP_FMT_4DW	0x20
 #define	PCIE_TLP_FMT_3DW_DATA	0x40
 #define	PCIE_TLP_FMT_4DW_DATA	0x60
 
 #define	PCIE_TLP_TYPE_MEM	0x0
 #define	PCIE_TLP_TYPE_MEMLK	0x1
-#define	PCIE_TLP_TYPE_IO 	0x2
+#define	PCIE_TLP_TYPE_IO	0x2
 #define	PCIE_TLP_TYPE_CFG0	0x4
 #define	PCIE_TLP_TYPE_CFG1	0x5
-#define	PCIE_TLP_TYPE_MSG 	0x10
+#define	PCIE_TLP_TYPE_MSG	0x10
 #define	PCIE_TLP_TYPE_CPL	0xA
 #define	PCIE_TLP_TYPE_CPLLK	0xB
 #define	PCIE_TLP_TYPE_MSI	0x18
@@ -528,14 +545,14 @@
 #define	PCIE_TLP_MRDLK4		(PCIE_TLP_FMT_4DW | PCIE_TLP_TYPE_MEMLK)
 #define	PCIE_TLP_MRDWR3		(PCIE_TLP_FMT_3DW_DATA | PCIE_TLP_TYPE_MEM)
 #define	PCIE_TLP_MRDWR4		(PCIE_TLP_FMT_4DW_DATA | PCIE_TLP_TYPE_MEM)
-#define	PCIE_TLP_IORD 		(PCIE_TLP_FMT_3DW | PCIE_TLP_TYPE_IO)
-#define	PCIE_TLP_IOWR 		(PCIE_TLP_FMT_3DW_DATA | PCIE_TLP_TYPE_IO)
+#define	PCIE_TLP_IORD		(PCIE_TLP_FMT_3DW | PCIE_TLP_TYPE_IO)
+#define	PCIE_TLP_IOWR		(PCIE_TLP_FMT_3DW_DATA | PCIE_TLP_TYPE_IO)
 #define	PCIE_TLP_CFGRD0		(PCIE_TLP_FMT_3DW | PCIE_TLP_TYPE_CFG0)
 #define	PCIE_TLP_CFGWR0		(PCIE_TLP_FMT_3DW_DATA | PCIE_TLP_TYPE_CFG0)
 #define	PCIE_TLP_CFGRD1		(PCIE_TLP_FMT_3DW | PCIE_TLP_TYPE_CFG1)
 #define	PCIE_TLP_CFGWR1		(PCIE_TLP_FMT_3DW_DATA | PCIE_TLP_TYPE_CFG1)
-#define	PCIE_TLP_MSG 		(PCIE_TLP_FMT_4DW | PCIE_TLP_TYPE_MSG)
-#define	PCIE_TLP_MSGD 		(PCIE_TLP_FMT_4DW_DATA | PCIE_TLP_TYPE_MSG)
+#define	PCIE_TLP_MSG		(PCIE_TLP_FMT_4DW | PCIE_TLP_TYPE_MSG)
+#define	PCIE_TLP_MSGD		(PCIE_TLP_FMT_4DW_DATA | PCIE_TLP_TYPE_MSG)
 #define	PCIE_TLP_CPL		(PCIE_TLP_FMT_3DW | PCIE_TLP_TYPE_CPL)
 #define	PCIE_TLP_CPLD		(PCIE_TLP_FMT_3DW_DATA | PCIE_TLP_TYPE_CPL)
 #define	PCIE_TLP_CPLLK		(PCIE_TLP_FMT_3DW | PCIE_TLP_TYPE_CPLLK)
@@ -552,32 +569,157 @@
 #define	PCIE_REQ_ID_FUNC_SHIFT	0
 #define	PCIE_REQ_ID_FUNC_MASK	0x0007
 
+#if defined(_BIT_FIELDS_LTOH)
+/*
+ * PCI Express little-endian common TLP header format
+ */
+typedef struct pcie_tlp_hdr {
+	uint32_t	len	:10,
+			rsvd3   :2,
+			attr    :2,
+			ep	:1,
+			td	:1,
+			rsvd2   :4,
+			tc	:3,
+			rsvd1   :1,
+			type    :5,
+			fmt	:2,
+			rsvd0   :1;
+} pcie_tlp_hdr_t;
+
+typedef struct pcie_mem64 {
+	uint32_t	fbe	:4,
+			lbe	:4,
+			tag	:8,
+			rid	:16;
+	uint32_t	addr1;
+	uint32_t	rsvd0   :2,
+			addr0   :30;
+} pcie_mem64_t;
+
+typedef struct pcie_memio32 {
+	uint32_t	fbe	:4,
+			lbe	:4,
+			tag	:8,
+			rid	:16;
+	uint32_t	rsvd0   :2,
+			addr0   :30;
+} pcie_memio32_t;
+
+typedef struct pcie_cfg {
+	uint32_t	fbe	:4,
+			lbe	:4,
+			tag	:8,
+			rid	:16;
+	uint32_t	rsvd1   :2,
+			reg	:6,
+			extreg  :4,
+			rsvd0   :4,
+			func    :3,
+			dev	:5,
+			bus	:8;
+} pcie_cfg_t;
+
+typedef struct pcie_cpl {
+	uint32_t	bc	:12,
+			bcm	:1,
+			status  :3,
+			cid	:16;
+	uint32_t	laddr   :7,
+			rsvd0   :1,
+			tag	:8,
+			rid	:16;
+} pcie_cpl_t;
+
 /*
  * PCI-Express Message Request Header
  */
 typedef struct pcie_msg {
-	uint32_t	rsvd1	:16,	/* DW0 */
+	uint32_t	msg_code:8,	/* DW1 */
+			tag	:8,
+			rid	:16;
+	uint32_t	unused[2];	/* DW 2 & 3 */
+} pcie_msg_t;
+
+#elif defined(_BIT_FIELDS_HTOL)
+/*
+ * PCI Express big-endian common TLP header format
+ */
+typedef struct pcie_tlp_hdr {
+	uint32_t	rsvd0	:1,
+			fmt	:2,
+			type	:5,
+			rsvd1	:1,
+			tc	:3,
+			rsvd2	:4,
 			td	:1,
 			ep	:1,
 			attr	:2,
-			rsvd2	:2,
+			rsvd3	:2,
 			len	:10;
+} pcie_tlp_hdr_t;
+
+typedef struct pcie_mem64 {
+	uint32_t	rid	:16,
+			tag	:8,
+			lbe	:4,
+			fbe	:4;
+	uint32_t	addr1;
+	uint32_t	addr0	:30,
+			rsvd0	:2;
+} pcie_mem64_t;
+
+typedef struct pcie_memio32 {
+	uint32_t	rid	:16,
+			tag	:8,
+			lbe	:4,
+			fbe	:4;
+	uint32_t	addr0	:30,
+			rsvd0	:2;
+} pcie_memio32_t;
+
+typedef struct pcie_cfg {
+	uint32_t	rid	:16,
+			tag	:8,
+			lbe	:4,
+			fbe	:4;
+	uint32_t	bus	:8,
+			dev	:5,
+			func	:3,
+			rsvd0	:4,
+			extreg	:4,
+			reg	:6,
+			rsvd1	:2;
+} pcie_cfg_t;
+
+typedef struct pcie_cpl {
+	uint32_t	cid	:16,
+			status	:3,
+			bcm	:1,
+			bc	:12;
+	uint32_t	rid	:16,
+			tag	:8,
+			rsvd0	:1,
+			laddr	:7;
+} pcie_cpl_t;
+
+/*
+ * PCI-Express Message Request Header
+ */
+typedef struct pcie_msg {
 	uint32_t	rid	:16,	/* DW1 */
 			tag	:8,
 			msg_code:8;
 	uint32_t	unused[2];	/* DW 2 & 3 */
 } pcie_msg_t;
+#else
+#error "bit field not defined"
+#endif
 
 #define	PCIE_MSG_CODE_ERR_COR		0x30
 #define	PCIE_MSG_CODE_ERR_NONFATAL	0x31
 #define	PCIE_MSG_CODE_ERR_FATAL		0x33
 
-/*
- * Exported PCI-express property names
- */
-#define	SAVED_PCIEX_CAP_REG	"pciex-cap-reg"
-#define	SAVED_PCIEX_SLOTCAP_REG	"pciex-slotcap-reg"
-
 #ifdef	__cplusplus
 }
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/sys/pcifm.h	Sun Apr 23 15:26:28 2006 -0700
@@ -0,0 +1,209 @@
+/*
+ * 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	_SYS_PCIFM_H
+#define	_SYS_PCIFM_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#include <sys/dditypes.h>		/* for ddi_acc_handle_t */
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * PCI device type defines.
+ */
+#define	PCI_BRIDGE_DEV			0x02
+#define	PCIX_DEV			0x04
+#define	PCIEX_DEV			0x08
+#define	PCIEX_ADV_DEV			0x10
+#define	PCIEX_RC_DEV			0x20
+#define	PCIEX_2PCI_DEV			0x40
+
+/*
+ * PCI and PCI-X valid flags
+ */
+#define	PCI_ERR_STATUS_VALID		0x1
+#define	PCI_BDG_SEC_STAT_VALID		0x2
+#define	PCI_BDG_CTRL_VALID		0x4
+#define	PCIX_ERR_STATUS_VALID		0x8
+#define	PCIX_ERR_ECC_STS_VALID		0x10
+#define	PCIX_ERR_S_ECC_STS_VALID	0x20
+#define	PCIX_BDG_STATUS_VALID		0x40
+#define	PCIX_BDG_SEC_STATUS_VALID	0x80
+
+/*
+ * PCI Express valid flags
+ */
+#define	PCIE_ERR_STATUS_VALID		0x1
+#define	PCIE_CE_STATUS_VALID		0x2
+#define	PCIE_UE_STATUS_VALID		0x4
+#define	PCIE_RC_ERR_STATUS_VALID	0x8
+#define	PCIE_SUE_STATUS_VALID		0x10
+#define	PCIE_SUE_HDR_VALID		0x20
+#define	PCIE_UE_HDR_VALID		0x40
+#define	PCIE_SRC_ID_VALID		0x80
+
+/*
+ * PCI(-X) structures used (by pci_ereport_setup, pci_ereport_post, and
+ * pci_ereport_teardown) to gather and report errors detected by PCI(-X)
+ * compliant devices.
+ */
+typedef struct pci_bdg_error_regs {
+	uint16_t pci_bdg_vflags;	/* status valid bits */
+	uint16_t pci_bdg_sec_stat;	/* PCI secondary status reg */
+	uint16_t pci_bdg_ctrl;		/* PCI bridge control reg */
+} pci_bdg_error_regs_t;
+
+typedef struct pci_error_regs {
+	uint16_t pci_vflags;		/* status valid bits */
+	uint8_t pci_cap_ptr;		/* PCI Capability pointer */
+	uint16_t pci_err_status;	/* pci status register */
+	uint16_t pci_cfg_comm;		/* pci command register */
+	pci_bdg_error_regs_t *pci_bdg_regs;
+} pci_error_regs_t;
+
+typedef struct pci_erpt {
+	ddi_acc_handle_t pe_hdl;	/* Config space access handle */
+	uint64_t pe_dflags;		/* Device type flags */
+	uint16_t pe_bdf;		/* bus/device/function of device */
+	pci_error_regs_t *pe_pci_regs;	/* PCI generic error registers */
+	void *pe_regs;			/* Pointer to extended error regs */
+} pci_erpt_t;
+
+typedef struct pcix_ecc_regs {
+	uint16_t pcix_ecc_vflags;	/* pcix ecc valid flags */
+	uint16_t pcix_ecc_bdf;		/* pcix ecc bdf */
+	uint32_t pcix_ecc_ctlstat;	/* pcix ecc control status reg */
+	uint32_t pcix_ecc_fstaddr;	/* pcix ecc first address reg */
+	uint32_t pcix_ecc_secaddr;	/* pcix ecc second address reg */
+	uint32_t pcix_ecc_attr;		/* pcix ecc attributes reg */
+} pcix_ecc_regs_t;
+
+typedef struct pcix_error_regs {
+	uint16_t pcix_vflags;		/* pcix valid flags */
+	uint8_t pcix_cap_ptr;		/* pcix capability pointer */
+	uint16_t pcix_ver;		/* pcix version */
+	uint16_t pcix_command;		/* pcix command register */
+	uint32_t pcix_status;		/* pcix status register */
+	pcix_ecc_regs_t *pcix_ecc_regs;	/* pcix ecc registers */
+} pcix_error_regs_t;
+
+typedef struct pcix_bdg_error_regs {
+	uint16_t pcix_bdg_vflags;	/* pcix valid flags */
+	uint8_t pcix_bdg_cap_ptr;	/* pcix bridge capability pointer */
+	uint16_t pcix_bdg_ver;		/* pcix version */
+	uint16_t pcix_bdg_sec_stat;	/* pcix bridge secondary status reg */
+	uint32_t pcix_bdg_stat;		/* pcix bridge status reg */
+	pcix_ecc_regs_t *pcix_bdg_ecc_regs[2];	/* pcix ecc registers */
+} pcix_bdg_error_regs_t;
+
+/*
+ * PCI Express error register structures used (by pci_ereport_setup,
+ * pci_ereport_post, and pci_ereport_teardown) to gather and report errors
+ * detected by PCI Express compliant devices.
+ */
+typedef struct pcie_adv_bdg_error_regs {
+	uint32_t pcie_sue_status;	/* pcie bridge secondary ue status */
+	uint32_t pcie_sue_mask;		/* pcie bridge secondary ue mask */
+	uint32_t pcie_sue_sev;		/* pcie bridge secondary ue severity */
+	uint32_t pcie_sue_hdr0;		/* pcie bridge secondary ue hdr log */
+	uint32_t pcie_sue_hdr[3];	/* pcie bridge secondary ue hdr log */
+} pcie_adv_bdg_error_regs_t;
+
+typedef struct pcie_adv_rc_error_regs {
+	uint32_t pcie_rc_err_status;	/* pcie root complex error status reg */
+	uint32_t pcie_rc_err_cmd;	/* pcie root complex error cmd reg */
+	uint16_t pcie_rc_ce_src_id;	/* pcie root complex ce source id */
+	uint16_t pcie_rc_ue_src_id;	/* pcie root complex ue source id */
+} pcie_adv_rc_error_regs_t;
+
+typedef struct pcie_adv_error_regs {
+	uint16_t pcie_adv_vflags;	/* pcie advanced error valid flags */
+	uint16_t pcie_adv_cap_ptr;	/* pcie advanced capability pointer */
+	uint16_t pcie_adv_bdf;		/* pcie bdf */
+	uint32_t pcie_adv_ctl;		/* pcie advanced control reg */
+	uint32_t pcie_ce_status;	/* pcie ce error status reg */
+	uint32_t pcie_ce_mask;		/* pcie ce error mask reg */
+	uint32_t pcie_ue_status;	/* pcie ue error status reg */
+	uint32_t pcie_ue_mask;		/* pcie ue error mask reg */
+	uint32_t pcie_ue_sev;		/* pcie ue error severity reg */
+	uint32_t pcie_ue_hdr0;		/* pcie ue header log */
+	uint32_t pcie_ue_hdr[3];	/* pcie ue header log */
+	pcie_adv_bdg_error_regs_t *pcie_adv_bdg_regs;	/* pcie bridge regs */
+	pcie_adv_rc_error_regs_t *pcie_adv_rc_regs;	/* pcie rc regs */
+} pcie_adv_error_regs_t;
+
+typedef struct pcie_rc_error_regs {
+	uint32_t pcie_rc_status;	/* root complex status register */
+	uint16_t pcie_rc_ctl;		/* root complex control register */
+} pcie_rc_error_regs_t;
+
+typedef struct pcie_error_regs {
+	uint16_t pcie_vflags;		/* pcie valid flags */
+	uint8_t pcie_cap_ptr;		/* PCI Express capability pointer */
+	uint16_t pcie_cap;		/* PCI Express capability register */
+	uint16_t pcie_err_status;	/* pcie device status register */
+	uint16_t pcie_err_ctl;		/* pcie error control register */
+	pcix_bdg_error_regs_t *pcix_bdg_regs;	/* pcix bridge regs */
+	pcie_rc_error_regs_t *pcie_rc_regs;	/* pcie root complex regs */
+	pcie_adv_error_regs_t *pcie_adv_regs;	/* pcie advanced err regs */
+} pcie_error_regs_t;
+
+/*
+ * target error queue defines
+ */
+#define	TARGET_MAX_ERRS			6
+#define	TGT_PCI_SPACE_UNKNOWN		4
+
+typedef struct pci_target_err {
+	uint64_t tgt_err_addr;
+	uint64_t tgt_err_ena;
+	uint64_t tgt_pci_addr;
+	uint32_t tgt_pci_space;
+	dev_info_t *tgt_dip;
+	char *tgt_err_class;
+	char *tgt_bridge_type;
+} pci_target_err_t;
+
+#define	PCI_FM_SEV_INC(x)	((x) == DDI_FM_FATAL) ? fatal++ :\
+				(((x) == DDI_FM_NONFATAL) ? nonfatal++ :\
+				(((x) == DDI_FM_UNKNOWN) ? unknown++ : ok++));
+
+#define	PCIEX_TYPE_CE			0x0
+#define	PCIEX_TYPE_UE			0x1
+#define	PCIEX_TYPE_GEN			0x2
+#define	PCIEX_TYPE_RC_UE_MSG		0x3
+#define	PCIEX_TYPE_RC_CE_MSG		0x4
+#define	PCIEX_TYPE_RC_MULT_MSG		0x5
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _SYS_PCIFM_H */
--- a/usr/src/uts/common/sys/sunddi.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/common/sys/sunddi.h	Sun Apr 23 15:26:28 2006 -0700
@@ -1874,12 +1874,18 @@
 void
 pci_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, uint16_t *status);
 
-void
-pci_bdg_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, uint16_t *status);
+#if defined(__i386) || defined(__amd64)
+int
+pci_peekpoke_check(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *, void *,
+	int (*handler)(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *,
+	void *), kmutex_t *, kmutex_t *);
+#endif
 
-int
-pci_bdg_check_status(dev_info_t *dip, ddi_fm_error_t *derr,
-    uint16_t pci_cfg_stat, uint16_t pci_cfg_sec_stat);
+void
+pci_target_enqueue(uint64_t, char *, char *, uint64_t);
+
+void
+pci_targetq_init(void);
 
 /*
  * the prototype for the C Language Type Model inquiry.
--- a/usr/src/uts/i86pc/io/mc/mcamd_drv.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/mc/mcamd_drv.c	Sun Apr 23 15:26:28 2006 -0700
@@ -757,7 +757,7 @@
 mc_fm_handle(dev_info_t *dip, ddi_fm_error_t *fmerr, const void *arg)
 {
 	pci_ereport_post(dip, fmerr, NULL);
-	return (DDI_FM_NONFATAL);
+	return (fmerr->fme_status);
 }
 
 static void
--- a/usr/src/uts/i86pc/io/pci/pci.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/pci/pci.c	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -36,6 +35,9 @@
 #include <sys/pci_impl.h>
 #include <sys/sysmacros.h>
 #include <sys/sunndi.h>
+#include <sys/ddifm.h>
+#include <sys/ndifm.h>
+#include <sys/fm/protocol.h>
 #include <sys/hotplug/pci/pcihp.h>
 #include <io/pci/pci_common.h>
 #include <io/pci/pci_tools_ext.h>
@@ -52,6 +54,9 @@
 		    void *, void *);
 static int	pci_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t,
 		    ddi_intr_handle_impl_t *, void *);
+static int	pci_fm_init(dev_info_t *, dev_info_t *, int,
+		    ddi_iblock_cookie_t *);
+static int	pci_fm_callback(dev_info_t *, ddi_fm_error_t *, const void *);
 
 struct bus_ops pci_bus_ops = {
 	BUSO_REV,
@@ -77,7 +82,7 @@
 	0,		/* (*bus_intr_ctl)(); */
 	0,		/* (*bus_config)(); */
 	0,		/* (*bus_unconfig)(); */
-	NULL,		/* (*bus_fm_init)(); */
+	pci_fm_init,	/* (*bus_fm_init)(); */
 	NULL,		/* (*bus_fm_fini)(); */
 	NULL,		/* (*bus_fm_access_enter)(); */
 	NULL,		/* (*bus_fm_access_exit)(); */
@@ -248,6 +253,18 @@
 		goto bad_pcitool_init;
 	}
 
+	pcip->pci_fmcap = DDI_FM_ERRCB_CAPABLE |
+	    DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
+	ddi_fm_init(devi, &pcip->pci_fmcap, &pcip->pci_fm_ibc);
+	mutex_init(&pcip->pci_err_mutex, NULL, MUTEX_DRIVER,
+	    (void *)pcip->pci_fm_ibc);
+	mutex_init(&pcip->pci_peek_poke_mutex, NULL, MUTEX_DRIVER,
+	    (void *)pcip->pci_fm_ibc);
+	if (pcip->pci_fmcap & DDI_FM_ERRCB_CAPABLE) {
+		pci_ereport_setup(devi);
+		ddi_fm_handler_register(devi, pci_fm_callback, NULL);
+	}
+
 	ddi_report_dev(devi);
 
 	return (DDI_SUCCESS);
@@ -265,6 +282,16 @@
 pci_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
 {
 	int instance = ddi_get_instance(devi);
+	pci_state_t *pcip;
+
+	pcip = ddi_get_soft_state(pci_statep, ddi_get_instance(devi));
+	if (pcip->pci_fmcap & DDI_FM_ERRCB_CAPABLE) {
+		ddi_fm_handler_unregister(devi);
+		pci_ereport_teardown(devi);
+	}
+	mutex_destroy(&pcip->pci_peek_poke_mutex);
+	mutex_destroy(&pcip->pci_err_mutex);
+	ddi_fm_fini(devi);
 
 	/* Uninitialize pcitool support. */
 	pcitool_uninit(devi);
@@ -284,7 +311,6 @@
 	struct regspec reg;
 	ddi_map_req_t mr;
 	ddi_acc_hdl_t *hp;
-	ddi_acc_impl_t *ap;
 	pci_regspec_t pci_reg;
 	pci_regspec_t *pci_rp;
 	int 	rnumber;
@@ -408,56 +434,19 @@
 	 * indicate that the common routines to call the nexus driver.
 	 */
 	if (space == PCI_ADDR_CONFIG) {
+		/* Can't map config space without a handle */
 		hp = (ddi_acc_hdl_t *)mp->map_handlep;
-
-		/* Can't map config space without a handle */
 		if (hp == NULL)
 			return (DDI_FAILURE);
 
-		ap = (ddi_acc_impl_t *)hp->ah_platform_private;
-
-		/* endian-ness check */
-		if (hp->ah_acc.devacc_attr_endian_flags == DDI_STRUCTURE_BE_ACC)
-			return (DDI_FAILURE);
-
-		/*
-		 * range check
-		 */
-		if ((offset >= 256) || (len > 256) || (offset + len > 256))
-			return (DDI_FAILURE);
-		*vaddrp = (caddr_t)offset;
-
-		ap->ahi_acc_attr |= DDI_ACCATTR_CONFIG_SPACE;
-		ap->ahi_put8 = pci_config_wr8;
-		ap->ahi_get8 = pci_config_rd8;
-		ap->ahi_put64 = pci_config_wr64;
-		ap->ahi_get64 = pci_config_rd64;
-		ap->ahi_rep_put8 = pci_config_rep_wr8;
-		ap->ahi_rep_get8 = pci_config_rep_rd8;
-		ap->ahi_rep_put64 = pci_config_rep_wr64;
-		ap->ahi_rep_get64 = pci_config_rep_rd64;
-		ap->ahi_get16 = pci_config_rd16;
-		ap->ahi_get32 = pci_config_rd32;
-		ap->ahi_put16 = pci_config_wr16;
-		ap->ahi_put32 = pci_config_wr32;
-		ap->ahi_rep_get16 = pci_config_rep_rd16;
-		ap->ahi_rep_get32 = pci_config_rep_rd32;
-		ap->ahi_rep_put16 = pci_config_rep_wr16;
-		ap->ahi_rep_put32 = pci_config_rep_wr32;
-
-		/* Initialize to default check/notify functions */
-		ap->ahi_fault_check = i_ddi_acc_fault_check;
-		ap->ahi_fault_notify = i_ddi_acc_fault_notify;
-		ap->ahi_fault = 0;
-		impl_acc_err_init(hp);
-
 		/* record the device address for future reference */
 		cfp = (pci_acc_cfblk_t *)&hp->ah_bus_private;
 		cfp->c_busnum = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
 		cfp->c_devnum = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
 		cfp->c_funcnum = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
 
-		return (DDI_SUCCESS);
+		*vaddrp = (caddr_t)offset;
+		return (pci_fm_acc_setup(hp, offset, len));
 	}
 
 	/*
@@ -520,6 +509,7 @@
 	uint_t	reglen;
 	int	rn;
 	int	totreg;
+	pci_state_t *pcip;
 
 	switch (ctlop) {
 	case DDI_CTLOPS_REPORTDEV:
@@ -581,6 +571,13 @@
 		return (ddi_ctlops(dip, rdip, ctlop, arg, result));
 	}
 
+	case DDI_CTLOPS_PEEK:
+	case DDI_CTLOPS_POKE:
+		pcip = ddi_get_soft_state(pci_statep, ddi_get_instance(dip));
+		return (pci_peekpoke_check(dip, rdip, ctlop, arg, result,
+		    pci_common_peekpoke, &pcip->pci_err_mutex,
+		    &pcip->pci_peek_poke_mutex));
+
 	default:
 		return (ddi_ctlops(dip, rdip, ctlop, arg, result));
 	}
@@ -762,3 +759,30 @@
 {
 	return (pcihp_info(dip, cmd, arg, result));
 }
+
+/*ARGSUSED*/
+static int
+pci_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
+    ddi_iblock_cookie_t *ibc)
+{
+	pci_state_t  *pcip = ddi_get_soft_state(pci_statep,
+	    ddi_get_instance(dip));
+
+	ASSERT(ibc != NULL);
+	*ibc = pcip->pci_fm_ibc;
+
+	return (pcip->pci_fmcap);
+}
+
+/*ARGSUSED*/
+static int
+pci_fm_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *no_used)
+{
+	pci_state_t  *pcip = ddi_get_soft_state(pci_statep,
+	    ddi_get_instance(dip));
+
+	mutex_enter(&pcip->pci_err_mutex);
+	pci_ereport_post(dip, derr, NULL);
+	mutex_exit(&pcip->pci_err_mutex);
+	return (derr->fme_status);
+}
--- a/usr/src/uts/i86pc/io/pci/pci_boot.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/pci/pci_boot.c	Sun Apr 23 15:26:28 2006 -0700
@@ -586,9 +586,6 @@
 	subcl = (classcode >> 8) & 0xff;
 	pciide = is_pciide(basecl, subcl, revid, vendorid, deviceid,
 	    subvenid, subdevid);
-	if (check_if_device_is_pciex(bus, dev, func, &slot_num,
-	    &is_pci_bridge) == B_TRUE)
-		pciex = 1;
 
 	if (pciide)
 		(void) snprintf(nodename, sizeof (nodename), "pci-ide");
@@ -609,6 +606,10 @@
 	ndi_devi_alloc_sleep(pci_bus_res[bus].dip, nodename,
 	    DEVI_SID_NODEID, &dip);
 
+	if (check_if_device_is_pciex(dip, bus, dev, func, &slot_num,
+	    &is_pci_bridge) == B_TRUE)
+		pciex = 1;
+
 	/* add properties */
 	(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "device-id", deviceid);
 	(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "vendor-id", vendorid);
@@ -1407,30 +1408,18 @@
 	}
 }
 
-/* this should be in some header file, shared with pcicfg */
-struct pcicfg_range {
-	uint32_t child_hi;
-	uint32_t child_mid;
-	uint32_t child_lo;
-	uint32_t parent_hi;
-	uint32_t parent_mid;
-	uint32_t parent_lo;
-	uint32_t size_hi;
-	uint32_t size_lo;
-};
-
 static int
-memlist_to_range(struct pcicfg_range *rp, struct memlist *entry, int type)
+memlist_to_range(ppb_ranges_t *rp, struct memlist *entry, int type)
 {
 	if (entry == NULL)
 		return (0);
 
 	/* assume 32-bit addresses */
-	rp->child_hi = rp->parent_hi = type;
+	rp->child_high = rp->parent_high = type;
 	rp->child_mid = rp->parent_mid = 0;
-	rp->child_lo = rp->parent_lo = (uint32_t)entry->address;
-	rp->size_hi = 0;
-	rp->size_lo = (uint32_t)entry->size;
+	rp->child_low = rp->parent_low = (uint32_t)entry->address;
+	rp->size_high = 0;
+	rp->size_low = (uint32_t)entry->size;
 	return (1);
 }
 
@@ -1438,7 +1427,7 @@
 add_ppb_ranges_prop(int bus)
 {
 	int i = 0;
-	struct pcicfg_range *rp;
+	ppb_ranges_t *rp;
 
 	rp = kmem_alloc(3 * sizeof (*rp), KM_SLEEP);
 
@@ -1452,7 +1441,7 @@
 	if (i != 0)
 		(void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
 		    pci_bus_res[bus].dip, "ranges", (int *)rp,
-		    i * sizeof (struct pcicfg_range) / sizeof (int));
+		    i * sizeof (ppb_ranges_t) / sizeof (int));
 	kmem_free(rp, 3 * sizeof (*rp));
 }
 
--- a/usr/src/uts/i86pc/io/pci/pci_common.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/pci/pci_common.c	Sun Apr 23 15:26:28 2006 -0700
@@ -830,6 +830,391 @@
 }
 
 
+int
+pci_common_ctlops_poke(peekpoke_ctlops_t *in_args)
+{
+	size_t size = in_args->size;
+	uintptr_t dev_addr = in_args->dev_addr;
+	uintptr_t host_addr = in_args->host_addr;
+	ddi_acc_impl_t *hp = (ddi_acc_impl_t *)in_args->handle;
+	ddi_acc_hdl_t *hdlp = (ddi_acc_hdl_t *)in_args->handle;
+	size_t repcount = in_args->repcount;
+	uint_t flags = in_args->flags;
+	int err = DDI_SUCCESS;
+
+	/*
+	 * if no handle then this is a poke. We have to return failure here
+	 * as we have no way of knowing whether this is a MEM or IO space access
+	 */
+	if (in_args->handle == NULL)
+		return (DDI_FAILURE);
+
+	/*
+	 * rest of this function is actually for cautious puts
+	 */
+	for (; repcount; repcount--) {
+		if (hp->ahi_acc_attr == DDI_ACCATTR_CONFIG_SPACE) {
+			switch (size) {
+			case sizeof (uint8_t):
+				pci_config_wr8(hp, (uint8_t *)dev_addr,
+				    *(uint8_t *)host_addr);
+				break;
+			case sizeof (uint16_t):
+				pci_config_wr16(hp, (uint16_t *)dev_addr,
+				    *(uint16_t *)host_addr);
+				break;
+			case sizeof (uint32_t):
+				pci_config_wr32(hp, (uint32_t *)dev_addr,
+				    *(uint32_t *)host_addr);
+				break;
+			case sizeof (uint64_t):
+				pci_config_wr64(hp, (uint64_t *)dev_addr,
+				    *(uint64_t *)host_addr);
+				break;
+			default:
+				err = DDI_FAILURE;
+				break;
+			}
+		} else if (hp->ahi_acc_attr & DDI_ACCATTR_IO_SPACE) {
+			if (hdlp->ah_acc.devacc_attr_endian_flags ==
+			    DDI_STRUCTURE_BE_ACC) {
+				switch (size) {
+				case sizeof (uint8_t):
+					i_ddi_io_put8(hp,
+					    (uint8_t *)dev_addr,
+					    *(uint8_t *)host_addr);
+					break;
+				case sizeof (uint16_t):
+					i_ddi_io_swap_put16(hp,
+					    (uint16_t *)dev_addr,
+					    *(uint16_t *)host_addr);
+					break;
+				case sizeof (uint32_t):
+					i_ddi_io_swap_put32(hp,
+					    (uint32_t *)dev_addr,
+					    *(uint32_t *)host_addr);
+					break;
+				/*
+				 * note the 64-bit case is a dummy
+				 * function - so no need to swap
+				 */
+				case sizeof (uint64_t):
+					i_ddi_io_put64(hp,
+					    (uint64_t *)dev_addr,
+					    *(uint64_t *)host_addr);
+					break;
+				default:
+					err = DDI_FAILURE;
+					break;
+				}
+			} else {
+				switch (size) {
+				case sizeof (uint8_t):
+					i_ddi_io_put8(hp,
+					    (uint8_t *)dev_addr,
+					    *(uint8_t *)host_addr);
+					break;
+				case sizeof (uint16_t):
+					i_ddi_io_put16(hp,
+					    (uint16_t *)dev_addr,
+					    *(uint16_t *)host_addr);
+					break;
+				case sizeof (uint32_t):
+					i_ddi_io_put32(hp,
+					    (uint32_t *)dev_addr,
+					    *(uint32_t *)host_addr);
+					break;
+				case sizeof (uint64_t):
+					i_ddi_io_put64(hp,
+					    (uint64_t *)dev_addr,
+					    *(uint64_t *)host_addr);
+					break;
+				default:
+					err = DDI_FAILURE;
+					break;
+				}
+			}
+		} else {
+			if (hdlp->ah_acc.devacc_attr_endian_flags ==
+			    DDI_STRUCTURE_BE_ACC) {
+				switch (size) {
+				case sizeof (uint8_t):
+					*(uint8_t *)dev_addr =
+					    *(uint8_t *)host_addr;
+					break;
+				case sizeof (uint16_t):
+					*(uint16_t *)dev_addr =
+					    ddi_swap16(*(uint16_t *)host_addr);
+					break;
+				case sizeof (uint32_t):
+					*(uint32_t *)dev_addr =
+					    ddi_swap32(*(uint32_t *)host_addr);
+					break;
+				case sizeof (uint64_t):
+					*(uint64_t *)dev_addr =
+					    ddi_swap64(*(uint64_t *)host_addr);
+					break;
+				default:
+					err = DDI_FAILURE;
+					break;
+				}
+			} else {
+				switch (size) {
+				case sizeof (uint8_t):
+					*(uint8_t *)dev_addr =
+					    *(uint8_t *)host_addr;
+					break;
+				case sizeof (uint16_t):
+					*(uint16_t *)dev_addr =
+					    *(uint16_t *)host_addr;
+					break;
+				case sizeof (uint32_t):
+					*(uint32_t *)dev_addr =
+					    *(uint32_t *)host_addr;
+					break;
+				case sizeof (uint64_t):
+					*(uint64_t *)dev_addr =
+					    *(uint64_t *)host_addr;
+					break;
+				default:
+					err = DDI_FAILURE;
+					break;
+				}
+			}
+		}
+		host_addr += size;
+		if (flags == DDI_DEV_AUTOINCR)
+			dev_addr += size;
+	}
+	return (err);
+}
+
+
+int
+pci_fm_acc_setup(ddi_acc_hdl_t *hp, off_t offset, off_t len)
+{
+	ddi_acc_impl_t	*ap = (ddi_acc_impl_t *)hp->ah_platform_private;
+
+	/* endian-ness check */
+	if (hp->ah_acc.devacc_attr_endian_flags == DDI_STRUCTURE_BE_ACC)
+		return (DDI_FAILURE);
+
+	/*
+	 * range check
+	 */
+	if ((offset >= PCI_CONF_HDR_SIZE) ||
+	    (len > PCI_CONF_HDR_SIZE) ||
+	    (offset + len > PCI_CONF_HDR_SIZE))
+		return (DDI_FAILURE);
+
+	ap->ahi_acc_attr |= DDI_ACCATTR_CONFIG_SPACE;
+	/*
+	 * always use cautious mechanism for config space gets
+	 */
+	ap->ahi_get8 = i_ddi_caut_get8;
+	ap->ahi_get16 = i_ddi_caut_get16;
+	ap->ahi_get32 = i_ddi_caut_get32;
+	ap->ahi_get64 = i_ddi_caut_get64;
+	ap->ahi_rep_get8 = i_ddi_caut_rep_get8;
+	ap->ahi_rep_get16 = i_ddi_caut_rep_get16;
+	ap->ahi_rep_get32 = i_ddi_caut_rep_get32;
+	ap->ahi_rep_get64 = i_ddi_caut_rep_get64;
+	if (hp->ah_acc.devacc_attr_access == DDI_CAUTIOUS_ACC) {
+		ap->ahi_put8 = i_ddi_caut_put8;
+		ap->ahi_put16 = i_ddi_caut_put16;
+		ap->ahi_put32 = i_ddi_caut_put32;
+		ap->ahi_put64 = i_ddi_caut_put64;
+		ap->ahi_rep_put8 = i_ddi_caut_rep_put8;
+		ap->ahi_rep_put16 = i_ddi_caut_rep_put16;
+		ap->ahi_rep_put32 = i_ddi_caut_rep_put32;
+		ap->ahi_rep_put64 = i_ddi_caut_rep_put64;
+	} else {
+		ap->ahi_put8 = pci_config_wr8;
+		ap->ahi_put16 = pci_config_wr16;
+		ap->ahi_put32 = pci_config_wr32;
+		ap->ahi_put64 = pci_config_wr64;
+		ap->ahi_rep_put8 = pci_config_rep_wr8;
+		ap->ahi_rep_put16 = pci_config_rep_wr16;
+		ap->ahi_rep_put32 = pci_config_rep_wr32;
+		ap->ahi_rep_put64 = pci_config_rep_wr64;
+	}
+
+	/* Initialize to default check/notify functions */
+	ap->ahi_fault_check = i_ddi_acc_fault_check;
+	ap->ahi_fault_notify = i_ddi_acc_fault_notify;
+	ap->ahi_fault = 0;
+	impl_acc_err_init(hp);
+	return (DDI_SUCCESS);
+}
+
+
+int
+pci_common_ctlops_peek(peekpoke_ctlops_t *in_args)
+{
+	size_t size = in_args->size;
+	uintptr_t dev_addr = in_args->dev_addr;
+	uintptr_t host_addr = in_args->host_addr;
+	ddi_acc_impl_t *hp = (ddi_acc_impl_t *)in_args->handle;
+	ddi_acc_hdl_t *hdlp = (ddi_acc_hdl_t *)in_args->handle;
+	size_t repcount = in_args->repcount;
+	uint_t flags = in_args->flags;
+	int err = DDI_SUCCESS;
+
+	/*
+	 * if no handle then this is a peek. We have to return failure here
+	 * as we have no way of knowing whether this is a MEM or IO space access
+	 */
+	if (in_args->handle == NULL)
+		return (DDI_FAILURE);
+
+	for (; repcount; repcount--) {
+		if (hp->ahi_acc_attr == DDI_ACCATTR_CONFIG_SPACE) {
+			switch (size) {
+			case sizeof (uint8_t):
+				*(uint8_t *)host_addr = pci_config_rd8(hp,
+				    (uint8_t *)dev_addr);
+				break;
+			case sizeof (uint16_t):
+				*(uint16_t *)host_addr = pci_config_rd16(hp,
+				    (uint16_t *)dev_addr);
+				break;
+			case sizeof (uint32_t):
+				*(uint32_t *)host_addr = pci_config_rd32(hp,
+				    (uint32_t *)dev_addr);
+				break;
+			case sizeof (uint64_t):
+				*(uint64_t *)host_addr = pci_config_rd64(hp,
+				    (uint64_t *)dev_addr);
+				break;
+			default:
+				err = DDI_FAILURE;
+				break;
+			}
+		} else if (hp->ahi_acc_attr & DDI_ACCATTR_IO_SPACE) {
+			if (hdlp->ah_acc.devacc_attr_endian_flags ==
+			    DDI_STRUCTURE_BE_ACC) {
+				switch (size) {
+				case sizeof (uint8_t):
+					*(uint8_t *)host_addr =
+					    i_ddi_io_get8(hp,
+					    (uint8_t *)dev_addr);
+					break;
+				case sizeof (uint16_t):
+					*(uint16_t *)host_addr =
+					    i_ddi_io_swap_get16(hp,
+					    (uint16_t *)dev_addr);
+					break;
+				case sizeof (uint32_t):
+					*(uint32_t *)host_addr =
+					    i_ddi_io_swap_get32(hp,
+					    (uint32_t *)dev_addr);
+					break;
+				/*
+				 * note the 64-bit case is a dummy
+				 * function - so no need to swap
+				 */
+				case sizeof (uint64_t):
+					*(uint64_t *)host_addr =
+					    i_ddi_io_get64(hp,
+					    (uint64_t *)dev_addr);
+					break;
+				default:
+					err = DDI_FAILURE;
+					break;
+				}
+			} else {
+				switch (size) {
+				case sizeof (uint8_t):
+					*(uint8_t *)host_addr =
+					    i_ddi_io_get8(hp,
+					    (uint8_t *)dev_addr);
+					break;
+				case sizeof (uint16_t):
+					*(uint16_t *)host_addr =
+					    i_ddi_io_get16(hp,
+					    (uint16_t *)dev_addr);
+					break;
+				case sizeof (uint32_t):
+					*(uint32_t *)host_addr =
+					    i_ddi_io_get32(hp,
+					    (uint32_t *)dev_addr);
+					break;
+				case sizeof (uint64_t):
+					*(uint64_t *)host_addr =
+					    i_ddi_io_get64(hp,
+					    (uint64_t *)dev_addr);
+					break;
+				default:
+					err = DDI_FAILURE;
+					break;
+				}
+			}
+		} else {
+			if (hdlp->ah_acc.devacc_attr_endian_flags ==
+			    DDI_STRUCTURE_BE_ACC) {
+				switch (in_args->size) {
+				case sizeof (uint8_t):
+					*(uint8_t *)host_addr =
+					    *(uint8_t *)dev_addr;
+					break;
+				case sizeof (uint16_t):
+					*(uint16_t *)host_addr =
+					    ddi_swap16(*(uint16_t *)dev_addr);
+					break;
+				case sizeof (uint32_t):
+					*(uint32_t *)host_addr =
+					    ddi_swap32(*(uint32_t *)dev_addr);
+					break;
+				case sizeof (uint64_t):
+					*(uint64_t *)host_addr =
+					    ddi_swap64(*(uint64_t *)dev_addr);
+					break;
+				default:
+					err = DDI_FAILURE;
+					break;
+				}
+			} else {
+				switch (in_args->size) {
+				case sizeof (uint8_t):
+					*(uint8_t *)host_addr =
+					    *(uint8_t *)dev_addr;
+					break;
+				case sizeof (uint16_t):
+					*(uint16_t *)host_addr =
+					    *(uint16_t *)dev_addr;
+					break;
+				case sizeof (uint32_t):
+					*(uint32_t *)host_addr =
+					    *(uint32_t *)dev_addr;
+					break;
+				case sizeof (uint64_t):
+					*(uint64_t *)host_addr =
+					    *(uint64_t *)dev_addr;
+					break;
+				default:
+					err = DDI_FAILURE;
+					break;
+				}
+			}
+		}
+		host_addr += size;
+		if (flags == DDI_DEV_AUTOINCR)
+			dev_addr += size;
+	}
+	return (err);
+}
+
+/*ARGSUSED*/
+int
+pci_common_peekpoke(dev_info_t *dip, dev_info_t *rdip,
+	ddi_ctl_enum_t ctlop, void *arg, void *result)
+{
+	if (ctlop == DDI_CTLOPS_PEEK)
+		return (pci_common_ctlops_peek((peekpoke_ctlops_t *)arg));
+	else
+		return (pci_common_ctlops_poke((peekpoke_ctlops_t *)arg));
+}
+
 /*
  * These are the get and put functions to be shared with drivers. The
  * mutex locking is done inside the functions referenced, rather than
--- a/usr/src/uts/i86pc/io/pci/pci_common.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/pci/pci_common.h	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -42,6 +41,10 @@
 /* State structure. */
 typedef struct pci_state {
 	dev_info_t *pci_dip;
+	int pci_fmcap;
+	ddi_iblock_cookie_t pci_fm_ibc;
+	kmutex_t pci_peek_poke_mutex;
+	kmutex_t pci_err_mutex;
 } pci_state_t;
 
 /* AMD's northbridges vendor-id and device-ids */
@@ -121,6 +124,9 @@
  */
 int	pci_common_get_reg_prop(dev_info_t *dip, pci_regspec_t *pci_rp);
 int	pci_common_name_child(dev_info_t *child, char *name, int namelen);
+int	pci_common_peekpoke(dev_info_t *dip, dev_info_t *rdip,
+	ddi_ctl_enum_t ctlop, void *arg, void *result);
+int	pci_fm_acc_setup(ddi_acc_hdl_t *hp, off_t offset, off_t len);
 
 #ifdef	__cplusplus
 }
--- a/usr/src/uts/i86pc/io/pciex/npe.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/pciex/npe.c	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -38,6 +37,10 @@
 #include <sys/sysmacros.h>
 #include <sys/ddi_intr.h>
 #include <sys/sunndi.h>
+#include <sys/sunddi.h>
+#include <sys/ddifm.h>
+#include <sys/ndifm.h>
+#include <sys/fm/util.h>
 #include <sys/hotplug/pci/pcihp.h>
 #include <io/pci/pci_common.h>
 #include <io/pci/pci_tools_ext.h>
@@ -48,11 +51,14 @@
  */
 static int	npe_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
 		    off_t, off_t, caddr_t *);
-static int	npe_map_legacy_pci(off_t, off_t, caddr_t *, ddi_acc_hdl_t *);
 static int	npe_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
 		    void *, void *);
 static int	npe_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t,
 		    ddi_intr_handle_impl_t *, void *);
+static int	npe_fm_init(dev_info_t *, dev_info_t *, int,
+		    ddi_iblock_cookie_t *);
+
+static int	npe_fm_callback(dev_info_t *, ddi_fm_error_t *, const void *);
 
 struct bus_ops npe_bus_ops = {
 	BUSO_REV,
@@ -78,7 +84,7 @@
 	0,		/* (*bus_intr_ctl)(); */
 	0,		/* (*bus_config)(); */
 	0,		/* (*bus_unconfig)(); */
-	NULL,		/* (*bus_fm_init)(); */
+	npe_fm_init,	/* (*bus_fm_init)(); */
 	NULL,		/* (*bus_fm_fini)(); */
 	NULL,		/* (*bus_fm_access_enter)(); */
 	NULL,		/* (*bus_fm_access_exit)(); */
@@ -145,7 +151,6 @@
  */
 static int npe_removechild(dev_info_t *child);
 static int npe_initchild(dev_info_t *child);
-static int npe_check_if_device_is_pci(dev_info_t *);
 
 /*
  * External support routine
@@ -211,7 +216,6 @@
 	return (mod_info(&modlinkage, modinfop));
 }
 
-
 /*ARGSUSED*/
 static int
 npe_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
@@ -254,6 +258,12 @@
 		ddi_soft_state_free(npe_statep, instance);
 		return (DDI_FAILURE);
 	}
+	pcip->pci_fmcap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE |
+	    DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
+	ddi_fm_init(devi, &pcip->pci_fmcap, &pcip->pci_fm_ibc);
+
+	if (pcip->pci_fmcap & DDI_FM_ERRCB_CAPABLE)
+		ddi_fm_handler_register(devi, npe_fm_callback, NULL);
 
 	npe_query_acpi_mcfg(devi);
 	ddi_report_dev(devi);
@@ -267,6 +277,9 @@
 npe_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
 {
 	int instance = ddi_get_instance(devi);
+	pci_state_t *pcip;
+
+	pcip = ddi_get_soft_state(npe_statep, ddi_get_instance(devi));
 
 	/* Uninitialize pcitool support. */
 	pcitool_uninit(devi);
@@ -275,6 +288,11 @@
 	 * Uninitialize hotplug support on this bus.
 	 */
 	(void) pcihp_uninit(devi);
+
+	if (pcip->pci_fmcap & DDI_FM_ERRCB_CAPABLE)
+		ddi_fm_handler_unregister(devi);
+
+	ddi_fm_fini(devi);
 	ddi_soft_state_free(npe_statep, instance);
 	return (DDI_SUCCESS);
 }
@@ -287,14 +305,14 @@
 	int 		rnumber;
 	int		length;
 	int		space;
-	dev_info_t	*parent;
+	ddi_acc_impl_t	*ap;
 	ddi_acc_hdl_t	*hp;
 	ddi_map_req_t	mr;
 	pci_regspec_t	pci_reg;
 	pci_regspec_t	*pci_rp;
 	struct regspec	reg;
 	pci_acc_cfblk_t	*cfp;
-
+	int		retval;
 
 	mr = *mp; /* Get private copy of request */
 	mp = &mr;
@@ -359,46 +377,40 @@
 	 * check for unmap and unlock of address space
 	 */
 	if ((mp->map_op == DDI_MO_UNMAP) || (mp->map_op == DDI_MO_UNLOCK)) {
-		/*
-		 * Adjust offset and length
-		 * A non-zero length means override the one in the regspec.
-		 */
-		pci_rp->pci_phys_low += (uint_t)offset;
-		if (len != 0)
-			pci_rp->pci_size_low = len;
-
 		switch (space) {
 		case PCI_ADDR_IO:
 			reg.regspec_bustype = 1;
 			break;
 
 		case PCI_ADDR_CONFIG:
-			/* Check for AMD's northbridges */
-			if (is_amd_northbridge(rdip) == 0)
-				return (DDI_SUCCESS);
-
 			/*
+			 * Check for AMD's northbridges
+			 *	AND
+			 * for any PCI device.
 			 *
-			 * Next two checks are workarounds to fix
+			 * This is a workaround fix for
 			 * AMD-8132's inability to handle MMCFG
-			 * accesses on Galaxy's PE servers.
+			 * accesses on Galaxy's PE servers
+			 *	AND
+			 * to disable MMCFG for any PCI device.
 			 *
-			 * Solution: Check if device_type is "pci"
-			 * and for any such device do I/O based config space
-			 * access.
-			 *
-			 * Leaf devices under AMD-8132 may not
-			 * have a device_type of "pci". This was observed
-			 * during testing. Hence, if first check fails
-			 * then check if the parent has "device_type"
-			 * of "pci" and allow I/O based config space access
+			 * If a device is *not* found to have PCIe
+			 * capability, then assume it is a PCI device.
 			 */
-			if (npe_check_if_device_is_pci(rdip))
-				return (DDI_SUCCESS);
 
-			parent = ddi_get_parent(rdip);
-			if (parent && npe_check_if_device_is_pci(parent))
+			if (is_amd_northbridge(rdip) == 0 ||
+			    (ddi_prop_get_int(DDI_DEV_T_ANY, rdip,
+			    DDI_PROP_DONTPASS, "pcie-capid-pointer",
+			    PCI_CAP_NEXT_PTR_NULL) == PCI_CAP_NEXT_PTR_NULL)) {
+				if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) &&
+				    mp->map_handlep->ah_acc.devacc_attr_access
+				    != DDI_DEFAULT_ACC) {
+					ndi_fmc_remove(rdip, ACC_HANDLE,
+					    (void *)mp->map_handlep);
+				}
 				return (DDI_SUCCESS);
+			}
+
 
 			/* FALLTHROUGH */
 		case PCI_ADDR_MEM64:
@@ -416,11 +428,27 @@
 		default:
 			return (DDI_FAILURE);
 		}
+
+		/*
+		 * Adjust offset and length
+		 * A non-zero length means override the one in the regspec.
+		 */
+		pci_rp->pci_phys_low += (uint_t)offset;
+		if (len != 0)
+			pci_rp->pci_size_low = len;
+
 		reg.regspec_addr = pci_rp->pci_phys_low;
 		reg.regspec_size = pci_rp->pci_size_low;
 
 		mp->map_obj.rp = &reg;
-		return (ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp));
+		retval = ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp);
+		if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) &&
+		    mp->map_handlep->ah_acc.devacc_attr_access !=
+		    DDI_DEFAULT_ACC) {
+			ndi_fmc_remove(rdip, ACC_HANDLE,
+			    (void *)mp->map_handlep);
+		}
+		return (retval);
 
 	}
 
@@ -431,6 +459,11 @@
 	}
 
 
+	/*
+	 * Note that pci_fm_acc_setup() is called to serve two purposes
+	 * i) enable legacy PCI I/O style config space access
+	 * ii) register with FMA
+	 */
 	if (space == PCI_ADDR_CONFIG) {
 		/* Can't map config space without a handle */
 		hp = (ddi_acc_hdl_t *)mp->map_handlep;
@@ -443,16 +476,30 @@
 		cfp->c_devnum = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
 		cfp->c_funcnum = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
 
-		/* Check for AMD's northbridges */
-		if (is_amd_northbridge(rdip) == 0)
-			return (npe_map_legacy_pci(offset, len, vaddrp, hp));
+		*vaddrp = (caddr_t)offset;
 
-		if (npe_check_if_device_is_pci(rdip))
-			return (npe_map_legacy_pci(offset, len, vaddrp, hp));
+		/*
+		 * Check for AMD's northbridges, pci devices and
+		 * devices underneath a pci bridge.  This is to setup
+		 * I/O based config space access.
+		 */
+		if (is_amd_northbridge(rdip) == 0 ||
+		    (ddi_prop_get_int(DDI_DEV_T_ANY, rdip, DDI_PROP_DONTPASS,
+		    "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL) ==
+		    PCI_CAP_NEXT_PTR_NULL)) {
+			int ret;
 
-		parent = ddi_get_parent(rdip);
-		if (parent && npe_check_if_device_is_pci(parent))
-			return (npe_map_legacy_pci(offset, len, vaddrp, hp));
+			if ((ret = pci_fm_acc_setup(hp, offset, len)) ==
+			    DDI_SUCCESS) {
+				if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) &&
+				    mp->map_handlep->ah_acc.devacc_attr_access
+				    != DDI_DEFAULT_ACC) {
+					ndi_fmc_insert(rdip, ACC_HANDLE,
+					    (void *)mp->map_handlep, NULL);
+				}
+			}
+			return (ret);
+		}
 
 		pci_rp->pci_phys_low = ddi_prop_get_int64(DDI_DEV_T_ANY,
 		    rdip, 0, "ecfga-base-address", 0);
@@ -510,64 +557,36 @@
 	reg.regspec_size = pci_rp->pci_size_low;
 
 	mp->map_obj.rp = &reg;
-	return (ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp));
+	retval = ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp);
+	if (retval == DDI_SUCCESS) {
+		/*
+		 * For config space gets force use of cautious access routines.
+		 * These will handle default and protected mode accesses too.
+		 */
+		if (space == PCI_ADDR_CONFIG) {
+			ap = (ddi_acc_impl_t *)mp->map_handlep;
+			ap->ahi_acc_attr &= ~DDI_ACCATTR_DIRECT;
+			ap->ahi_acc_attr |= DDI_ACCATTR_CONFIG_SPACE;
+			ap->ahi_get8 = i_ddi_caut_get8;
+			ap->ahi_get16 = i_ddi_caut_get16;
+			ap->ahi_get32 = i_ddi_caut_get32;
+			ap->ahi_get64 = i_ddi_caut_get64;
+			ap->ahi_rep_get8 = i_ddi_caut_rep_get8;
+			ap->ahi_rep_get16 = i_ddi_caut_rep_get16;
+			ap->ahi_rep_get32 = i_ddi_caut_rep_get32;
+			ap->ahi_rep_get64 = i_ddi_caut_rep_get64;
+		}
+		if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) &&
+		    mp->map_handlep->ah_acc.devacc_attr_access !=
+		    DDI_DEFAULT_ACC) {
+			ndi_fmc_insert(rdip, ACC_HANDLE,
+			    (void *)mp->map_handlep, NULL);
+		}
+	}
+	return (retval);
 }
 
 
-static int
-npe_map_legacy_pci(off_t offset, off_t len, caddr_t *vaddrp, ddi_acc_hdl_t *hp)
-{
-	ddi_acc_impl_t	*ap;
-
-	/*
-	 * check for config space
-	 * On x86, CONFIG is not mapped via MMU and there is
-	 * no endian-ness issues. Set the attr field in the handle to
-	 * indicate that the common routines to call the nexus driver.
-	 */
-
-	ap = (ddi_acc_impl_t *)hp->ah_platform_private;
-
-	/* endian-ness check */
-	if (hp->ah_acc.devacc_attr_endian_flags == DDI_STRUCTURE_BE_ACC)
-		return (DDI_FAILURE);
-
-	/*
-	 * range check
-	 */
-	if ((offset >= PCI_CONF_HDR_SIZE) ||
-	    (len > PCI_CONF_HDR_SIZE) ||
-	    (offset + len > PCI_CONF_HDR_SIZE))
-		return (DDI_FAILURE);
-	*vaddrp = (caddr_t)offset;
-
-	ap->ahi_acc_attr |= DDI_ACCATTR_CONFIG_SPACE;
-	ap->ahi_put8 = pci_config_wr8;
-	ap->ahi_get8 = pci_config_rd8;
-	ap->ahi_put64 = pci_config_wr64;
-	ap->ahi_get64 = pci_config_rd64;
-	ap->ahi_rep_put8 = pci_config_rep_wr8;
-	ap->ahi_rep_get8 = pci_config_rep_rd8;
-	ap->ahi_rep_put64 = pci_config_rep_wr64;
-	ap->ahi_rep_get64 = pci_config_rep_rd64;
-	ap->ahi_get16 = pci_config_rd16;
-	ap->ahi_get32 = pci_config_rd32;
-	ap->ahi_put16 = pci_config_wr16;
-	ap->ahi_put32 = pci_config_wr32;
-	ap->ahi_rep_get16 = pci_config_rep_rd16;
-	ap->ahi_rep_get32 = pci_config_rep_rd32;
-	ap->ahi_rep_put16 = pci_config_rep_wr16;
-	ap->ahi_rep_put32 = pci_config_rep_wr32;
-
-	/* Initialize to default check/notify functions */
-	ap->ahi_fault_check = i_ddi_acc_fault_check;
-	ap->ahi_fault_notify = i_ddi_acc_fault_notify;
-	ap->ahi_fault = 0;
-	impl_acc_err_init(hp);
-
-	return (DDI_SUCCESS);
-}
-
 
 /*ARGSUSED*/
 static int
@@ -638,6 +657,10 @@
 		break;
 	}
 
+	case DDI_CTLOPS_PEEK:
+	case DDI_CTLOPS_POKE:
+		return (pci_common_peekpoke(dip, rdip, ctlop, arg, result));
+
 	default:
 		break;
 	}
@@ -814,18 +837,23 @@
 	return (pcihp_info(dip, cmd, arg, result));
 }
 
+/*ARGSUSED*/
 static int
-npe_check_if_device_is_pci(dev_info_t *child)
+npe_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
+    ddi_iblock_cookie_t *ibc)
 {
-	int		ret = 0;
-	char		*dev_type = NULL;
+	pci_state_t  *pcip = ddi_get_soft_state(npe_statep,
+	    ddi_get_instance(dip));
 
-	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
-	    "device_type", &dev_type) == DDI_SUCCESS) {
-		if (strcmp(dev_type, "pci") == 0)
-			ret = 1;
-		ddi_prop_free(dev_type);
-	}
+	ASSERT(ibc != NULL);
+	*ibc = pcip->pci_fm_ibc;
+
+	return (pcip->pci_fmcap);
+}
 
-	return (ret);
+/*ARGSUSED*/
+static int
+npe_fm_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *no_used)
+{
+	return (ndi_fm_handler_dispatch(dip, NULL, derr));
 }
--- a/usr/src/uts/i86pc/io/pciex/pcie_ck804_boot.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/pciex/pcie_ck804_boot.c	Sun Apr 23 15:26:28 2006 -0700
@@ -40,15 +40,16 @@
 /*
  * PCI Configuration (ck804, PCIe) related library functions
  */
-static boolean_t look_for_any_pciex_device(uchar_t);
+static boolean_t	look_for_any_pciex_device(uchar_t);
 
 /* Globals */
 extern int pci_boot_debug;
 
 boolean_t
-check_if_device_is_pciex(uchar_t bus, uchar_t dev, uchar_t func,
-    ushort_t *slot_number, ushort_t *is_pci_bridge)
+check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev,
+    uchar_t func, ushort_t *slot_number, ushort_t *is_pci_bridge)
 {
+	boolean_t found_pciex = B_FALSE;
 	ushort_t cap;
 	ushort_t capsp;
 	ushort_t cap_count = PCI_CAP_MAX_PTR;
@@ -66,6 +67,10 @@
 		capsp &= PCI_CAP_PTR_MASK;
 		cap = (*pci_getb_func)(bus, dev, func, capsp);
 
+		if (cap == PCI_CAP_ID_PCIX && cdip)
+			(void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
+			    "pcix-capid-pointer", capsp);
+
 		if (cap == PCI_CAP_ID_PCI_E) {
 #ifdef	DEBUG
 			if (pci_boot_debug)
@@ -94,13 +99,35 @@
 				    capsp + PCIE_SLOTCAP);
 				*slot_number =
 				    PCIE_SLOTCAP_PHY_SLOT_NUM(slot_cap);
+
+				if (cdip)
+					(void) ndi_prop_update_int(
+					    DDI_DEV_T_NONE, cdip,
+					    "pcie-slotcap-reg", slot_cap);
 			}
-			return (B_TRUE);
+
+			/*
+			 * Can only do I/O based config space access at
+			 * this early stage. Meaning, one cannot access
+			 * extended config space i.e. > 256 bytes.
+			 * So, AER cap_id property will be created much later.
+			 */
+			if (cdip) {
+				(void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
+				    "pcie-capid-reg",
+				    (*pci_getw_func)(bus, dev, func,
+					capsp + PCIE_PCIECAP));
+				(void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
+				    "pcie-capid-pointer", capsp);
+			}
+
+			found_pciex = B_TRUE;
 		}
 		capsp = (*pci_getb_func)(bus, dev, func,
 		    capsp + PCI_CAP_NEXT_PTR);
 	}
-	return (B_FALSE);
+
+	return (found_pciex);
 }
 
 
@@ -145,7 +172,7 @@
 			if ((func == 0) && (header & PCI_HEADER_MULTI))
 				nfunc = 8;
 
-			if (check_if_device_is_pciex(bus, dev, func,
+			if (check_if_device_is_pciex(NULL, bus, dev, func,
 			    &slot_num, &is_pci_bridge) == B_TRUE)
 				return (B_TRUE);
 		} /* end of func */
--- a/usr/src/uts/i86pc/io/pciex/pcie_ck804_boot.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/pciex/pcie_ck804_boot.h	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -37,8 +36,8 @@
 /*
  * PCI Configuration (ck804, PCIe) related library functions
  */
-boolean_t	check_if_device_is_pciex(uchar_t, uchar_t, uchar_t,
-		    ushort_t *, ushort_t *);
+boolean_t	check_if_device_is_pciex(dev_info_t *, uchar_t, uchar_t,
+		    uchar_t, ushort_t *, ushort_t *);
 boolean_t	create_pcie_root_bus(uchar_t, dev_info_t *);
 void		add_ck804_isa_bridge_props(dev_info_t *, uchar_t, uchar_t,
 		    uchar_t);
--- a/usr/src/uts/i86pc/io/pciex/pcie_error.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/pciex/pcie_error.c	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -73,6 +72,7 @@
 		    PCIE_DEVCTL_CE_REPORTING_EN | \
 		    PCIE_DEVCTL_NFE_REPORTING_EN | \
 		    PCIE_DEVCTL_FE_REPORTING_EN | \
+		    PCIE_DEVCTL_UR_REPORTING_EN | \
 		    PCIE_DEVCTL_RO_EN;
 
 /* PCI-Express AER Root Control Register */
@@ -92,9 +92,25 @@
  * Can be defined to mask off certain types of AER errors
  * By default all are set to 0; as no errors are masked
  */
-uint32_t	pcie_aer_uce_mask = 0;		/* Uncorrectable errors mask */
-uint32_t	pcie_aer_ce_mask = 0;		/* Correctable errors mask */
-uint32_t	pcie_aer_suce_mask = 0;		/* Secondary UNCOR error mask */
+uint32_t	pcie_aer_uce_mask = 0;
+uint32_t	pcie_aer_ce_mask = PCIE_AER_CE_AD_NFE;
+uint32_t	pcie_aer_suce_mask = 0;
+
+/*
+ * PCI-Express related severity (AER only)
+ * Used to set the severity levels of errors detected by devices on the PCI
+ * Express fabric, which in turn results in either a fatal or nonfatal error
+ * message to the root complex.  A set bit (1) indictates a fatal error, an
+ * unset one is nonfatal.  For more information refer to the PCI Express Base
+ * Specification and the PCI Express to PCI/PCI-X Bridge Specification.
+ * default values are set below:
+ */
+uint32_t	pcie_aer_uce_severity = PCIE_AER_UCE_MTLP | PCIE_AER_UCE_RO | \
+    PCIE_AER_UCE_FCP | PCIE_AER_UCE_SD | PCIE_AER_UCE_DLP | \
+    PCIE_AER_UCE_TRAINING;
+uint32_t	pcie_aer_suce_severity = PCIE_AER_SUCE_SERR_ASSERT | \
+    PCIE_AER_SUCE_UC_ADDR_ERR | PCIE_AER_SUCE_UC_ATTR_ERR | \
+    PCIE_AER_SUCE_USC_MSG_DATA_ERR;
 
 /*
  * By default, error handling is enabled
@@ -117,7 +133,7 @@
  */
 uint32_t	pcie_error_disable_flag = 0;
 uint32_t	pcie_serr_disable_flag = 1;
-uint32_t	pcie_aer_disable_flag = 1;
+uint32_t	pcie_aer_disable_flag = 0;
 
 /*
  * Function prototypes
@@ -125,7 +141,7 @@
 static void	pcie_error_clear_errors(ddi_acc_handle_t, uint16_t,
 		    uint16_t, uint16_t);
 static uint16_t pcie_error_find_cap_reg(ddi_acc_handle_t, uint8_t);
-static uint16_t	pcie_error_find_ext_cap_reg(ddi_acc_handle_t, uint16_t);
+static uint16_t	pcie_error_find_ext_aer_capid(ddi_acc_handle_t);
 static void	pcie_ck804_error_init(dev_info_t *, ddi_acc_handle_t,
 		    uint16_t, uint16_t);
 static void	pcie_ck804_error_fini(ddi_acc_handle_t, uint16_t, uint16_t);
@@ -145,6 +161,7 @@
 	uint16_t		device_ctl;
 	uint16_t		dev_type = 0;
 	uint32_t		aer_reg;
+	uint32_t		uce_mask = pcie_aer_uce_mask;
 
 	/*
 	 * flag to turn this off
@@ -199,8 +216,10 @@
 	/* Look for PCIe capability */
 	cap_ptr = pcie_error_find_cap_reg(cfg_hdl, PCI_CAP_ID_PCI_E);
 	if (cap_ptr != PCI_CAP_NEXT_PTR_NULL) {	/* PCIe found */
-		aer_ptr = pcie_error_find_ext_cap_reg(cfg_hdl,
-		    PCIE_EXT_CAP_ID_AER);
+		aer_ptr = pcie_error_find_ext_aer_capid(cfg_hdl);
+		if (aer_ptr != PCI_CAP_NEXT_PTR_NULL)
+			(void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
+			    "pcie-aer-pointer", aer_ptr);
 		dev_type = pci_config_get16(cfg_hdl, cap_ptr +
 		    PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
 	}
@@ -250,18 +269,31 @@
 	if (pcie_aer_disable_flag)
 		goto cleanup;
 
+	/* Disable PTLP/ECRC (or mask these two) for Switches */
+	if (dev_type == PCIE_PCIECAP_DEV_TYPE_UP ||
+	    dev_type == PCIE_PCIECAP_DEV_TYPE_DOWN)
+		uce_mask |= (PCIE_AER_UCE_PTLP | PCIE_AER_UCE_ECRC);
+
+	/* Set Uncorrectable error severity */
+	aer_reg = pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_UCE_SERV);
+	pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_UCE_SERV,
+	    pcie_aer_uce_severity);
+	PCIE_ERROR_DBG("%s: AER UCE severity=0x%x->0x%x\n",
+	    ddi_driver_name(cdip), aer_reg, pci_config_get32(cfg_hdl,
+	    aer_ptr + PCIE_AER_UCE_SERV));
+
 	/* Enable Uncorrectable errors */
 	aer_reg = pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_UCE_MASK);
 	pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_UCE_MASK,
-	    aer_reg | pcie_aer_uce_mask);
-	PCIE_ERROR_DBG("%s: AER UCE=0x%x->0x%x\n", ddi_driver_name(cdip),
+	    aer_reg | uce_mask);
+	PCIE_ERROR_DBG("%s: AER UCE mask=0x%x->0x%x\n", ddi_driver_name(cdip),
 	    aer_reg, pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_UCE_MASK));
 
 	/* Enable Correctable errors */
 	aer_reg = pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_CE_MASK);
 	pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_CE_MASK,
 	    aer_reg | pcie_aer_ce_mask);
-	PCIE_ERROR_DBG("%s: AER CE=0x%x->0x%x\n", ddi_driver_name(cdip),
+	PCIE_ERROR_DBG("%s: AER CE mask=0x%x->0x%x\n", ddi_driver_name(cdip),
 	    aer_reg, pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_CE_MASK));
 
 	/*
@@ -270,13 +302,21 @@
 	if (!(dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI))
 		goto cleanup;
 
+	/* Set Secondary Uncorrectable error severity */
+	aer_reg = pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_SERV);
+	pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_SERV,
+	    pcie_aer_suce_severity);
+	PCIE_ERROR_DBG("%s: AER SUCE severity=0x%x->0x%x\n",
+	    ddi_driver_name(cdip), aer_reg,
+	    pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_SERV));
+
 	/*
 	 * Enable secondary bus errors
 	 */
 	aer_reg = pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_MASK);
 	pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_MASK,
 	    aer_reg | pcie_aer_suce_mask);
-	PCIE_ERROR_DBG("%s: AER SUCE=0x%x->0x%x\n",
+	PCIE_ERROR_DBG("%s: AER SUCE mask=0x%x->0x%x\n",
 	    ddi_driver_name(cdip), aer_reg,
 	    pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_MASK));
 
@@ -317,6 +357,14 @@
 		PCIE_ERROR_DBG("%s: PCIe AER Root Error Command "
 		    "Register=0x%x->0x%x\n", ddi_driver_name(child), rc_ctl,
 		    pci_config_get16(cfg_hdl, aer_ptr + PCIE_AER_RE_CMD));
+
+		/* Also enable ECRC checking */
+		rc_ctl = pci_config_get16(cfg_hdl, aer_ptr + PCIE_AER_CTL);
+		if (rc_ctl & PCIE_AER_CTL_ECRC_GEN_CAP)
+			rc_ctl |= PCIE_AER_CTL_ECRC_GEN_ENA;
+		if (rc_ctl & PCIE_AER_CTL_ECRC_CHECK_CAP)
+			rc_ctl |= PCIE_AER_CTL_ECRC_CHECK_ENA;
+		pci_config_put16(cfg_hdl, aer_ptr + PCIE_AER_CTL, rc_ctl);
 	}
 }
 
@@ -377,7 +425,8 @@
 	/* Disable PCI-Express Baseline Error Handling */
 	pci_config_put16(cfg_hdl, cap_ptr + PCIE_DEVCTL, 0x0);
 
-	aer_ptr = pcie_error_find_ext_cap_reg(cfg_hdl, PCIE_EXT_CAP_ID_AER);
+	aer_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS,
+	    "pcie-aer-pointer", PCIE_EXT_CAP_NEXT_PTR_NULL);
 
 	/*
 	 * Only disable these set of errors for CK8-04/IO-4 devices
@@ -433,6 +482,14 @@
 		rc_ctl = pci_config_get16(cfg_hdl, aer_ptr + PCIE_AER_RE_CMD);
 		rc_ctl &= ~pcie_root_error_cmd_default;
 		pci_config_put16(cfg_hdl, aer_ptr + PCIE_AER_RE_CMD, rc_ctl);
+
+		/* Disable ECRC checking */
+		rc_ctl = pci_config_get16(cfg_hdl, aer_ptr + PCIE_AER_CTL);
+		if (rc_ctl & PCIE_AER_CTL_ECRC_GEN_CAP)
+			rc_ctl &= ~PCIE_AER_CTL_ECRC_GEN_ENA;
+		if (rc_ctl & PCIE_AER_CTL_ECRC_CHECK_CAP)
+			rc_ctl &= ~PCIE_AER_CTL_ECRC_CHECK_ENA;
+		pci_config_put16(cfg_hdl, aer_ptr + PCIE_AER_CTL, rc_ctl);
 	}
 }
 
@@ -509,7 +566,7 @@
  * for the pci-express capability id pointer.
  */
 static uint16_t
-pcie_error_find_ext_cap_reg(ddi_acc_handle_t cfg_hdl, uint16_t cap_id)
+pcie_error_find_ext_aer_capid(ddi_acc_handle_t cfg_hdl)
 {
 	uint32_t	hdr, hdr_next_ptr, hdr_cap_id;
 	uint16_t	offset = P2ALIGN(PCIE_EXT_CAP, 4);
@@ -520,7 +577,7 @@
 	hdr_cap_id = (hdr >> PCIE_EXT_CAP_ID_SHIFT) & PCIE_EXT_CAP_ID_MASK;
 
 	while ((hdr_next_ptr != PCIE_EXT_CAP_NEXT_PTR_NULL) &&
-	    (hdr_cap_id != cap_id)) {
+	    (hdr_cap_id != PCIE_EXT_CAP_ID_AER)) {
 		offset = P2ALIGN(hdr_next_ptr, 4);
 		hdr = pci_config_get32(cfg_hdl, offset);
 		hdr_next_ptr = (hdr >> PCIE_EXT_CAP_NEXT_PTR_SHIFT) &
@@ -529,7 +586,7 @@
 		    PCIE_EXT_CAP_ID_MASK;
 	}
 
-	if (hdr_cap_id == cap_id)
+	if (hdr_cap_id == PCIE_EXT_CAP_ID_AER)
 		return (P2ALIGN(offset, 4));
 
 	return (PCIE_EXT_CAP_NEXT_PTR_NULL);
--- a/usr/src/uts/i86pc/io/pciex/pcie_pci.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/pciex/pcie_pci.c	Sun Apr 23 15:26:28 2006 -0700
@@ -40,6 +40,10 @@
 #include <sys/ddi.h>
 #include <sys/sunddi.h>
 #include <sys/sunndi.h>
+#include <sys/ddifm.h>
+#include <sys/ndifm.h>
+#include <sys/fm/util.h>
+#include <sys/fm/protocol.h>
 #include <sys/pcie.h>
 #include <sys/pcie_impl.h>
 #include <sys/hotplug/pci/pcihp.h>
@@ -61,6 +65,10 @@
 		    off_t, caddr_t *);
 static int	pepb_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *,
 		    void *);
+static int	pepb_fm_init(dev_info_t *, dev_info_t *, int,
+		    ddi_iblock_cookie_t *);
+
+static int	pepb_fm_callback(dev_info_t *, ddi_fm_error_t *, const void *);
 
 struct bus_ops pepb_bus_ops = {
 	BUSO_REV,
@@ -86,7 +94,7 @@
 	0,		/* (*bus_intr_ctl)();		*/
 	0,		/* (*bus_config)(); 		*/
 	0,		/* (*bus_unconfig)(); 		*/
-	NULL,		/* (*bus_fm_init)(); 		*/
+	pepb_fm_init,	/* (*bus_fm_init)(); 		*/
 	NULL,		/* (*bus_fm_fini)(); 		*/
 	NULL,		/* (*bus_fm_access_enter)(); 	*/
 	NULL,		/* (*bus_fm_access_exit)(); 	*/
@@ -129,6 +137,7 @@
 static int	pepb_probe(dev_info_t *);
 static int	pepb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
 static int	pepb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
+static int	pepb_check_slot_disabled(dev_info_t *dip);
 
 struct dev_ops pepb_ops = {
 	DEVO_REV,		/* devo_rev */
@@ -200,13 +209,18 @@
 	/*
 	 * interrupt support
 	 */
-	ddi_intr_handle_t	*htable;	/* Intr Handlers */
+	ddi_intr_handle_t	*htable;	/* interrupt handles */
 	int			htable_size;	/* htable size */
 	int			intr_count;	/* Num of Intr */
 	uint_t			intr_priority;	/* Intr Priority */
 	int			intr_type;	/* (MSI | FIXED) */
 	uint32_t		soft_state;	/* soft state flags */
 	kmutex_t		pepb_mutex;	/* Mutex for this ctrl */
+	kmutex_t		pepb_err_mutex;	/* Error handling mutex */
+	kmutex_t		pepb_peek_poke_mutex;
+	int			pepb_fmcap;
+	ddi_iblock_cookie_t	pepb_fm_ibc;
+	int			port_type;
 } pepb_devstate_t;
 
 /* soft state flags */
@@ -220,6 +234,14 @@
 /* default interrupt priority for all interrupts (hotplug or non-hotplug */
 #define	PEPB_INTR_PRI	1
 
+/* flag to turn on MSI support */
+static int pepb_enable_msi = 1;
+/* panic on unknown flag, defaulted to on */
+int pepb_panic_unknown = 1;
+int pepb_panic_fatal = 1;
+
+extern errorq_t *pci_target_queue;
+
 /*
  * forward function declarations:
  */
@@ -230,10 +252,12 @@
 static int	pepb_pcie_device_type(dev_info_t *dip, int *port_type);
 static int	pepb_pcie_port_type(dev_info_t *dip,
 			ddi_acc_handle_t config_handle);
-static int	pepb_get_cap(ddi_acc_handle_t config_handle, uint8_t cap_id);
 
 /* interrupt related declarations */
-static uint_t	pepb_intr(caddr_t arg, caddr_t arg2);
+static uint_t	pepb_intx_intr(caddr_t arg, caddr_t arg2);
+static uint_t	pepb_pwr_msi_intr(caddr_t arg, caddr_t arg2);
+static uint_t	pepb_err_msi_intr(caddr_t arg, caddr_t arg2);
+static int	pepb_is_ck804_root_port(dev_info_t *);
 static int	pepb_intr_init(pepb_devstate_t *pepb_p, int intr_type);
 static void	pepb_intr_fini(pepb_devstate_t *pepb_p);
 
@@ -253,8 +277,15 @@
 {
 	int e;
 
-	if ((e = mod_remove(&modlinkage)) == 0)
+	if ((e = mod_remove(&modlinkage)) == 0) {
+		/*
+		 * Destroy pci_target_queue, and set it to NULL.
+		 */
+		if (pci_target_queue)
+			errorq_destroy(pci_target_queue);
+		pci_target_queue = NULL;
 		ddi_soft_state_fini(&pepb_state);
+	}
 	return (e);
 }
 
@@ -275,7 +306,6 @@
 pepb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
 {
 	int			instance;
-	int			port_type;
 	int			intr_types;
 	char			device_type[8];
 	pepb_devstate_t		*pepb;
@@ -299,6 +329,14 @@
 	}
 
 	/*
+	 * If PCIE_LINKCTL_LINK_DISABLE bit in the PCIe Config
+	 * Space (PCIe Capability Link Control Register) is set,
+	 * then do not bind the driver.
+	 */
+	if (pepb_check_slot_disabled(devi) == 1)
+		return (DDI_FAILURE);
+
+	/*
 	 * Allocate and get soft state structure.
 	 */
 	instance = ddi_get_instance(devi);
@@ -308,9 +346,28 @@
 	pepb->dip = devi;
 
 	/*
+	 * initalise fma support before we start accessing config space
+	 */
+	pci_targetq_init();
+	pepb->pepb_fmcap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE |
+	    DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
+	ddi_fm_init(devi, &pepb->pepb_fmcap, &pepb->pepb_fm_ibc);
+
+	mutex_init(&pepb->pepb_err_mutex, NULL, MUTEX_DRIVER,
+	    (void *)pepb->pepb_fm_ibc);
+	mutex_init(&pepb->pepb_peek_poke_mutex, NULL, MUTEX_DRIVER,
+	    (void *)pepb->pepb_fm_ibc);
+
+	if (pepb->pepb_fmcap & (DDI_FM_ERRCB_CAPABLE|DDI_FM_EREPORT_CAPABLE))
+		pci_ereport_setup(devi);
+
+	if (pepb->pepb_fmcap & DDI_FM_ERRCB_CAPABLE)
+		ddi_fm_handler_register(devi, pepb_fm_callback, NULL);
+
+	/*
 	 * Make sure the "device_type" property exists.
 	 */
-	if (pepb_pcie_device_type(devi, &port_type) == DDI_SUCCESS)
+	if (pepb_pcie_device_type(devi, &pepb->port_type) == DDI_SUCCESS)
 		(void) strcpy(device_type, "pciex");
 	else
 		(void) strcpy(device_type, "pci");
@@ -326,6 +383,19 @@
 	if (ddi_intr_get_supported_types(devi, &intr_types) != DDI_SUCCESS)
 		goto next_step;
 
+	PEPB_DEBUG((CE_NOTE, "%s#%d: intr_types = 0x%x\n",
+	    ddi_driver_name(devi), ddi_get_instance(devi), intr_types));
+
+	if (pepb_enable_msi && (intr_types & DDI_INTR_TYPE_MSI) &&
+	    pepb_is_ck804_root_port(devi) == DDI_SUCCESS) {
+		if (pepb_intr_init(pepb, DDI_INTR_TYPE_MSI) == DDI_SUCCESS)
+			goto next_step;
+		else
+			PEPB_DEBUG((CE_WARN,
+			    "%s#%d: Unable to attach MSI handler",
+			    ddi_driver_name(devi), ddi_get_instance(devi)));
+	}
+
 	/*
 	 * Only register hotplug interrupts for now.
 	 * Check if device supports PCIe hotplug or not?
@@ -410,6 +480,15 @@
 	 * Uninitialize hotplug support on this bus.
 	 */
 	(void) pcihp_uninit(devi);
+	if (pepb->pepb_fmcap & DDI_FM_ERRCB_CAPABLE)
+		ddi_fm_handler_unregister(devi);
+
+	if (pepb->pepb_fmcap & (DDI_FM_ERRCB_CAPABLE|DDI_FM_EREPORT_CAPABLE))
+		pci_ereport_teardown(devi);
+
+	mutex_destroy(&pepb->pepb_err_mutex);
+	mutex_destroy(&pepb->pepb_peek_poke_mutex);
+	ddi_fm_fini(devi);
 	return (DDI_SUCCESS);
 }
 
@@ -432,6 +511,7 @@
 	int	reglen;
 	int	rn;
 	int	totreg;
+	pepb_devstate_t		*pepb;
 
 	switch (ctlop) {
 	case DDI_CTLOPS_REPORTDEV:
@@ -459,6 +539,15 @@
 			return (DDI_FAILURE);
 		break;
 
+	case DDI_CTLOPS_PEEK:
+	case DDI_CTLOPS_POKE:
+		pepb = ddi_get_soft_state(pepb_state, ddi_get_instance(dip));
+		if (pepb->port_type != PCIE_PCIECAP_DEV_TYPE_ROOT)
+			return (ddi_ctlops(dip, rdip, ctlop, arg, result));
+		return (pci_peekpoke_check(dip, rdip, ctlop, arg, result,
+		    ddi_ctlops, &pepb->pepb_err_mutex,
+		    &pepb->pepb_peek_poke_mutex));
+
 	default:
 		return (ddi_ctlops(dip, rdip, ctlop, arg, result));
 	}
@@ -844,6 +933,9 @@
 	int		request = 1, count, x;
 	int		ret;
 	int		intr_cap = 0;
+	int		inum = 0;
+	ddi_intr_handler_t	**isr_tab = NULL;
+	int		isr_tab_size = 0;
 
 	PEPB_DEBUG((CE_NOTE, "pepb_intr_init: Attaching %s handler\n",
 	    (intr_type == DDI_INTR_TYPE_MSI) ? "MSI" : "INTx"));
@@ -863,12 +955,14 @@
 		return (DDI_FAILURE);
 	}
 
+	PEPB_DEBUG((CE_NOTE, "ddi_intr_get_nintrs: NINTRS = %x\n", request));
+
 	/* Allocate an array of interrupt handlers */
 	pepb_p->htable_size = sizeof (ddi_intr_handle_t) * request;
 	pepb_p->htable = kmem_zalloc(pepb_p->htable_size, KM_SLEEP);
 	pepb_p->soft_state |= PEPB_SOFT_STATE_INIT_HTABLE;
 
-	ret = ddi_intr_alloc(dip, pepb_p->htable, intr_type, 0, request,
+	ret = ddi_intr_alloc(dip, pepb_p->htable, intr_type, inum, request,
 	    &count, DDI_INTR_ALLOC_NORMAL);
 	if ((ret != DDI_SUCCESS) || (count == 0)) {
 		PEPB_DEBUG((CE_NOTE, "ddi_intr_alloc() ret: %d ask: %d"
@@ -894,12 +988,23 @@
 
 	/* initialize the interrupt mutex */
 	mutex_init(&pepb_p->pepb_mutex, NULL, MUTEX_DRIVER,
-	    DDI_INTR_PRI(PEPB_INTR_PRI));
+	    DDI_INTR_PRI(pepb_p->intr_priority));
 	pepb_p->soft_state |= PEPB_SOFT_STATE_INIT_MUTEX;
 
+	isr_tab_size = sizeof (*isr_tab) * pepb_p->intr_count;
+	isr_tab = kmem_alloc(isr_tab_size, KM_SLEEP);
+	if (pepb_enable_msi && pepb_p->intr_count == 2 &&
+	    intr_type == DDI_INTR_TYPE_MSI &&
+	    pepb_is_ck804_root_port(dip) == DDI_SUCCESS) {
+		isr_tab[0] = pepb_pwr_msi_intr;
+		isr_tab[1] = pepb_err_msi_intr;
+	} else
+		isr_tab[0] = pepb_intx_intr;
+
 	for (count = 0; count < pepb_p->intr_count; count++) {
 		ret = ddi_intr_add_handler(pepb_p->htable[count],
-		    pepb_intr, (caddr_t)pepb_p, NULL);
+		    isr_tab[count], (caddr_t)pepb_p,
+		    (caddr_t)(uintptr_t)(inum + count));
 
 		if (ret != DDI_SUCCESS) {
 			PEPB_DEBUG((CE_WARN, "Cannot add interrupt(%d)\n",
@@ -908,6 +1013,8 @@
 		}
 	}
 
+	kmem_free(isr_tab, isr_tab_size);
+
 	/* If unsucessful, remove the added handlers */
 	if (ret != DDI_SUCCESS) {
 		for (x = 0; x < count; x++) {
@@ -985,17 +1092,17 @@
 }
 
 /*
- * pepb_intr()
+ * pepb_intx_intr()
  *
  * This is the common interrupt handler for both hotplug and non-hotplug
  * interrupts. For handling hot plug interrupts it calls pciehpc_intr().
  *
  * NOTE: Currently only hot plug interrupts are enabled so it simply
- * calls pciehpc_intr().
+ * calls pciehpc_intr(). This is for INTx interrupts *ONLY*.
  */
 /*ARGSUSED*/
 static uint_t
-pepb_intr(caddr_t arg, caddr_t arg2)
+pepb_intx_intr(caddr_t arg, caddr_t arg2)
 {
 	pepb_devstate_t *pepb_p = (pepb_devstate_t *)arg;
 	int ret = DDI_INTR_UNCLAIMED;
@@ -1015,53 +1122,145 @@
 }
 
 /*
- * given a cap_id, return its cap_id location in config space
+ * pepb_is_ck804_root_port()
+ *
+ * This helper function checks if the device is a Nvidia ck8-04 or not
  */
 static int
-pepb_get_cap(ddi_acc_handle_t config_handle, uint8_t cap_id)
+pepb_is_ck804_root_port(dev_info_t *dip)
 {
-	uint8_t curcap;
-	uint_t	cap_id_loc;
-	uint16_t	status;
-	int location = -1;
+	int ret = DDI_FAILURE;
+	ddi_acc_handle_t handle;
+
+	if (pci_config_setup(dip, &handle) != DDI_SUCCESS)
+		return (ret);
+
+	if (pci_config_get16(handle, PCI_CONF_VENID) ==
+	    NVIDIA_CK804_VENDOR_ID &&
+	    pci_config_get16(handle, PCI_CONF_DEVID) ==
+	    NVIDIA_CK804_DEVICE_ID)
+		ret = DDI_SUCCESS;
+
+	pci_config_teardown(&handle);
+	return (ret);
+}
 
-	/*
-	 * Need to check the Status register for ECP support first.
-	 * Also please note that for type 1 devices, the
-	 * offset could change. Should support type 1 next.
-	 */
-	status = pci_config_get16(config_handle, PCI_CONF_STAT);
-	if (!(status & PCI_STAT_CAP))
-		return (-1);
+/*
+ * pepb_pwr_msi_intr()
+ *
+ * This is the MSI interrupt handler for PM related events.
+ */
+/*ARGSUSED*/
+static uint_t
+pepb_pwr_msi_intr(caddr_t arg, caddr_t arg2)
+{
+	pepb_devstate_t	*pepb_p = (pepb_devstate_t *)arg;
 
-	cap_id_loc = pci_config_get8(config_handle, PCI_CONF_CAP_PTR);
+	if (!(pepb_p->soft_state & PEPB_SOFT_STATE_INIT_ENABLE))
+		return (DDI_INTR_UNCLAIMED);
 
-	/* Walk the list of capabilities */
-	while (cap_id_loc) {
-		curcap = pci_config_get8(config_handle, cap_id_loc);
+	mutex_enter(&pepb_p->pepb_mutex);
+	PEPB_DEBUG((CE_NOTE, "pepb_pwr_msi_intr: received intr number %d\n",
+	    (int)(uintptr_t)arg2));
+	mutex_exit(&pepb_p->pepb_mutex);
+	return (DDI_INTR_CLAIMED);
+}
 
-		if (curcap == cap_id) {
-			location = cap_id_loc;
-			break;
-		}
-		cap_id_loc = pci_config_get8(config_handle, cap_id_loc + 1);
-	}
-	return (location);
+static int
+pepb_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
+{
+	uint_t cap_loc;
+
+	/* Need to look at the port type information here */
+	cap_loc = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
+	    DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
+
+	return (cap_loc == PCI_CAP_NEXT_PTR_NULL ? -1 :
+	    pci_config_get16(handle, cap_loc + PCIE_PCIECAP) &
+		PCIE_PCIECAP_DEV_TYPE_MASK);
 }
 
 /*ARGSUSED*/
-static int
-pepb_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
+int
+pepb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
+    ddi_iblock_cookie_t *ibc)
+{
+	pepb_devstate_t	 *pepb = ddi_get_soft_state(pepb_state,
+	    ddi_get_instance(dip));
+
+	ASSERT(ibc != NULL);
+	*ibc = pepb->pepb_fm_ibc;
+
+	return (pepb->pepb_fmcap);
+}
+
+/*ARGSUSED*/
+int
+pepb_fm_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *no_used)
 {
-	int port_type = -1;
-	uint_t cap_loc;
+	pepb_devstate_t *pepb_p = (pepb_devstate_t *)
+	    ddi_get_soft_state(pepb_state, ddi_get_instance(dip));
+
+	mutex_enter(&pepb_p->pepb_err_mutex);
+	pci_ereport_post(dip, derr, NULL);
+	mutex_exit(&pepb_p->pepb_err_mutex);
+	return (derr->fme_status);
+}
+
+/*ARGSUSED*/
+static uint_t
+pepb_err_msi_intr(caddr_t arg, caddr_t arg2)
+{
+	pepb_devstate_t *pepb_p = (pepb_devstate_t *)arg;
+	ddi_fm_error_t derr;
+
+	bzero(&derr, sizeof (ddi_fm_error_t));
+
+	if (!(pepb_p->soft_state & PEPB_SOFT_STATE_INIT_ENABLE))
+		return (DDI_INTR_UNCLAIMED);
 
-	/* Need to look at the port type information here XXX KINI */
-	if ((cap_loc = pepb_get_cap(handle, PCI_CAP_ID_PCI_E)) > 0)
-		port_type = pci_config_get16(handle,
-			cap_loc + PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
+	mutex_enter(&pepb_p->pepb_peek_poke_mutex);
+	mutex_enter(&pepb_p->pepb_err_mutex);
+	PEPB_DEBUG((CE_NOTE, "pepb_err_msi_intr: received intr number %d\n",
+	    (int)(uintptr_t)arg2));
+
+	/* if HPC is initialized then call the interrupt handler */
+	if (pepb_p->pepb_fmcap & DDI_FM_EREPORT_CAPABLE)
+		pci_ereport_post(pepb_p->dip, &derr, NULL);
+
+	if ((pepb_panic_fatal && derr.fme_status == DDI_FM_FATAL) ||
+	    (pepb_panic_unknown && derr.fme_status == DDI_FM_UNKNOWN))
+		fm_panic("%s-%d: PCI(-X) Express Fatal Error",
+		    ddi_driver_name(pepb_p->dip),
+		    ddi_get_instance(pepb_p->dip));
+
+	mutex_exit(&pepb_p->pepb_err_mutex);
+	mutex_exit(&pepb_p->pepb_peek_poke_mutex);
+
+	return (DDI_INTR_CLAIMED);
+}
 
-	return (port_type);
+static int
+pepb_check_slot_disabled(dev_info_t *dip)
+{
+	int			rval = 0;
+	uint8_t			pcie_cap_ptr;
+	ddi_acc_handle_t	config_handle;
+
+	if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS)
+		return (rval);
+
+	pcie_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
+	    DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
+
+	if (pcie_cap_ptr != PCI_CAP_NEXT_PTR_NULL) {
+		if (pci_config_get16(config_handle,
+		    pcie_cap_ptr + PCIE_LINKCTL) & PCIE_LINKCTL_LINK_DISABLE)
+			rval = 1;
+	}
+
+	pci_config_teardown(&config_handle);
+	return (rval);
 }
 
 static int
--- a/usr/src/uts/i86pc/io/rootnex.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/io/rootnex.c	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -62,6 +61,7 @@
 #include <sys/sdt.h>
 #include <sys/rootnex.h>
 #include <vm/hat_i86.h>
+#include <sys/ddifm.h>
 
 /*
  * enable/disable extra checking of function parameters. Useful for debugging
@@ -191,6 +191,8 @@
     off_t *offp, size_t *lenp, caddr_t *objp, uint_t cache_flags);
 static int rootnex_ctlops(dev_info_t *dip, dev_info_t *rdip,
     ddi_ctl_enum_t ctlop, void *arg, void *result);
+static int rootnex_fm_init(dev_info_t *dip, dev_info_t *tdip, int tcap,
+    ddi_iblock_cookie_t *ibc);
 static int rootnex_intr_ops(dev_info_t *pdip, dev_info_t *rdip,
     ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result);
 
@@ -219,7 +221,7 @@
 	0,			/* bus_intr_ctl */
 	0,			/* bus_config */
 	0,			/* bus_unconfig */
-	NULL,			/* bus_fm_init */
+	rootnex_fm_init,	/* bus_fm_init */
 	NULL,			/* bus_fm_fini */
 	NULL,			/* bus_fm_access_enter */
 	NULL,			/* bus_fm_access_exit */
@@ -288,8 +290,6 @@
 static void rootnex_add_props(dev_info_t *);
 static int rootnex_ctl_reportdev(dev_info_t *dip);
 static struct intrspec *rootnex_get_ispec(dev_info_t *rdip, int inum);
-static int rootnex_ctlops_poke(peekpoke_ctlops_t *in_args);
-static int rootnex_ctlops_peek(peekpoke_ctlops_t *in_args, void *result);
 static int rootnex_map_regspec(ddi_map_req_t *mp, caddr_t *vaddrp);
 static int rootnex_unmap_regspec(ddi_map_req_t *mp, caddr_t *vaddrp);
 static int rootnex_map_handle(ddi_map_req_t *mp);
@@ -323,9 +323,8 @@
 static int rootnex_valid_sync_parms(ddi_dma_impl_t *hp, rootnex_window_t *win,
     off_t offset, size_t size, uint_t cache_flags);
 static int rootnex_verify_buffer(rootnex_dma_t *dma);
-static int rootnex_fm_callback(dev_info_t *dip, ddi_fm_error_t *derr,
-    const void *no_used);
-
+static int rootnex_dma_check(dev_info_t *dip, const void *handle,
+    const void *comp_addr, const void *not_used);
 
 /*
  * _init()
@@ -394,24 +393,19 @@
 	rootnex_state->r_reserved_msg_printed = B_FALSE;
 	rootnex_cnt = &rootnex_state->r_counters[0];
 
-	mutex_init(&rootnex_state->r_peekpoke_mutex, NULL, MUTEX_SPIN,
-	    (void *)ipltospl(15));
-
 	/*
 	 * Set minimum fm capability level for i86pc platforms and then
 	 * initialize error handling. Since we're the rootnex, we don't
 	 * care what's returned in the fmcap field.
 	 */
-	ddi_system_fmcap = DDI_FM_ERRCB_CAPABLE;
+	ddi_system_fmcap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE |
+	    DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
 	fmcap = ddi_system_fmcap;
 	ddi_fm_init(dip, &fmcap, &rootnex_state->r_err_ibc);
-	if (fmcap & DDI_FM_ERRCB_CAPABLE)
-		ddi_fm_handler_register(dip, rootnex_fm_callback, NULL);
 
 	/* initialize DMA related state */
 	e = rootnex_dma_init();
 	if (e != DDI_SUCCESS) {
-		mutex_destroy(&rootnex_state->r_peekpoke_mutex);
 		kmem_free(rootnex_state, sizeof (rootnex_state_t));
 		return (DDI_FAILURE);
 	}
@@ -564,12 +558,6 @@
 		*(ulong_t *)result = btopr(*(ulong_t *)arg);
 		return (DDI_SUCCESS);
 
-	case DDI_CTLOPS_POKE:
-		return (rootnex_ctlops_poke((peekpoke_ctlops_t *)arg));
-
-	case DDI_CTLOPS_PEEK:
-		return (rootnex_ctlops_peek((peekpoke_ctlops_t *)arg, result));
-
 	case DDI_CTLOPS_INITCHILD:
 		return (impl_ddi_sunbus_initchild(arg));
 
@@ -712,114 +700,6 @@
 
 
 /*
- * rootnex_ctlops_poke()
- *
- */
-static int
-rootnex_ctlops_poke(peekpoke_ctlops_t *in_args)
-{
-	int err = DDI_SUCCESS;
-	on_trap_data_t otd;
-
-	/* Cautious access not supported. */
-	if (in_args->handle != NULL)
-		return (DDI_FAILURE);
-
-	mutex_enter(&rootnex_state->r_peekpoke_mutex);
-
-	/* Set up protected environment. */
-	if (!on_trap(&otd, OT_DATA_ACCESS)) {
-		switch (in_args->size) {
-		case sizeof (uint8_t):
-			*(uint8_t *)in_args->dev_addr = *(uint8_t *)
-			    in_args->host_addr;
-			break;
-
-		case sizeof (uint16_t):
-			*(uint16_t *)in_args->dev_addr =
-			    *(uint16_t *)in_args->host_addr;
-			break;
-
-		case sizeof (uint32_t):
-			*(uint32_t *)in_args->dev_addr =
-			    *(uint32_t *)in_args->host_addr;
-			break;
-
-		case sizeof (uint64_t):
-			*(uint64_t *)in_args->dev_addr =
-			    *(uint64_t *)in_args->host_addr;
-			break;
-
-		default:
-			err = DDI_FAILURE;
-			break;
-		}
-	} else
-		err = DDI_FAILURE;
-
-	/* Take down protected environment. */
-	no_trap();
-	mutex_exit(&rootnex_state->r_peekpoke_mutex);
-
-	return (err);
-}
-
-
-/*
- * rootnex_ctlops_peek()
- *
- */
-static int
-rootnex_ctlops_peek(peekpoke_ctlops_t *in_args, void *result)
-{
-	int err = DDI_SUCCESS;
-	on_trap_data_t otd;
-
-	/* Cautious access not supported. */
-	if (in_args->handle != NULL)
-		return (DDI_FAILURE);
-
-	mutex_enter(&rootnex_state->r_peekpoke_mutex);
-
-	if (!on_trap(&otd, OT_DATA_ACCESS)) {
-		switch (in_args->size) {
-		case sizeof (uint8_t):
-			*(uint8_t *)in_args->host_addr =
-			    *(uint8_t *)in_args->dev_addr;
-			break;
-
-		case sizeof (uint16_t):
-			*(uint16_t *)in_args->host_addr =
-			    *(uint16_t *)in_args->dev_addr;
-			break;
-
-		case sizeof (uint32_t):
-			*(uint32_t *)in_args->host_addr =
-			    *(uint32_t *)in_args->dev_addr;
-			break;
-
-		case sizeof (uint64_t):
-			*(uint64_t *)in_args->host_addr =
-			    *(uint64_t *)in_args->dev_addr;
-			break;
-
-		default:
-			err = DDI_FAILURE;
-			break;
-		}
-		result = (void *)in_args->host_addr;
-	} else
-		err = DDI_FAILURE;
-
-	no_trap();
-	mutex_exit(&rootnex_state->r_peekpoke_mutex);
-
-	return (err);
-}
-
-
-
-/*
  * ******************
  *  map related code
  * ******************
@@ -1107,6 +987,11 @@
 			    (rp->regspec_bustype > 1 && rp->regspec_addr == 0) ?
 				((caddr_t)(uintptr_t)rp->regspec_bustype) :
 				((caddr_t)(uintptr_t)rp->regspec_addr);
+
+			hp->ah_pfn = mmu_btop((ulong_t)rp->regspec_addr &
+			    (~MMU_PAGEOFFSET));
+			hp->ah_pnum = mmu_btopr(rp->regspec_size +
+			    (ulong_t)rp->regspec_addr & MMU_PAGEOFFSET);
 		}
 
 #ifdef	DDI_MAP_DEBUG
@@ -1182,6 +1067,13 @@
 		hat_devload(kas.a_hat, cvaddr, mmu_ptob(npages), mmu_btop(base),
 		    mp->map_prot | hat_acc_flags, HAT_LOAD_LOCK);
 		*vaddrp = (caddr_t)cvaddr + pgoffset;
+
+		/* save away pfn and npages for FMA */
+		hp = mp->map_handlep;
+		if (hp) {
+			hp->ah_pfn = mmu_btop(base);
+			hp->ah_pnum = npages;
+		}
 	}
 
 #ifdef	DDI_MAP_DEBUG
@@ -1904,6 +1796,15 @@
 	}
 
 	/*
+	 * If the driver supports FMA, insert the handle in the FMA DMA handle
+	 * cache.
+	 */
+	if (attr->dma_attr_flags & DDI_DMA_FLAGERR) {
+		hp->dmai_error.err_cf = rootnex_dma_check;
+		(void) ndi_fmc_insert(rdip, DMA_HANDLE, hp, NULL);
+	}
+
+	/*
 	 * if we don't need the copybuf and we don't need to do a partial,  we
 	 * hit the fast path. All the high performance devices should be trying
 	 * to hit this path. To hit this path, a device should be able to reach
@@ -2012,6 +1913,17 @@
 	}
 
 	/*
+	 * If the driver supports FMA, remove the handle in the FMA DMA handle
+	 * cache.
+	 */
+	if (hp->dmai_attr.dma_attr_flags & DDI_DMA_FLAGERR) {
+		if ((DEVI(rdip)->devi_fmhdl != NULL) &&
+		    (DDI_FM_DMA_ERR_CAP(DEVI(rdip)->devi_fmhdl->fh_cap))) {
+			(void) ndi_fmc_remove(rdip, DMA_HANDLE, hp);
+		}
+	}
+
+	/*
 	 * cleanup and copy buffer or window state. if we didn't use the copy
 	 * buffer or windows, there won't be much to do :-)
 	 */
@@ -2050,16 +1962,13 @@
 static int
 rootnex_verify_buffer(rootnex_dma_t *dma)
 {
-	peekpoke_ctlops_t peek;
 	page_t **pplist;
 	caddr_t vaddr;
 	uint_t pcnt;
 	uint_t poff;
 	page_t *pp;
-	uint8_t b;
+	char b;
 	int i;
-	int e;
-
 
 	/* Figure out how many pages this buffer occupies */
 	if (dma->dp_dma.dmao_type == DMA_OTYP_PAGES) {
@@ -2102,16 +2011,11 @@
 		/* For a virtual address, try to peek at each page */
 		} else {
 			if (dma->dp_sglinfo.si_asp == &kas) {
-				bzero(&peek, sizeof (peekpoke_ctlops_t));
-				peek.host_addr = (uintptr_t)&b;
-				peek.size = sizeof (uint8_t);
-				peek.dev_addr = (uintptr_t)vaddr;
 				for (i = 0; i < pcnt; i++) {
-					e = rootnex_ctlops_peek(&peek, &b);
-					if (e != DDI_SUCCESS) {
+					if (ddi_peek8(NULL, vaddr, &b) ==
+					    DDI_FAILURE)
 						return (DDI_FAILURE);
-					}
-					peek.dev_addr += MMU_PAGESIZE;
+					vaddr += MMU_PAGESIZE;
 				}
 			}
 		}
@@ -2164,6 +2068,7 @@
 	hp->dmai_error.err_expected = DDI_FM_ERR_UNEXPECTED;
 	hp->dmai_error.err_ontrap = NULL;
 	hp->dmai_error.err_fep = NULL;
+	hp->dmai_error.err_cf = NULL;
 }
 
 
@@ -4425,9 +4330,126 @@
 #endif /* defined(__amd64) */
 }
 
-/*ARGSUSED*/
+
+/*
+ * *********
+ *  FMA Code
+ * *********
+ */
+
+/*
+ * rootnex_fm_init()
+ *    FMA init busop
+ */
+/* ARGSUSED */
+static int
+rootnex_fm_init(dev_info_t *dip, dev_info_t *tdip, int tcap,
+    ddi_iblock_cookie_t *ibc)
+{
+	*ibc = rootnex_state->r_err_ibc;
+
+	return (ddi_system_fmcap);
+}
+
+/*
+ * rootnex_dma_check()
+ *    Function called after a dma fault occurred to find out whether the
+ *    fault address is associated with a driver that is able to handle faults
+ *    and recover from faults.
+ */
+/* ARGSUSED */
 static int
-rootnex_fm_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *no_used)
+rootnex_dma_check(dev_info_t *dip, const void *handle, const void *addr,
+    const void *not_used)
 {
-	return (rootnex_fm_ma_ta_panic_flag ? DDI_FM_FATAL : DDI_FM_NONFATAL);
+	rootnex_window_t *window;
+	uint64_t start_addr;
+	uint64_t fault_addr;
+	ddi_dma_impl_t *hp;
+	rootnex_dma_t *dma;
+	uint64_t end_addr;
+	size_t csize;
+	int i;
+	int j;
+
+
+	/* The driver has to set DDI_DMA_FLAGERR to recover from dma faults */
+	hp = (ddi_dma_impl_t *)handle;
+	ASSERT(hp);
+
+	dma = (rootnex_dma_t *)hp->dmai_private;
+
+	/* Get the address that we need to search for */
+	fault_addr = *(uint64_t *)addr;
+
+	/*
+	 * if we don't have any windows, we can just walk through all the
+	 * cookies.
+	 */
+	if (dma->dp_window == NULL) {
+		/* for each cookie */
+		for (i = 0; i < dma->dp_sglinfo.si_sgl_size; i++) {
+			/*
+			 * if the faulted address is within the physical address
+			 * range of the cookie, return DDI_FM_NONFATAL.
+			 */
+			if ((fault_addr >= dma->dp_cookies[i].dmac_laddress) &&
+			    (fault_addr <= (dma->dp_cookies[i].dmac_laddress +
+			    dma->dp_cookies[i].dmac_size))) {
+				return (DDI_FM_NONFATAL);
+			}
+		}
+
+		/* fault_addr not within this DMA handle */
+		return (DDI_FM_UNKNOWN);
+	}
+
+	/* we have mutiple windows, walk through each window */
+	for (i = 0; i < hp->dmai_nwin; i++) {
+		window = &dma->dp_window[i];
+
+		/* Go through all the cookies in the window */
+		for (j = 0; j < window->wd_cookie_cnt; j++) {
+
+			start_addr = window->wd_first_cookie[j].dmac_laddress;
+			csize = window->wd_first_cookie[j].dmac_size;
+
+			/*
+			 * if we are trimming the first cookie in the window,
+			 * and this is the first cookie, adjust the start
+			 * address and size of the cookie to account for the
+			 * trim.
+			 */
+			if (window->wd_trim.tr_trim_first && (j == 0)) {
+				start_addr = window->wd_trim.tr_first_paddr;
+				csize = window->wd_trim.tr_first_size;
+			}
+
+			/*
+			 * if we are trimming the last cookie in the window,
+			 * and this is the last cookie, adjust the start
+			 * address and size of the cookie to account for the
+			 * trim.
+			 */
+			if (window->wd_trim.tr_trim_last &&
+			    (j == (window->wd_cookie_cnt - 1))) {
+				start_addr = window->wd_trim.tr_last_paddr;
+				csize = window->wd_trim.tr_last_size;
+			}
+
+			end_addr = start_addr + csize;
+
+			/*
+			 * if the faulted address is within the physical address
+			 * range of the cookie, return DDI_FM_NONFATAL.
+			 */
+			if ((fault_addr >= start_addr) &&
+			    (fault_addr <= end_addr)) {
+				return (DDI_FM_NONFATAL);
+			}
+		}
+	}
+
+	/* fault_addr not within this DMA handle */
+	return (DDI_FM_UNKNOWN);
 }
--- a/usr/src/uts/i86pc/os/ddi_impl.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/i86pc/os/ddi_impl.c	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -56,6 +55,7 @@
 #include <sys/archsystm.h>
 #include <vm/seg_kmem.h>
 #include <sys/ontrap.h>
+#include <sys/fm/protocol.h>
 #include <sys/ramdisk.h>
 #include <sys/sunndi.h>
 #include <sys/vmem.h>
@@ -2092,6 +2092,182 @@
 	return (cmd == DDI_CTLOPS_PEEK ? peek_mem(in_args) : poke_mem(in_args));
 }
 
+/*
+ * we've just done a cautious put/get. Check if it was successful by
+ * calling pci_ereport_post() on all puts and for any gets that return -1
+ */
+static int
+pci_peekpoke_check_fma(dev_info_t *dip, void *arg, ddi_ctl_enum_t ctlop)
+{
+	int	rval = DDI_SUCCESS;
+	peekpoke_ctlops_t *in_args = (peekpoke_ctlops_t *)arg;
+	ddi_fm_error_t de;
+	ddi_acc_impl_t *hp = (ddi_acc_impl_t *)in_args->handle;
+	ddi_acc_hdl_t *hdlp = (ddi_acc_hdl_t *)in_args->handle;
+	int check_err = 0;
+	int repcount = in_args->repcount;
+
+	if (ctlop == DDI_CTLOPS_PEEK &&
+	    hdlp->ah_acc.devacc_attr_access != DDI_CAUTIOUS_ACC) {
+		for (; repcount; repcount--) {
+			switch (in_args->size) {
+			case sizeof (uint8_t):
+				if (*(uint8_t *)in_args->host_addr == 0xff)
+					check_err = 1;
+				break;
+			case sizeof (uint16_t):
+				if (*(uint16_t *)in_args->host_addr == 0xffff)
+					check_err = 1;
+				break;
+			case sizeof (uint32_t):
+				if (*(uint32_t *)in_args->host_addr ==
+				    0xffffffff)
+					check_err = 1;
+				break;
+			case sizeof (uint64_t):
+				if (*(uint64_t *)in_args->host_addr ==
+				    0xffffffffffffffff)
+					check_err = 1;
+				break;
+			}
+		}
+		if (check_err == 0)
+			return (DDI_SUCCESS);
+	}
+	/*
+	 * for a cautious put or get or a non-cautious get that returned -1 call
+	 * io framework to see if there really was an error
+	 */
+	bzero(&de, sizeof (ddi_fm_error_t));
+	de.fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
+	de.fme_bus_specific = (void *)in_args->dev_addr;
+	if (hdlp->ah_acc.devacc_attr_access == DDI_CAUTIOUS_ACC) {
+		de.fme_flag = DDI_FM_ERR_EXPECTED;
+		de.fme_acc_handle = in_args->handle;
+	} else if (hdlp->ah_acc.devacc_attr_access == DDI_DEFAULT_ACC) {
+		/*
+		 * We only get here with DDI_DEFAULT_ACC for config space gets.
+		 * Non-hardened drivers may be probing the hardware and
+		 * expecting -1 returned. So need to treat errors on
+		 * DDI_DEFAULT_ACC as DDI_FM_ERR_EXPECTED.
+		 */
+		de.fme_flag = DDI_FM_ERR_EXPECTED;
+		de.fme_acc_handle = in_args->handle;
+	} else {
+		/*
+		 * Hardened driver doing protected accesses shouldn't
+		 * get errors unless there's a hardware problem. Treat
+		 * as nonfatal if there's an error, but set UNEXPECTED
+		 * so we raise ereports on any errors and potentially
+		 * fault the device
+		 */
+		de.fme_flag = DDI_FM_ERR_UNEXPECTED;
+	}
+	pci_ereport_post(dip, &de, NULL);
+	if (hdlp->ah_acc.devacc_attr_access != DDI_DEFAULT_ACC &&
+	    de.fme_status != DDI_FM_OK) {
+		ndi_err_t *errp = (ndi_err_t *)hp->ahi_err;
+		rval = DDI_FAILURE;
+		errp->err_ena = de.fme_ena;
+		errp->err_expected = de.fme_flag;
+		errp->err_status = DDI_FM_NONFATAL;
+	}
+	return (rval);
+}
+
+/*
+ * pci_peekpoke_check_nofma() is for when an error occurs on a register access
+ * during pci_ereport_post(). We can't call pci_ereport_post() again or we'd
+ * recurse, so assume all puts are OK and gets have failed if they return -1
+ */
+static int
+pci_peekpoke_check_nofma(void *arg, ddi_ctl_enum_t ctlop)
+{
+	int rval = DDI_SUCCESS;
+	peekpoke_ctlops_t *in_args = (peekpoke_ctlops_t *)arg;
+	ddi_acc_impl_t *hp = (ddi_acc_impl_t *)in_args->handle;
+	ddi_acc_hdl_t *hdlp = (ddi_acc_hdl_t *)in_args->handle;
+	int repcount = in_args->repcount;
+
+	if (ctlop == DDI_CTLOPS_POKE)
+		return (rval);
+
+	for (; repcount; repcount--) {
+		switch (in_args->size) {
+		case sizeof (uint8_t):
+			if (*(uint8_t *)in_args->host_addr == 0xff)
+				rval = DDI_FAILURE;
+			break;
+		case sizeof (uint16_t):
+			if (*(uint16_t *)in_args->host_addr == 0xffff)
+				rval = DDI_FAILURE;
+			break;
+		case sizeof (uint32_t):
+			if (*(uint32_t *)in_args->host_addr == 0xffffffff)
+				rval = DDI_FAILURE;
+			break;
+		case sizeof (uint64_t):
+			if (*(uint64_t *)in_args->host_addr ==
+			    0xffffffffffffffff)
+				rval = DDI_FAILURE;
+			break;
+		}
+	}
+	if (hdlp->ah_acc.devacc_attr_access != DDI_DEFAULT_ACC &&
+	    rval == DDI_FAILURE) {
+		ndi_err_t *errp = (ndi_err_t *)hp->ahi_err;
+		errp->err_ena = fm_ena_generate(0, FM_ENA_FMT1);
+		errp->err_expected = DDI_FM_ERR_UNEXPECTED;
+		errp->err_status = DDI_FM_NONFATAL;
+	}
+	return (rval);
+}
+
+int
+pci_peekpoke_check(dev_info_t *dip, dev_info_t *rdip,
+	ddi_ctl_enum_t ctlop, void *arg, void *result,
+	int (*handler)(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *,
+	void *), kmutex_t *err_mutexp, kmutex_t *peek_poke_mutexp)
+{
+	int rval;
+	peekpoke_ctlops_t *in_args = (peekpoke_ctlops_t *)arg;
+	ddi_acc_impl_t *hp = (ddi_acc_impl_t *)in_args->handle;
+
+	if (hp->ahi_acc_attr & DDI_ACCATTR_CONFIG_SPACE) {
+	    if (!mutex_tryenter(err_mutexp)) {
+			/*
+			 * As this may be a recursive call from within
+			 * pci_ereport_post() we can't wait for the mutexes.
+			 * Fortunately we know someone is already calling
+			 * pci_ereport_post() which will handle the error bits
+			 * for us, and as this is a config space access we can
+			 * just do the access and check return value for -1
+			 * using pci_peekpoke_check_nofma().
+			 */
+			rval = handler(dip, rdip, ctlop, arg, result);
+			if (rval == DDI_SUCCESS)
+				rval = pci_peekpoke_check_nofma(arg, ctlop);
+			return (rval);
+		}
+		/*
+		 * This can't be a recursive call. Drop the err_mutex and get
+		 * both mutexes in the right order. If an error hasn't already
+		 * been detected by the ontrap code, use pci_peekpoke_check_fma
+		 * which will call pci_ereport_post() to check error status.
+		 */
+		mutex_exit(err_mutexp);
+	}
+	mutex_enter(peek_poke_mutexp);
+	rval = handler(dip, rdip, ctlop, arg, result);
+	if (rval == DDI_SUCCESS) {
+		mutex_enter(err_mutexp);
+		rval = pci_peekpoke_check_fma(dip, arg, ctlop);
+		mutex_exit(err_mutexp);
+	}
+	mutex_exit(peek_poke_mutexp);
+	return (rval);
+}
+
 void
 impl_setup_ddi(void)
 {
@@ -2235,3 +2411,161 @@
 		probe = probe->next;
 	}
 }
+
+
+/*
+ * The following functions ready a cautious request to go up to the nexus
+ * driver.  It is up to the nexus driver to decide how to process the request.
+ * It may choose to call i_ddi_do_caut_get/put in this file, or do it
+ * differently.
+ */
+
+static void
+i_ddi_caut_getput_ctlops(ddi_acc_impl_t *hp, uint64_t host_addr,
+    uint64_t dev_addr, size_t size, size_t repcount, uint_t flags,
+    ddi_ctl_enum_t cmd)
+{
+	peekpoke_ctlops_t	cautacc_ctlops_arg;
+
+	cautacc_ctlops_arg.size = size;
+	cautacc_ctlops_arg.dev_addr = dev_addr;
+	cautacc_ctlops_arg.host_addr = host_addr;
+	cautacc_ctlops_arg.handle = (ddi_acc_handle_t)hp;
+	cautacc_ctlops_arg.repcount = repcount;
+	cautacc_ctlops_arg.flags = flags;
+
+	(void) ddi_ctlops(hp->ahi_common.ah_dip, hp->ahi_common.ah_dip, cmd,
+	    &cautacc_ctlops_arg, NULL);
+}
+
+uint8_t
+i_ddi_caut_get8(ddi_acc_impl_t *hp, uint8_t *addr)
+{
+	uint8_t value;
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)&value, (uintptr_t)addr,
+	    sizeof (uint8_t), 1, 0, DDI_CTLOPS_PEEK);
+
+	return (value);
+}
+
+uint16_t
+i_ddi_caut_get16(ddi_acc_impl_t *hp, uint16_t *addr)
+{
+	uint16_t value;
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)&value, (uintptr_t)addr,
+	    sizeof (uint16_t), 1, 0, DDI_CTLOPS_PEEK);
+
+	return (value);
+}
+
+uint32_t
+i_ddi_caut_get32(ddi_acc_impl_t *hp, uint32_t *addr)
+{
+	uint32_t value;
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)&value, (uintptr_t)addr,
+	    sizeof (uint32_t), 1, 0, DDI_CTLOPS_PEEK);
+
+	return (value);
+}
+
+uint64_t
+i_ddi_caut_get64(ddi_acc_impl_t *hp, uint64_t *addr)
+{
+	uint64_t value;
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)&value, (uintptr_t)addr,
+	    sizeof (uint64_t), 1, 0, DDI_CTLOPS_PEEK);
+
+	return (value);
+}
+
+void
+i_ddi_caut_put8(ddi_acc_impl_t *hp, uint8_t *addr, uint8_t value)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)&value, (uintptr_t)addr,
+	    sizeof (uint8_t), 1, 0, DDI_CTLOPS_POKE);
+}
+
+void
+i_ddi_caut_put16(ddi_acc_impl_t *hp, uint16_t *addr, uint16_t value)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)&value, (uintptr_t)addr,
+	    sizeof (uint16_t), 1, 0, DDI_CTLOPS_POKE);
+}
+
+void
+i_ddi_caut_put32(ddi_acc_impl_t *hp, uint32_t *addr, uint32_t value)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)&value, (uintptr_t)addr,
+	    sizeof (uint32_t), 1, 0, DDI_CTLOPS_POKE);
+}
+
+void
+i_ddi_caut_put64(ddi_acc_impl_t *hp, uint64_t *addr, uint64_t value)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)&value, (uintptr_t)addr,
+	    sizeof (uint64_t), 1, 0, DDI_CTLOPS_POKE);
+}
+
+void
+i_ddi_caut_rep_get8(ddi_acc_impl_t *hp, uint8_t *host_addr, uint8_t *dev_addr,
+	size_t repcount, uint_t flags)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)host_addr, (uintptr_t)dev_addr,
+	    sizeof (uint8_t), repcount, flags, DDI_CTLOPS_PEEK);
+}
+
+void
+i_ddi_caut_rep_get16(ddi_acc_impl_t *hp, uint16_t *host_addr,
+    uint16_t *dev_addr, size_t repcount, uint_t flags)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)host_addr, (uintptr_t)dev_addr,
+	    sizeof (uint16_t), repcount, flags, DDI_CTLOPS_PEEK);
+}
+
+void
+i_ddi_caut_rep_get32(ddi_acc_impl_t *hp, uint32_t *host_addr,
+    uint32_t *dev_addr, size_t repcount, uint_t flags)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)host_addr, (uintptr_t)dev_addr,
+	    sizeof (uint32_t), repcount, flags, DDI_CTLOPS_PEEK);
+}
+
+void
+i_ddi_caut_rep_get64(ddi_acc_impl_t *hp, uint64_t *host_addr,
+    uint64_t *dev_addr, size_t repcount, uint_t flags)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)host_addr, (uintptr_t)dev_addr,
+	    sizeof (uint64_t), repcount, flags, DDI_CTLOPS_PEEK);
+}
+
+void
+i_ddi_caut_rep_put8(ddi_acc_impl_t *hp, uint8_t *host_addr, uint8_t *dev_addr,
+	size_t repcount, uint_t flags)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)host_addr, (uintptr_t)dev_addr,
+	    sizeof (uint8_t), repcount, flags, DDI_CTLOPS_POKE);
+}
+
+void
+i_ddi_caut_rep_put16(ddi_acc_impl_t *hp, uint16_t *host_addr,
+    uint16_t *dev_addr, size_t repcount, uint_t flags)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)host_addr, (uintptr_t)dev_addr,
+	    sizeof (uint16_t), repcount, flags, DDI_CTLOPS_POKE);
+}
+
+void
+i_ddi_caut_rep_put32(ddi_acc_impl_t *hp, uint32_t *host_addr,
+    uint32_t *dev_addr, size_t repcount, uint_t flags)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)host_addr, (uintptr_t)dev_addr,
+	    sizeof (uint32_t), repcount, flags, DDI_CTLOPS_POKE);
+}
+
+void
+i_ddi_caut_rep_put64(ddi_acc_impl_t *hp, uint64_t *host_addr,
+    uint64_t *dev_addr, size_t repcount, uint_t flags)
+{
+	i_ddi_caut_getput_ctlops(hp, (uintptr_t)host_addr, (uintptr_t)dev_addr,
+	    sizeof (uint64_t), repcount, flags, DDI_CTLOPS_POKE);
+}
--- a/usr/src/uts/intel/ia32/os/ddi_i86.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/intel/ia32/os/ddi_i86.c	Sun Apr 23 15:26:28 2006 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -32,6 +32,8 @@
 #include <sys/ddi.h>
 #include <sys/sunddi.h>
 #include <sys/ddifm.h>
+#include <sys/fm/io/ddi.h>
+#include <sys/ontrap.h>
 
 
 /*
@@ -152,21 +154,35 @@
 impl_acc_hdl_alloc(int (*waitfp)(caddr_t), caddr_t arg)
 {
 	ddi_acc_impl_t *hp;
+	on_trap_data_t *otp;
 	int sleepflag;
 
 	sleepflag = ((waitfp == (int (*)())KM_SLEEP) ? KM_SLEEP : KM_NOSLEEP);
 	/*
-	 * Allocate and initialize the data access handle.
+	 * Allocate and initialize the data access handle and error status.
 	 */
-	hp = kmem_zalloc(sizeof (ddi_acc_impl_t), sleepflag);
-	if (!hp) {
-		if ((waitfp != (int (*)())KM_SLEEP) &&
-		    (waitfp != (int (*)())KM_NOSLEEP))
-			ddi_set_callback(waitfp, arg, &impl_acc_hdl_id);
-		return (NULL);
+	if ((hp = kmem_zalloc(sizeof (ddi_acc_impl_t), sleepflag)) == NULL)
+		goto fail;
+	if ((hp->ahi_err = (ndi_err_t *)kmem_zalloc(
+	    sizeof (ndi_err_t), sleepflag)) == NULL) {
+		kmem_free(hp, sizeof (ddi_acc_impl_t));
+		goto fail;
 	}
+	if ((otp = (on_trap_data_t *)kmem_zalloc(
+	    sizeof (on_trap_data_t), sleepflag)) == NULL) {
+		kmem_free(hp->ahi_err, sizeof (ndi_err_t));
+		kmem_free(hp, sizeof (ddi_acc_impl_t));
+		goto fail;
+	}
+	hp->ahi_err->err_ontrap = otp;
 	hp->ahi_common.ah_platform_private = (void *)hp;
+
 	return ((ddi_acc_handle_t)hp);
+fail:
+	if ((waitfp != (int (*)())KM_SLEEP) &&
+	    (waitfp != (int (*)())KM_NOSLEEP))
+		ddi_set_callback(waitfp, arg, &impl_acc_hdl_id);
+	return (NULL);
 }
 
 void
@@ -174,107 +190,199 @@
 {
 	ddi_acc_impl_t *hp;
 
+	/*
+	 * The supplied (ddi_acc_handle_t) is actually a (ddi_acc_impl_t *),
+	 * because that's what we allocated in impl_acc_hdl_alloc() above.
+	 */
 	hp = (ddi_acc_impl_t *)handle;
 	if (hp) {
-		kmem_free(hp, sizeof (*hp));
+		kmem_free(hp->ahi_err->err_ontrap, sizeof (on_trap_data_t));
+		kmem_free(hp->ahi_err, sizeof (ndi_err_t));
+		kmem_free(hp, sizeof (ddi_acc_impl_t));
 		if (impl_acc_hdl_id)
 			ddi_run_callback(&impl_acc_hdl_id);
 	}
 }
 
+/*
+ * Function used to check if a given access handle owns the failing address.
+ * Called by ndi_fmc_error, when we detect a PIO error.
+ */
+/* ARGSUSED */
+static int
+impl_acc_check(dev_info_t *dip, const void *handle, const void *addr,
+    const void *not_used)
+{
+	pfn_t pfn, fault_pfn;
+	ddi_acc_hdl_t *hp;
+
+	hp = impl_acc_hdl_get((ddi_acc_handle_t)handle);
+
+	ASSERT(hp);
+
+	if (addr != NULL) {
+		pfn = hp->ah_pfn;
+		fault_pfn = mmu_btop(*(uint64_t *)addr);
+		if (fault_pfn >= pfn && fault_pfn < (pfn + hp->ah_pnum))
+			return (DDI_FM_NONFATAL);
+	}
+	return (DDI_FM_UNKNOWN);
+}
+
 void
 impl_acc_err_init(ddi_acc_hdl_t *handlep)
 {
-	/* Error handling not supported */
-	handlep->ah_acc.devacc_attr_access = DDI_DEFAULT_ACC;
+	int fmcap;
+	ndi_err_t *errp;
+	on_trap_data_t *otp;
+	ddi_acc_impl_t *hp = (ddi_acc_impl_t *)handlep;
+
+	fmcap = ddi_fm_capable(handlep->ah_dip);
+
+	if (handlep->ah_acc.devacc_attr_version < DDI_DEVICE_ATTR_V1 ||
+	    !DDI_FM_ACC_ERR_CAP(fmcap)) {
+		handlep->ah_acc.devacc_attr_access = DDI_DEFAULT_ACC;
+	} else if (DDI_FM_ACC_ERR_CAP(fmcap)) {
+		if (handlep->ah_acc.devacc_attr_access == DDI_DEFAULT_ACC) {
+			i_ddi_drv_ereport_post(handlep->ah_dip, DVR_EFMCAP,
+			    NULL, DDI_NOSLEEP);
+		} else {
+			errp = hp->ahi_err;
+			otp = (on_trap_data_t *)errp->err_ontrap;
+			otp->ot_handle = (void *)(hp);
+			otp->ot_prot = OT_DATA_ACCESS;
+			errp->err_status = DDI_FM_OK;
+			errp->err_expected = DDI_FM_ERR_UNEXPECTED;
+			errp->err_cf = impl_acc_check;
+		}
+	}
+}
+
+/* ARGSUSED */
+int
+impl_dma_check(dev_info_t *dip, const void *handle, const void *pci_hdl,
+    const void *not_used)
+{
+	return (DDI_FM_UNKNOWN);
 }
 
 void
 impl_acc_hdl_init(ddi_acc_hdl_t *handlep)
 {
 	ddi_acc_impl_t *hp;
+	int fmcap;
+	int devacc_attr_access;
 
 	if (!handlep)
 		return;
-	hp = (ddi_acc_impl_t *)handlep->ah_platform_private;
-
-	if (hp->ahi_acc_attr & DDI_ACCATTR_IO_SPACE) {
-		hp->ahi_get8 = i_ddi_io_get8;
-		hp->ahi_put8 = i_ddi_io_put8;
-		hp->ahi_rep_get8 = i_ddi_io_rep_get8;
-		hp->ahi_rep_put8 = i_ddi_io_rep_put8;
-
-		/* temporary set these 64 functions to no-ops */
-		hp->ahi_get64 = i_ddi_io_get64;
-		hp->ahi_put64 = i_ddi_io_put64;
-		hp->ahi_rep_get64 = i_ddi_io_rep_get64;
-		hp->ahi_rep_put64 = i_ddi_io_rep_put64;
+	fmcap = ddi_fm_capable(handlep->ah_dip);
+	if (handlep->ah_acc.devacc_attr_version < DDI_DEVICE_ATTR_V1 ||
+	    !DDI_FM_ACC_ERR_CAP(fmcap))
+		devacc_attr_access = DDI_DEFAULT_ACC;
+	else
+		devacc_attr_access = handlep->ah_acc.devacc_attr_access;
 
-		/*
-		 * check for BIG endian access
-		 */
-		if (handlep->ah_acc.devacc_attr_endian_flags ==
-			DDI_STRUCTURE_BE_ACC) {
-			hp->ahi_get16 = i_ddi_io_swap_get16;
-			hp->ahi_get32 = i_ddi_io_swap_get32;
-			hp->ahi_put16 = i_ddi_io_swap_put16;
-			hp->ahi_put32 = i_ddi_io_swap_put32;
-			hp->ahi_rep_get16 = i_ddi_io_swap_rep_get16;
-			hp->ahi_rep_get32 = i_ddi_io_swap_rep_get32;
-			hp->ahi_rep_put16 = i_ddi_io_swap_rep_put16;
-			hp->ahi_rep_put32 = i_ddi_io_swap_rep_put32;
-		} else {
-			hp->ahi_acc_attr |= DDI_ACCATTR_DIRECT;
-			hp->ahi_get16 = i_ddi_io_get16;
-			hp->ahi_get32 = i_ddi_io_get32;
-			hp->ahi_put16 = i_ddi_io_put16;
-			hp->ahi_put32 = i_ddi_io_put32;
-			hp->ahi_rep_get16 = i_ddi_io_rep_get16;
-			hp->ahi_rep_get32 = i_ddi_io_rep_get32;
-			hp->ahi_rep_put16 = i_ddi_io_rep_put16;
-			hp->ahi_rep_put32 = i_ddi_io_rep_put32;
-		}
+	hp = (ddi_acc_impl_t *)handlep->ah_platform_private;
+	switch (devacc_attr_access) {
+	case DDI_FLAGERR_ACC:
+	case DDI_CAUTIOUS_ACC:
+		hp->ahi_get8 = i_ddi_caut_get8;
+		hp->ahi_put8 = i_ddi_caut_put8;
+		hp->ahi_rep_get8 = i_ddi_caut_rep_get8;
+		hp->ahi_rep_put8 = i_ddi_caut_rep_put8;
+		hp->ahi_get16 = i_ddi_caut_get16;
+		hp->ahi_get32 = i_ddi_caut_get32;
+		hp->ahi_put16 = i_ddi_caut_put16;
+		hp->ahi_put32 = i_ddi_caut_put32;
+		hp->ahi_rep_get16 = i_ddi_caut_rep_get16;
+		hp->ahi_rep_get32 = i_ddi_caut_rep_get32;
+		hp->ahi_rep_put16 = i_ddi_caut_rep_put16;
+		hp->ahi_rep_put32 = i_ddi_caut_rep_put32;
+		hp->ahi_get64 = i_ddi_caut_get64;
+		hp->ahi_put64 = i_ddi_caut_put64;
+		hp->ahi_rep_get64 = i_ddi_caut_rep_get64;
+		hp->ahi_rep_put64 = i_ddi_caut_rep_put64;
+		break;
+	case DDI_DEFAULT_ACC:
+		if (hp->ahi_acc_attr & DDI_ACCATTR_IO_SPACE) {
+			hp->ahi_get8 = i_ddi_io_get8;
+			hp->ahi_put8 = i_ddi_io_put8;
+			hp->ahi_rep_get8 = i_ddi_io_rep_get8;
+			hp->ahi_rep_put8 = i_ddi_io_rep_put8;
+
+			/* temporary set these 64 functions to no-ops */
+			hp->ahi_get64 = i_ddi_io_get64;
+			hp->ahi_put64 = i_ddi_io_put64;
+			hp->ahi_rep_get64 = i_ddi_io_rep_get64;
+			hp->ahi_rep_put64 = i_ddi_io_rep_put64;
 
-	} else if (hp->ahi_acc_attr & DDI_ACCATTR_CPU_VADDR) {
+			/*
+			 * check for BIG endian access
+			 */
+			if (handlep->ah_acc.devacc_attr_endian_flags ==
+				DDI_STRUCTURE_BE_ACC) {
+				hp->ahi_get16 = i_ddi_io_swap_get16;
+				hp->ahi_get32 = i_ddi_io_swap_get32;
+				hp->ahi_put16 = i_ddi_io_swap_put16;
+				hp->ahi_put32 = i_ddi_io_swap_put32;
+				hp->ahi_rep_get16 = i_ddi_io_swap_rep_get16;
+				hp->ahi_rep_get32 = i_ddi_io_swap_rep_get32;
+				hp->ahi_rep_put16 = i_ddi_io_swap_rep_put16;
+				hp->ahi_rep_put32 = i_ddi_io_swap_rep_put32;
+			} else {
+				hp->ahi_acc_attr |= DDI_ACCATTR_DIRECT;
+				hp->ahi_get16 = i_ddi_io_get16;
+				hp->ahi_get32 = i_ddi_io_get32;
+				hp->ahi_put16 = i_ddi_io_put16;
+				hp->ahi_put32 = i_ddi_io_put32;
+				hp->ahi_rep_get16 = i_ddi_io_rep_get16;
+				hp->ahi_rep_get32 = i_ddi_io_rep_get32;
+				hp->ahi_rep_put16 = i_ddi_io_rep_put16;
+				hp->ahi_rep_put32 = i_ddi_io_rep_put32;
+			}
 
-		hp->ahi_get8 = i_ddi_vaddr_get8;
-		hp->ahi_put8 = i_ddi_vaddr_put8;
-		hp->ahi_rep_get8 = i_ddi_vaddr_rep_get8;
-		hp->ahi_rep_put8 = i_ddi_vaddr_rep_put8;
+		} else if (hp->ahi_acc_attr & DDI_ACCATTR_CPU_VADDR) {
 
-		/*
-		 * check for BIG endian access
-		 */
-		if (handlep->ah_acc.devacc_attr_endian_flags ==
-			DDI_STRUCTURE_BE_ACC) {
+			hp->ahi_get8 = i_ddi_vaddr_get8;
+			hp->ahi_put8 = i_ddi_vaddr_put8;
+			hp->ahi_rep_get8 = i_ddi_vaddr_rep_get8;
+			hp->ahi_rep_put8 = i_ddi_vaddr_rep_put8;
 
-			hp->ahi_get16 = i_ddi_vaddr_swap_get16;
-			hp->ahi_get32 = i_ddi_vaddr_swap_get32;
-			hp->ahi_get64 = i_ddi_vaddr_swap_get64;
-			hp->ahi_put16 = i_ddi_vaddr_swap_put16;
-			hp->ahi_put32 = i_ddi_vaddr_swap_put32;
-			hp->ahi_put64 = i_ddi_vaddr_swap_put64;
-			hp->ahi_rep_get16 = i_ddi_vaddr_swap_rep_get16;
-			hp->ahi_rep_get32 = i_ddi_vaddr_swap_rep_get32;
-			hp->ahi_rep_get64 = i_ddi_vaddr_swap_rep_get64;
-			hp->ahi_rep_put16 = i_ddi_vaddr_swap_rep_put16;
-			hp->ahi_rep_put32 = i_ddi_vaddr_swap_rep_put32;
-			hp->ahi_rep_put64 = i_ddi_vaddr_swap_rep_put64;
-		} else {
-			hp->ahi_acc_attr |= DDI_ACCATTR_DIRECT;
-			hp->ahi_get16 = i_ddi_vaddr_get16;
-			hp->ahi_get32 = i_ddi_vaddr_get32;
-			hp->ahi_get64 = i_ddi_vaddr_get64;
-			hp->ahi_put16 = i_ddi_vaddr_put16;
-			hp->ahi_put32 = i_ddi_vaddr_put32;
-			hp->ahi_put64 = i_ddi_vaddr_put64;
-			hp->ahi_rep_get16 = i_ddi_vaddr_rep_get16;
-			hp->ahi_rep_get32 = i_ddi_vaddr_rep_get32;
-			hp->ahi_rep_get64 = i_ddi_vaddr_rep_get64;
-			hp->ahi_rep_put16 = i_ddi_vaddr_rep_put16;
-			hp->ahi_rep_put32 = i_ddi_vaddr_rep_put32;
-			hp->ahi_rep_put64 = i_ddi_vaddr_rep_put64;
+			/*
+			 * check for BIG endian access
+			 */
+			if (handlep->ah_acc.devacc_attr_endian_flags ==
+				DDI_STRUCTURE_BE_ACC) {
+
+				hp->ahi_get16 = i_ddi_vaddr_swap_get16;
+				hp->ahi_get32 = i_ddi_vaddr_swap_get32;
+				hp->ahi_get64 = i_ddi_vaddr_swap_get64;
+				hp->ahi_put16 = i_ddi_vaddr_swap_put16;
+				hp->ahi_put32 = i_ddi_vaddr_swap_put32;
+				hp->ahi_put64 = i_ddi_vaddr_swap_put64;
+				hp->ahi_rep_get16 = i_ddi_vaddr_swap_rep_get16;
+				hp->ahi_rep_get32 = i_ddi_vaddr_swap_rep_get32;
+				hp->ahi_rep_get64 = i_ddi_vaddr_swap_rep_get64;
+				hp->ahi_rep_put16 = i_ddi_vaddr_swap_rep_put16;
+				hp->ahi_rep_put32 = i_ddi_vaddr_swap_rep_put32;
+				hp->ahi_rep_put64 = i_ddi_vaddr_swap_rep_put64;
+			} else {
+				hp->ahi_acc_attr |= DDI_ACCATTR_DIRECT;
+				hp->ahi_get16 = i_ddi_vaddr_get16;
+				hp->ahi_get32 = i_ddi_vaddr_get32;
+				hp->ahi_get64 = i_ddi_vaddr_get64;
+				hp->ahi_put16 = i_ddi_vaddr_put16;
+				hp->ahi_put32 = i_ddi_vaddr_put32;
+				hp->ahi_put64 = i_ddi_vaddr_put64;
+				hp->ahi_rep_get16 = i_ddi_vaddr_rep_get16;
+				hp->ahi_rep_get32 = i_ddi_vaddr_rep_get32;
+				hp->ahi_rep_get64 = i_ddi_vaddr_rep_get64;
+				hp->ahi_rep_put16 = i_ddi_vaddr_rep_put16;
+				hp->ahi_rep_put32 = i_ddi_vaddr_rep_put32;
+				hp->ahi_rep_put64 = i_ddi_vaddr_rep_put64;
+			}
 		}
+		break;
 	}
 	hp->ahi_fault_check = i_ddi_acc_fault_check;
 	hp->ahi_fault_notify = i_ddi_acc_fault_notify;
--- a/usr/src/uts/intel/sys/ddi_isa.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/intel/sys/ddi_isa.h	Sun Apr 23 15:26:28 2006 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -334,6 +334,37 @@
 void
 i_ddi_acc_fault_notify(ddi_acc_impl_t *hdlp);
 
+/* DDI Fault Services functions */
+void i_ddi_caut_get(size_t size, void *addr, void *val);
+
+uint8_t i_ddi_caut_get8(ddi_acc_impl_t *hdlp, uint8_t *addr);
+uint16_t i_ddi_caut_get16(ddi_acc_impl_t *hdlp, uint16_t *addr);
+uint32_t i_ddi_caut_get32(ddi_acc_impl_t *hdlp, uint32_t *addr);
+uint64_t i_ddi_caut_get64(ddi_acc_impl_t *hdlp, uint64_t *addr);
+
+void i_ddi_caut_put8(ddi_acc_impl_t *hdlp, uint8_t *addr, uint8_t value);
+void i_ddi_caut_put16(ddi_acc_impl_t *hdlp, uint16_t *addr, uint16_t value);
+void i_ddi_caut_put32(ddi_acc_impl_t *hdlp, uint32_t *addr, uint32_t value);
+void i_ddi_caut_put64(ddi_acc_impl_t *hdlp, uint64_t *addr, uint64_t value);
+
+void i_ddi_caut_rep_get8(ddi_acc_impl_t *hdlp, uint8_t *host_addr,
+    uint8_t *dev_addr, size_t repcount, uint_t flags);
+void i_ddi_caut_rep_get16(ddi_acc_impl_t *hdlp, uint16_t *host_addr,
+    uint16_t *dev_addr, size_t repcount, uint_t flags);
+void i_ddi_caut_rep_get32(ddi_acc_impl_t *hdlp, uint32_t *host_addr,
+    uint32_t *dev_addr, size_t repcount, uint_t flags);
+void i_ddi_caut_rep_get64(ddi_acc_impl_t *hdlp, uint64_t *host_addr,
+    uint64_t *dev_addr, size_t repcount, uint_t flags);
+
+void i_ddi_caut_rep_put8(ddi_acc_impl_t *hdlp, uint8_t *host_addr,
+    uint8_t *dev_addr, size_t repcount, uint_t flags);
+void i_ddi_caut_rep_put16(ddi_acc_impl_t *hdlp, uint16_t *host_addr,
+    uint16_t *dev_addr, size_t repcount, uint_t flags);
+void i_ddi_caut_rep_put32(ddi_acc_impl_t *hdl, uint32_t *host_addr,
+    uint32_t *dev_addr, size_t repcount, uint_t flags);
+void i_ddi_caut_rep_put64(ddi_acc_impl_t *hdl, uint64_t *host_addr,
+    uint64_t *dev_addr, size_t repcount, uint_t flags);
+
 #endif	/* __STDC__ */
 
 #endif	/* _KERNEL */
--- a/usr/src/uts/sun4/io/px/px.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4/io/px/px.c	Sun Apr 23 15:26:28 2006 -0700
@@ -62,6 +62,8 @@
 static int px_pwr_setup(dev_info_t *dip);
 static void px_pwr_teardown(dev_info_t *dip);
 
+extern errorq_t *pci_target_queue;
+
 /*
  * function prototypes for hotplug routines:
  */
@@ -170,6 +172,13 @@
 	e = mod_remove(&modlinkage);
 	if (e != DDI_SUCCESS)
 		return (e);
+	/*
+	 * Destroy pci_target_queue, and set it to NULL.
+	 */
+	if (pci_target_queue)
+		errorq_destroy(pci_target_queue);
+
+	pci_target_queue = NULL;
 
 	/* Free px soft state */
 	ddi_soft_state_fini(&px_state_p);
@@ -941,8 +950,10 @@
 	px_dump_dma_handle(DBG_DMA_MAP, dip, mp);
 
 	/* insert dma handle into FMA cache */
-	if (mp->dmai_attr.dma_attr_flags & DDI_DMA_FLAGERR)
+	if (mp->dmai_attr.dma_attr_flags & DDI_DMA_FLAGERR) {
 		(void) ndi_fmc_insert(rdip, DMA_HANDLE, mp, NULL);
+		mp->dmai_error.err_cf = impl_dma_check;
+	}
 
 	return (mp->dmai_nwin == 1 ? DDI_DMA_MAPPED : DDI_DMA_PARTIAL_MAP);
 map_err:
--- a/usr/src/uts/sun4/io/px/px_dma.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4/io/px/px_dma.c	Sun Apr 23 15:26:28 2006 -0700
@@ -110,6 +110,7 @@
 	mp->dmai_error.err_expected = DDI_FM_ERR_UNEXPECTED;
 	mp->dmai_error.err_ontrap = NULL;
 	mp->dmai_error.err_fep = NULL;
+	mp->dmai_error.err_cf = NULL;
 
 	if (px_child_prefetch(mp->dmai_rdip))
 		mp->dmai_flags |= (PX_DMAI_FLAGS_MAP_BUFZONE |
--- a/usr/src/uts/sun4/io/px/px_fm.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4/io/px/px_fm.c	Sun Apr 23 15:26:28 2006 -0700
@@ -93,6 +93,12 @@
 		DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
 
 	/*
+	 * Initialize pci_target_queue for FMA handling of
+	 * pci errors.
+	 */
+	pci_targetq_init();
+
+	/*
 	 * check parents' capability
 	 */
 	ddi_fm_init(px_p->px_dip, &px_p->px_fm_cap, &px_p->px_fm_ibc);
@@ -191,80 +197,13 @@
 }
 
 /*
- * Function called after a dma fault occurred to find out whether the
- * fault address is associated with a driver that is able to handle faults
- * and recover from faults. The driver has to set DDI_DMA_FLAGERR and
- * cache dma handles in order to make this checking effective to help
- * recovery from dma faults.
- */
-/* ARGSUSED */
-static int
-px_dma_check(dev_info_t *dip, const void *handle, const void *comp_addr,
-    const void *not_used)
-{
-	ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle;
-	pfn_t fault_pfn = mmu_btop(*(uint64_t *)comp_addr);
-	pfn_t comp_pfn;
-	int page;
-
-	/*
-	 * Assertion failure if DDI_FM_DMACHK_CAPABLE capability has not
-	 * been effectively initialized during attach.
-	 */
-	ASSERT(mp);
-
-	for (page = 0; page < mp->dmai_ndvmapages; page++) {
-		comp_pfn = PX_GET_MP_PFN(mp, page);
-		if (fault_pfn == comp_pfn)
-			return (DDI_FM_NONFATAL);
-	}
-
-	return (DDI_FM_UNKNOWN);
-}
-
-/*
- * Function used to check if a given access handle owns the failing address.
- * Called by ndi_fmc_error, when we detect a PIO error.
- */
-/* ARGSUSED */
-static int
-px_acc_check(dev_info_t *dip, const void *handle, const void *comp_addr,
-    const void *not_used)
-{
-	pfn_t pfn, fault_pfn;
-	ddi_acc_hdl_t *hp = impl_acc_hdl_get((ddi_acc_handle_t)handle);
-
-	/*
-	 * Assertion failure if DDI_FM_ACCCHK_CAPABLE capability has not
-	 * been effectively initialized during attach.
-	 */
-	ASSERT(hp);
-
-	pfn = hp->ah_pfn;
-	fault_pfn = mmu_btop(*(uint64_t *)comp_addr);
-	if (fault_pfn >= pfn && fault_pfn < (pfn + hp->ah_pnum))
-		return (DDI_FM_NONFATAL);
-
-	return (DDI_FM_UNKNOWN);
-}
-
-/*
  * Function used by PCI error handlers to check if captured address is stored
  * in the DMA or ACC handle caches.
  */
 int
 px_handle_lookup(dev_info_t *dip, int type, uint64_t fme_ena, void *afar)
 {
-	uint32_t cap = ((px_t *)DIP_TO_STATE(dip))->px_fm_cap;
-	int	ret = DDI_FM_FATAL;
-
-	int (*f)() = type == DMA_HANDLE ?
-	    (DDI_FM_DMA_ERR_CAP(cap) ? px_dma_check : NULL) :
-	    (DDI_FM_ACC_ERR_CAP(cap) ? px_acc_check : NULL);
-
-	if (f)
-		ret = ndi_fmc_error(dip, NULL, type, f, fme_ena, afar);
-
+	int ret = ndi_fmc_error(dip, NULL, type, fme_ena, afar);
 	return (ret == DDI_FM_UNKNOWN ? DDI_FM_FATAL : ret);
 }
 
@@ -749,7 +688,6 @@
 	if (px_fabric_die &&
 	    (ret & (PX_FATAL_GOS | PX_FATAL_SW)))
 			ret = DDI_FM_FATAL;
-
 	return (ret);
 }
 
--- a/usr/src/uts/sun4/io/px/px_pci.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4/io/px/px_pci.c	Sun Apr 23 15:26:28 2006 -0700
@@ -302,18 +302,6 @@
 			ddi_get_soft_state(pxb_state, instance);
 		(void) pcie_pwr_resume(devi);
 
-		mutex_enter(&DEVI(devi)->devi_lock);
-		DEVI_SET_ATTACHING(devi);
-		mutex_exit(&DEVI(devi)->devi_lock);
-
-		if (pxb_fm_init(pxb) != DDI_SUCCESS)
-			cmn_err(CE_WARN, "px_pci: dip0x%p failed pxb_fm_init "
-			    "at resume\n", (void *) devi);
-
-		mutex_enter(&DEVI(devi)->devi_lock);
-		DEVI_CLR_ATTACHING(devi);
-		mutex_exit(&DEVI(devi)->devi_lock);
-
 		return (DDI_SUCCESS);
 
 	case DDI_ATTACH:
@@ -523,16 +511,6 @@
 		pxb = (pxb_devstate_t *)
 			ddi_get_soft_state(pxb_state, ddi_get_instance(devi));
 
-		mutex_enter(&DEVI(devi)->devi_lock);
-		DEVI_SET_DETACHING(devi);
-		mutex_exit(&DEVI(devi)->devi_lock);
-
-		pxb_fm_fini(pxb);
-
-		mutex_enter(&DEVI(devi)->devi_lock);
-		DEVI_CLR_DETACHING(devi);
-		mutex_exit(&DEVI(devi)->devi_lock);
-
 		error = pcie_pwr_suspend(devi);
 
 		return (error);
@@ -1693,11 +1671,10 @@
 static int
 pxb_fm_init(pxb_devstate_t *pxb_p)
 {
-	ddi_fm_error_t	derr;
 	dev_info_t	*dip = pxb_p->pxb_dip;
 
 	pxb_p->pxb_fm_cap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE |
-		DDI_FM_ACCCHK_CAPABLE;
+		DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
 
 	/*
 	 * Request our capability level and get our parents capability
@@ -1708,15 +1685,6 @@
 	pci_ereport_setup(dip);
 
 	/*
-	 * clear any outstanding error bits
-	 */
-	bzero(&derr, sizeof (ddi_fm_error_t));
-	derr.fme_version = DDI_FME_VERSION;
-	derr.fme_flag = DDI_FM_ERR_EXPECTED;
-	pci_ereport_post(dip, &derr, NULL);
-	pci_bdg_ereport_post(dip, &derr, NULL);
-
-	/*
 	 * Register error callback with our parent.
 	 */
 	ddi_fm_handler_register(pxb_p->pxb_dip, pxb_fm_err_callback,
@@ -1763,16 +1731,8 @@
 pxb_fm_err_callback(dev_info_t *dip, ddi_fm_error_t *derr,
     const void *impl_data)
 {
-	uint16_t pci_cfg_stat, pci_cfg_sec_stat;
-	int ret;
-	ddi_acc_handle_t hdl = *(ddi_acc_handle_t *)impl_data;
-
-	pci_ereport_post(dip, derr, &pci_cfg_stat);
-	pci_bdg_ereport_post(dip, derr, &pci_cfg_sec_stat);
-	ret = pci_bdg_check_status(dip, derr, pci_cfg_stat, pci_cfg_sec_stat);
-	/* do this till Fabric FMA is in place. */
-	pcie_clear_errors(dip, hdl);
-	return (ret);
+	pci_ereport_post(dip, derr, NULL);
+	return (derr->fme_status);
 }
 
 /*
--- a/usr/src/uts/sun4/os/ddi_impl.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4/os/ddi_impl.c	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1269,6 +1268,62 @@
 	}
 }
 
+#define	PCI_GET_MP_PFN(mp, page_no)	((mp)->dmai_ndvmapages == 1 ? \
+	(pfn_t)(mp)->dmai_iopte:(((pfn_t *)(mp)->dmai_iopte)[page_no]))
+
+/*
+ * Function called after a dma fault occurred to find out whether the
+ * fault address is associated with a driver that is able to handle faults
+ * and recover from faults.
+ */
+/* ARGSUSED */
+int
+impl_dma_check(dev_info_t *dip, const void *handle, const void *addr,
+    const void *not_used)
+{
+	ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle;
+	pfn_t fault_pfn = mmu_btop(*(uint64_t *)addr);
+	pfn_t comp_pfn;
+
+	/*
+	 * The driver has to set DDI_DMA_FLAGERR to recover from dma faults.
+	 */
+	int page;
+
+	ASSERT(mp);
+	for (page = 0; page < mp->dmai_ndvmapages; page++) {
+		comp_pfn = PCI_GET_MP_PFN(mp, page);
+		if (fault_pfn == comp_pfn)
+			return (DDI_FM_NONFATAL);
+	}
+	return (DDI_FM_UNKNOWN);
+}
+
+/*
+ * Function used to check if a given access handle owns the failing address.
+ * Called by ndi_fmc_error, when we detect a PIO error.
+ */
+/* ARGSUSED */
+static int
+impl_acc_check(dev_info_t *dip, const void *handle, const void *addr,
+    const void *not_used)
+{
+	pfn_t pfn, fault_pfn;
+	ddi_acc_hdl_t *hp;
+
+	hp = impl_acc_hdl_get((ddi_acc_handle_t)handle);
+
+	ASSERT(hp);
+
+	if (addr != NULL) {
+		pfn = hp->ah_pfn;
+		fault_pfn = mmu_btop(*(uint64_t *)addr);
+		if (fault_pfn >= pfn && fault_pfn < (pfn + hp->ah_pnum))
+			return (DDI_FM_NONFATAL);
+	}
+	return (DDI_FM_UNKNOWN);
+}
+
 void
 impl_acc_err_init(ddi_acc_hdl_t *handlep)
 {
@@ -1300,6 +1355,7 @@
 				    (uintptr_t)&i_ddi_prot_trampoline;
 			errp->err_status = DDI_FM_OK;
 			errp->err_expected = DDI_FM_ERR_UNEXPECTED;
+			errp->err_cf = impl_acc_check;
 		}
 	}
 }
--- a/usr/src/uts/sun4u/io/pci/db21554.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/db21554.c	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -3054,8 +3053,6 @@
 static void
 db_fm_init(db_ctrl_t *db_p)
 {
-	ddi_fm_error_t derr;
-
 	db_p->fm_cap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE |
 		DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
 
@@ -3070,15 +3067,6 @@
 	pci_ereport_setup(db_p->dip);
 
 	/*
-	 * clear any outstanding error bits
-	 */
-	bzero(&derr, sizeof (ddi_fm_error_t));
-	derr.fme_version = DDI_FME_VERSION;
-	derr.fme_flag = DDI_FM_ERR_EXPECTED;
-	pci_ereport_post(db_p->dip, &derr, NULL);
-	pci_bdg_ereport_post(db_p->dip, &derr, NULL);
-
-	/*
 	 * Register error callback with our parent.
 	 */
 	ddi_fm_handler_register(db_p->dip, db_err_callback, NULL);
@@ -3119,13 +3107,9 @@
 static int
 db_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *impl_data)
 {
-	uint16_t pci_cfg_stat, pci_cfg_sec_stat;
-
 	ASSERT(impl_data == NULL);
-	pci_ereport_post(dip, derr, &pci_cfg_stat);
-	pci_bdg_ereport_post(dip, derr, &pci_cfg_sec_stat);
-	return (pci_bdg_check_status(dip, derr, pci_cfg_stat,
-	    pci_cfg_sec_stat));
+	pci_ereport_post(dip, derr, NULL);
+	return (derr->fme_status);
 }
 
 static void
--- a/usr/src/uts/sun4u/io/pci/pci.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/pci.c	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -141,10 +140,9 @@
 void *per_pci_common_state;	/* per-psycho soft state pointer */
 kmutex_t pci_global_mutex;	/* attach/detach common struct lock */
 errorq_t *pci_ecc_queue = NULL;	/* per-system ecc handling queue */
-errorq_t *pci_target_queue = NULL;	/* per-system target handling queue */
+extern errorq_t *pci_target_queue;
 struct cb_ops *pcihp_ops = NULL;	/* hotplug module cb ops */
 
-
 extern void pci_child_cfg_save(dev_info_t *dip);
 extern void pci_child_cfg_restore(dev_info_t *dip);
 
@@ -757,8 +755,10 @@
 	    cookiep->dmac_size);
 	dump_dma_handle(DBG_DMA_MAP, dip, mp);
 
-	if (mp->dmai_attr.dma_attr_flags & DDI_DMA_FLAGERR)
+	if (mp->dmai_attr.dma_attr_flags & DDI_DMA_FLAGERR) {
 		(void) ndi_fmc_insert(rdip, DMA_HANDLE, mp, NULL);
+		mp->dmai_error.err_cf = impl_dma_check;
+	}
 
 	mp->dmai_flags |= DMAI_FLAGS_MAPPED;
 	return (mp->dmai_nwin == 1 ? DDI_DMA_MAPPED : DDI_DMA_PARTIAL_MAP);
--- a/usr/src/uts/sun4u/io/pci/pci_dma.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/pci_dma.c	Sun Apr 23 15:26:28 2006 -0700
@@ -300,6 +300,7 @@
 	mp->dmai_error.err_expected = DDI_FM_ERR_UNEXPECTED;
 	mp->dmai_error.err_ontrap = NULL;
 	mp->dmai_error.err_fep = NULL;
+	mp->dmai_error.err_cf = NULL;
 
 	SYNC_BUF_PA(mp) = 0ull;
 	return (mp);
--- a/usr/src/uts/sun4u/io/pci/pci_fm.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/pci_fm.c	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -67,79 +66,6 @@
  */
 
 /*
- * Function called after a dma fault occurred to find out whether the
- * fault address is associated with a driver that is able to handle faults
- * and recover from faults.
- */
-/* ARGSUSED */
-static int
-pci_dma_check(dev_info_t *dip, const void *handle, const void *comp_addr,
-    const void *not_used)
-{
-	ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle;
-	pfn_t fault_pfn = mmu_btop(*(uint64_t *)comp_addr);
-	pfn_t comp_pfn;
-	int page;
-
-	/*
-	 * The driver has to set DDI_DMA_FLAGERR to recover from dma faults.
-	 */
-	ASSERT(mp);
-
-	for (page = 0; page < mp->dmai_ndvmapages; page++) {
-		comp_pfn = PCI_GET_MP_PFN(mp, page);
-		if (fault_pfn == comp_pfn)
-			return (DDI_FM_NONFATAL);
-	}
-
-	return (DDI_FM_UNKNOWN);
-}
-
-/*
- * Function used to check if a given access handle owns the failing address.
- * Called by ndi_fmc_error, when we detect a PIO error.
- */
-/* ARGSUSED */
-static int
-pci_acc_check(dev_info_t *dip, const void *handle, const void *comp_addr,
-    const void *not_used)
-{
-	pfn_t pfn, fault_pfn;
-	ddi_acc_hdl_t *hp;
-
-	hp = impl_acc_hdl_get((ddi_acc_handle_t)handle);
-
-	ASSERT(hp);
-
-	pfn = hp->ah_pfn;
-	fault_pfn = mmu_btop(*(uint64_t *)comp_addr);
-	if (fault_pfn >= pfn && fault_pfn < (pfn + hp->ah_pnum))
-		return (DDI_FM_NONFATAL);
-
-	return (DDI_FM_UNKNOWN);
-}
-
-/*
- * Function used by PCI error handlers to check if captured address is stored
- * in the DMA or ACC handle caches.
- */
-int
-pci_handle_lookup(dev_info_t *dip, int type, uint64_t fme_ena, void *afar)
-{
-	int status = DDI_FM_UNKNOWN;
-	pci_t *pci_p = get_pci_soft_state(ddi_get_instance(dip));
-
-	if (type == DMA_HANDLE && DDI_FM_DMA_ERR_CAP(pci_p->pci_fm_cap))
-		status = ndi_fmc_error(dip, NULL, type, pci_dma_check,
-		    fme_ena, afar);
-	else if (DDI_FM_ACC_ERR_CAP(pci_p->pci_fm_cap))
-		status = ndi_fmc_error(dip, NULL, type, pci_acc_check,
-		    fme_ena, afar);
-
-	return (status);
-}
-
-/*
  * Function used to setup access functions depending on level of desired
  * protection.
  */
@@ -213,7 +139,7 @@
 	pci_t *pci_p = get_pci_soft_state(ddi_get_instance(dip));
 
 	ASSERT(ibc != NULL);
-	*ibc = pci_p->pci_pbm_p->pbm_iblock_cookie;
+	*ibc = pci_p->pci_fm_ibc;
 
 	return (pci_p->pci_fm_cap);
 }
@@ -319,231 +245,6 @@
 		return (DDI_FM_OK);
 }
 
-/*
- * private version of walk_devs() that can be used during panic. No
- * sleeping or locking required.
- */
-static int
-pci_tgt_walk_devs(dev_info_t *dip, int (*f)(dev_info_t *, void *), void *arg)
-{
-	while (dip) {
-		switch ((*f)(dip, arg)) {
-		case DDI_WALK_TERMINATE:
-			return (DDI_WALK_TERMINATE);
-		case DDI_WALK_CONTINUE:
-			if (pci_tgt_walk_devs(ddi_get_child(dip), f,
-			    arg) == DDI_WALK_TERMINATE)
-				return (DDI_WALK_TERMINATE);
-			break;
-		case DDI_WALK_PRUNECHILD:
-			break;
-		}
-		dip = ddi_get_next_sibling(dip);
-	}
-	return (DDI_WALK_CONTINUE);
-}
-
-static int
-pci_check_regs(dev_info_t *dip, void *arg)
-{
-	int reglen;
-	int rn;
-	int totreg;
-	pci_regspec_t *drv_regp;
-	pci_target_err_t *tgt_err = (pci_target_err_t *)arg;
-
-	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
-	    "assigned-addresses", (caddr_t)&drv_regp, &reglen) != DDI_SUCCESS)
-		return (DDI_WALK_CONTINUE);
-
-	totreg = reglen / sizeof (pci_regspec_t);
-	for (rn = 0; rn < totreg; rn++) {
-		if (tgt_err->tgt_pci_space ==
-		    PCI_REG_ADDR_G(drv_regp[rn].pci_phys_hi) &&
-		    (tgt_err->tgt_pci_addr >=
-		    (uint64_t)drv_regp[rn].pci_phys_low +
-		    ((uint64_t)drv_regp[rn].pci_phys_mid << 32)) &&
-		    (tgt_err->tgt_pci_addr <
-		    (uint64_t)drv_regp[rn].pci_phys_low +
-		    ((uint64_t)drv_regp[rn].pci_phys_mid << 32) +
-		    (uint64_t)drv_regp[rn].pci_size_low +
-		    ((uint64_t)drv_regp[rn].pci_size_hi << 32))) {
-			tgt_err->tgt_dip = dip;
-			kmem_free(drv_regp, reglen);
-			return (DDI_WALK_TERMINATE);
-		}
-	}
-	kmem_free(drv_regp, reglen);
-	return (DDI_WALK_CONTINUE);
-}
-
-static int
-pci_check_ranges(dev_info_t *dip, void *arg)
-{
-	uint64_t range_parent_begin;
-	uint64_t range_parent_size;
-	uint64_t range_parent_end;
-	uint32_t space_type;
-	uint32_t bus_num;
-	uint32_t range_offset;
-	pci_ranges_t *pci_ranges, *rangep;
-	pci_bus_range_t *pci_bus_rangep;
-	int pci_ranges_length;
-	int nrange;
-	pci_target_err_t *tgt_err = (pci_target_err_t *)arg;
-	int i, size;
-
-	if (strcmp(ddi_node_name(dip), "pci") != 0)
-		return (DDI_WALK_CONTINUE);
-
-	/*
-	 * Get the ranges property.
-	 */
-	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "ranges",
-		(caddr_t)&pci_ranges, &pci_ranges_length) != DDI_SUCCESS) {
-		return (DDI_WALK_CONTINUE);
-	}
-	nrange = pci_ranges_length / sizeof (pci_ranges_t);
-	rangep = pci_ranges;
-	pci_fix_ranges(pci_ranges, nrange);
-
-	for (i = 0; i < nrange; i++, rangep++) {
-		range_parent_begin = ((uint64_t)rangep->parent_high << 32) +
-		    rangep->parent_low;
-		range_parent_size = ((uint64_t)rangep->size_high << 32) +
-		    rangep->size_low;
-		range_parent_end = range_parent_begin + range_parent_size - 1;
-
-		if ((tgt_err->tgt_err_addr < range_parent_begin) ||
-		    (tgt_err->tgt_err_addr > range_parent_end)) {
-			/* Not in range */
-			continue;
-		}
-		space_type = PCI_REG_ADDR_G(rangep->child_high);
-		if (space_type == PCI_REG_ADDR_G(PCI_ADDR_CONFIG)) {
-			/* Config space address - check bus range */
-			range_offset = tgt_err->tgt_err_addr -
-			    range_parent_begin;
-			bus_num = PCI_REG_BUS_G(range_offset);
-			if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
-			    DDI_PROP_DONTPASS, "bus-range",
-			    (caddr_t)&pci_bus_rangep, &size) != DDI_SUCCESS) {
-				continue;
-			}
-			if ((bus_num < pci_bus_rangep->lo) ||
-			    (bus_num > pci_bus_rangep->hi)) {
-				/*
-				 * Bus number not appropriate for this
-				 * pci nexus.
-				 */
-				kmem_free(pci_bus_rangep, size);
-				continue;
-			}
-			kmem_free(pci_bus_rangep, size);
-		}
-
-		/* We have a match if we get here - compute pci address */
-		tgt_err->tgt_pci_addr = tgt_err->tgt_err_addr -
-		    range_parent_begin;
-		tgt_err->tgt_pci_addr += (((uint64_t)rangep->child_mid << 32) +
-		    rangep->child_low);
-		tgt_err->tgt_pci_space = space_type;
-		if (panicstr)
-			pci_tgt_walk_devs(dip, pci_check_regs, (void *)tgt_err);
-		else
-			ddi_walk_devs(dip, pci_check_regs, (void *)tgt_err);
-		if (tgt_err->tgt_dip != NULL) {
-			kmem_free(pci_ranges, pci_ranges_length);
-			return (DDI_WALK_TERMINATE);
-		}
-	}
-	kmem_free(pci_ranges, pci_ranges_length);
-	return (DDI_WALK_PRUNECHILD);
-}
-
-/*
- * need special version of ddi_fm_ereport_post() as the leaf driver may
- * not be hardened.
- */
-void
-pci_tgt_ereport_post(dev_info_t *dip, const char *error_class, uint64_t ena,
-    uint8_t version, ...)
-{
-	char *name;
-	char device_path[MAXPATHLEN];
-	char ddi_error_class[FM_MAX_CLASS];
-	nvlist_t *ereport, *detector;
-	nv_alloc_t *nva;
-	errorq_elem_t *eqep;
-	va_list ap;
-
-	if (panicstr) {
-		eqep = errorq_reserve(ereport_errorq);
-		if (eqep == NULL)
-			return;
-		ereport = errorq_elem_nvl(ereport_errorq, eqep);
-		nva = errorq_elem_nva(ereport_errorq, eqep);
-		detector = fm_nvlist_create(nva);
-	} else {
-		ereport = fm_nvlist_create(NULL);
-		detector = fm_nvlist_create(NULL);
-	}
-
-	(void) ddi_pathname(dip, device_path);
-	fm_fmri_dev_set(detector, FM_DEV_SCHEME_VERSION, NULL,
-	    device_path, NULL);
-	(void) snprintf(ddi_error_class, FM_MAX_CLASS, "%s.%s",
-	    DDI_IO_CLASS, error_class);
-	fm_ereport_set(ereport, version, ddi_error_class, ena, detector, NULL);
-
-	va_start(ap, version);
-	name = va_arg(ap, char *);
-	(void) i_fm_payload_set(ereport, name, ap);
-	va_end(ap);
-
-	if (panicstr) {
-		errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC);
-	} else {
-		(void) fm_ereport_post(ereport, EVCH_TRYHARD);
-		fm_nvlist_destroy(ereport, FM_NVA_FREE);
-		fm_nvlist_destroy(detector, FM_NVA_FREE);
-	}
-}
-
-/*
- * Function used to drain pci_target_queue, either during panic or after softint
- * is generated, to generate target device ereports based on captured physical
- * addresss
- */
-static void
-pci_target_drain(void *private_p, pci_target_err_t *tgt_err)
-{
-	char buf[FM_MAX_CLASS];
-
-	/*
-	 * The following assumes that all pci_pci bridge devices
-	 * are configured as transparant. Find the top-level pci
-	 * nexus which has tgt_err_addr in one of its ranges, converting this
-	 * to a pci address in the process. Then starting at this node do
-	 * another tree walk to find a device with the pci address we've
-	 * found within range of one of it's assigned-addresses properties.
-	 */
-	tgt_err->tgt_dip = NULL;
-	if (panicstr)
-		pci_tgt_walk_devs(ddi_root_node(), pci_check_ranges,
-		    (void *)tgt_err);
-	else
-		ddi_walk_devs(ddi_root_node(), pci_check_ranges,
-		    (void *)tgt_err);
-	if (tgt_err->tgt_dip == NULL)
-		return;
-
-	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", tgt_err->tgt_bridge_type,
-	    tgt_err->tgt_err_class);
-	pci_tgt_ereport_post(tgt_err->tgt_dip, buf, tgt_err->tgt_err_ena, 0,
-	    PCI_PA, DATA_TYPE_UINT64, tgt_err->tgt_err_addr, NULL);
-}
-
 void
 pci_fm_create(pci_t *pci_p)
 {
@@ -558,7 +259,7 @@
 	if (pci_ecc_queue == NULL) {
 		pci_ecc_queue = errorq_create("pci_ecc_queue",
 				(errorq_func_t)ecc_err_drain,
-				(void *)NULL,
+				(void *)pci_p->pci_ecc_p,
 				ECC_MAX_ERRS, sizeof (ecc_errstate_t),
 				PIL_2, ERRORQ_VITAL);
 		if (pci_ecc_queue == NULL)
@@ -566,20 +267,9 @@
 	}
 
 	/*
-	 * PCI target errorq, to schedule async handling of generation of
-	 * target device ereports based on captured physical address.
-	 * The errorq is created here but destroyed when _fini is called
-	 * for the pci module.
+	 * Initialize pci_target_queue for FMA handling of pci errors.
 	 */
-	if (pci_target_queue == NULL) {
-		pci_target_queue = errorq_create("pci_target_queue",
-				(errorq_func_t)pci_target_drain,
-				(void *)NULL,
-				TARGET_MAX_ERRS, sizeof (pci_target_err_t),
-				PIL_2, ERRORQ_VITAL);
-		if (pci_target_queue == NULL)
-			panic("failed to create required system error queue");
-	}
+	pci_targetq_init();
 
 	/*
 	 * Initialize FMA support
--- a/usr/src/uts/sun4u/io/pci/pci_pbm.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/pci_pbm.c	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -323,7 +322,6 @@
 	int ret = 0;
 	pci_t *pci_p = get_pci_soft_state(ddi_get_instance(dip));
 	pci_common_t *cmn_p = pci_p->pci_common_p;
-	pci_target_err_t tgt_err;
 
 	ASSERT(MUTEX_HELD(&cmn_p->pci_fm_mutex));
 
@@ -338,26 +336,18 @@
 	/*
 	 * Lookup and fault errant handle
 	 */
-	if (((ret = pci_handle_lookup(dip, ACC_HANDLE, fme_ena,
-				(void *)&pbm_err_p->pbm_pci.pci_pa))
-			== DDI_FM_FATAL) || (ret == DDI_FM_UNKNOWN)) {
+	if (((ret = ndi_fmc_error(dip, NULL, ACC_HANDLE, fme_ena,
+	    (void *)&pbm_err_p->pbm_pci.pci_pa)) == DDI_FM_FATAL) ||
+	    (ret == DDI_FM_UNKNOWN))
 		fatal++;
-	}
 
 	/*
 	 * queue target ereport if appropriate
 	 */
-	if (pbm_err_p->pbm_terr_class) {
-		tgt_err.tgt_err_ena = fme_ena;
-		tgt_err.tgt_err_class = pbm_err_p->pbm_terr_class;
-		if (pbm_err_p->pbm_log == FM_LOG_PCI)
-			tgt_err.tgt_bridge_type = "pci";
-		else
-			tgt_err.tgt_bridge_type = pbm_err_p->pbm_bridge_type;
-		tgt_err.tgt_err_addr = pbm_err_p->pbm_pci.pci_pa;
-		errorq_dispatch(pci_target_queue, (void *)&tgt_err,
-		    sizeof (pci_target_err_t), ERRORQ_ASYNC);
-	}
+	if (pbm_err_p->pbm_terr_class)
+		pci_target_enqueue(fme_ena, pbm_err_p->pbm_terr_class,
+		    (pbm_err_p->pbm_log == FM_LOG_PCI) ? "pci" :
+		    pbm_err_p->pbm_bridge_type, pbm_err_p->pbm_pci.pci_pa);
 
 	/*
 	 * We are currently not dealing with the multiple error
--- a/usr/src/uts/sun4u/io/pci/pci_pci.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/pci_pci.c	Sun Apr 23 15:26:28 2006 -0700
@@ -74,21 +74,6 @@
 } slot_table_t;
 
 /*
- * The following typedef is used to represent an entry in the "ranges"
- * property of a device node.
- */
-typedef struct {
-	uint32_t child_high;
-	uint32_t child_mid;
-	uint32_t child_low;
-	uint32_t parent_high;
-	uint32_t parent_mid;
-	uint32_t parent_low;
-	uint32_t size_high;
-	uint32_t size_low;
-} ppb_ranges_t;
-
-/*
  * The variable controls the default setting of the command register
  * for pci devices.  See ppb_initchild() for details.
  */
@@ -1643,8 +1628,6 @@
 static void
 ppb_fm_init(ppb_devstate_t *ppb_p)
 {
-	ddi_fm_error_t derr;
-
 	ppb_p->fm_cap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE |
 		DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
 
@@ -1659,15 +1642,6 @@
 	pci_ereport_setup(ppb_p->dip);
 
 	/*
-	 * clear any outstanding error bits
-	 */
-	bzero(&derr, sizeof (ddi_fm_error_t));
-	derr.fme_version = DDI_FME_VERSION;
-	derr.fme_flag = DDI_FM_ERR_EXPECTED;
-	pci_ereport_post(ppb_p->dip, &derr, NULL);
-	pci_bdg_ereport_post(ppb_p->dip, &derr, NULL);
-
-	/*
 	 * Register error callback with our parent.
 	 */
 	ddi_fm_handler_register(ppb_p->dip, ppb_err_callback, NULL);
@@ -1708,13 +1682,9 @@
 static int
 ppb_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *impl_data)
 {
-	uint16_t pci_cfg_stat, pci_cfg_sec_stat;
-
 	ASSERT(impl_data == NULL);
-	pci_ereport_post(dip, derr, &pci_cfg_stat);
-	pci_bdg_ereport_post(dip, derr, &pci_cfg_sec_stat);
-	return (pci_bdg_check_status(dip, derr, pci_cfg_stat,
-	    pci_cfg_sec_stat));
+	pci_ereport_post(dip, derr, NULL);
+	return (derr->fme_status);
 }
 
 static void
--- a/usr/src/uts/sun4u/io/pci/pci_util.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/pci_util.c	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -721,7 +720,6 @@
 	int fatal = 0;
 	int nonfatal = 0;
 	int i;
-	pci_target_err_t tgt_err;
 
 	ASSERT(dip);
 
@@ -776,17 +774,11 @@
 				 * pci_lookup_handle() to determine if sync
 				 * or async
 				 */
-				tgt_err.tgt_err_ena = derr->fme_ena;
-				tgt_err.tgt_err_class =
-				    pci_err_tbl[i].terr_class;
-				tgt_err.tgt_bridge_type = PCI_ERROR_SUBCLASS;
-				tgt_err.tgt_err_addr =
-				    (uint64_t)derr->fme_bus_specific;
 				nonfatal++;
-				errorq_dispatch(pci_target_queue,
-				    (void *)&tgt_err,
-				    sizeof (pci_target_err_t),
-				    ERRORQ_ASYNC);
+				pci_target_enqueue(derr->fme_ena,
+				    pci_err_tbl[i].terr_class,
+				    PCI_ERROR_SUBCLASS,
+				    (uint64_t)derr->fme_bus_specific);
 				break;
 			default:
 				/*
--- a/usr/src/uts/sun4u/io/pci/pcipsy.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/pcipsy.c	Sun Apr 23 15:26:28 2006 -0700
@@ -1674,7 +1674,7 @@
 	}
 	if (e & PSYCHO_PCI_AFSR_E_RTRY) {
 		pbm_err_p->pbm_err_class = pbm_err_p->pbm_pri ?
-			PCI_PBM_RETRY : PCI_SEC_PBM_RETRY;
+		    PCI_PBM_RETRY : PCI_SEC_PBM_RETRY;
 		pbm_err_p->pbm_log = FM_LOG_PBM;
 		nerr++;
 	}
@@ -1711,7 +1711,6 @@
 	int fatal = 0;
 	int nonfatal = 0;
 	int unknown = 0;
-	int rserr = 0;
 	uint32_t prierr, secerr;
 	pbm_errstate_t pbm_err;
 	char buf[FM_MAX_CLASS];
@@ -1821,7 +1820,7 @@
 			    pbm_err.pbm_pci.pci_cfg_comm, PCI_PA,
 			    DATA_TYPE_UINT64, (uint64_t)0, NULL);
 		}
-		rserr++;
+		unknown++;
 	}
 
 	/* Streaming Byte Hole Error */
@@ -1846,7 +1845,7 @@
 	/*
 	 * rserr not claimed as nonfatal by a child is treated as fatal
 	 */
-	if (rserr && ret != DDI_FM_NONFATAL)
+	if (unknown && !nonfatal && !fatal)
 		fatal++;
 
 	/* Cleanup and reset error bits */
--- a/usr/src/uts/sun4u/io/pci/pcisch.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/pcisch.c	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -472,6 +471,7 @@
 	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
 
 	attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
+
 	/*
 	 * Register set 0 is PCI CSR Base
 	 */
@@ -1635,10 +1635,10 @@
 		 * logged DMA address
 		 */
 		if (cb_err_p->cb_pbm[i].pbm_va_log) {
-			ret = pci_handle_lookup(cb_p->cb_pci_cmn_p->pci_p[i]->
-					pci_dip, DMA_HANDLE, fme_ena,
-					(void *)&cb_err_p->cb_pbm[i].
-					pbm_va_log);
+			void *addr = (void *)&cb_err_p->cb_pbm[i].pbm_va_log;
+			ret = ndi_fmc_error(cb_p->cb_pci_cmn_p->pci_p[i]->
+					pci_dip, NULL, DMA_HANDLE, fme_ena,
+					(void *)addr);
 			if (ret == DDI_FM_NONFATAL)
 				break;
 		}
@@ -1885,7 +1885,7 @@
 			ret = DDI_FM_UNKNOWN;
 			if (cmn_p->pci_p[j] == NULL)
 				continue;
-			ret = pci_handle_lookup(cmn_p->pci_p[j]->pci_dip,
+			ret = ndi_fmc_error(cmn_p->pci_p[j]->pci_dip, NULL,
 					flag, ecc_err_p->ecc_ena,
 					(void *)&ecc_err_p->ecc_err_addr);
 			if (ret == DDI_FM_NONFATAL) {
@@ -2203,16 +2203,17 @@
 			 * Fault the address in iommu_tfar
 			 * register to inform target driver of error
 			 */
-			ret = pci_handle_lookup(pci_p->pci_dip, DMA_HANDLE,
+			ret = ndi_fmc_error(pci_p->pci_dip, NULL, DMA_HANDLE,
 				ena, (void *)&pbm_err_p->pbm_iommu.iommu_tfar);
 
-			if (ret == DDI_FM_NONFATAL)
+			if (ret != DDI_FM_NONFATAL)
 				if (ta_signalled)
 					nonfatal++;
 				else
 					fatal++;
 			else
-				fatal++;
+				nonfatal++;
+
 			iommu_ereport_post(dip, ena, pbm_err_p);
 			break;
 		case TOMATILLO_IOMMU_TIMEOUT_ERR:
@@ -2309,13 +2310,11 @@
 	int fatal = 0;
 	int nonfatal = 0;
 	int unknown = 0;
-	int rserr = 0;
 	uint32_t prierr, secerr;
 	pbm_errstate_t pbm_err;
 	char buf[FM_MAX_CLASS];
 	pci_t *pci_p = (pci_t *)impl_data;
 	pbm_t *pbm_p = pci_p->pci_pbm_p;
-	pci_target_err_t tgt_err;
 	int i, ret = 0;
 
 	ASSERT(MUTEX_HELD(&pci_p->pci_common_p->pci_fm_mutex));
@@ -2422,18 +2421,11 @@
 			else
 				nonfatal++;
 			if (caller == PCI_TRAP_CALL &&
-			    pci_pbm_err_tbl[i].pbm_terr_class) {
-				tgt_err.tgt_err_ena = derr->fme_ena;
-				tgt_err.tgt_err_class =
-				    pci_pbm_err_tbl[i].pbm_terr_class;
-				tgt_err.tgt_bridge_type =
-				    pbm_err.pbm_bridge_type;
-				tgt_err.tgt_err_addr =
-				    (uint64_t)derr->fme_bus_specific;
-				errorq_dispatch(pci_target_queue,
-				    (void *)&tgt_err, sizeof (pci_target_err_t),
-				    ERRORQ_ASYNC);
-			}
+			    pci_pbm_err_tbl[i].pbm_terr_class)
+				pci_target_enqueue(derr->fme_ena,
+				    pci_pbm_err_tbl[i].pbm_terr_class,
+				    pbm_err.pbm_bridge_type,
+				    (uint64_t)derr->fme_bus_specific);
 		}
 	}
 
@@ -2469,7 +2461,7 @@
 			    DATA_TYPE_UINT16, pbm_err.pbm_pci.pci_cfg_comm,
 			    PCI_PA, DATA_TYPE_UINT64, (uint64_t)0, NULL);
 		}
-		rserr++;
+		unknown++;
 	}
 
 	/*
@@ -2506,10 +2498,10 @@
 		 */
 		ret = DDI_FM_FATAL;
 		if (caller != PCI_TRAP_CALL) {
-			if (pbm_err.pbm_va_log)
-				ret = pci_handle_lookup(dip, DMA_HANDLE,
-						derr->fme_ena,
-						(void *)&pbm_err.pbm_va_log);
+			if (pbm_err.pbm_va_log) {
+				ret = ndi_fmc_error(dip, NULL, DMA_HANDLE,
+				    derr->fme_ena, (void *)&pbm_err.pbm_va_log);
+			}
 			if (ret == DDI_FM_NONFATAL)
 				nonfatal++;
 			else
@@ -2541,7 +2533,7 @@
 	/*
 	 * RSERR not claimed as nonfatal by a child is considered fatal
 	 */
-	if (rserr && ret != DDI_FM_NONFATAL)
+	if (unknown && !fatal && !nonfatal)
 		fatal++;
 
 	/* Cleanup and reset error bits */
@@ -2911,11 +2903,14 @@
 {
 	char buf[FM_MAX_CLASS];
 
+	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
+		    pbm_err->pbm_bridge_type, pbm_err->pbm_err_class);
+
 	ena = ena ? ena : fm_ena_generate(0, FM_ENA_FMT1);
 
 	DEBUG1(DBG_ERR_INTR, dip, "pcix_ereport_post: ereport_post: %s", buf);
 
-	ddi_fm_ereport_post(dip, pbm_err->pbm_err_class, ena, DDI_NOSLEEP,
+	ddi_fm_ereport_post(dip, buf, ena, DDI_NOSLEEP,
 	    FM_VERSION, DATA_TYPE_UINT8, 0,
 	    PCI_CONFIG_STATUS, DATA_TYPE_UINT16, pbm_err->pbm_pci.pci_cfg_stat,
 	    PCI_CONFIG_COMMAND, DATA_TYPE_UINT16, pbm_err->pbm_pci.pci_cfg_comm,
--- a/usr/src/uts/sun4u/io/pci/simba.c	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/io/pci/simba.c	Sun Apr 23 15:26:28 2006 -0700
@@ -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.
@@ -374,7 +373,6 @@
 {
 	int instance;
 	simba_devstate_t *simba;
-	ddi_fm_error_t derr;
 
 	switch (cmd) {
 	case DDI_ATTACH:
@@ -451,15 +449,6 @@
 
 		pci_ereport_setup(devi);
 
-		/*
-		 * clear any outstanding error bits
-		 */
-		bzero(&derr, sizeof (ddi_fm_error_t));
-		derr.fme_version = DDI_FME_VERSION;
-		derr.fme_flag = DDI_FM_ERR_EXPECTED;
-		pci_ereport_post(devi, &derr, NULL);
-		pci_bdg_ereport_post(devi, &derr, NULL);
-
 		ddi_fm_handler_register(devi, simba_err_callback, simba);
 
 		ddi_report_dev(devi);
@@ -538,17 +527,13 @@
 	simba_err.afar = pci_config_get64(simba->config_handle, 0xf0);
 	derr->fme_ena = fm_ena_generate(0, FM_ENA_FMT1);
 
-	pci_ereport_post(dip, derr, &simba_err.pci_cfg_stat);
-	pci_bdg_ereport_post(dip, derr, &simba_err.pci_cfg_sec_stat);
-	ret = pci_bdg_check_status(dip, derr, simba_err.pci_cfg_stat,
-	    simba_err.pci_cfg_sec_stat);
+	pci_ereport_post(dip, derr, NULL);
+	ret = derr->fme_status;
 
 	DEBUG6(D_FAULT, "%s-%d: cleaning up fault bits %x %x %x.%8x\n",
-			ddi_driver_name(simba->dip),
-			ddi_get_instance(simba->dip), simba_err.pci_cfg_stat,
-			simba_err.pci_cfg_sec_stat,
-			(uint_t)(simba_err.afsr >> 32),
-			(uint_t)simba_err.afsr);
+	    ddi_driver_name(simba->dip), ddi_get_instance(simba->dip),
+	    simba_err.pci_cfg_stat, simba_err.pci_cfg_sec_stat,
+	    (uint_t)(simba_err.afsr >> 32), (uint_t)simba_err.afsr);
 	pci_config_put64(simba->config_handle, 0xe8, simba_err.afsr);
 
 	return (ret);
--- a/usr/src/uts/sun4u/sys/pci/db21554_ctrl.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/sys/pci/db21554_ctrl.h	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -55,18 +54,6 @@
 #define	DB_PIF_PRIMARY_TO_HOST		0x40
 
 /*
- * The following definition could have been inherited from sys/pci/pci_var.h
- * but that runs into including many other dependent files which are
- * host-pci nexus specific. So declaring our own bus_range structure makes
- * it lot easier and simpler. This is ok as bus-range format is in the
- * pci bindings.
- */
-typedef struct bus_range {
-	uint32_t lo;
-	uint32_t hi;
-} db_pci_bus_range_t;
-
-/*
  * the  following definition is used to save the state of all PCI children
  * under us.
  */
@@ -89,7 +76,7 @@
 	caddr_t		conf_io;	/* pointer to Conf indirect map */
 
 	/* our bus range information */
-	db_pci_bus_range_t	range;
+	pci_bus_range_t	range;
 
 	/* any device tuning parameters here. */
 	uint16_t	p_command;
--- a/usr/src/uts/sun4u/sys/pci/pci_fm.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/sys/pci/pci_fm.h	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -48,7 +47,6 @@
 #define	PCI_SIDEA		0
 #define	PCI_SIDEB		1
 #define	ECC_MAX_ERRS		6
-#define	TARGET_MAX_ERRS		6
 
 /*
  * Since pci_pbm_err_handler() is called by various interrupt/trap/callback
@@ -68,7 +66,6 @@
 #define	PCIX_PFAR		"pcix-pfar"
 
 extern errorq_t *pci_ecc_queue;		/* per-system ecc handling queue */
-extern errorq_t *pci_target_queue;	/* per-system target handling queue */
 
 /*
  * region where schizo pio ecc error was detected
@@ -92,16 +89,6 @@
 	char *pbm_terr_class;
 } pbm_fm_err_t;
 
-typedef struct pci_target_err {
-	uint64_t tgt_err_addr;
-	uint64_t tgt_err_ena;
-	uint64_t tgt_pci_addr;
-	uint32_t tgt_pci_space;
-	dev_info_t *tgt_dip;
-	char *tgt_err_class;
-	char *tgt_bridge_type;
-} pci_target_err_t;
-
 typedef struct ecc_format {
 	ecc_region_t ecc_region;
 	uint64_t ecc_space;
@@ -219,8 +206,6 @@
 extern void pbm_ereport_post(dev_info_t *dip, uint64_t ena,
 		pbm_errstate_t *pbm_err);
 extern void pci_fm_acc_setup(ddi_map_req_t *mp, dev_info_t *rdip);
-extern int pci_handle_lookup(dev_info_t *dip, int type, uint64_t fme_ena,
-		void *afar);
 extern void pci_fmri_create(dev_info_t *dip, pci_common_t *cmn_p);
 extern void pci_fm_create(pci_t *pci_p);
 extern void pci_fm_destroy(pci_t *pci_p);
--- a/usr/src/uts/sun4u/sys/pci/pci_var.h	Sat Apr 22 17:28:28 2006 -0700
+++ b/usr/src/uts/sun4u/sys/pci/pci_var.h	Sun Apr 23 15:26:28 2006 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -35,15 +34,6 @@
 
 /*
  * The following typedef is used to represent a
- * 1275 "bus-range" property of a PCI Bus node.
- */
-typedef struct bus_range {
-	uint32_t lo;
-	uint32_t hi;
-} pci_bus_range_t;
-
-/*
- * The following typedef is used to represent a
  * 1275 "reg" property of a PCI nexus.
  */
 typedef struct pci_nexus_regspec {
@@ -51,20 +41,6 @@
 	uint64_t size;
 } pci_nexus_regspec_t;
 
-/*
- * The following typedef is used to represent an entry in the "ranges"
- * property of a device node.
- */
-typedef struct ranges {
-	uint32_t child_high;
-	uint32_t child_mid;
-	uint32_t child_low;
-	uint32_t parent_high;
-	uint32_t parent_low;
-	uint32_t size_high;
-	uint32_t size_low;
-} pci_ranges_t;
-
 typedef enum { PSYCHO, SCHIZO } pci_bridge_t;
 typedef enum { A, B } pci_side_t;
 typedef enum { PCI_NEW, PCI_ATTACHED, PCI_DETACHED, PCI_SUSPENDED } pci_state_t;