summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io/pciex
diff options
context:
space:
mode:
authorkrishnae <none@none>2008-03-28 12:11:52 -0700
committerkrishnae <none@none>2008-03-28 12:11:52 -0700
commiteae2e508a8e70b1ec407b10bd068c080651bbe5c (patch)
tree997c76ef99a46a31e13e027aae4085ea65f05e1d /usr/src/uts/intel/io/pciex
parentc45cbb52ab3d9544ffb196de6b0a1c5f332c93a4 (diff)
downloadillumos-joyent-eae2e508a8e70b1ec407b10bd068c080651bbe5c.tar.gz
PSARC 2008/157 PCIe Fabric portfolio for SPARC and x86
6510830 SPARC and x86 PCIe IO error handling should be merged --HG-- rename : usr/src/uts/intel/io/pciex/pcie_error.c => deleted_files/usr/src/uts/intel/io/pciex/pcie_error.c rename : usr/src/uts/intel/io/pciex/pcie_error.h => deleted_files/usr/src/uts/intel/io/pciex/pcie_error.h rename : deleted_files/usr/src/cmd/fm/modules/common/fabric-xlate/Makefile => usr/src/cmd/fm/modules/common/fabric-xlate/Makefile rename : deleted_files/usr/src/cmd/fm/modules/common/fabric-xlate/fabric-xlate.c => usr/src/cmd/fm/modules/common/fabric-xlate/fabric-xlate.c rename : deleted_files/usr/src/cmd/fm/modules/common/fabric-xlate/fabric-xlate.conf => usr/src/cmd/fm/modules/common/fabric-xlate/fabric-xlate.conf
Diffstat (limited to 'usr/src/uts/intel/io/pciex')
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_error.c747
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_error.h53
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_pci.c129
3 files changed, 60 insertions, 869 deletions
diff --git a/usr/src/uts/intel/io/pciex/pcie_error.c b/usr/src/uts/intel/io/pciex/pcie_error.c
deleted file mode 100644
index dd68840476..0000000000
--- a/usr/src/uts/intel/io/pciex/pcie_error.c
+++ /dev/null
@@ -1,747 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * Library file that has code for PCIe error handling
- */
-
-#include <sys/conf.h>
-#include <sys/sysmacros.h>
-#include <sys/kmem.h>
-#include <sys/modctl.h>
-#include <sys/pci.h>
-#include <sys/pci_impl.h>
-#include <sys/sunndi.h>
-#include <sys/pcie.h>
-#include <sys/pcie_impl.h>
-#include <sys/promif.h>
-#include <io/pciex/pcie_error.h>
-#include <io/pciex/pcie_nvidia.h>
-#include <io/pciex/pcie_nb5000.h>
-
-extern uint32_t pcie_expected_ue_mask;
-int pcie_intel_error_disable = 1;
-
-#ifdef DEBUG
-uint_t pcie_error_debug_flags = 0;
-#define PCIE_ERROR_DBG pcie_error_dbg
-
-static void pcie_error_dbg(char *fmt, ...);
-#else /* DEBUG */
-#define PCIE_ERROR_DBG 0 &&
-#endif /* DEBUG */
-
-/* Variables to control error settings */
-
-
-/* Device Command Register */
-ushort_t pcie_command_default = \
- PCI_COMM_SERR_ENABLE | \
- PCI_COMM_WAIT_CYC_ENAB | \
- PCI_COMM_PARITY_DETECT | \
- PCI_COMM_ME | \
- PCI_COMM_MAE | \
- PCI_COMM_IO;
-
-/* PCI-Express Device Control Register */
-ushort_t pcie_device_ctrl_default = \
- 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 */
-#if defined(__xpv)
-ushort_t pcie_root_ctrl_default = \
- PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | \
- PCIE_ROOTCTL_SYS_ERR_ON_FE_EN;
-#else
-ushort_t pcie_root_ctrl_default = \
- PCIE_ROOTCTL_SYS_ERR_ON_CE_EN | \
- PCIE_ROOTCTL_SYS_ERR_ON_NFE_EN | \
- PCIE_ROOTCTL_SYS_ERR_ON_FE_EN;
-#endif /* __xpv */
-
-/* PCI-Express Root Error Command Register */
-ushort_t pcie_root_error_cmd_default = \
- PCIE_AER_RE_CMD_CE_REP_EN | \
- PCIE_AER_RE_CMD_NFE_REP_EN | \
- PCIE_AER_RE_CMD_FE_REP_EN;
-
-/*
- * PCI-Express related masks (AER only)
- * 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 = PCIE_AER_UCE_UC;
-uint32_t pcie_aer_ce_mask = 0;
-uint32_t pcie_aer_suce_mask = PCIE_AER_SUCE_RCVD_MA;
-
-/*
- * 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
- * Enable error handling flags. There are two flags
- * pcie_error_disable_flag : disable AER, Baseline error handling, SERR
- * default value = 0 (do not disable error handling)
- * 1 (disable all error handling)
- *
- * pcie_serr_disable_flag : disable SERR only (in RCR and command reg)
- * default value = 1 (disable SERR bits)
- * 0 (enable SERR handling)
- *
- * pcie_aer_disable_flag : disable AER only
- * default value = 1 (disable AER bits)
- * 0 (enable AER handling)
- *
- * NOTE: pci_serr_disable_flag is a subset of pcie_error_disable_flag
- * If pcie_error_disable_flag is set; then pcie_serr_disable_flag is ignored
- * Above is also true for pcie_aer_disable_flag
- */
-uint32_t pcie_error_disable_flag = 0;
-uint32_t pcie_serr_disable_flag = 1;
-uint32_t pcie_aer_disable_flag = 0;
-
-/*
- * Function prototypes
- */
-static void pcie_error_clear_errors(ddi_acc_handle_t, uint16_t,
- uint16_t, uint16_t);
-static void pcie_check_io_mem_range(ddi_acc_handle_t, boolean_t *,
- boolean_t *);
-static uint16_t pcie_error_find_cap_reg(ddi_acc_handle_t, uint8_t);
-static uint16_t pcie_error_find_ext_aer_capid(ddi_acc_handle_t);
-static void pcie_error_init(dev_info_t *, ddi_acc_handle_t,
- uint16_t, uint16_t);
-static void pcie_error_fini(ddi_acc_handle_t, uint16_t, uint16_t);
-
-/*
- * modload support
- */
-
-struct modlmisc modlmisc = {
- &mod_miscops, /* Type of module */
- "PCI Express Error Support %I%"
-};
-
-struct modlinkage modlinkage = {
- MODREV_1, (void *)&modlmisc, NULL
-};
-
-int
-_init(void)
-{
- return (mod_install(&modlinkage));
-}
-
-int
-_fini()
-{
- return (mod_remove(&modlinkage));
-}
-
-int
-_info(struct modinfo *modinfop)
-{
- return (mod_info(&modlinkage, modinfop));
-}
-
-static int
-pcie_error_supported(uint16_t vendor_id, uint16_t device_id)
-{
- if ((vendor_id == NVIDIA_VENDOR_ID) && NVIDIA_PCIE_RC_DEV_ID(device_id))
- return (1);
- if ((vendor_id == INTEL_VENDOR_ID) &&
- INTEL_NB5000_PCIE_DEV_ID(device_id) && !pcie_intel_error_disable)
- return (1);
-
- return (0);
-}
-
-/*
- * PCI-Express error initialization.
- */
-
-/*
- * Enable generic pci-express interrupts and error handling.
- */
-int
-pcie_error_enable(dev_info_t *cdip, ddi_acc_handle_t cfg_hdl)
-{
- uint8_t header_type;
- uint8_t bcr;
- uint16_t command_reg, status_reg;
- uint16_t cap_ptr = 0;
- uint16_t aer_ptr = 0;
- uint16_t device_ctl;
- uint16_t dev_type = 0;
- uint16_t vendor_id, device_id;
- uint32_t aer_reg;
- uint32_t uce_mask = pcie_aer_uce_mask;
- boolean_t empty_io_range = B_FALSE;
- boolean_t empty_mem_range = B_FALSE;
-
- /*
- * flag to turn this off
- */
- if (pcie_error_disable_flag)
- return (DDI_SUCCESS);
-
- /* Determine the configuration header type */
- header_type = pci_config_get8(cfg_hdl, PCI_CONF_HEADER);
- PCIE_ERROR_DBG("%s: header_type=%x\n",
- ddi_driver_name(cdip), header_type);
-
- /* 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_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;
- }
-
- /* Setup the device's command register */
- status_reg = pci_config_get16(cfg_hdl, PCI_CONF_STAT);
- pci_config_put16(cfg_hdl, PCI_CONF_STAT, status_reg);
- command_reg = pci_config_get16(cfg_hdl, PCI_CONF_COMM);
- if (pcie_serr_disable_flag && cap_ptr != PCI_CAP_NEXT_PTR_NULL) {
- pcie_command_default &= ~PCI_COMM_SERR_ENABLE;
- /* shouldn't happen; just in case */
- if (command_reg & PCI_COMM_SERR_ENABLE)
- command_reg &= ~PCI_COMM_SERR_ENABLE;
- }
- /* Check io and mem ranges for empty bridges */
- pcie_check_io_mem_range(cfg_hdl, &empty_io_range, &empty_mem_range);
- if ((empty_io_range == B_TRUE) &&
- (pcie_command_default & PCI_COMM_IO)) {
- pcie_command_default &= ~PCI_COMM_IO;
- PCIE_ERROR_DBG("%s: No I/O range found\n",
- ddi_driver_name(cdip));
- }
- if ((empty_mem_range == B_TRUE) &&
- (pcie_command_default & PCI_COMM_MAE)) {
- pcie_command_default &= ~PCI_COMM_MAE;
- PCIE_ERROR_DBG("%s: No Mem range found\n",
- ddi_driver_name(cdip));
- }
- command_reg |= pcie_command_default;
- pci_config_put16(cfg_hdl, PCI_CONF_COMM, command_reg);
-
- PCIE_ERROR_DBG("%s: command=%x\n", ddi_driver_name(cdip),
- pci_config_get16(cfg_hdl, PCI_CONF_COMM));
-
- /*
- * If the device has a bus control register then program it
- * based on the settings in the command register.
- */
- if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
- status_reg = pci_config_get16(cfg_hdl, PCI_BCNF_SEC_STATUS);
- pci_config_put16(cfg_hdl, PCI_BCNF_SEC_STATUS, status_reg);
- bcr = pci_config_get8(cfg_hdl, PCI_BCNF_BCNTRL);
- if (pcie_command_default & PCI_COMM_PARITY_DETECT)
- bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
- if (pcie_command_default & PCI_COMM_SERR_ENABLE) {
- if (pcie_serr_disable_flag &&
- cap_ptr != PCI_CAP_NEXT_PTR_NULL &&
- dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT)
- bcr &= ~PCI_BCNF_BCNTRL_SERR_ENABLE;
- else
- bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE;
- }
-
- /* Always clear Master Abort Mode bit */
- bcr &= ~PCI_BCNF_BCNTRL_MAST_AB_MODE;
- pci_config_put8(cfg_hdl, PCI_BCNF_BCNTRL, bcr);
- }
-
- /*
- * Clear any pending errors
- */
- pcie_error_clear_errors(cfg_hdl, cap_ptr, aer_ptr, dev_type);
-
- /* No PCIe; just return */
- if (cap_ptr == PCI_CAP_NEXT_PTR_NULL)
- return (DDI_SUCCESS);
-
- /*
- * Enable PCI-Express Baseline Error Handling
- */
- device_ctl = pci_config_get16(cfg_hdl, cap_ptr + PCIE_DEVCTL);
- device_ctl |= pcie_device_ctrl_default;
-
- /*
- * Disable UR for any non-RBER enabled leaf PCIe device,
- * bridge or switch devices.
- */
- if ((dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV ||
- dev_type == PCIE_PCIECAP_DEV_TYPE_UP ||
- dev_type == PCIE_PCIECAP_DEV_TYPE_DOWN ||
- dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) &&
- ((pci_config_get16(cfg_hdl, cap_ptr + PCIE_DEVCAP) &
- PCIE_DEVCAP_ROLE_BASED_ERR_REP) !=
- PCIE_DEVCAP_ROLE_BASED_ERR_REP))
- device_ctl &= ~PCIE_DEVCTL_UR_REPORTING_EN;
-
- /*
- * Disable AER for CK8-04 devices with revid < 0xA3
- */
- vendor_id = pci_config_get16(cfg_hdl, PCI_CONF_VENID);
- device_id = pci_config_get16(cfg_hdl, PCI_CONF_DEVID);
- if ((vendor_id == NVIDIA_VENDOR_ID) &&
- (device_id == NVIDIA_CK804_DEVICE_ID) &&
- (pci_config_get8(cfg_hdl, PCI_CONF_REVID) <
- NVIDIA_CK804_AER_VALID_REVID)) {
- aer_ptr = PCIE_EXT_CAP_NEXT_PTR_NULL;
- }
-
- /*
- * For Nvidia, Intel 5000 and 7300 chipset, call pcie_error_init().
- *
- * For other Root Ports, disable UR for all child devices by
- * changing the default ue mask (for AER devices) and the default
- * device control value (for non-AER device).
- */
- if (pcie_error_supported(vendor_id, device_id))
- pcie_error_init(cdip, cfg_hdl, cap_ptr, aer_ptr);
- else if (dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT) {
- pcie_expected_ue_mask |= PCIE_AER_UCE_UR;
- pcie_device_ctrl_default &= ~PCIE_DEVCTL_UR_REPORTING_EN;
- device_ctl &= ~PCIE_DEVCTL_UR_REPORTING_EN;
- }
-
- pci_config_put16(cfg_hdl, cap_ptr + PCIE_DEVCTL, device_ctl);
-
- PCIE_ERROR_DBG("%s: device control=0x%x->0x%x\n",
- ddi_driver_name(cdip), device_ctl,
- pci_config_get16(cfg_hdl, cap_ptr + PCIE_DEVCTL));
-
- /*
- * Enable PCI-Express Advanced Error Handling if Exists
- */
- if (aer_ptr == PCIE_EXT_CAP_NEXT_PTR_NULL)
- return (DDI_SUCCESS);
-
-
- if (pcie_aer_disable_flag)
- return (DDI_SUCCESS);
-
- /* 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 | 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 mask=0x%x->0x%x\n", ddi_driver_name(cdip),
- aer_reg, pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_CE_MASK));
-
- /*
- * Enable Secondary Uncorrectable errors if this is a bridge
- */
- if (!(dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI))
- return (DDI_SUCCESS);
-
- /* 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 mask=0x%x->0x%x\n",
- ddi_driver_name(cdip), aer_reg,
- pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_MASK));
-
- return (DDI_SUCCESS);
-}
-
-
-static void
-pcie_check_io_mem_range(ddi_acc_handle_t cfg_hdl, boolean_t *empty_io_range,
- boolean_t *empty_mem_range)
-{
- uint8_t class, subclass;
- uint_t val;
-
- class = pci_config_get8(cfg_hdl, PCI_CONF_BASCLASS);
- subclass = pci_config_get8(cfg_hdl, PCI_CONF_SUBCLASS);
-
- if ((class == PCI_CLASS_BRIDGE) && (subclass == PCI_BRIDGE_PCI)) {
- val = (((uint_t)pci_config_get8(cfg_hdl, PCI_BCNF_IO_BASE_LOW) &
- 0xf0) << 8);
- /*
- * Assuming that a zero based io_range[0] implies an
- * invalid I/O range. Likewise for mem_range[0].
- */
- if (val == 0)
- *empty_io_range = B_TRUE;
- val = (((uint_t)pci_config_get16(cfg_hdl, PCI_BCNF_MEM_BASE) &
- 0xfff0) << 16);
- if (val == 0)
- *empty_mem_range = B_TRUE;
- }
-}
-
-/* ARGSUSED */
-static void
-pcie_error_init(dev_info_t *child, ddi_acc_handle_t cfg_hdl,
- uint16_t cap_ptr, uint16_t aer_ptr)
-{
- uint16_t rc_ctl;
-
- /* Program SERR_FORWARD bit in NV_XVR_INTR_BCR */
- rc_ctl = pci_config_get16(cfg_hdl, PCI_BCNF_BCNTRL);
- pci_config_put16(cfg_hdl, PCI_BCNF_BCNTRL,
- rc_ctl | PCI_BCNF_BCNTRL_SERR_ENABLE);
- PCIE_ERROR_DBG("%s: PCIe NV_XVR_INTR_BCR=0x%x->0x%x\n",
- ddi_driver_name(child), rc_ctl,
- pci_config_get16(cfg_hdl, PCI_BCNF_BCNTRL));
-
-#if defined(__xpv)
- /*
- * When we're booted under the hypervisor we won't receive MSI's, so
- * to ensure that uncorrectable errors aren't ignored we set the
- * SERR_FAT and SERR_NONFAT bits in the Root Control Register.
- */
- rc_ctl = pci_config_get16(cfg_hdl, cap_ptr + PCIE_ROOTCTL);
- pci_config_put16(cfg_hdl, cap_ptr + PCIE_ROOTCTL,
- rc_ctl | pcie_root_ctrl_default);
- PCIE_ERROR_DBG("%s: PCIe Root Control Register=0x%x->0x%x\n",
- ddi_driver_name(child), rc_ctl,
- pci_config_get16(cfg_hdl, cap_ptr + PCIE_ROOTCTL));
-#else
- rc_ctl = pci_config_get16(cfg_hdl, cap_ptr + PCIE_ROOTCTL);
- pci_config_put16(cfg_hdl, cap_ptr + PCIE_ROOTCTL,
- pcie_serr_disable_flag ? (rc_ctl & ~pcie_root_ctrl_default) :
- (rc_ctl | pcie_root_ctrl_default));
- PCIE_ERROR_DBG("%s: PCIe Root Control Register=0x%x->0x%x\n",
- ddi_driver_name(child), rc_ctl,
- pci_config_get16(cfg_hdl, cap_ptr + PCIE_ROOTCTL));
-
- /* Root Error Command Register */
- if (!aer_ptr || pcie_aer_disable_flag)
- return;
-
- rc_ctl = pci_config_get16(cfg_hdl, aer_ptr + PCIE_AER_RE_CMD);
- pci_config_put16(cfg_hdl, aer_ptr + PCIE_AER_RE_CMD,
- rc_ctl | pcie_root_error_cmd_default);
- 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);
-#endif /* __xpv */
-}
-
-/*
- * Disable generic pci-express interrupts and error handling.
- */
-void
-pcie_error_disable(dev_info_t *cdip, ddi_acc_handle_t cfg_hdl)
-{
- uint16_t cap_ptr, aer_ptr;
- uint16_t dev_type;
- uint8_t header_type;
- uint8_t bcr;
- uint16_t command_reg, status_reg;
- uint16_t vendor_id, device_id;
-
- if (pcie_error_disable_flag)
- return;
-
- /* Determine the configuration header type */
- header_type = pci_config_get8(cfg_hdl, PCI_CONF_HEADER);
- status_reg = pci_config_get16(cfg_hdl, PCI_CONF_STAT);
- pci_config_put16(cfg_hdl, PCI_CONF_STAT, status_reg);
-
- /* Clear the device's command register (SERR and PARITY detect) */
- command_reg = pci_config_get16(cfg_hdl, PCI_CONF_COMM);
- if (pcie_serr_disable_flag || (command_reg & PCI_COMM_SERR_ENABLE))
- command_reg &= ~PCI_COMM_SERR_ENABLE;
- command_reg &= ~PCI_COMM_PARITY_DETECT;
- pci_config_put16(cfg_hdl, PCI_CONF_COMM, command_reg);
-
- /*
- * If the device has a bus control register then clear
- * SERR, Master Abort and Parity detect
- */
- if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
- status_reg = pci_config_get16(cfg_hdl, PCI_BCNF_SEC_STATUS);
- pci_config_put16(cfg_hdl, PCI_BCNF_SEC_STATUS, status_reg);
- bcr = pci_config_get8(cfg_hdl, PCI_BCNF_BCNTRL);
- if (pcie_command_default & PCI_COMM_PARITY_DETECT)
- bcr &= ~PCI_BCNF_BCNTRL_PARITY_ENABLE;
- if ((pcie_command_default & PCI_COMM_SERR_ENABLE) ||
- (pcie_serr_disable_flag))
- bcr &= ~PCI_BCNF_BCNTRL_SERR_ENABLE;
- bcr &= ~PCI_BCNF_BCNTRL_MAST_AB_MODE;
- pci_config_put8(cfg_hdl, PCI_BCNF_BCNTRL, bcr);
- }
-
- cap_ptr = pcie_error_find_cap_reg(cfg_hdl, PCI_CAP_ID_PCI_E);
- if (cap_ptr == PCI_CAP_NEXT_PTR_NULL)
- return;
-
- /* Disable PCI-Express Baseline Error Handling */
- pci_config_put16(cfg_hdl, cap_ptr + PCIE_DEVCTL, 0x0);
-
- aer_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS,
- "pcie-aer-pointer", PCIE_EXT_CAP_NEXT_PTR_NULL);
-
- /*
- * Disable AER for CK8-04 devices with revid < 0xA3
- */
- vendor_id = pci_config_get16(cfg_hdl, PCI_CONF_VENID);
- device_id = pci_config_get16(cfg_hdl, PCI_CONF_DEVID);
- if ((vendor_id == NVIDIA_VENDOR_ID) &&
- (device_id == NVIDIA_CK804_DEVICE_ID) &&
- (pci_config_get8(cfg_hdl, PCI_CONF_REVID) <
- NVIDIA_CK804_AER_VALID_REVID)) {
- aer_ptr = PCIE_EXT_CAP_NEXT_PTR_NULL;
- }
-
- /*
- * Only disable these set of errors for CK8-04/IO-4 devices
- */
- if (pcie_error_supported(vendor_id, device_id))
- pcie_error_fini(cfg_hdl, cap_ptr, aer_ptr);
-
- if (aer_ptr == PCIE_EXT_CAP_NEXT_PTR_NULL)
- return;
-
- /* Disable AER bits */
- if (!pcie_aer_disable_flag) {
- /* Disable Uncorrectable errors */
- pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_UCE_MASK,
- PCIE_AER_UCE_BITS);
-
- /* Disable Correctable errors */
- pci_config_put32(cfg_hdl,
- aer_ptr + PCIE_AER_CE_MASK, PCIE_AER_CE_BITS);
-
- /* Disable Secondary Uncorrectable errors if this is a bridge */
- dev_type = pci_config_get16(cfg_hdl, cap_ptr + PCIE_PCIECAP) &
- PCIE_PCIECAP_DEV_TYPE_MASK;
- if (!(dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI))
- return;
-
- pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_MASK,
- PCIE_AER_SUCE_BITS);
- }
-}
-
-
-static void
-pcie_error_fini(ddi_acc_handle_t cfg_hdl, uint16_t cap_ptr,
- uint16_t aer_ptr)
-{
- uint16_t rc_ctl;
-
- if (!pcie_serr_disable_flag) {
- rc_ctl = pci_config_get16(cfg_hdl, cap_ptr + PCIE_ROOTCTL);
- rc_ctl &= ~pcie_root_ctrl_default;
- pci_config_put16(cfg_hdl, cap_ptr + PCIE_ROOTCTL, rc_ctl);
- }
-
- /* Root Error Command Register */
- if (aer_ptr && !pcie_aer_disable_flag) {
- 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);
- }
-}
-
-/*
- * Clear any pending errors
- */
-static void
-pcie_error_clear_errors(ddi_acc_handle_t cfg_hdl, uint16_t cap_ptr,
- uint16_t aer_ptr, uint16_t dev_type)
-{
- uint16_t device_sts;
-
- /* 1. clear the Advanced PCIe Errors */
- if (cap_ptr && aer_ptr) {
- pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_CE_STS, -1);
- pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_UCE_STS, -1);
- if (dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI)
- pci_config_put32(cfg_hdl,
- aer_ptr + PCIE_AER_SUCE_STS, -1);
- }
-
- /* 2. clear the PCIe Errors */
- if (cap_ptr) {
- device_sts = pci_config_get16(cfg_hdl, cap_ptr + PCIE_DEVSTS);
- pci_config_put16(cfg_hdl, cap_ptr + PCIE_DEVSTS, device_sts);
- }
-
- /* 3. clear the Legacy PCI Errors */
- device_sts = pci_config_get16(cfg_hdl, PCI_CONF_STAT);
- pci_config_put16(cfg_hdl, PCI_CONF_STAT, device_sts);
- if (dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
- device_sts = pci_config_get16(cfg_hdl, PCI_BCNF_SEC_STATUS);
- pci_config_put16(cfg_hdl, PCI_BCNF_SEC_STATUS, device_sts);
- }
-}
-
-
-/*
- * Helper Function to traverse the pci-express config space looking
- * for the pci-express capability id pointer.
- */
-static uint16_t
-pcie_error_find_cap_reg(ddi_acc_handle_t cfg_hdl, uint8_t cap_id)
-{
- uint16_t caps_ptr, cap;
- ushort_t status;
-
- /*
- * Check if capabilities list is supported. If not then it is a PCI
- * device.
- */
- status = pci_config_get16(cfg_hdl, PCI_CONF_STAT);
- if (status == 0xff || !((status & PCI_STAT_CAP)))
- return (PCI_CAP_NEXT_PTR_NULL);
-
- caps_ptr = P2ALIGN(pci_config_get8(cfg_hdl, PCI_CONF_CAP_PTR), 4);
- while (caps_ptr && caps_ptr >= PCI_CAP_PTR_OFF) {
- caps_ptr &= PCI_CAP_PTR_MASK;
- cap = pci_config_get8(cfg_hdl, caps_ptr);
- if (cap == cap_id) {
- break;
- } else if (cap == 0xff)
- return (PCI_CAP_NEXT_PTR_NULL);
-
- caps_ptr = P2ALIGN(pci_config_get8(cfg_hdl,
- (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
- }
-
- return (caps_ptr);
-}
-
-/*
- * Helper Function to traverse the pci-express extended config space looking
- * for the pci-express capability id pointer.
- */
-static uint16_t
-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);
-
- hdr = pci_config_get32(cfg_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(cfg_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)
- return (P2ALIGN(offset, 4));
-
- return (PCIE_EXT_CAP_NEXT_PTR_NULL);
-}
-
-#ifdef DEBUG
-static void
-pcie_error_dbg(char *fmt, ...)
-{
- va_list ap;
-
- if (!pcie_error_debug_flags)
- return;
-
- va_start(ap, fmt);
- prom_vprintf(fmt, ap);
- va_end(ap);
-}
-#endif /* DEBUG */
diff --git a/usr/src/uts/intel/io/pciex/pcie_error.h b/usr/src/uts/intel/io/pciex/pcie_error.h
deleted file mode 100644
index 396aaab3a5..0000000000
--- a/usr/src/uts/intel/io/pciex/pcie_error.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (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 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _PCIEX_PCIE_ERROR_H
-#define _PCIEX_PCIE_ERROR_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * PCI Error related library header file
- */
-
-
-/*
- * Error related library functions
- */
-
-int pcie_error_enable(dev_info_t *cdip, ddi_acc_handle_t cfg_hdl);
-void pcie_error_disable(dev_info_t *cdip, ddi_acc_handle_t cfg_hdl);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _PCIEX_PCIE_ERROR_H */
diff --git a/usr/src/uts/intel/io/pciex/pcie_pci.c b/usr/src/uts/intel/io/pciex/pcie_pci.c
index cf73c743be..8f0b5f451f 100644
--- a/usr/src/uts/intel/io/pciex/pcie_pci.c
+++ b/usr/src/uts/intel/io/pciex/pcie_pci.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,11 +48,10 @@
#include <sys/pcie_impl.h>
#include <sys/hotplug/pci/pcihp.h>
#include <sys/hotplug/pci/pciehpc.h>
-#include <io/pciex/pcie_error.h>
#include <io/pciex/pcie_nvidia.h>
#include <io/pciex/pcie_nb5000.h>
-#ifdef DEBUG
+#ifdef DEBUG
static int pepb_debug = 0;
#define PEPB_DEBUG(args) if (pepb_debug) cmn_err args
#else
@@ -69,8 +68,6 @@ static int pepb_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, 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,
pepb_bus_map,
@@ -113,6 +110,7 @@ static int pepb_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
static int pepb_prop_op(dev_t, dev_info_t *, ddi_prop_op_t, int, char *,
caddr_t, int *);
static int pepb_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
+static void pepb_peekpoke_cb(dev_info_t *, ddi_fm_error_t *);
struct cb_ops pepb_cb_ops = {
pepb_open, /* open */
@@ -176,7 +174,7 @@ static struct modlinkage modlinkage = {
static void *pepb_state;
typedef struct {
- dev_info_t *dip;
+ dev_info_t *dip;
/*
* cpr support:
@@ -223,13 +221,13 @@ typedef struct {
#define PEPB_SOFT_STATE_INIT_MUTEX 0x20 /* mutex initialized */
/* default interrupt priority for all interrupts (hotplug or non-hotplug */
-#define PEPB_INTR_PRI 1
+#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;
+
+/* panic on PF_PANIC flag */
+static int pepb_die = PF_ERR_FATAL_FLAGS;
extern errorq_t *pci_target_queue;
@@ -242,12 +240,11 @@ static void pepb_save_config_regs(pepb_devstate_t *pepb_p);
static void pepb_restore_config_regs(pepb_devstate_t *pepb_p);
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);
-
+ ddi_acc_handle_t config_handle);
/* interrupt related declarations */
-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 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_intr_on_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);
@@ -333,15 +330,16 @@ pepb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
instance = ddi_get_instance(devi);
if (ddi_soft_state_zalloc(pepb_state, instance) != DDI_SUCCESS)
return (DDI_FAILURE);
+
pepb = ddi_get_soft_state(pepb_state, instance);
pepb->dip = devi;
/*
- * initalise fma support before we start accessing config space
+ * initialize 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;
+ pepb->pepb_fmcap = DDI_FM_EREPORT_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,
@@ -349,12 +347,6 @@ pepb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
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.
*/
@@ -468,11 +460,6 @@ pepb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
* 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);
@@ -505,7 +492,10 @@ pepb_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
int reglen;
int rn;
int totreg;
- pepb_devstate_t *pepb;
+ pepb_devstate_t *pepb = ddi_get_soft_state(pepb_state,
+ ddi_get_instance(dip));
+ struct detachspec *ds;
+ struct attachspec *as;
switch (ctlop) {
case DDI_CTLOPS_REPORTDEV:
@@ -535,13 +525,32 @@ pepb_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
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));
+ &pepb->pepb_peek_poke_mutex,
+ pepb_peekpoke_cb));
+ case DDI_CTLOPS_ATTACH:
+ if (!pcie_is_child(dip, rdip))
+ return (DDI_SUCCESS);
+
+ as = (struct attachspec *)arg;
+ if ((as->when == DDI_POST) && (as->result == DDI_SUCCESS)) {
+ pf_init(rdip, (void *)pepb->pepb_fm_ibc, as->cmd);
+ (void) pcie_postattach_child(rdip);
+ }
+
+ return (DDI_SUCCESS);
+ case DDI_CTLOPS_DETACH:
+ if (!pcie_is_child(dip, rdip))
+ return (DDI_SUCCESS);
+
+ ds = (struct detachspec *)arg;
+ if (ds->when == DDI_PRE)
+ pf_fini(rdip, ds->cmd);
+ return (DDI_SUCCESS);
default:
return (ddi_ctlops(dip, rdip, ctlop, arg, result));
}
@@ -622,7 +631,7 @@ static int
pepb_initchild(dev_info_t *child)
{
struct ddi_parent_private_data *pdptr;
- ddi_acc_handle_t cfg_hdl;
+ struct pcie_bus *bus_p;
char name[MAXNAMELEN];
if (pepb_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
@@ -678,10 +687,9 @@ pepb_initchild(dev_info_t *child)
} else
ddi_set_parent_data(child, NULL);
- if (pci_config_setup(child, &cfg_hdl) == DDI_SUCCESS) {
- (void) pcie_error_enable(child, cfg_hdl);
- pci_config_teardown(&cfg_hdl);
- }
+ bus_p = pcie_init_bus(child);
+ if (!bus_p || pcie_initchild(child) != DDI_SUCCESS)
+ return (DDI_FAILURE);
return (DDI_SUCCESS);
}
@@ -689,22 +697,15 @@ pepb_initchild(dev_info_t *child)
static void
pepb_uninitchild(dev_info_t *dip)
{
- ddi_acc_handle_t cfg_hdl;
struct ddi_parent_private_data *pdptr;
- /*
- * Do it way early.
- * Otherwise ddi_map() call form pcie_error_fini crashes
- */
- if (pci_config_setup(dip, &cfg_hdl) == DDI_SUCCESS) {
- pcie_error_disable(dip, cfg_hdl);
- pci_config_teardown(&cfg_hdl);
- }
+ pcie_uninitchild(dip);
if ((pdptr = ddi_get_parent_data(dip)) != NULL) {
kmem_free(pdptr, (sizeof (*pdptr) + sizeof (struct intrspec)));
ddi_set_parent_data(dip, NULL);
}
+
ddi_set_name_addr(dip, NULL);
/*
@@ -975,7 +976,6 @@ pepb_intr_init(pepb_devstate_t *pepb_p, int intr_type)
pepb_p->intr_type = intr_type;
return (DDI_SUCCESS);
-
fail:
pepb_intr_fini(pepb_p);
@@ -1132,24 +1132,13 @@ pepb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
}
/*ARGSUSED*/
-int
-pepb_fm_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *no_used)
-{
- 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;
+ dev_info_t *dip = pepb_p->dip;
+ ddi_fm_error_t derr;
+ int sts;
bzero(&derr, sizeof (ddi_fm_error_t));
derr.fme_version = DDI_FME_VERSION;
@@ -1162,19 +1151,16 @@ pepb_err_msi_intr(caddr_t arg, caddr_t arg2)
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));
+ sts = pf_scan_fabric(dip, &derr, NULL);
mutex_exit(&pepb_p->pepb_err_mutex);
mutex_exit(&pepb_p->pepb_peek_poke_mutex);
+ if (pepb_die & sts)
+ fm_panic("%s-%d: PCI(-X) Express Fatal Error",
+ ddi_driver_name(dip), ddi_get_instance(dip));
+
return (DDI_INTR_CLAIMED);
}
@@ -1234,3 +1220,8 @@ pepb_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
{
return (pcihp_info(dip, cmd, arg, result));
}
+
+void
+pepb_peekpoke_cb(dev_info_t *dip, ddi_fm_error_t *derr) {
+ (void) pf_scan_fabric(dip, derr, NULL);
+}