pcie_fault.c revision f41150baf74bdaf964ddfe42d865d3c2380b3623
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * CDDL HEADER START
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * The contents of this file are subject to the terms of the
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * Common Development and Distribution License (the "License").
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * You may not use this file except in compliance with the License.
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * See the License for the specific language governing permissions
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * and limitations under the License.
c49a898cb851f8fef7d7a6a9501c66b8f03ae05cPhill Cunnington * When distributing Covered Code, include this CDDL HEADER in each
c49a898cb851f8fef7d7a6a9501c66b8f03ae05cPhill Cunnington * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * If applicable, add the following below this CDDL HEADER, with the
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * fields enclosed by brackets "[]" replaced with your own identifying
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * information: Portions Copyright [yyyy] [name of copyright owner]
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * CDDL HEADER END
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden * Use is subject to license terms.
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden#pragma ident "%Z%%M% %I% %E% SMI"
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden#define PF_PCIE_BDG_ERR (PCIE_DEVSTS_FE_DETECTED | PCIE_DEVSTS_NFE_DETECTED | \
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden#define PF_PCI_BDG_ERR (PCI_STAT_S_SYSERR | PCI_STAT_S_TARG_AB | \
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PCI_STAT_R_MAST_AB | PCI_STAT_R_TARG_AB | PCI_STAT_S_PERROR)
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden#define PF_AER_FATAL_ERR (PCIE_AER_UCE_DLP | PCIE_AER_UCE_SD |\
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PCIE_AER_UCE_FCP | PCIE_AER_UCE_RO | PCIE_AER_UCE_MTLP)
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden#define PF_AER_NON_FATAL_ERR (PCIE_AER_UCE_PTLP | PCIE_AER_UCE_TO | \
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PCIE_AER_UCE_CA | PCIE_AER_UCE_ECRC | PCIE_AER_UCE_UR)
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden#define PF_SAER_FATAL_ERR (PCIE_AER_SUCE_USC_MSG_DATA_ERR | \
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PCIE_AER_SUCE_UC_ATTR_ERR | PCIE_AER_SUCE_UC_ADDR_ERR | \
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden#define PF_SAER_NON_FATAL_ERR (PCIE_AER_SUCE_TA_ON_SC | \
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PCIE_AER_SUCE_MA_ON_SC | PCIE_AER_SUCE_RCVD_TA | \
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PCIE_AER_SUCE_RCVD_MA | PCIE_AER_SUCE_USC_ERR | \
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PCIE_AER_SUCE_UC_DATA_ERR | PCIE_AER_SUCE_TIMER_EXPIRED | \
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PCIE_AER_SUCE_PERR_ASSERT | PCIE_AER_SUCE_INTERNAL_ERR)
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden#define PF_PCI_PARITY_ERR (PCI_STAT_S_PERROR | PCI_STAT_PERROR)
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden (bit & (1 << (adv->pcie_adv_ctl & PCIE_AER_CTL_FST_ERR_PTR_MASK)))
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden (bit & (1 << (adv->pcie_sue_ctl & PCIE_AER_SCTL_FST_ERR_PTR_MASK)))
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PF_FIRST_SAER_ERR(bit, PCIE_ADV_BDG_REG(pfd_p)))
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden PCIE_AER_SUCE_HDR_CMD_LWR_SHIFT) & PCIE_AER_SUCE_HDR_CMD_LWR_MASK)
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden (PCIE_ADV_REG(pfd_p)->pcie_ce_status & PCIE_AER_CE_AD_NFE)
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden/* PCIe Fault Fabric Error analysis table */
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddentypedef struct pf_fab_err_tbl {
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden/* Functions for scanning errors */
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic int pf_default_hdl(dev_info_t *, pf_impl_t *);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic int pf_dispatch(dev_info_t *, pf_impl_t *, boolean_t);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic boolean_t pf_in_bus_range(pcie_bus_t *, pcie_req_id_t);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic boolean_t pf_in_addr_range(pcie_bus_t *, uint64_t);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic int pf_pci_decode(pf_data_t *, uint16_t *);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden/* Functions for gathering errors */
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic void pf_pcix_ecc_regs_gather(pf_pcix_ecc_regs_t *pcix_ecc_regs,
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic void pf_pcix_regs_gather(pf_data_t *pfd_p, pcie_bus_t *bus_p);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic void pf_pcie_regs_gather(pf_data_t *pfd_p, pcie_bus_t *bus_p);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic void pf_pci_regs_gather(pf_data_t *pfd_p, pcie_bus_t *bus_p);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic int pf_dummy_cb(dev_info_t *, ddi_fm_error_t *, const void *);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic void pf_en_dq(pf_data_t *pfd_p, pf_impl_t *impl_p);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Madden/* Functions for analysing errors */
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic int pf_analyse_error(ddi_fm_error_t *, pf_impl_t *);
9c1ec205dd4a7c6a5a2b06fa7385cf5b33274208Neil Maddenstatic pf_data_t *pf_get_pcie_bridge(pf_data_t *, pcie_req_id_t);
uint32_t);
if (pcie_disable_scan)
return (analyse_flag);
!root_pfd_p) {
goto done;
goto done;
if (full_scan)
done:
return (analyse_flag);
if (full_scan ||
case PCIE_PCIECAP_DEV_TYPE_UP:
return (scan_flag);
static boolean_t
return (B_TRUE);
return (B_FALSE);
static boolean_t
uint_t i;
return (B_TRUE);
return (B_FALSE);
case PCI_ADDR_MEM32:
return (B_TRUE);
case PCI_ADDR_MEM64:
return (B_TRUE);
return (B_FALSE);
static pcie_bus_t *
if (!bus_p)
return (NULL);
return (NULL);
return (bus_p);
if (bdg) {
B_TRUE);
int num_faults = 0;
num_faults++;
num_faults++;
num_faults++;
num_faults++;
if (num_faults == 0)
num_faults--;
num_faults--;
DDI_SUCCESS)) {
num_faults--;
if (num_faults > 0)
goto done;
return (PF_SCAN_BAD_RESPONSE);
done:
return (scan_flag);
if (!bus_p) {
if (fmhdl) {
int cap;
* fm-capable in driver.conf can be used to set fm_capabilities.
if (!fmhdl) {
if (need_cb_register)
if (!bus_p)
return (DDI_FM_OK);
if (!head_p) {
if (last_p)
sts_flags = 0;
if (PCIE_DEVSTS_CE_DETECTED &
case PCIE_PCIECAP_DEV_TYPE_UP:
if (PCIE_DEVSTS_CE_DETECTED &
if (PCIE_DEVSTS_CE_DETECTED &
return (error_flags);
int err = 0;
row++) {
pfd_p);
if (!err)
return (err);
return (PF_ERR_NO_PANIC);
goto handle_lookup;
return (PF_ERR_MATCHED_RC);
return (PF_ERR_MATCHED_DEVICE);
return (PF_ERR_PANIC);
return (PF_ERR_NO_PANIC);
return (PF_ERR_MATCHED_RC);
return (PF_ERR_PANIC);
return (PF_ERR_MATCHED_DEVICE);
return (PF_ERR_PANIC);
return (PF_ERR_PANIC);
return (PF_ERR_NO_PANIC);
return (PF_ERR_PANIC);
return (PF_ERR_PANIC);
return (PF_ERR_PANIC);
return (PF_ERR_MATCHED_PARENT);
return (PF_ERR_MATCHED_PARENT);
return (PF_ERR_PANIC);
return (PF_ERR_PANIC);
switch (cmd) {
case PCI_PCIX_CMD_IOWR:
case PCI_PCIX_CMD_MEMWR:
case PCI_PCIX_CMD_MEMWR_BL:
case PCI_PCIX_CMD_MEMWRBL:
B_FALSE);
case PCI_PCIX_CMD_CFWR:
goto done;
B_FALSE);
case PCI_PCIX_CMD_SPL:
B_FALSE);
case PCI_PCIX_CMD_DADR:
goto cmd_switch;
done:
return (err);
return (PF_ERR_MATCHED_DEVICE);
return (PF_ERR_PANIC);
return (PF_ERR_MATCHED_RC);
return (PF_ERR_MATCHED_PARENT);
goto done;
goto done;
done:
return (PF_ERR_PANIC);
return (PF_ERR_PANIC);
return (PF_ERR_PANIC);
return (PF_ERR_MATCHED_DEVICE);
return (PF_ERR_PANIC);
return (PF_ERR_NO_PANIC);
return (PF_ERR_PANIC);
return (PF_ERR_NO_PANIC);
return (PF_ERR_PANIC);
return (PF_ERR_PANIC);
return (PF_ERR_MATCHED_RC);
return (PF_ERR_MATCHED_DEVICE);
return (PF_ERR_PANIC);
return (PF_ERR_NO_PANIC);
return (PF_ERR_PANIC);
static pf_data_t *
return (bdg_pfd_p);
return (NULL);
static pf_data_t *
return (NULL);
return (NULL);
static boolean_t
return (B_TRUE);
return (B_TRUE);
return (B_TRUE);
return (B_FALSE);
case PCIE_AER_SUCE_TA_ON_SC:
case PCIE_AER_SUCE_MA_ON_SC:
case PCIE_AER_SUCE_RCVD_TA:
case PCIE_AER_SUCE_RCVD_MA:
*bdf = 0;
case PCIE_AER_SUCE_USC_ERR:
*addr = 0;
*bdf = 0;
*trans_type = 0;
*bdf = 0;
PCI_STAT_PERROR)) {
switch (*cmd) {
case PCI_PCIX_CMD_IORD:
case PCI_PCIX_CMD_IOWR:
case PCI_PCIX_CMD_MEMRD_DW:
case PCI_PCIX_CMD_MEMRD_BL:
case PCI_PCIX_CMD_MEMRDBL:
case PCI_PCIX_CMD_MEMWR:
case PCI_PCIX_CMD_MEMWR_BL:
case PCI_PCIX_CMD_MEMWRBL:
case PCI_PCIX_CMD_CFRD:
case PCI_PCIX_CMD_CFWR:
addr = 0;
case PCI_PCIX_CMD_SPL:
addr = 0;
case PCI_PCIX_CMD_DADR:
goto cmd_switch;
return (DDI_FAILURE);
return (DDI_SUCCESS);
return (PF_HDL_NOTFOUND);
return (PF_HDL_NOTFOUND);
return (status);
if (fcp)
if (fcp)
goto done;
goto done;
bdf);
goto done;
done:
return (status);
int found = 0;
int status;
found++;
found++;
if (is_primary) {
return (lookup);
case PCIE_TLP_TYPE_IO:
case PCIE_TLP_TYPE_MEM:
case PCIE_TLP_TYPE_MEMLK:
flt_bdf = 0;
case PCIE_TLP_TYPE_CFG0:
case PCIE_TLP_TYPE_CFG1:
flt_addr = 0;
case PCIE_TLP_TYPE_CPL:
case PCIE_TLP_TYPE_CPLLK:
return (DDI_FAILURE);
return (DDI_SUCCESS);
if (ena == 0)
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
NULL);
&eqep);
return (PF_SCAN_SUCCESS);
return (PF_SCAN_SUCCESS);
return (PF_SCAN_DEADLOCK);
return (cb_sts);