summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorprasad <none@none>2006-10-27 11:06:53 -0700
committerprasad <none@none>2006-10-27 11:06:53 -0700
commit28cae8e27cd02e5b8df9666bb34af9786c217a1a (patch)
tree7af5b7e1e37acfc4a6c3a090d293dfcbffbf9c48 /usr/src
parent3a61361bc1b158495f091aef41d27d7cbdeb8986 (diff)
downloadillumos-joyent-28cae8e27cd02e5b8df9666bb34af9786c217a1a.tar.gz
6470966 x64: PCIe software should mask off fabric errors during hotplug operations
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/hotplug/pciehpc/pciehpc.c25
-rw-r--r--usr/src/uts/common/sys/hotplug/pci/pciehpc_impl.h10
-rw-r--r--usr/src/uts/i86pc/Makefile.files2
-rw-r--r--usr/src/uts/i86pc/io/pciex/pcie_error.c96
-rw-r--r--usr/src/uts/i86pc/io/pciex/pcie_error.h2
5 files changed, 78 insertions, 57 deletions
diff --git a/usr/src/uts/common/io/hotplug/pciehpc/pciehpc.c b/usr/src/uts/common/io/hotplug/pciehpc/pciehpc.c
index f0d0608891..ea7210ab25 100644
--- a/usr/src/uts/common/io/hotplug/pciehpc/pciehpc.c
+++ b/usr/src/uts/common/io/hotplug/pciehpc/pciehpc.c
@@ -51,6 +51,9 @@
#include <sys/pcie_impl.h>
#endif
#include <sys/hotplug/pci/pciehpc_impl.h>
+#if defined(__i386) || defined(__amd64)
+#include <io/pciex/pcie_error.h>
+#endif
/*
* Local data/functions
@@ -74,10 +77,8 @@ static void pciehpc_attn_btn_handler(pciehpc_t *ctrl_p);
static void pciehpc_dev_info(pciehpc_t *ctrl_p);
static int pciehpc_pcie_dev(dev_info_t *dip, ddi_acc_handle_t handle);
-#if defined(__sparc)
static void pciehpc_disable_errors(pciehpc_t *ctrl_p);
static void pciehpc_enable_errors(pciehpc_t *ctrl_p);
-#endif
#ifdef DEBUG
int pciehpc_debug = 0;
@@ -195,7 +196,7 @@ pciehpc_init(dev_info_t *dip, pciehpc_regops_t *regops)
goto cleanup;
}
- PCIEHPC_DISABLE_ERRORS(ctrl_p);
+ pciehpc_disable_errors(ctrl_p);
/*
* Set the platform specific hot plug mode.
@@ -256,7 +257,7 @@ cleanup2:
(void) (ctrl_p->ops.uninit_hpc_hw)(ctrl_p);
cleanup1:
- PCIEHPC_ENABLE_ERRORS(ctrl_p);
+ pciehpc_enable_errors(ctrl_p);
/* free up the HPC register mapping if applicable */
if (ctrl_p->cfghdl)
pciehpc_regs_teardown(&ctrl_p->cfghdl);
@@ -299,7 +300,7 @@ pciehpc_uninit(dev_info_t *dip)
/* uninitialize hpc, remove interrupt handler, etc. */
(void) (ctrl_p->ops.uninit_hpc_hw)(ctrl_p);
- PCIEHPC_ENABLE_ERRORS(ctrl_p);
+ pciehpc_enable_errors(ctrl_p);
/* free up the HPC register mapping if applicable */
if (ctrl_p->cfghdl)
@@ -1420,7 +1421,7 @@ pciehpc_slot_control(caddr_t ops_arg, hpc_slot_t slot_hdl,
/* if power to the slot is still on then set Power led to ON */
if (ctrl_p->slot.slot_state == HPC_SLOT_CONNECTED)
pciehpc_set_led_state(ctrl_p, HPC_POWER_LED, HPC_LED_ON);
- PCIEHPC_ENABLE_ERRORS(ctrl_p);
+ pciehpc_enable_errors(ctrl_p);
break;
case HPC_CTRL_ENABLE_AUTOCFG:
case HPC_CTRL_DISABLE_AUTOCFG:
@@ -1434,15 +1435,14 @@ pciehpc_slot_control(caddr_t ops_arg, hpc_slot_t slot_hdl,
case HPC_CTRL_DEV_CONFIG_START:
case HPC_CTRL_DEV_UNCONFIG_START:
- PCIEHPC_DISABLE_ERRORS(ctrl_p);
+ pciehpc_disable_errors(ctrl_p);
/* no action is needed here */
break;
case HPC_CTRL_DEV_CONFIGURED:
case HPC_CTRL_DEV_UNCONFIGURED:
/* no action is needed here */
if (request == HPC_CTRL_DEV_CONFIGURED) {
- /*EMPTY*/
- PCIEHPC_ENABLE_ERRORS(ctrl_p);
+ pciehpc_enable_errors(ctrl_p);
}
break;
default:
@@ -1962,12 +1962,11 @@ pciehpc_pcie_dev(dev_info_t *dip, ddi_acc_handle_t handle)
return (rc);
}
-#if defined(__sparc)
static void
pciehpc_disable_errors(pciehpc_t *ctrl_p)
{
if (ctrl_p->soft_state & PCIEHPC_SOFT_STATE_PCIE_DEV) {
- pcie_disable_errors(ctrl_p->dip, ctrl_p->cfghdl);
+ PCIE_DISABLE_ERRORS(ctrl_p->dip, ctrl_p->cfghdl);
PCIEHPC_DEBUG3((CE_NOTE, "%s%d: pciehpc_disable_errors\n",
ddi_driver_name(ctrl_p->dip),
ddi_get_instance(ctrl_p->dip)));
@@ -1978,11 +1977,9 @@ static void
pciehpc_enable_errors(pciehpc_t *ctrl_p)
{
if (ctrl_p->soft_state & PCIEHPC_SOFT_STATE_PCIE_DEV) {
- pcie_enable_errors(ctrl_p->dip, ctrl_p->cfghdl);
- (void) pcie_enable_ce(ctrl_p->dip, ctrl_p->cfghdl);
+ (void) PCIE_ENABLE_ERRORS(ctrl_p->dip, ctrl_p->cfghdl);
PCIEHPC_DEBUG3((CE_NOTE, "%s%d: pciehpc_enable_errors\n",
ddi_driver_name(ctrl_p->dip),
ddi_get_instance(ctrl_p->dip)));
}
}
-#endif
diff --git a/usr/src/uts/common/sys/hotplug/pci/pciehpc_impl.h b/usr/src/uts/common/sys/hotplug/pci/pciehpc_impl.h
index 278e213e3c..ffc4ba5d0c 100644
--- a/usr/src/uts/common/sys/hotplug/pci/pciehpc_impl.h
+++ b/usr/src/uts/common/sys/hotplug/pci/pciehpc_impl.h
@@ -222,11 +222,13 @@ extern int pciehpc_debug;
#define PCIEHPC_INTR_PRI 1
#if defined(__sparc)
-#define PCIEHPC_ENABLE_ERRORS(arg) pciehpc_enable_errors(arg)
-#define PCIEHPC_DISABLE_ERRORS(arg) pciehpc_disable_errors(arg)
+#define PCIE_ENABLE_ERRORS(arg1,arg2) \
+ pcie_enable_errors(arg1,arg2); \
+ (void) pcie_enable_ce(arg1,arg2)
+#define PCIE_DISABLE_ERRORS(arg1,arg2) pcie_disable_errors(arg1,arg2)
#else
-#define PCIEHPC_ENABLE_ERRORS(arg)
-#define PCIEHPC_DISABLE_ERRORS(arg)
+#define PCIE_ENABLE_ERRORS(arg1,arg2) pcie_error_enable(arg1,arg2)
+#define PCIE_DISABLE_ERRORS(arg1,arg2) pcie_error_disable(arg1,arg2)
#endif
#ifdef __cplusplus
diff --git a/usr/src/uts/i86pc/Makefile.files b/usr/src/uts/i86pc/Makefile.files
index 4ce4e25847..a82851d393 100644
--- a/usr/src/uts/i86pc/Makefile.files
+++ b/usr/src/uts/i86pc/Makefile.files
@@ -152,7 +152,7 @@ MCAMD_OBJS += \
PCI_E_NEXUS_OBJS += npe.o npe_misc.o
PCI_E_NEXUS_OBJS += pci_common.o pci_kstats.o pci_tools.o pcie_error.o
PCI_E_PCINEXUS_OBJS += pcie_pci.o pcie_error.o
-PCIEHPCNEXUS_OBJS += pciehpc_x86.o pciehpc_acpi.o pciehpc_nvidia.o
+PCIEHPCNEXUS_OBJS += pciehpc_x86.o pciehpc_acpi.o pciehpc_nvidia.o pcie_error.o
#
# platform specific modules
diff --git a/usr/src/uts/i86pc/io/pciex/pcie_error.c b/usr/src/uts/i86pc/io/pciex/pcie_error.c
index 3550a33301..e7b1a5b5f1 100644
--- a/usr/src/uts/i86pc/io/pciex/pcie_error.c
+++ b/usr/src/uts/i86pc/io/pciex/pcie_error.c
@@ -156,17 +156,50 @@ int
pcie_error_init(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;
- 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;
+ int status;
+
+ if (pci_config_setup(cdip, &cfg_hdl) != DDI_SUCCESS)
+ return (DDI_FAILURE);
+
+ status = pcie_error_enable(cdip, cfg_hdl);
+
+ pci_config_teardown(&cfg_hdl);
+ return (status);
+}
+
+/*
+ * PCI-Express CK8-04 child device de-initialization.
+ */
+void
+pcie_error_fini(dev_info_t *cdip)
+{
+ ddi_acc_handle_t cfg_hdl;
+
+ if (pci_config_setup(cdip, &cfg_hdl) != DDI_SUCCESS)
+ return;
+
+ pcie_error_disable(cdip, cfg_hdl);
+
+ pci_config_teardown(&cfg_hdl);
+}
+
+/*
+ * 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;
+ 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
@@ -174,9 +207,6 @@ pcie_error_init(dev_info_t *cdip)
if (pcie_error_disable_flag)
return (DDI_SUCCESS);
- if (pci_config_setup(cdip, &cfg_hdl) != DDI_SUCCESS)
- return (DDI_FAILURE);
-
/* Determine the configuration header type */
header_type = pci_config_get8(cfg_hdl, PCI_CONF_HEADER);
PCIE_ERROR_DBG("%s: header_type=%x\n",
@@ -253,7 +283,7 @@ pcie_error_init(dev_info_t *cdip)
/* No PCIe; just return */
if (cap_ptr == PCI_CAP_NEXT_PTR_NULL)
- goto cleanup;
+ return (DDI_SUCCESS);
/*
* Enable PCI-Express Baseline Error Handling
@@ -287,11 +317,11 @@ pcie_error_init(dev_info_t *cdip)
* Enable PCI-Express Advanced Error Handling if Exists
*/
if (aer_ptr == PCIE_EXT_CAP_NEXT_PTR_NULL)
- goto cleanup;
+ return (DDI_SUCCESS);
if (pcie_aer_disable_flag)
- goto cleanup;
+ return (DDI_SUCCESS);
/* Disable PTLP/ECRC (or mask these two) for Switches */
if (dev_type == PCIE_PCIECAP_DEV_TYPE_UP ||
@@ -324,7 +354,7 @@ pcie_error_init(dev_info_t *cdip)
* Enable Secondary Uncorrectable errors if this is a bridge
*/
if (!(dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI))
- goto cleanup;
+ return (DDI_SUCCESS);
/* Set Secondary Uncorrectable error severity */
aer_reg = pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_SERV);
@@ -344,8 +374,6 @@ pcie_error_init(dev_info_t *cdip)
ddi_driver_name(cdip), aer_reg,
pci_config_get32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_MASK));
-cleanup:
- pci_config_teardown(&cfg_hdl);
return (DDI_SUCCESS);
}
@@ -419,25 +447,20 @@ pcie_nvidia_error_init(dev_info_t *child, ddi_acc_handle_t cfg_hdl,
}
/*
- * PCI-Express CK8-04 child device de-initialization.
- * This function disables generic pci-express interrupts and error handling.
+ * Disable generic pci-express interrupts and error handling.
*/
void
-pcie_error_fini(dev_info_t *cdip)
+pcie_error_disable(dev_info_t *cdip, ddi_acc_handle_t cfg_hdl)
{
- 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 cap_ptr, aer_ptr;
+ uint16_t dev_type;
+ uint8_t header_type;
+ uint8_t bcr;
+ uint16_t command_reg, status_reg;
if (pcie_error_disable_flag)
return;
- if (pci_config_setup(cdip, &cfg_hdl) != DDI_SUCCESS)
- 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);
@@ -469,7 +492,7 @@ pcie_error_fini(dev_info_t *cdip)
cap_ptr = pcie_error_find_cap_reg(cfg_hdl, PCI_CAP_ID_PCI_E);
if (cap_ptr == PCI_CAP_NEXT_PTR_NULL)
- goto error_fini_exit;
+ return;
/* Disable PCI-Express Baseline Error Handling */
pci_config_put16(cfg_hdl, cap_ptr + PCIE_DEVCTL, 0x0);
@@ -485,7 +508,7 @@ pcie_error_fini(dev_info_t *cdip)
pcie_nvidia_error_fini(cfg_hdl, cap_ptr, aer_ptr);
if (aer_ptr == PCIE_EXT_CAP_NEXT_PTR_NULL)
- goto error_fini_exit;
+ return;
/* Disable AER bits */
if (!pcie_aer_disable_flag) {
@@ -501,14 +524,11 @@ pcie_error_fini(dev_info_t *cdip)
dev_type = pci_config_get16(cfg_hdl, cap_ptr + PCIE_PCIECAP) &
PCIE_PCIECAP_DEV_TYPE_MASK;
if (!(dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI))
- goto error_fini_exit;
+ return;
pci_config_put32(cfg_hdl, aer_ptr + PCIE_AER_SUCE_MASK,
PCIE_AER_SUCE_BITS);
}
-
-error_fini_exit:
- pci_config_teardown(&cfg_hdl);
}
diff --git a/usr/src/uts/i86pc/io/pciex/pcie_error.h b/usr/src/uts/i86pc/io/pciex/pcie_error.h
index 408cb903a2..16950f1453 100644
--- a/usr/src/uts/i86pc/io/pciex/pcie_error.h
+++ b/usr/src/uts/i86pc/io/pciex/pcie_error.h
@@ -46,6 +46,8 @@ extern "C" {
int pcie_error_init(dev_info_t *cdip);
void pcie_error_fini(dev_info_t *cdip);
+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
}