diff options
| author | prasad <none@none> | 2006-10-27 11:06:53 -0700 |
|---|---|---|
| committer | prasad <none@none> | 2006-10-27 11:06:53 -0700 |
| commit | 28cae8e27cd02e5b8df9666bb34af9786c217a1a (patch) | |
| tree | 7af5b7e1e37acfc4a6c3a090d293dfcbffbf9c48 /usr/src | |
| parent | 3a61361bc1b158495f091aef41d27d7cbdeb8986 (diff) | |
| download | illumos-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.c | 25 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/hotplug/pci/pciehpc_impl.h | 10 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/Makefile.files | 2 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/io/pciex/pcie_error.c | 96 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/io/pciex/pcie_error.h | 2 |
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 } |
