changeset 2997:d50afcd8c0c0

6470966 x64: PCIe software should mask off fabric errors during hotplug operations
author prasad
date Fri, 27 Oct 2006 11:06:53 -0700
parents 5f9b187160a5
children bb849cbe4319
files usr/src/uts/common/io/hotplug/pciehpc/pciehpc.c usr/src/uts/common/sys/hotplug/pci/pciehpc_impl.h usr/src/uts/i86pc/Makefile.files usr/src/uts/i86pc/io/pciex/pcie_error.c usr/src/uts/i86pc/io/pciex/pcie_error.h
diffstat 5 files changed, 78 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/hotplug/pciehpc/pciehpc.c	Fri Oct 27 10:29:14 2006 -0700
+++ b/usr/src/uts/common/io/hotplug/pciehpc/pciehpc.c	Fri Oct 27 11:06:53 2006 -0700
@@ -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_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 @@
 		    goto cleanup;
 	}
 
-	PCIEHPC_DISABLE_ERRORS(ctrl_p);
+	pciehpc_disable_errors(ctrl_p);
 
 	/*
 	 * Set the platform specific hot plug mode.
@@ -256,7 +257,7 @@
 	(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 @@
 	/* 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 @@
 		/* 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 @@
 
 	    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 @@
 	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 @@
 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
--- a/usr/src/uts/common/sys/hotplug/pci/pciehpc_impl.h	Fri Oct 27 10:29:14 2006 -0700
+++ b/usr/src/uts/common/sys/hotplug/pci/pciehpc_impl.h	Fri Oct 27 11:06:53 2006 -0700
@@ -222,11 +222,13 @@
 #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
--- a/usr/src/uts/i86pc/Makefile.files	Fri Oct 27 10:29:14 2006 -0700
+++ b/usr/src/uts/i86pc/Makefile.files	Fri Oct 27 11:06:53 2006 -0700
@@ -152,7 +152,7 @@
 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
--- a/usr/src/uts/i86pc/io/pciex/pcie_error.c	Fri Oct 27 10:29:14 2006 -0700
+++ b/usr/src/uts/i86pc/io/pciex/pcie_error.c	Fri Oct 27 11:06:53 2006 -0700
@@ -156,17 +156,50 @@
 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 @@
 	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 @@
 
 	/* 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 @@
 	 * 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 @@
 	 * 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 @@
 	    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 @@
 }
 
 /*
- * 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 @@
 
 	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_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 @@
 		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);
 }
 
 
--- a/usr/src/uts/i86pc/io/pciex/pcie_error.h	Fri Oct 27 10:29:14 2006 -0700
+++ b/usr/src/uts/i86pc/io/pciex/pcie_error.h	Fri Oct 27 11:06:53 2006 -0700
@@ -46,6 +46,8 @@
 
 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
 }