summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/fm/topo/modules/common/pcibus/did.c73
-rw-r--r--usr/src/lib/fm/topo/modules/common/pcibus/did.h5
-rw-r--r--usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h7
-rw-r--r--usr/src/lib/fm/topo/modules/common/pcibus/did_props.c9
-rw-r--r--usr/src/lib/fm/topo/modules/common/pcibus/did_props.h4
-rw-r--r--usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c76
-rw-r--r--usr/src/uts/common/io/pcie_fault.c5
-rw-r--r--usr/src/uts/common/os/pcifm.c1250
-rw-r--r--usr/src/uts/common/sys/pcie_impl.h2
-rw-r--r--usr/src/uts/common/sys/pcifm.h80
-rw-r--r--usr/src/uts/i86pc/io/mp_platform_common.c10
-rw-r--r--usr/src/uts/i86pc/io/pci/pci_common.c29
-rw-r--r--usr/src/uts/i86pc/io/pci/pci_common.h26
-rw-r--r--usr/src/uts/i86pc/io/pciex/npe.c34
-rw-r--r--usr/src/uts/i86pc/io/pciex/npe_misc.c118
-rw-r--r--usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c77
-rw-r--r--usr/src/uts/intel/io/pci/pci_boot.c49
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_nvidia.c30
-rw-r--r--usr/src/uts/intel/io/pciex/pcie_pci.c74
-rw-r--r--usr/src/uts/sun4/io/px/px_fm.c10
20 files changed, 373 insertions, 1595 deletions
diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did.c b/usr/src/lib/fm/topo/modules/common/pcibus/did.c
index 7c13a73942..40c83a808e 100644
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did.c
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.c
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* did.c
* The acronym did means "Dev-Info-Data". Many properties and
@@ -114,27 +112,37 @@ slotnm_cp(did_t *from, did_t *to, int *nslots)
}
static int
-di_physlotinfo_get(topo_mod_t *mp, di_node_t src, uint_t excap,
- int *slotnum, char **slotnm)
+di_devtype_get(topo_mod_t *mp, di_node_t src, char **devtype)
{
- char *slotbuf;
int sz;
uchar_t *buf;
- *slotnum = -1;
- (void) di_uintprop_get(mp, src, DI_PHYSPROP, (uint_t *)slotnum);
/*
- * If no physical slot number property was found, then the
- * capabilities register may indicate the pci-express device
- * implements a slot, and we should record which slot.
+ * For PCI the device type defined the type of device directly below.
+ * For PCIe RP and Switches, the device-type should be "pciex". For
+ * PCIe-PCI and PCI-PCI bridges it should be "pci". NICs = "network",
+ * Graphics = "display", etc..
*/
- if (*slotnum == -1 && (excap & PCIE_PCIECAP_SLOT_IMPL) != 0) {
- uint_t slotcap;
- int e;
- e = di_uintprop_get(mp, src, "pcie-slotcap-reg", &slotcap);
- if (e == 0)
- *slotnum = slotcap >> PCIE_SLOTCAP_PHY_SLOT_NUM_SHIFT;
+ if (di_bytes_get(mp, src, DI_DEVTYPPROP, &sz, &buf) == 0) {
+ *devtype = topo_mod_strdup(mp, (char *)buf);
+ } else {
+ *devtype = NULL;
}
+
+ if (*devtype != NULL)
+ return (0);
+ return (-1);
+}
+
+static int
+di_physlotinfo_get(topo_mod_t *mp, di_node_t src, int *slotnum, char **slotnm)
+{
+ char *slotbuf;
+ int sz;
+ uchar_t *buf;
+
+ *slotnum = -1;
+ (void) di_uintprop_get(mp, src, DI_PHYSPROP, (uint_t *)slotnum);
if (*slotnum == -1)
return (0);
@@ -263,16 +271,16 @@ did_create(topo_mod_t *mp, di_node_t src,
np->dp_class = -1;
}
/*
- * There *may* be a PCI-express capabilities register we can capture.
- * If there wasn't one, the capabilities will be the out-of-bounds
- * value of zero.
+ * There *may* be a device type we can capture.
*/
- (void) di_uintprop_get(mp, src, "pcie-capid-reg", &np->dp_excap);
+ (void) di_devtype_get(mp, src, &np->dp_devtype);
/*
* There *may* be a physical slot number property we can capture.
*/
if (di_physlotinfo_get(mp,
- src, np->dp_excap, &np->dp_physlot, &np->dp_physlot_label) < 0) {
+ src, &np->dp_physlot, &np->dp_physlot_label) < 0) {
+ if (np->dp_devtype != NULL)
+ topo_mod_strfree(mp, np->dp_devtype);
topo_mod_free(mp, np, sizeof (did_t));
return (NULL);
}
@@ -280,6 +288,8 @@ did_create(topo_mod_t *mp, di_node_t src,
* There *may* be PCI slot info we can capture
*/
if (di_slotinfo_get(mp, src, &np->dp_nslots, &np->dp_slotnames) < 0) {
+ if (np->dp_devtype != NULL)
+ topo_mod_strfree(mp, np->dp_devtype);
if (np->dp_physlot_label != NULL)
topo_mod_strfree(mp, np->dp_physlot_label);
topo_mod_free(mp, np, sizeof (did_t));
@@ -345,6 +355,8 @@ did_destroy(did_t *dp)
* code will need to change
*/
+ if (dp->dp_devtype != NULL)
+ topo_mod_strfree(dp->dp_mod, dp->dp_devtype);
if (dp->dp_physlot_label != NULL)
topo_mod_strfree(dp->dp_mod, dp->dp_physlot_label);
slotnm_destroy(dp->dp_slotnames);
@@ -435,6 +447,12 @@ did_excap(did_t *dp)
return ((int)dp->dp_excap);
}
+void
+did_excap_set(did_t *dp, int type)
+{
+ dp->dp_excap = type;
+}
+
int
did_bdf(did_t *dp)
{
@@ -495,6 +513,17 @@ pci_classcode_get(topo_mod_t *mp, di_node_t dn, uint_t *class, uint_t *sub)
return (0);
}
+char *
+pci_devtype_get(topo_mod_t *mp, di_node_t dn)
+{
+ did_t *dp;
+
+ if ((dp = did_find(mp, dn)) == NULL)
+ return (NULL);
+ did_rele(dp);
+ return (dp->dp_devtype);
+}
+
int
pciex_cap_get(topo_mod_t *mp, di_node_t dn)
{
diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did.h b/usr/src/lib/fm/topo/modules/common/pcibus/did.h
index 8d1a941562..66bccde65f 100644
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did.h
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did.h
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _DID_H
#define _DID_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/pci.h>
#include <fm/topo_mod.h>
#include <libdevinfo.h>
@@ -61,6 +59,7 @@ extern int did_rc(did_t *);
extern int did_physslot(did_t *);
extern int did_inherit(did_t *, did_t *);
extern int did_excap(did_t *);
+extern void did_excap_set(did_t *, int);
extern int did_bdf(did_t *);
extern did_t *did_link_get(did_t *);
extern did_t *did_chain_get(did_t *);
diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h b/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h
index e6a4218794..53642e0df5 100644
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_impl.h
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _DID_IMPL_H
#define _DID_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/pci.h>
#include <fm/libtopo.h>
#include <libdevinfo.h>
@@ -70,11 +68,12 @@ struct did {
topo_mod_t *dp_mod; /* module that allocated the did private data */
di_node_t dp_src; /* di_node_t from which the info was derived */
int dp_refcnt; /* multiple nodes allowed to point at a did_t */
- uint_t dp_excap; /* PCI-Express capabilities */
+ uint_t dp_excap; /* PCI-Express port/device type */
int dp_physlot; /* PCI-Express physical slot # */
char *dp_physlot_label; /* PCI-Express slot implemented */
int dp_class; /* PCI class */
int dp_subclass; /* PCI subclass */
+ char *dp_devtype; /* PCI 1275 spec device-type */
int dp_board; /* Board number */
int dp_bridge; /* Bridge number */
int dp_rc; /* Root Complex number */
diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c
index 07406fdb4e..3724e78c5a 100644
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <assert.h>
#include <alloca.h>
#include <string.h>
@@ -446,7 +444,7 @@ FRU_fmri_set(topo_mod_t *mp, tnode_t *tn)
return (0);
}
-static tnode_t *
+tnode_t *
find_predecessor(tnode_t *tn, char *mod_name)
{
tnode_t *pnode = topo_node_parent(tn);
@@ -620,13 +618,10 @@ static int
EXCAP_set(tnode_t *tn, did_t *pd,
const char *dpnm, const char *tpgrp, const char *tpnm)
{
- int excap;
+ int excap = did_excap(pd);
int err;
int e = 0;
- if ((excap = did_excap(pd)) <= 0)
- return (0);
-
switch (excap & PCIE_PCIECAP_DEV_TYPE_MASK) {
case PCIE_PCIECAP_DEV_TYPE_ROOT:
e = topo_prop_set_string(tn, TOPO_PGROUP_PCI,
diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h
index af2e2a5316..20ae8a5b3e 100644
--- a/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/did_props.h
@@ -27,8 +27,6 @@
#ifndef _DID_PROPS_H
#define _DID_PROPS_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/pci.h>
#include <fm/topo_mod.h>
#include <libdevinfo.h>
@@ -72,7 +70,9 @@ typedef struct txprop {
#define DI_AADDRPROP "assigned-addresses"
extern int did_props_set(tnode_t *, did_t *, txprop_t[], int);
+extern tnode_t *find_predecessor(tnode_t *, char *);
+extern char *pci_devtype_get(topo_mod_t *, di_node_t);
extern int pciex_cap_get(topo_mod_t *, di_node_t);
extern int pci_BDF_get(topo_mod_t *, di_node_t, int *, int *, int *);
extern int pci_classcode_get(topo_mod_t *, di_node_t, uint_t *, uint_t *);
diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c
index e22f562f6d..5c1f8c8554 100644
--- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c
+++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/fm/protocol.h>
#include <assert.h>
#include <stdio.h>
@@ -161,10 +159,70 @@ pciexfn_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn,
topo_instance_t i)
{
did_t *pd;
- tnode_t *ntn;
+ tnode_t *ntn, *ptn;
+ di_node_t pdn;
+ uint_t class, subclass;
+ char *devtyp, *pdevtyp;
+ int pcie_devtyp, pexcap;
+ boolean_t dev_is_pcie, pdev_is_pcie;
+
+ /* We need the parent's dev info node for some of the info */
+ ptn = find_predecessor(parent, PCIEX_FUNCTION);
+ /* If this is the first child under root, get root's ptn */
+ if (ptn == NULL)
+ ptn = find_predecessor(parent, PCIEX_ROOT);
+ if (ptn == NULL)
+ return (NULL);
+ pdn = topo_node_getspecific(ptn);
+
+ /* Get the required info to populate the excap */
+ (void) pci_classcode_get(mod, dn, &class, &subclass);
+ devtyp = pci_devtype_get(mod, dn);
+ pdevtyp = pci_devtype_get(mod, pdn);
+ pexcap = pciex_cap_get(mod, pdn);
+
+ dev_is_pcie = devtyp && (strcmp(devtyp, "pciex") == 0);
+ pdev_is_pcie = pdevtyp && (strcmp(pdevtyp, "pciex") == 0);
+
+ /*
+ * Populate the excap with correct PCIe device type.
+ *
+ * Device Parent Device Parent Device
+ * excap device-type device-type excap Class Code
+ * -------------------------------------------------------------------
+ * PCI(default) pci N/A N/A != bridge
+ * PCIe pciex N/A N/A != bridge
+ * Root Port Defined in hostbridge
+ * Switch Up pciex pciex != up = bridge
+ * Switch Down pciex pciex = up = bridge
+ * PCIe-PCI pciex pci N/A = bridge
+ * PCI-PCIe pci pciex N/A = bridge
+ */
+ pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_PCI_DEV;
+ if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) {
+ if (pdev_is_pcie) {
+ if (dev_is_pcie) {
+ if (pexcap != PCIE_PCIECAP_DEV_TYPE_UP)
+ pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_UP;
+ else
+ pcie_devtyp =
+ PCIE_PCIECAP_DEV_TYPE_DOWN;
+ } else {
+ pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_PCIE2PCI;
+ }
+ } else {
+ if (dev_is_pcie)
+ pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_PCI2PCIE;
+ }
+ } else {
+ if (pdev_is_pcie)
+ pcie_devtyp = PCIE_PCIECAP_DEV_TYPE_PCIE_DEV;
+ }
if ((pd = did_find(mod, dn)) == NULL)
return (NULL);
+ did_excap_set(pd, pcie_devtyp);
+
if ((ntn = pci_tnode_create(mod, parent, PCIEX_FUNCTION, i, dn))
== NULL)
return (NULL);
@@ -252,6 +310,8 @@ pcifn_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn,
if ((pd = did_find(mod, dn)) == NULL)
return (NULL);
+ did_excap_set(pd, PCIE_PCIECAP_DEV_TYPE_PCI_DEV);
+
if ((ntn = pci_tnode_create(mod, parent, PCI_FUNCTION, i, dn)) == NULL)
return (NULL);
if (did_props_set(ntn, pd, Fn_common_props, Fn_propcnt) < 0) {
@@ -348,12 +408,12 @@ static int
pci_bridge_declare(topo_mod_t *mod, tnode_t *fn, di_node_t din, int board,
int bridge, int rc, int depth)
{
- int err, excap, extyp;
+ int err;
+ char *devtyp;
- excap = pciex_cap_get(mod, din);
- extyp = excap & PCIE_PCIECAP_DEV_TYPE_MASK;
- if (excap <= 0 ||
- extyp != PCIE_PCIECAP_DEV_TYPE_PCIE2PCI)
+ devtyp = pci_devtype_get(mod, din);
+ /* Check if the children are PCI or PCIe */
+ if (strcmp(devtyp, "pciex") == 0)
err = pci_children_instantiate(mod, fn, din, board, bridge,
rc, TRUST_BDF, depth + 1);
else
diff --git a/usr/src/uts/common/io/pcie_fault.c b/usr/src/uts/common/io/pcie_fault.c
index aadb8d11ad..94b7307919 100644
--- a/usr/src/uts/common/io/pcie_fault.c
+++ b/usr/src/uts/common/io/pcie_fault.c
@@ -1762,7 +1762,8 @@ pf_adjust_for_no_aer(pf_data_t *pfd_p)
aer_ue &= ~PCIE_AER_UCE_CA;
/* Check if the device sent a UR */
- if (!(status & PCIE_DEVSTS_UR_DETECTED))
+ if (!(PCIE_ERR_REG(pfd_p)->pcie_err_status &
+ PCIE_DEVSTS_UR_DETECTED))
aer_ue &= ~PCIE_AER_UCE_UR;
/*
@@ -1782,7 +1783,7 @@ pf_adjust_for_no_aer(pf_data_t *pfd_p)
* occur, SERR should be set since they are not masked. So if
* SERR is not set, none of them occurred.
*/
- if (!(PCI_ERR_REG(pfd_p)->pci_err_status & PCI_STAT_S_SYSERR))
+ if (!(status & PCI_STAT_S_SYSERR))
aer_ue &= ~PCIE_AER_UCE_TO;
}
diff --git a/usr/src/uts/common/os/pcifm.c b/usr/src/uts/common/os/pcifm.c
index 6dd300d401..ca81c7fc9e 100644
--- a/usr/src/uts/common/os/pcifm.c
+++ b/usr/src/uts/common/os/pcifm.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/sunndi.h>
#include <sys/sysmacros.h>
@@ -35,7 +33,7 @@
#include <sys/fm/io/pci.h>
#include <sys/fm/io/ddi.h>
#include <sys/pci.h>
-#include <sys/pcie.h>
+#include <sys/pci_cap.h>
#include <sys/pci_impl.h>
#include <sys/epm.h>
#include <sys/pcifm.h>
@@ -43,18 +41,6 @@
#define PCIX_ECC_VER_CHECK(x) (((x) == PCI_PCIX_VER_1) ||\
((x) == PCI_PCIX_VER_2))
-/*
- * Expected PCI Express error mask values
- *
- * !!NOTE!! All PCI Express functionality including PCIe initialization, PCIe
- * error handling has been moved to the common pcie misc module. All functions
- * and variables dealting with PCIe in this file have been deprecated and will
- * be eventually removed. All Legacy PCI and PCI-X related code should remain
- * as is.
- */
-uint32_t pcie_aer_uce_log_bits = PCIE_AER_UCE_LOG_BITS;
-uint32_t pcie_aer_suce_log_bits = PCIE_AER_SUCE_LOG_BITS;
-
errorq_t *pci_target_queue = NULL;
pci_fm_err_t pci_err_tbl[] = {
@@ -79,51 +65,6 @@ pci_fm_err_t pci_bdg_err_tbl[] = {
NULL, NULL, NULL, NULL,
};
-static pci_fm_err_t pciex_ce_err_tbl[] = {
- PCIEX_RE, PCIE_AER_CE_RECEIVER_ERR, NULL, DDI_FM_OK,
- PCIEX_RNR, PCIE_AER_CE_REPLAY_ROLLOVER, NULL, DDI_FM_OK,
- PCIEX_RTO, PCIE_AER_CE_REPLAY_TO, NULL, DDI_FM_OK,
- PCIEX_BDP, PCIE_AER_CE_BAD_DLLP, NULL, DDI_FM_OK,
- PCIEX_BTP, PCIE_AER_CE_BAD_TLP, NULL, DDI_FM_OK,
- PCIEX_ANFE, PCIE_AER_CE_AD_NFE, NULL, DDI_FM_OK,
- NULL, NULL, NULL, NULL,
-};
-
-static pci_fm_err_t pciex_ue_err_tbl[] = {
- PCIEX_TE, PCIE_AER_UCE_TRAINING, NULL, DDI_FM_FATAL,
- PCIEX_DLP, PCIE_AER_UCE_DLP, NULL, DDI_FM_FATAL,
- PCIEX_SD, PCIE_AER_UCE_SD, NULL, DDI_FM_FATAL,
- PCIEX_ROF, PCIE_AER_UCE_RO, NULL, DDI_FM_FATAL,
- PCIEX_FCP, PCIE_AER_UCE_FCP, NULL, DDI_FM_FATAL,
- PCIEX_MFP, PCIE_AER_UCE_MTLP, NULL, DDI_FM_FATAL,
- PCIEX_CTO, PCIE_AER_UCE_TO, NULL, DDI_FM_UNKNOWN,
- PCIEX_UC, PCIE_AER_UCE_UC, NULL, DDI_FM_OK,
- PCIEX_ECRC, PCIE_AER_UCE_ECRC, NULL, DDI_FM_UNKNOWN,
- PCIEX_CA, PCIE_AER_UCE_CA, NULL, DDI_FM_UNKNOWN,
- PCIEX_UR, PCIE_AER_UCE_UR, NULL, DDI_FM_UNKNOWN,
- PCIEX_POIS, PCIE_AER_UCE_PTLP, NULL, DDI_FM_UNKNOWN,
- NULL, NULL, NULL, NULL,
-};
-
-static pci_fm_err_t pcie_sue_err_tbl[] = {
- PCIEX_S_TA_SC, PCIE_AER_SUCE_TA_ON_SC, NULL, DDI_FM_UNKNOWN,
- PCIEX_S_MA_SC, PCIE_AER_SUCE_MA_ON_SC, NULL, DDI_FM_UNKNOWN,
- PCIEX_S_RTA, PCIE_AER_SUCE_RCVD_TA, NULL, DDI_FM_UNKNOWN,
-#if defined(__sparc)
- PCIEX_S_RMA, PCIE_AER_SUCE_RCVD_MA, NULL, DDI_FM_UNKNOWN,
-#endif
- PCIEX_S_USC, PCIE_AER_SUCE_USC_ERR, NULL, DDI_FM_UNKNOWN,
- PCIEX_S_USCMD, PCIE_AER_SUCE_USC_MSG_DATA_ERR, NULL, DDI_FM_FATAL,
- PCIEX_S_UDE, PCIE_AER_SUCE_UC_DATA_ERR, NULL, DDI_FM_UNKNOWN,
- PCIEX_S_UAT, PCIE_AER_SUCE_UC_ATTR_ERR, NULL, DDI_FM_FATAL,
- PCIEX_S_UADR, PCIE_AER_SUCE_UC_ADDR_ERR, NULL, DDI_FM_FATAL,
- PCIEX_S_TEX, PCIE_AER_SUCE_TIMER_EXPIRED, NULL, DDI_FM_FATAL,
- PCIEX_S_PERR, PCIE_AER_SUCE_PERR_ASSERT, NULL, DDI_FM_UNKNOWN,
- PCIEX_S_SERR, PCIE_AER_SUCE_SERR_ASSERT, NULL, DDI_FM_FATAL,
- PCIEX_INTERR, PCIE_AER_SUCE_INTERNAL_ERR, NULL, DDI_FM_FATAL,
- NULL, NULL, NULL, NULL,
-};
-
static pci_fm_err_t pcix_err_tbl[] = {
PCIX_SPL_DIS, PCI_PCIX_SPL_DSCD, NULL, DDI_FM_UNKNOWN,
PCIX_UNEX_SPL, PCI_PCIX_UNEX_SPL, NULL, DDI_FM_UNKNOWN,
@@ -139,14 +80,6 @@ static pci_fm_err_t pcix_sec_err_tbl[] = {
NULL, NULL, NULL, NULL,
};
-static pci_fm_err_t pciex_nadv_err_tbl[] = {
- PCIEX_UR, PCIE_DEVSTS_UR_DETECTED, NULL, DDI_FM_UNKNOWN,
- PCIEX_FAT, PCIE_DEVSTS_FE_DETECTED, NULL, DDI_FM_FATAL,
- PCIEX_NONFAT, PCIE_DEVSTS_NFE_DETECTED, NULL, DDI_FM_UNKNOWN,
- PCIEX_CORR, PCIE_DEVSTS_CE_DETECTED, NULL, DDI_FM_OK,
- NULL, NULL, NULL, NULL,
-};
-
static int
pci_config_check(ddi_acc_handle_t handle, int fme_flag)
{
@@ -222,27 +155,16 @@ pcix_regs_gather(pci_erpt_t *erpt_p, void *pe_regs, int fme_flag)
return;
if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) {
pcix_ecc_regs_t *pcix_bdg_ecc_regs;
- /*
- * PCI Express to PCI-X bridges only implement the
- * secondary side of the PCI-X ECC registers, bit one is
- * read-only so we make sure we do not write to it.
- */
- if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) {
+
+ for (i = 0; i < 2; i++) {
pcix_bdg_ecc_regs =
- pcix_bdg_regs->pcix_bdg_ecc_regs[1];
- pcix_ecc_regs_gather(erpt_p, pcix_bdg_ecc_regs,
+ pcix_bdg_regs->pcix_bdg_ecc_regs[i];
+ pci_config_put32(erpt_p->pe_hdl,
+ (pcix_bdg_cap_ptr +
+ PCI_PCIX_BDG_ECC_STATUS), i);
+ pcix_ecc_regs_gather(erpt_p,
+ pcix_bdg_ecc_regs,
pcix_bdg_cap_ptr, fme_flag);
- } else {
- for (i = 0; i < 2; i++) {
- pcix_bdg_ecc_regs =
- pcix_bdg_regs->pcix_bdg_ecc_regs[i];
- pci_config_put32(erpt_p->pe_hdl,
- (pcix_bdg_cap_ptr +
- PCI_PCIX_BDG_ECC_STATUS), i);
- pcix_ecc_regs_gather(erpt_p,
- pcix_bdg_ecc_regs,
- pcix_bdg_cap_ptr, fme_flag);
- }
}
}
} else {
@@ -269,139 +191,6 @@ pcix_regs_gather(pci_erpt_t *erpt_p, void *pe_regs, int fme_flag)
}
}
-static void
-pcie_regs_gather(pci_erpt_t *erpt_p, int fme_flag)
-{
- pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
- uint8_t pcie_cap_ptr;
- pcie_adv_error_regs_t *pcie_adv_regs;
- uint16_t pcie_ecap_ptr;
-
- pcie_cap_ptr = pcie_regs->pcie_cap_ptr;
-
- pcie_regs->pcie_err_status = pci_config_get16(erpt_p->pe_hdl,
- pcie_cap_ptr + PCIE_DEVSTS);
- if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK)
- pcie_regs->pcie_vflags |= PCIE_ERR_STATUS_VALID;
- else
- return;
-
- pcie_regs->pcie_err_ctl = pci_config_get16(erpt_p->pe_hdl,
- (pcie_cap_ptr + PCIE_DEVCTL));
- pcie_regs->pcie_dev_cap = pci_config_get16(erpt_p->pe_hdl,
- (pcie_cap_ptr + PCIE_DEVCAP));
-
- if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) && (erpt_p->pe_dflags &
- PCIX_DEV))
- pcix_regs_gather(erpt_p, pcie_regs->pcix_bdg_regs, fme_flag);
-
- if (erpt_p->pe_dflags & PCIEX_RC_DEV) {
- pcie_rc_error_regs_t *pcie_rc_regs = pcie_regs->pcie_rc_regs;
-
- pcie_rc_regs->pcie_rc_status = pci_config_get32(erpt_p->pe_hdl,
- (pcie_cap_ptr + PCIE_ROOTSTS));
- pcie_rc_regs->pcie_rc_ctl = pci_config_get16(erpt_p->pe_hdl,
- (pcie_cap_ptr + PCIE_ROOTCTL));
- }
-
- if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV))
- return;
-
- pcie_adv_regs = pcie_regs->pcie_adv_regs;
-
- pcie_ecap_ptr = pcie_adv_regs->pcie_adv_cap_ptr;
-
- pcie_adv_regs->pcie_ue_status = pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_UCE_STS);
- if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK)
- pcie_adv_regs->pcie_adv_vflags |= PCIE_UE_STATUS_VALID;
-
- pcie_adv_regs->pcie_ue_mask = pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_UCE_MASK);
- pcie_adv_regs->pcie_ue_sev = pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_UCE_SERV);
- pcie_adv_regs->pcie_adv_ctl = pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_CTL);
- pcie_adv_regs->pcie_ue_hdr0 = pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_HDR_LOG);
- if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) {
- int i;
- pcie_adv_regs->pcie_adv_vflags |= PCIE_UE_HDR_VALID;
-
- for (i = 0; i < 3; i++) {
- pcie_adv_regs->pcie_ue_hdr[i] = pci_config_get32(
- erpt_p->pe_hdl, pcie_ecap_ptr + PCIE_AER_HDR_LOG +
- (4 * (i + 1)));
- }
- }
-
- pcie_adv_regs->pcie_ce_status = pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_CE_STS);
- if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK)
- pcie_adv_regs->pcie_adv_vflags |= PCIE_CE_STATUS_VALID;
-
- pcie_adv_regs->pcie_ce_mask = pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_CE_MASK);
-
- /*
- * If pci express to pci bridge then grab the bridge
- * error registers.
- */
- if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) {
- pcie_adv_bdg_error_regs_t *pcie_bdg_regs =
- pcie_adv_regs->pcie_adv_bdg_regs;
-
- pcie_bdg_regs->pcie_sue_status =
- pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_SUCE_STS);
- pcie_bdg_regs->pcie_sue_mask =
- pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_SUCE_MASK);
- if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK)
- pcie_adv_regs->pcie_adv_vflags |= PCIE_SUE_STATUS_VALID;
- pcie_bdg_regs->pcie_sue_hdr0 = pci_config_get32(erpt_p->pe_hdl,
- (pcie_ecap_ptr + PCIE_AER_SHDR_LOG));
-
- if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK) {
- int i;
-
- pcie_adv_regs->pcie_adv_vflags |= PCIE_SUE_HDR_VALID;
-
- for (i = 0; i < 3; i++) {
- pcie_bdg_regs->pcie_sue_hdr[i] =
- pci_config_get32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_SHDR_LOG +
- (4 * (i + 1)));
- }
- }
- }
- /*
- * If PCI Express root complex then grab the root complex
- * error registers.
- */
- if (erpt_p->pe_dflags & PCIEX_RC_DEV) {
- pcie_adv_rc_error_regs_t *pcie_rc_regs =
- pcie_adv_regs->pcie_adv_rc_regs;
-
- pcie_rc_regs->pcie_rc_err_cmd = pci_config_get32(erpt_p->pe_hdl,
- (pcie_ecap_ptr + PCIE_AER_RE_CMD));
- pcie_rc_regs->pcie_rc_err_status =
- pci_config_get32(erpt_p->pe_hdl,
- (pcie_ecap_ptr + PCIE_AER_RE_STS));
- if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK)
- pcie_adv_regs->pcie_adv_vflags |=
- PCIE_RC_ERR_STATUS_VALID;
- pcie_rc_regs->pcie_rc_ce_src_id =
- pci_config_get16(erpt_p->pe_hdl,
- (pcie_ecap_ptr + PCIE_AER_CE_SRC_ID));
- pcie_rc_regs->pcie_rc_ue_src_id =
- pci_config_get16(erpt_p->pe_hdl,
- (pcie_ecap_ptr + PCIE_AER_ERR_SRC_ID));
- if (pci_config_check(erpt_p->pe_hdl, fme_flag) == DDI_FM_OK)
- pcie_adv_regs->pcie_adv_vflags |= PCIE_SRC_ID_VALID;
- }
-}
-
/*ARGSUSED*/
static void
pci_regs_gather(dev_info_t *dip, pci_erpt_t *erpt_p, int fme_flag)
@@ -438,14 +227,8 @@ pci_regs_gather(dev_info_t *dip, pci_erpt_t *erpt_p, int fme_flag)
PCI_BDG_CTRL_VALID;
}
- /*
- * If pci express device grab pci express error registers and
- * check for advanced error reporting features and grab them if
- * available.
- */
- if (erpt_p->pe_dflags & PCIEX_DEV)
- pcie_regs_gather(erpt_p, fme_flag);
- else if (erpt_p->pe_dflags & PCIX_DEV)
+ /* If pci-x device grab error registers */
+ if (erpt_p->pe_dflags & PCIX_DEV)
pcix_regs_gather(erpt_p, erpt_p->pe_regs, fme_flag);
}
@@ -475,17 +258,16 @@ pcix_regs_clear(pci_erpt_t *erpt_p, void *pe_regs)
if (PCIX_ECC_VER_CHECK(pcix_bdg_regs->pcix_bdg_ver)) {
pcix_ecc_regs_t *pcix_bdg_ecc_regs;
- /*
- * PCI Express to PCI-X bridges only implement the
- * secondary side of the PCI-X ECC registers, bit one is
- * read-only so we make sure we do not write to it.
- */
- if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) {
+ for (i = 0; i < 2; i++) {
pcix_bdg_ecc_regs =
- pcix_bdg_regs->pcix_bdg_ecc_regs[1];
+ pcix_bdg_regs->pcix_bdg_ecc_regs[i];
if (pcix_bdg_ecc_regs->pcix_ecc_vflags &
PCIX_ERR_ECC_STS_VALID) {
+ pci_config_put32(erpt_p->pe_hdl,
+ (pcix_bdg_cap_ptr +
+ PCI_PCIX_BDG_ECC_STATUS),
+ i);
pci_config_put32(erpt_p->pe_hdl,
(pcix_bdg_cap_ptr +
@@ -493,29 +275,8 @@ pcix_regs_clear(pci_erpt_t *erpt_p, void *pe_regs)
pcix_bdg_ecc_regs->
pcix_ecc_ctlstat);
}
- pcix_bdg_ecc_regs->pcix_ecc_vflags = 0x0;
- } else {
- for (i = 0; i < 2; i++) {
- pcix_bdg_ecc_regs =
- pcix_bdg_regs->pcix_bdg_ecc_regs[i];
-
-
- if (pcix_bdg_ecc_regs->pcix_ecc_vflags &
- PCIX_ERR_ECC_STS_VALID) {
- pci_config_put32(erpt_p->pe_hdl,
- (pcix_bdg_cap_ptr +
- PCI_PCIX_BDG_ECC_STATUS),
- i);
-
- pci_config_put32(erpt_p->pe_hdl,
- (pcix_bdg_cap_ptr +
- PCI_PCIX_BDG_ECC_STATUS),
- pcix_bdg_ecc_regs->
- pcix_ecc_ctlstat);
- }
- pcix_bdg_ecc_regs->pcix_ecc_vflags =
- 0x0;
- }
+ pcix_bdg_ecc_regs->pcix_ecc_vflags =
+ 0x0;
}
}
} else {
@@ -547,79 +308,12 @@ pcix_regs_clear(pci_erpt_t *erpt_p, void *pe_regs)
}
static void
-pcie_regs_clear(pci_erpt_t *erpt_p)
-{
- pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
- uint8_t pcie_cap_ptr;
- pcie_adv_error_regs_t *pcie_adv_regs;
- uint16_t pcie_ecap_ptr;
-
- pcie_cap_ptr = pcie_regs->pcie_cap_ptr;
-
- if (pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID)
- pci_config_put16(erpt_p->pe_hdl, pcie_cap_ptr + PCIE_DEVSTS,
- pcie_regs->pcie_err_status);
-
- pcie_regs->pcie_vflags = 0x0;
-
- if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) &&
- (erpt_p->pe_dflags & PCIX_DEV))
- pcix_regs_clear(erpt_p, pcie_regs->pcix_bdg_regs);
-
- if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV))
- return;
-
- pcie_adv_regs = pcie_regs->pcie_adv_regs;
-
- pcie_ecap_ptr = pcie_adv_regs->pcie_adv_cap_ptr;
-
- if (pcie_adv_regs->pcie_adv_vflags & PCIE_UE_STATUS_VALID)
- pci_config_put32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_UCE_STS,
- pcie_adv_regs->pcie_ue_status);
-
- if (pcie_adv_regs->pcie_adv_vflags & PCIE_CE_STATUS_VALID)
- pci_config_put32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_CE_STS,
- pcie_adv_regs->pcie_ce_status);
-
-
- if (erpt_p->pe_dflags & PCIEX_2PCI_DEV) {
- pcie_adv_bdg_error_regs_t *pcie_bdg_regs =
- pcie_adv_regs->pcie_adv_bdg_regs;
-
-
- if (pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_STATUS_VALID)
- pci_config_put32(erpt_p->pe_hdl,
- pcie_ecap_ptr + PCIE_AER_SUCE_STS,
- pcie_bdg_regs->pcie_sue_status);
- }
- /*
- * If PCI Express root complex then clear the root complex
- * error registers.
- */
- if (erpt_p->pe_dflags & PCIEX_RC_DEV) {
- pcie_adv_rc_error_regs_t *pcie_rc_regs =
- pcie_adv_regs->pcie_adv_rc_regs;
-
-
- if (pcie_adv_regs->pcie_adv_vflags & PCIE_RC_ERR_STATUS_VALID)
- pci_config_put32(erpt_p->pe_hdl,
- (pcie_ecap_ptr + PCIE_AER_RE_STS),
- pcie_rc_regs->pcie_rc_err_status);
- }
- pcie_adv_regs->pcie_adv_vflags = 0x0;
-}
-
-static void
pci_regs_clear(pci_erpt_t *erpt_p)
{
/*
* Finally clear the error bits
*/
- if (erpt_p->pe_dflags & PCIEX_DEV)
- pcie_regs_clear(erpt_p);
- else if (erpt_p->pe_dflags & PCIX_DEV)
+ if (erpt_p->pe_dflags & PCIX_DEV)
pcix_regs_clear(erpt_p, erpt_p->pe_regs);
if (erpt_p->pe_pci_regs->pci_vflags & PCI_ERR_STATUS_VALID)
@@ -651,11 +345,13 @@ pci_regs_clear(pci_erpt_t *erpt_p)
static void
pcix_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p)
{
- uint8_t pcix_cap_ptr;
+ uint16_t pcix_cap_ptr = PCI_CAP_NEXT_PTR_NULL;
+ ddi_acc_handle_t eh;
int i;
- pcix_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "pcix-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
+ if (pci_config_setup(dip, &eh) != DDI_SUCCESS) {
+ (void) PCI_CAP_LOCATE(eh, PCI_CAP_ID_PCIX, &pcix_cap_ptr);
+ }
if (pcix_cap_ptr != PCI_CAP_NEXT_PTR_NULL)
erpt_p->pe_dflags |= PCIX_DEV;
@@ -694,190 +390,6 @@ pcix_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p)
}
}
-static void
-pcie_ereport_setup(dev_info_t *dip, pci_erpt_t *erpt_p)
-{
- pcie_error_regs_t *pcie_regs;
- pcie_adv_error_regs_t *pcie_adv_regs;
- uint8_t pcix_cap_ptr;
- uint8_t pcie_cap_ptr;
- uint16_t pcie_ecap_ptr;
- uint16_t dev_type = 0;
-
- /*
- * The following sparc specific code should be removed once the pci_cap
- * interfaces create the necessary properties for us.
- */
-#if defined(__sparc)
- ushort_t status;
- uint32_t slot_cap;
- uint8_t cap_ptr = 0;
- uint8_t cap_id = 0;
- uint32_t hdr, hdr_next_ptr, hdr_cap_id;
- uint16_t offset = P2ALIGN(PCIE_EXT_CAP, 4);
- uint16_t aer_ptr = 0;
-
- cap_ptr = pci_config_get8(erpt_p->pe_hdl, PCI_CONF_CAP_PTR);
- if (pci_config_check(erpt_p->pe_hdl, DDI_FM_ERR_UNEXPECTED) ==
- DDI_FM_OK) {
- while ((cap_id = pci_config_get8(erpt_p->pe_hdl, cap_ptr)) !=
- 0xff) {
- if (cap_id == PCI_CAP_ID_PCIX) {
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
- "pcix-capid-pointer", cap_ptr);
- }
- if (cap_id == PCI_CAP_ID_PCI_E) {
- status = pci_config_get16(erpt_p->pe_hdl, cap_ptr + 2);
- if (status & PCIE_PCIECAP_SLOT_IMPL) {
- /* offset 14h is Slot Cap Register */
- slot_cap = pci_config_get32(erpt_p->pe_hdl,
- cap_ptr + PCIE_SLOTCAP);
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
- "pcie-slotcap-reg", slot_cap);
- }
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
- "pcie-capid-reg", pci_config_get16(erpt_p->pe_hdl,
- cap_ptr + PCIE_PCIECAP));
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
- "pcie-capid-pointer", cap_ptr);
-
- }
- if ((cap_ptr = pci_config_get8(erpt_p->pe_hdl,
- cap_ptr + 1)) == 0xff || cap_ptr == 0 ||
- (pci_config_check(erpt_p->pe_hdl,
- DDI_FM_ERR_UNEXPECTED) != DDI_FM_OK))
- break;
- }
- }
-
-#endif
-
- pcix_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "pcix-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
-
- if (pcix_cap_ptr != PCI_CAP_NEXT_PTR_NULL)
- erpt_p->pe_dflags |= PCIX_DEV;
-
- pcie_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
-
- if (pcie_cap_ptr != PCI_CAP_NEXT_PTR_NULL) {
- erpt_p->pe_dflags |= PCIEX_DEV;
- erpt_p->pe_regs = kmem_zalloc(sizeof (pcie_error_regs_t),
- KM_SLEEP);
- pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
- pcie_regs->pcie_cap_ptr = pcie_cap_ptr;
- }
-
- if (!(erpt_p->pe_dflags & PCIEX_DEV))
- return;
-
- /*
- * Don't currently need to check for version here because we are
- * compliant with PCIE 1.0a which is version 0 and is guaranteed
- * software compatibility with future versions. We will need to
- * add errors for new detectors/features which are added in newer
- * revisions [sec 7.8.2].
- */
- pcie_regs->pcie_cap = pci_config_get16(erpt_p->pe_hdl,
- pcie_regs->pcie_cap_ptr + PCIE_PCIECAP);
-
- dev_type = pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK;
-
- if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) &&
- (erpt_p->pe_dflags & PCIX_DEV)) {
- int i;
-
- pcie_regs->pcix_bdg_regs =
- kmem_zalloc(sizeof (pcix_bdg_error_regs_t), KM_SLEEP);
-
- pcie_regs->pcix_bdg_regs->pcix_bdg_cap_ptr = pcix_cap_ptr;
- pcie_regs->pcix_bdg_regs->pcix_bdg_ver =
- pci_config_get16(erpt_p->pe_hdl,
- pcix_cap_ptr + PCI_PCIX_SEC_STATUS) & PCI_PCIX_VER_MASK;
-
- if (PCIX_ECC_VER_CHECK(pcie_regs->pcix_bdg_regs->pcix_bdg_ver))
- for (i = 0; i < 2; i++)
- pcie_regs->pcix_bdg_regs->pcix_bdg_ecc_regs[i] =
- kmem_zalloc(sizeof (pcix_ecc_regs_t),
- KM_SLEEP);
- }
-
- if (dev_type == PCIE_PCIECAP_DEV_TYPE_ROOT) {
- erpt_p->pe_dflags |= PCIEX_RC_DEV;
- pcie_regs->pcie_rc_regs = kmem_zalloc(
- sizeof (pcie_rc_error_regs_t), KM_SLEEP);
- }
- /*
- * The following sparc specific code should be removed once the pci_cap
- * interfaces create the necessary properties for us.
- */
-#if defined(__sparc)
-
- hdr = pci_config_get32(erpt_p->pe_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(erpt_p->pe_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)
- aer_ptr = P2ALIGN(offset, 4);
- if (aer_ptr != PCI_CAP_NEXT_PTR_NULL)
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
- "pcie-aer-pointer", aer_ptr);
-#endif
-
- /*
- * Find and store if this device is capable of pci express
- * advanced errors, if not report an error against the device.
- */
- pcie_ecap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "pcie-aer-pointer", PCI_CAP_NEXT_PTR_NULL);
- if (pcie_ecap_ptr != PCI_CAP_NEXT_PTR_NULL) {
- erpt_p->pe_dflags |= PCIEX_ADV_DEV;
- pcie_regs->pcie_adv_regs = kmem_zalloc(
- sizeof (pcie_adv_error_regs_t), KM_SLEEP);
- pcie_regs->pcie_adv_regs->pcie_adv_cap_ptr = pcie_ecap_ptr;
- }
-
- if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) {
- return;
- }
-
- pcie_adv_regs = pcie_regs->pcie_adv_regs;
-
- if (pcie_adv_regs == NULL)
- return;
- /*
- * Initialize structures for advanced PCI Express devices.
- */
-
- /*
- * Advanced error registers exist for PCI Express to PCI(X) Bridges and
- * may also exist for PCI(X) to PCI Express Bridges, the latter is not
- * well explained in the PCI Express to PCI/PCI-X Bridge Specification
- * 1.0 and will be left out of the current gathering of these registers.
- */
- if (dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) {
- erpt_p->pe_dflags |= PCIEX_2PCI_DEV;
- pcie_adv_regs->pcie_adv_bdg_regs = kmem_zalloc(
- sizeof (pcie_adv_bdg_error_regs_t), KM_SLEEP);
- }
-
- if (erpt_p->pe_dflags & PCIEX_RC_DEV)
- pcie_adv_regs->pcie_adv_rc_regs = kmem_zalloc(
- sizeof (pcie_adv_rc_error_regs_t), KM_SLEEP);
-}
-
/*
* pci_ereport_setup: Detect PCI device type and initialize structures to be
* used to generate ereports based on detected generic device errors.
@@ -952,16 +464,8 @@ pci_ereport_setup(dev_info_t *dip)
goto done;
}
- /*
- * Initialize structures for PCI Express and PCI-X devices.
- * Order matters below and pcie_ereport_setup should preceed
- * pcix_ereport_setup.
- */
- pcie_ereport_setup(dip, erpt_p);
-
- if (!(erpt_p->pe_dflags & PCIEX_DEV)) {
- pcix_ereport_setup(dip, erpt_p);
- }
+ /* Initialize structures for PCI-X devices. */
+ pcix_ereport_setup(dip, erpt_p);
done:
pci_regs_gather(dip, erpt_p, DDI_FM_ERR_UNEXPECTED);
@@ -1011,46 +515,6 @@ pcix_ereport_teardown(pci_erpt_t *erpt_p)
}
}
-static void
-pcie_ereport_teardown(pci_erpt_t *erpt_p)
-{
- pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
-
- if (erpt_p->pe_dflags & PCIEX_ADV_DEV) {
- pcie_adv_error_regs_t *pcie_adv = pcie_regs->pcie_adv_regs;
-
- if (erpt_p->pe_dflags & PCIEX_2PCI_DEV)
- kmem_free(pcie_adv->pcie_adv_bdg_regs,
- sizeof (pcie_adv_bdg_error_regs_t));
- if (erpt_p->pe_dflags & PCIEX_RC_DEV)
- kmem_free(pcie_adv->pcie_adv_rc_regs,
- sizeof (pcie_adv_rc_error_regs_t));
- kmem_free(pcie_adv, sizeof (pcie_adv_error_regs_t));
- }
-
- if (erpt_p->pe_dflags & PCIEX_RC_DEV)
- kmem_free(pcie_regs->pcie_rc_regs,
- sizeof (pcie_rc_error_regs_t));
-
- if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
- if (erpt_p->pe_dflags & PCIX_DEV) {
- uint16_t pcix_ver = pcie_regs->pcix_bdg_regs->
- pcix_bdg_ver;
-
- if (PCIX_ECC_VER_CHECK(pcix_ver)) {
- int i;
- for (i = 0; i < 2; i++)
- kmem_free(pcie_regs->pcix_bdg_regs->
- pcix_bdg_ecc_regs[i],
- sizeof (pcix_ecc_regs_t));
- }
- kmem_free(pcie_regs->pcix_bdg_regs,
- sizeof (pcix_bdg_error_regs_t));
- }
- }
- kmem_free(erpt_p->pe_regs, sizeof (pcie_error_regs_t));
-}
-
void
pci_ereport_teardown(dev_info_t *dip)
{
@@ -1068,9 +532,7 @@ pci_ereport_teardown(dev_info_t *dip)
if (erpt_p == NULL)
return;
- if (erpt_p->pe_dflags & PCIEX_DEV)
- pcie_ereport_teardown(erpt_p);
- else if (erpt_p->pe_dflags & PCIX_DEV)
+ if (erpt_p->pe_dflags & PCIX_DEV)
pcix_ereport_teardown(erpt_p);
pci_config_teardown((ddi_acc_handle_t *)&erpt_p->pe_hdl);
if (erpt_p->pe_dflags & PCI_BRIDGE_DEV)
@@ -1084,289 +546,6 @@ pci_ereport_teardown(dev_info_t *dip)
* The following sparc specific code should be removed once the pci_cap
* interfaces create the necessary properties for us.
*/
-#if defined(__sparc)
- (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcix-capid-pointer");
- (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-slotcap-reg");
- (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-capid-reg");
- (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-capid-pointer");
- (void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "pcie-aer-pointer");
-#endif
-}
-
-static void
-pcie_ereport_post(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p,
- char *buf, int errtype)
-{
- pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
- pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs;
- pcie_adv_rc_error_regs_t *pcie_adv_rc_regs;
-
- switch (errtype) {
- case PCIEX_TYPE_CE:
- ddi_fm_ereport_post(dip, buf, derr->fme_ena,
- DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
- PCIEX_DEVSTS_REG, DATA_TYPE_UINT16,
- pcie_regs->pcie_err_status,
- PCIEX_CE_STATUS_REG, DATA_TYPE_UINT32,
- pcie_adv_regs->pcie_ce_status, NULL);
- break;
- case PCIEX_TYPE_UE:
- ddi_fm_ereport_post(dip, buf, derr->fme_ena,
- DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
- PCIEX_DEVSTS_REG, DATA_TYPE_UINT16,
- pcie_regs->pcie_err_status,
- PCIEX_UE_STATUS_REG, DATA_TYPE_UINT32,
- pcie_adv_regs->pcie_ue_status, PCIEX_UE_SEV_REG,
- DATA_TYPE_UINT32, pcie_adv_regs->pcie_ue_sev,
- PCIEX_ADV_CTL, DATA_TYPE_UINT32,
- pcie_adv_regs->pcie_adv_ctl,
- PCIEX_SRC_ID, DATA_TYPE_UINT16,
- pcie_adv_regs->pcie_adv_bdf,
- PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE,
- (pcie_adv_regs->pcie_adv_bdf != NULL) ?
- 1 : NULL,
-#ifdef DEBUG
- PCIEX_UE_HDR0, DATA_TYPE_UINT32,
- pcie_adv_regs->pcie_ue_hdr0,
- PCIEX_UE_HDR1, DATA_TYPE_UINT32,
- pcie_adv_regs->pcie_ue_hdr[0],
- PCIEX_UE_HDR2, DATA_TYPE_UINT32,
- pcie_adv_regs->pcie_ue_hdr[1],
- PCIEX_UE_HDR3, DATA_TYPE_UINT32,
- pcie_adv_regs->pcie_ue_hdr[2],
-#endif
- NULL);
- break;
- case PCIEX_TYPE_GEN:
- ddi_fm_ereport_post(dip, buf, derr->fme_ena,
- DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8,
- 0, PCIEX_DEVSTS_REG, DATA_TYPE_UINT16,
- pcie_regs->pcie_err_status, NULL);
- break;
- case PCIEX_TYPE_RC_UE_MSG:
- case PCIEX_TYPE_RC_CE_MSG:
- pcie_adv_rc_regs = pcie_adv_regs->pcie_adv_rc_regs;
-
- ddi_fm_ereport_post(dip, buf, derr->fme_ena,
- DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
- PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32,
- pcie_adv_rc_regs->pcie_rc_err_status,
- PCIEX_SRC_ID, DATA_TYPE_UINT16,
- (errtype == PCIEX_TYPE_RC_UE_MSG) ?
- pcie_adv_rc_regs->pcie_rc_ue_src_id :
- pcie_adv_rc_regs->pcie_rc_ce_src_id,
- PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE,
- (errtype == PCIEX_TYPE_RC_UE_MSG) ?
- (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID &&
- pcie_adv_rc_regs->pcie_rc_ue_src_id != 0) :
- (pcie_adv_regs->pcie_adv_vflags & PCIE_SRC_ID_VALID &&
- pcie_adv_rc_regs->pcie_rc_ce_src_id != 0), NULL);
- break;
- case PCIEX_TYPE_RC_MULT_MSG:
- pcie_adv_rc_regs = pcie_adv_regs->pcie_adv_rc_regs;
-
- ddi_fm_ereport_post(dip, buf, derr->fme_ena,
- DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
- PCIEX_ROOT_ERRSTS_REG, DATA_TYPE_UINT32,
- pcie_adv_rc_regs->pcie_rc_err_status, NULL);
- break;
- default:
- break;
- }
-}
-
-/*ARGSUSED*/
-static void
-pcie_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
-{
- pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
- pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs;
- pcie_tlp_hdr_t *ue_hdr0;
- uint32_t *ue_hdr;
- uint64_t addr = NULL;
- int upstream = 0;
- pci_fme_bus_specific_t *pci_fme_bsp =
- (pci_fme_bus_specific_t *)derr->fme_bus_specific;
-
- if (!(pcie_adv_regs->pcie_adv_vflags & PCIE_UE_HDR_VALID))
- return;
-
- ue_hdr0 = (pcie_tlp_hdr_t *)&pcie_adv_regs->pcie_ue_hdr0;
- ue_hdr = pcie_adv_regs->pcie_ue_hdr;
-
- if ((pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK) ==
- PCIE_PCIECAP_DEV_TYPE_ROOT ||
- (pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK) ==
- PCIE_PCIECAP_DEV_TYPE_DOWN)
- upstream = 1;
-
- switch (ue_hdr0->type) {
- case PCIE_TLP_TYPE_MEM:
- case PCIE_TLP_TYPE_MEMLK:
- if ((ue_hdr0->fmt & 0x1) == 0x1) {
- pcie_mem64_t *mem64_tlp = (pcie_mem64_t *)ue_hdr;
-
- addr = (uint64_t)mem64_tlp->addr1 << 32 |
- (uint32_t)mem64_tlp->addr0 << 2;
- pcie_adv_regs->pcie_adv_bdf = mem64_tlp->rid;
- } else {
- pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr;
-
- addr = (uint32_t)memio32_tlp->addr0 << 2;
- pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid;
- }
- if (upstream) {
- pci_fme_bsp->pci_bs_bdf = pcie_adv_regs->pcie_adv_bdf;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID;
- } else if ((pcie_regs->pcie_cap & PCIE_PCIECAP_DEV_TYPE_MASK) ==
- PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
- pci_fme_bsp->pci_bs_bdf = erpt_p->pe_bdf;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID;
- }
- pci_fme_bsp->pci_bs_addr = addr;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_ADDR_VALID;
- pci_fme_bsp->pci_bs_type = upstream ? DMA_HANDLE : ACC_HANDLE;
- break;
-
- case PCIE_TLP_TYPE_IO:
- {
- pcie_memio32_t *memio32_tlp = (pcie_memio32_t *)ue_hdr;
-
- addr = (uint32_t)memio32_tlp->addr0 << 2;
- pcie_adv_regs->pcie_adv_bdf = memio32_tlp->rid;
- if ((pcie_regs->pcie_cap &
- PCIE_PCIECAP_DEV_TYPE_MASK) ==
- PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
- pci_fme_bsp->pci_bs_bdf = erpt_p->pe_bdf;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID;
- }
- pci_fme_bsp->pci_bs_addr = addr;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_ADDR_VALID;
- pci_fme_bsp->pci_bs_type = ACC_HANDLE;
- break;
- }
- case PCIE_TLP_TYPE_CFG0:
- case PCIE_TLP_TYPE_CFG1:
- {
- pcie_cfg_t *cfg_tlp = (pcie_cfg_t *)ue_hdr;
-
- pcie_adv_regs->pcie_adv_bdf = cfg_tlp->rid;
- pci_fme_bsp->pci_bs_bdf = (uint16_t)cfg_tlp->bus << 8 |
- (uint16_t)cfg_tlp->dev << 3 | cfg_tlp->func;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID;
- pci_fme_bsp->pci_bs_type = ACC_HANDLE;
- break;
- }
- case PCIE_TLP_TYPE_MSG:
- {
- pcie_msg_t *msg_tlp = (pcie_msg_t *)ue_hdr;
-
- pcie_adv_regs->pcie_adv_bdf = msg_tlp->rid;
- break;
- }
- case PCIE_TLP_TYPE_CPL:
- case PCIE_TLP_TYPE_CPLLK:
- {
- pcie_cpl_t *cpl_tlp = (pcie_cpl_t *)ue_hdr;
-
- pcie_adv_regs->pcie_adv_bdf = cpl_tlp->cid;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID;
- if (upstream) {
- pci_fme_bsp->pci_bs_bdf = cpl_tlp->cid;
- pci_fme_bsp->pci_bs_type = ACC_HANDLE;
- } else {
- pci_fme_bsp->pci_bs_bdf = cpl_tlp->rid;
- pci_fme_bsp->pci_bs_type = DMA_HANDLE;
- }
- break;
- }
- case PCIE_TLP_TYPE_MSI:
- default:
- break;
- }
-}
-
-/*ARGSUSED*/
-static void
-pcie_pci_check_addr(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p,
- int type)
-{
- pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
- pcie_adv_error_regs_t *pcie_adv_regs = pcie_regs->pcie_adv_regs;
- pcie_adv_bdg_error_regs_t *pcie_bdg_regs =
- pcie_adv_regs->pcie_adv_bdg_regs;
- uint64_t addr = NULL;
- pcix_attr_t *pcie_pci_sue_attr;
- int cmd;
- int dual_addr = 0;
- pci_fme_bus_specific_t *pci_fme_bsp =
- (pci_fme_bus_specific_t *)derr->fme_bus_specific;
-
- if (!(pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_HDR_VALID))
- return;
-
- pcie_pci_sue_attr = (pcix_attr_t *)&pcie_bdg_regs->pcie_sue_hdr0;
- cmd = (pcie_bdg_regs->pcie_sue_hdr[0] >>
- PCIE_AER_SUCE_HDR_CMD_LWR_SHIFT) & PCIE_AER_SUCE_HDR_CMD_LWR_MASK;
-
-cmd_switch:
- addr = pcie_bdg_regs->pcie_sue_hdr[2];
- addr = (addr << PCIE_AER_SUCE_HDR_ADDR_SHIFT) |
- pcie_bdg_regs->pcie_sue_hdr[1];
- switch (cmd) {
- case PCI_PCIX_CMD_IORD:
- case PCI_PCIX_CMD_IOWR:
- pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid;
- if (addr) {
- pci_fme_bsp->pci_bs_addr = addr;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_ADDR_VALID;
- pci_fme_bsp->pci_bs_type = ACC_HANDLE;
- }
- break;
- case PCI_PCIX_CMD_MEMRD_DW:
- case PCI_PCIX_CMD_MEMWR:
- case PCI_PCIX_CMD_MEMRD_BL:
- case PCI_PCIX_CMD_MEMWR_BL:
- case PCI_PCIX_CMD_MEMRDBL:
- case PCI_PCIX_CMD_MEMWRBL:
- pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid;
- if (addr) {
- pci_fme_bsp->pci_bs_addr = addr;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_ADDR_VALID;
- pci_fme_bsp->pci_bs_type = type;
- }
- break;
- case PCI_PCIX_CMD_CFRD:
- case PCI_PCIX_CMD_CFWR:
- pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid;
- /*
- * for type 1 config transaction we can find bdf from address
- */
- if ((addr & 3) == 1) {
- pci_fme_bsp->pci_bs_bdf = (addr >> 8) & 0xffffffff;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID;
- pci_fme_bsp->pci_bs_type = ACC_HANDLE;
- }
- break;
- case PCI_PCIX_CMD_SPL:
- pcie_adv_regs->pcie_adv_bdf = pcie_pci_sue_attr->rid;
- if (type == ACC_HANDLE) {
- pci_fme_bsp->pci_bs_bdf = pcie_adv_regs->pcie_adv_bdf;
- pci_fme_bsp->pci_bs_flags |= PCI_BS_BDF_VALID;
- pci_fme_bsp->pci_bs_type = type;
- }
- break;
- case PCI_PCIX_CMD_DADR:
- cmd = (pcie_bdg_regs->pcie_sue_hdr[0] >>
- PCIE_AER_SUCE_HDR_CMD_UP_SHIFT) &
- PCIE_AER_SUCE_HDR_CMD_UP_MASK;
- if (dual_addr)
- break;
- ++dual_addr;
- goto cmd_switch;
- default:
- break;
- }
}
/*ARGSUSED*/
@@ -1482,51 +661,6 @@ pci_bdg_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
pci_fme_bsp->pci_bs_addr);
}
}
-#if !defined(__sparc)
- /*
- * For x86, many drivers and even user-level code currently get
- * away with accessing bad addresses, getting a UR and getting
- * -1 returned. Unfortunately, we have no control over this, so
- * we will have to treat all URs as nonfatal. Moreover, if the
- * leaf driver is non-hardened, then we don't actually see the
- * UR directly. All we see is a secondary bus master abort at
- * the root complex - so it's this condition that we actually
- * need to treat as nonfatal (providing no other unrelated nfe
- * conditions have also been seen by the root complex).
- */
- if ((erpt_p->pe_dflags & PCIEX_RC_DEV) &&
- (pci_bdg_regs->pci_bdg_sec_stat & PCI_STAT_R_MAST_AB) &&
- !(pci_bdg_regs->pci_bdg_sec_stat & PCI_STAT_S_PERROR)) {
- pcie_error_regs_t *pcie_regs =
- (pcie_error_regs_t *)erpt_p->pe_regs;
- if ((pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID) &&
- !(pcie_regs->pcie_err_status &
- PCIE_DEVSTS_NFE_DETECTED))
- nonfatal++;
- if (erpt_p->pe_dflags & PCIEX_ADV_DEV) {
- pcie_adv_error_regs_t *pcie_adv_regs =
- pcie_regs->pcie_adv_regs;
- pcie_adv_rc_error_regs_t *pcie_rc_regs =
- pcie_adv_regs->pcie_adv_rc_regs;
- if ((pcie_adv_regs->pcie_adv_vflags &
- PCIE_RC_ERR_STATUS_VALID) &&
- (pcie_rc_regs->pcie_rc_err_status &
- PCIE_AER_RE_STS_NFE_MSGS_RCVD)) {
- (void) snprintf(buf, FM_MAX_CLASS,
- "%s.%s-%s", PCI_ERROR_SUBCLASS,
- PCI_SEC_ERROR_SUBCLASS, PCI_MA);
- ddi_fm_ereport_post(dip, buf,
- derr->fme_ena, DDI_NOSLEEP,
- FM_VERSION, DATA_TYPE_UINT8, 0,
- PCI_SEC_CONFIG_STATUS,
- DATA_TYPE_UINT16,
- pci_bdg_regs->pci_bdg_sec_stat,
- PCI_BCNTRL, DATA_TYPE_UINT16,
- pci_bdg_regs->pci_bdg_ctrl, NULL);
- }
- }
- }
-#endif
}
done:
@@ -1834,313 +968,6 @@ pcix_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
(unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
}
-static int
-pcie_rc_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p,
- void *pe_regs)
-{
- pcie_adv_error_regs_t *pcie_adv_regs = (pcie_adv_error_regs_t *)pe_regs;
- int fatal = 0;
- int nonfatal = 0;
- int unknown = 0;
- char buf[FM_MAX_CLASS];
-
- if (pcie_adv_regs->pcie_adv_vflags & PCIE_RC_ERR_STATUS_VALID) {
- pcie_adv_rc_error_regs_t *pcie_rc_regs =
- pcie_adv_regs->pcie_adv_rc_regs;
- int ce, ue, mult_ce, mult_ue, first_ue_fatal, nfe, fe;
-
- ce = pcie_rc_regs->pcie_rc_err_status &
- PCIE_AER_RE_STS_CE_RCVD;
- ue = pcie_rc_regs->pcie_rc_err_status &
- PCIE_AER_RE_STS_FE_NFE_RCVD;
- mult_ce = pcie_rc_regs->pcie_rc_err_status &
- PCIE_AER_RE_STS_MUL_CE_RCVD;
- mult_ue = pcie_rc_regs->pcie_rc_err_status &
- PCIE_AER_RE_STS_MUL_FE_NFE_RCVD;
- first_ue_fatal = pcie_rc_regs->pcie_rc_err_status &
- PCIE_AER_RE_STS_FIRST_UC_FATAL;
- nfe = pcie_rc_regs->pcie_rc_err_status &
- PCIE_AER_RE_STS_NFE_MSGS_RCVD;
- fe = pcie_rc_regs->pcie_rc_err_status &
- PCIE_AER_RE_STS_FE_MSGS_RCVD;
- /*
- * log fatal/nonfatal/corrected messages
- * recieved by root complex
- */
- if (ue && fe)
- fatal++;
-
- if (fe && first_ue_fatal) {
- (void) snprintf(buf, FM_MAX_CLASS,
- "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_FE_MSG);
- pcie_ereport_post(dip, derr, erpt_p, buf,
- PCIEX_TYPE_RC_UE_MSG);
- }
- if (nfe && !first_ue_fatal) {
- (void) snprintf(buf, FM_MAX_CLASS,
- "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_NFE_MSG);
- pcie_ereport_post(dip, derr, erpt_p, buf,
- PCIEX_TYPE_RC_UE_MSG);
- }
- if (ce) {
- (void) snprintf(buf, FM_MAX_CLASS,
- "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_CE_MSG);
- pcie_ereport_post(dip, derr, erpt_p, buf,
- PCIEX_TYPE_RC_CE_MSG);
- }
- if (mult_ce) {
- (void) snprintf(buf, FM_MAX_CLASS,
- "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MCE_MSG);
- pcie_ereport_post(dip, derr, erpt_p, buf,
- PCIEX_TYPE_RC_MULT_MSG);
- }
- if (mult_ue) {
- (void) snprintf(buf, FM_MAX_CLASS,
- "%s.%s", PCIEX_ERROR_SUBCLASS, PCIEX_RC_MUE_MSG);
- pcie_ereport_post(dip, derr, erpt_p, buf,
- PCIEX_TYPE_RC_MULT_MSG);
- }
- }
- return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
- (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
-}
-
-static int
-pcie_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
-{
- int fatal = 0;
- int nonfatal = 0;
- int unknown = 0;
- int ok = 0;
- int type;
- char buf[FM_MAX_CLASS];
- int i;
- pcie_error_regs_t *pcie_regs = (pcie_error_regs_t *)erpt_p->pe_regs;
- pcie_adv_error_regs_t *pcie_adv_regs;
- pcie_adv_bdg_error_regs_t *pcie_bdg_regs;
-
- if ((erpt_p->pe_dflags & PCI_BRIDGE_DEV) &&
- (erpt_p->pe_dflags & PCIX_DEV)) {
- int ret = pcix_bdg_error_report(dip, derr, erpt_p,
- (void *)pcie_regs->pcix_bdg_regs);
- PCI_FM_SEV_INC(ret);
- }
-
- if (!(erpt_p->pe_dflags & PCIEX_ADV_DEV)) {
- if (!(pcie_regs->pcie_vflags & PCIE_ERR_STATUS_VALID))
- goto done;
-#if !defined(__sparc)
- /*
- * On x86 ignore UR on non-RBER leaf devices, pciex-pci
- * bridges and switches.
- */
- if ((pcie_regs->pcie_err_status & PCIE_DEVSTS_UR_DETECTED) &&
- !(pcie_regs->pcie_err_status & PCIE_DEVSTS_FE_DETECTED) &&
- ((erpt_p->pe_dflags & (PCIEX_2PCI_DEV|PCIEX_SWITCH_DEV)) ||
- !(erpt_p->pe_dflags & PCI_BRIDGE_DEV)) &&
- !(pcie_regs->pcie_dev_cap & PCIE_DEVCAP_ROLE_BASED_ERR_REP))
- goto done;
-#endif
- for (i = 0; pciex_nadv_err_tbl[i].err_class != NULL; i++) {
- if (!(pcie_regs->pcie_err_status &
- pciex_nadv_err_tbl[i].reg_bit))
- continue;
-
- (void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
- PCIEX_ERROR_SUBCLASS,
- pciex_nadv_err_tbl[i].err_class);
- pcie_ereport_post(dip, derr, erpt_p, buf,
- PCIEX_TYPE_GEN);
- PCI_FM_SEV_INC(pciex_nadv_err_tbl[i].flags);
- }
- goto done;
- }
-
- pcie_adv_regs = pcie_regs->pcie_adv_regs;
-
- /*
- * Log PCI Express uncorrectable errors
- */
- if (pcie_adv_regs->pcie_adv_vflags & PCIE_UE_STATUS_VALID) {
- for (i = 0; pciex_ue_err_tbl[i].err_class != NULL; i++) {
- if (!(pcie_adv_regs->pcie_ue_status &
- pciex_ue_err_tbl[i].reg_bit))
- continue;
-
- (void) snprintf(buf, FM_MAX_CLASS,
- "%s.%s", PCIEX_ERROR_SUBCLASS,
- pciex_ue_err_tbl[i].err_class);
-
- /*
- * First check for advisary nonfatal conditions
- * - hardware endpoint successfully retrying a cto
- * - hardware endpoint receiving poisoned tlp and
- * dealing with it itself (but not if root complex)
- * If the device has declared these as correctable
- * errors then treat them as such.
- */
- if ((pciex_ue_err_tbl[i].reg_bit == PCIE_AER_UCE_TO ||
- (pciex_ue_err_tbl[i].reg_bit == PCIE_AER_UCE_PTLP &&
- !(erpt_p->pe_dflags & PCIEX_RC_DEV))) &&
- (pcie_regs->pcie_err_status &
- PCIE_DEVSTS_CE_DETECTED) &&
- !(pcie_regs->pcie_err_status &
- PCIE_DEVSTS_NFE_DETECTED)) {
- pcie_ereport_post(dip, derr, erpt_p, buf,
- PCIEX_TYPE_UE);
- continue;
- }
-
-#if !defined(__sparc)
- /*
- * On x86 for leaf devices and pciex-pci bridges,
- * ignore UR on non-RBER devices or on RBER devices when
- * advisory nonfatal.
- */
- if (pciex_ue_err_tbl[i].reg_bit == PCIE_AER_UCE_UR &&
- ((erpt_p->pe_dflags &
- (PCIEX_2PCI_DEV|PCIEX_SWITCH_DEV)) ||
- !(erpt_p->pe_dflags & PCI_BRIDGE_DEV))) {
- if (!(pcie_regs->pcie_dev_cap &
- PCIE_DEVCAP_ROLE_BASED_ERR_REP))
- continue;
- if (!(pcie_regs->pcie_err_status &
- PCIE_DEVSTS_NFE_DETECTED))
- continue;
- }
-#endif
- pcie_adv_regs->pcie_adv_bdf = 0;
- /*
- * Now try and look up handle if
- * - error bit is among PCIE_AER_UCE_LOG_BITS, and
- * - no other PCIE_AER_UCE_LOG_BITS are set, and
- * - error bit is not masked, and
- * - flag is DDI_FM_UNKNOWN
- */
- if ((pcie_adv_regs->pcie_ue_status &
- pcie_aer_uce_log_bits) ==
- pciex_ue_err_tbl[i].reg_bit &&
- !(pciex_ue_err_tbl[i].reg_bit &
- pcie_adv_regs->pcie_ue_mask) &&
- pciex_ue_err_tbl[i].flags == DDI_FM_UNKNOWN)
- pcie_check_addr(dip, derr, erpt_p);
-
- PCI_FM_SEV_INC(pciex_ue_err_tbl[i].flags);
- pcie_ereport_post(dip, derr, erpt_p, buf,
- PCIEX_TYPE_UE);
- }
- }
-
- /*
- * Log PCI Express correctable errors
- */
- if (pcie_adv_regs->pcie_adv_vflags & PCIE_CE_STATUS_VALID) {
- for (i = 0; pciex_ce_err_tbl[i].err_class != NULL; i++) {
- if (!(pcie_adv_regs->pcie_ce_status &
- pciex_ce_err_tbl[i].reg_bit))
- continue;
-
- (void) snprintf(buf, FM_MAX_CLASS,
- "%s.%s", PCIEX_ERROR_SUBCLASS,
- pciex_ce_err_tbl[i].err_class);
- pcie_ereport_post(dip, derr, erpt_p, buf,
- PCIEX_TYPE_CE);
- }
- }
-
- if (!(erpt_p->pe_dflags & PCI_BRIDGE_DEV))
- goto done;
-
- if (erpt_p->pe_dflags & PCIEX_RC_DEV) {
- int ret = pcie_rc_error_report(dip, derr, erpt_p,
- (void *)pcie_adv_regs);
- PCI_FM_SEV_INC(ret);
- }
-
- if (!((erpt_p->pe_dflags & PCIEX_2PCI_DEV) &&
- (pcie_adv_regs->pcie_adv_vflags & PCIE_SUE_STATUS_VALID)))
- goto done;
-
- pcie_bdg_regs = pcie_adv_regs->pcie_adv_bdg_regs;
-
- for (i = 0; pcie_sue_err_tbl[i].err_class != NULL; i++) {
- if ((pcie_bdg_regs->pcie_sue_status &
- pcie_sue_err_tbl[i].reg_bit)) {
- (void) snprintf(buf, FM_MAX_CLASS, "%s.%s",
- PCIEX_ERROR_SUBCLASS,
- pcie_sue_err_tbl[i].err_class);
-
- if ((pcie_bdg_regs->pcie_sue_status &
- pcie_aer_suce_log_bits) !=
- pcie_sue_err_tbl[i].reg_bit ||
- pcie_sue_err_tbl[i].flags != DDI_FM_UNKNOWN) {
- ddi_fm_ereport_post(dip, buf, derr->fme_ena,
- DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
- PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_status,
-#ifdef DEBUG
- PCIEX_SUE_HDR0, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_hdr0,
- PCIEX_SUE_HDR1, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_hdr[0],
- PCIEX_SUE_HDR2, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_hdr[1],
- PCIEX_SUE_HDR3, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_hdr[2],
-#endif
- NULL);
- } else {
- pcie_adv_regs->pcie_adv_bdf = 0;
- switch (pcie_sue_err_tbl[i].reg_bit) {
- case PCIE_AER_SUCE_RCVD_TA:
- case PCIE_AER_SUCE_RCVD_MA:
- case PCIE_AER_SUCE_USC_ERR:
- type = ACC_HANDLE;
- break;
- case PCIE_AER_SUCE_TA_ON_SC:
- case PCIE_AER_SUCE_MA_ON_SC:
- type = DMA_HANDLE;
- break;
- case PCIE_AER_SUCE_UC_DATA_ERR:
- case PCIE_AER_SUCE_PERR_ASSERT:
- if (erpt_p->pe_pci_regs->pci_bdg_regs->
- pci_bdg_sec_stat &
- PCI_STAT_S_PERROR)
- type = ACC_HANDLE;
- else
- type = DMA_HANDLE;
- break;
- }
- pcie_pci_check_addr(dip, derr, erpt_p, type);
- ddi_fm_ereport_post(dip, buf, derr->fme_ena,
- DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8, 0,
- PCIEX_SEC_UE_STATUS, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_status,
- PCIEX_SRC_ID, DATA_TYPE_UINT16,
- pcie_adv_regs->pcie_adv_bdf,
- PCIEX_SRC_VALID, DATA_TYPE_BOOLEAN_VALUE,
- (pcie_adv_regs->pcie_adv_bdf != NULL) ?
- 1 : NULL,
-#ifdef DEBUG
- PCIEX_SUE_HDR0, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_hdr0,
- PCIEX_SUE_HDR1, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_hdr[0],
- PCIEX_SUE_HDR2, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_hdr[1],
- PCIEX_SUE_HDR3, DATA_TYPE_UINT32,
- pcie_bdg_regs->pcie_sue_hdr[2],
-#endif
- NULL);
- }
- PCI_FM_SEV_INC(pcie_sue_err_tbl[i].flags);
- }
- }
-done:
- return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL :
- (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK)));
-}
-
static void
pci_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
{
@@ -2173,22 +1000,9 @@ pci_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
PCI_CONFIG_COMMAND, DATA_TYPE_UINT16,
erpt_p->pe_pci_regs->pci_cfg_comm, NULL);
- /*
- * The meaning of SERR is different for PCIEX (just
- * implies a message has been sent) so we don't want to
- * treat that one as fatal.
- */
- if ((erpt_p->pe_dflags & PCIEX_DEV) &&
- pci_err_tbl[i].reg_bit == PCI_STAT_S_SYSERR) {
- unknown++;
- } else {
- PCI_FM_SEV_INC(pci_err_tbl[i].flags);
- }
+ PCI_FM_SEV_INC(pci_err_tbl[i].flags);
}
- if (erpt_p->pe_dflags & PCIEX_DEV) {
- int ret = pcie_error_report(dip, derr, erpt_p);
- PCI_FM_SEV_INC(ret);
- } else if (erpt_p->pe_dflags & PCIX_DEV) {
+ if (erpt_p->pe_dflags & PCIX_DEV) {
if (erpt_p->pe_dflags & PCI_BRIDGE_DEV) {
int ret = pcix_bdg_error_report(dip, derr,
erpt_p, erpt_p->pe_regs);
@@ -2224,9 +1038,7 @@ pci_error_report(dev_info_t *dip, ddi_fm_error_t *derr, pci_erpt_t *erpt_p)
*/
if (ret == DDI_FM_UNKNOWN &&
(pci_fme_bsp->pci_bs_flags & PCI_BS_BDF_VALID) &&
- pci_fme_bsp->pci_bs_bdf == erpt_p->pe_bdf &&
- (erpt_p->pe_dflags & PCIEX_DEV) &&
- !(erpt_p->pe_dflags & PCIEX_2PCI_DEV)) {
+ pci_fme_bsp->pci_bs_bdf == erpt_p->pe_bdf) {
ret = ndi_fmc_entry_error_all(dip,
pci_fme_bsp->pci_bs_type, derr);
PCI_FM_SEV_INC(ret);
diff --git a/usr/src/uts/common/sys/pcie_impl.h b/usr/src/uts/common/sys/pcie_impl.h
index 7b350f2588..f3c99ebf9f 100644
--- a/usr/src/uts/common/sys/pcie_impl.h
+++ b/usr/src/uts/common/sys/pcie_impl.h
@@ -85,6 +85,8 @@ extern "C" {
PCIE_IS_BDG(bus_p))
#define PCIE_IS_PCIE_BDG(bus_p) \
(bus_p->bus_dev_type == PCIE_PCIECAP_DEV_TYPE_PCIE2PCI)
+#define PCIE_IS_PCI2PCIE(bus_p) \
+ (bus_p->bus_dev_type == PCIE_PCIECAP_DEV_TYPE_PCI2PCIE)
#define PCIE_IS_PCIE_SEC(bus_p) \
(PCIE_IS_PCIE(bus_p) && PCIE_IS_BDG(bus_p) && !PCIE_IS_PCIE_BDG(bus_p))
#define PCIX_ECC_VERSION_CHECK(bus_p) \
diff --git a/usr/src/uts/common/sys/pcifm.h b/usr/src/uts/common/sys/pcifm.h
index 5302313741..5df5c679c8 100644
--- a/usr/src/uts/common/sys/pcifm.h
+++ b/usr/src/uts/common/sys/pcifm.h
@@ -19,15 +19,13 @@
* 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.
*/
#ifndef _SYS_PCIFM_H
#define _SYS_PCIFM_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/dditypes.h> /* for ddi_acc_handle_t */
#ifdef __cplusplus
@@ -40,11 +38,6 @@ extern "C" {
*/
#define PCI_BRIDGE_DEV 0x02
#define PCIX_DEV 0x04
-#define PCIEX_DEV 0x08
-#define PCIEX_ADV_DEV 0x10
-#define PCIEX_RC_DEV 0x20
-#define PCIEX_2PCI_DEV 0x40
-#define PCIEX_SWITCH_DEV 0x80
/*
* PCI and PCI-X valid flags
@@ -58,17 +51,6 @@ extern "C" {
#define PCIX_BDG_STATUS_VALID 0x40
#define PCIX_BDG_SEC_STATUS_VALID 0x80
-/*
- * PCI Express valid flags
- */
-#define PCIE_ERR_STATUS_VALID 0x1
-#define PCIE_CE_STATUS_VALID 0x2
-#define PCIE_UE_STATUS_VALID 0x4
-#define PCIE_RC_ERR_STATUS_VALID 0x8
-#define PCIE_SUE_STATUS_VALID 0x10
-#define PCIE_SUE_HDR_VALID 0x20
-#define PCIE_UE_HDR_VALID 0x40
-#define PCIE_SRC_ID_VALID 0x80
/*
* PCI(-X) structures used (by pci_ereport_setup, pci_ereport_post, and
@@ -125,59 +107,6 @@ typedef struct pcix_bdg_error_regs {
} pcix_bdg_error_regs_t;
/*
- * PCI Express error register structures used (by pci_ereport_setup,
- * pci_ereport_post, and pci_ereport_teardown) to gather and report errors
- * detected by PCI Express compliant devices.
- */
-typedef struct pcie_adv_bdg_error_regs {
- uint32_t pcie_sue_status; /* pcie bridge secondary ue status */
- uint32_t pcie_sue_mask; /* pcie bridge secondary ue mask */
- uint32_t pcie_sue_sev; /* pcie bridge secondary ue severity */
- uint32_t pcie_sue_hdr0; /* pcie bridge secondary ue hdr log */
- uint32_t pcie_sue_hdr[3]; /* pcie bridge secondary ue hdr log */
-} pcie_adv_bdg_error_regs_t;
-
-typedef struct pcie_adv_rc_error_regs {
- uint32_t pcie_rc_err_status; /* pcie root complex error status reg */
- uint32_t pcie_rc_err_cmd; /* pcie root complex error cmd reg */
- uint16_t pcie_rc_ce_src_id; /* pcie root complex ce source id */
- uint16_t pcie_rc_ue_src_id; /* pcie root complex ue source id */
-} pcie_adv_rc_error_regs_t;
-
-typedef struct pcie_adv_error_regs {
- uint16_t pcie_adv_vflags; /* pcie advanced error valid flags */
- uint16_t pcie_adv_cap_ptr; /* pcie advanced capability pointer */
- uint16_t pcie_adv_bdf; /* pcie bdf */
- uint32_t pcie_adv_ctl; /* pcie advanced control reg */
- uint32_t pcie_ce_status; /* pcie ce error status reg */
- uint32_t pcie_ce_mask; /* pcie ce error mask reg */
- uint32_t pcie_ue_status; /* pcie ue error status reg */
- uint32_t pcie_ue_mask; /* pcie ue error mask reg */
- uint32_t pcie_ue_sev; /* pcie ue error severity reg */
- uint32_t pcie_ue_hdr0; /* pcie ue header log */
- uint32_t pcie_ue_hdr[3]; /* pcie ue header log */
- pcie_adv_bdg_error_regs_t *pcie_adv_bdg_regs; /* pcie bridge regs */
- pcie_adv_rc_error_regs_t *pcie_adv_rc_regs; /* pcie rc regs */
-} pcie_adv_error_regs_t;
-
-typedef struct pcie_rc_error_regs {
- uint32_t pcie_rc_status; /* root complex status register */
- uint16_t pcie_rc_ctl; /* root complex control register */
-} pcie_rc_error_regs_t;
-
-typedef struct pcie_error_regs {
- uint16_t pcie_vflags; /* pcie valid flags */
- uint8_t pcie_cap_ptr; /* PCI Express capability pointer */
- uint16_t pcie_cap; /* PCI Express capability register */
- uint16_t pcie_err_status; /* pcie device status register */
- uint16_t pcie_err_ctl; /* pcie error control register */
- uint16_t pcie_dev_cap; /* pcie device capabilities register */
- pcix_bdg_error_regs_t *pcix_bdg_regs; /* pcix bridge regs */
- pcie_rc_error_regs_t *pcie_rc_regs; /* pcie root complex regs */
- pcie_adv_error_regs_t *pcie_adv_regs; /* pcie advanced err regs */
-} pcie_error_regs_t;
-
-/*
* pcie bus specific structure
*/
@@ -211,13 +140,6 @@ typedef struct pci_target_err {
(((x) == DDI_FM_NONFATAL) ? nonfatal++ :\
(((x) == DDI_FM_UNKNOWN) ? unknown++ : ok++));
-#define PCIEX_TYPE_CE 0x0
-#define PCIEX_TYPE_UE 0x1
-#define PCIEX_TYPE_GEN 0x2
-#define PCIEX_TYPE_RC_UE_MSG 0x3
-#define PCIEX_TYPE_RC_CE_MSG 0x4
-#define PCIEX_TYPE_RC_MULT_MSG 0x5
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/i86pc/io/mp_platform_common.c b/usr/src/uts/i86pc/io/mp_platform_common.c
index a796804176..60dd3d683b 100644
--- a/usr/src/uts/i86pc/io/mp_platform_common.c
+++ b/usr/src/uts/i86pc/io/mp_platform_common.c
@@ -1774,12 +1774,14 @@ apic_introp_xlate(dev_info_t *dip, struct intrspec *ispec, int type)
parent_is_pci_or_pciex = 1;
}
- if (parent_is_pci_or_pciex && ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL) !=
- PCI_CAP_NEXT_PTR_NULL) {
- child_is_pciex = 1;
+ if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip,
+ DDI_PROP_DONTPASS, "compatible", (caddr_t)dev_type,
+ &dev_len) == DDI_PROP_SUCCESS) {
+ if (strstr(dev_type, "pciex"))
+ child_is_pciex = 1;
}
+
if (DDI_INTR_IS_MSI_OR_MSIX(type)) {
if ((airqp = apic_find_irq(dip, ispec, type)) != NULL) {
airqp->airq_iflag.bustype =
diff --git a/usr/src/uts/i86pc/io/pci/pci_common.c b/usr/src/uts/i86pc/io/pci/pci_common.c
index 2c12b83938..f1400d195b 100644
--- a/usr/src/uts/i86pc/io/pci/pci_common.c
+++ b/usr/src/uts/i86pc/io/pci/pci_common.c
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* File that has code which is common between pci(7d) and npe(7d)
* It shares the following:
@@ -67,7 +65,6 @@ static void pci_disable_intr(dev_info_t *, dev_info_t *,
extern int (*psm_intr_ops)(dev_info_t *, ddi_intr_handle_impl_t *,
psm_intr_op_t, int *);
-
/*
* pci_name_child:
*
@@ -1581,27 +1578,3 @@ pci_config_rep_wr64(ddi_acc_impl_t *hdlp, uint64_t *host_addr,
pci_config_wr64(hdlp, host_addr++, *dev_addr);
}
}
-
-
-/*
- * Enable Legacy PCI config space access for the following four north bridges
- * Host bridge: AMD HyperTransport Technology Configuration
- * Host bridge: AMD Address Map
- * Host bridge: AMD DRAM Controller
- * Host bridge: AMD Miscellaneous Control
- */
-int
-is_amd_northbridge(dev_info_t *dip)
-{
- int vendor_id, device_id;
-
- vendor_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "vendor-id", -1);
- device_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "device-id", -1);
-
- if (IS_AMD_NTBRIDGE(vendor_id, device_id))
- return (0);
-
- return (1);
-}
diff --git a/usr/src/uts/i86pc/io/pci/pci_common.h b/usr/src/uts/i86pc/io/pci/pci_common.h
index 3b66c23ea7..c5c05d4612 100644
--- a/usr/src/uts/i86pc/io/pci/pci_common.h
+++ b/usr/src/uts/i86pc/io/pci/pci_common.h
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _PCI_PCI_COMMON_H
#define _PCI_PCI_COMMON_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -47,28 +45,6 @@ typedef struct pci_state {
kmutex_t pci_err_mutex;
} pci_state_t;
-/* AMD's northbridges vendor-id and device-ids */
-#define AMD_NTBRDIGE_VID 0x1022 /* AMD vendor-id */
-#define AMD_HT_NTBRIDGE_DID 0x1100 /* HT Configuration */
-#define AMD_AM_NTBRIDGE_DID 0x1101 /* Address Map */
-#define AMD_DC_NTBRIDGE_DID 0x1102 /* DRAM Controller */
-#define AMD_MC_NTBRIDGE_DID 0x1103 /* Misc Controller */
-
-/*
- * Check if the given device is an AMD northbridge
- */
-#define IS_AMD_NTBRIDGE(vid, did) \
- (((vid) == AMD_NTBRDIGE_VID) && \
- (((did) == AMD_HT_NTBRIDGE_DID) || \
- ((did) == AMD_AM_NTBRIDGE_DID) || \
- ((did) == AMD_DC_NTBRIDGE_DID) || \
- ((did) == AMD_MC_NTBRIDGE_DID)))
-
-/*
- * Check if the give device is a PCI northbridge
- */
-int is_amd_northbridge(dev_info_t *dip);
-
/*
* These are the access routines.
* The pci_bus_map sets the handle to point to these in pci(7d).
diff --git a/usr/src/uts/i86pc/io/pciex/npe.c b/usr/src/uts/i86pc/io/pciex/npe.c
index abd3d2d54c..b31a03ae24 100644
--- a/usr/src/uts/i86pc/io/pciex/npe.c
+++ b/usr/src/uts/i86pc/io/pciex/npe.c
@@ -170,6 +170,7 @@ extern void npe_ck804_fix_aer_ptr(ddi_acc_handle_t cfg_hdl);
extern int npe_disable_empty_bridges_workaround(dev_info_t *child);
extern void npe_nvidia_error_mask(ddi_acc_handle_t cfg_hdl);
extern void npe_intel_error_mask(ddi_acc_handle_t cfg_hdl);
+extern boolean_t npe_check_and_set_mmcfg(dev_info_t *dip);
/*
* Module linkage information for the kernel.
@@ -416,25 +417,8 @@ npe_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
break;
case PCI_ADDR_CONFIG:
- /*
- * Check for AMD's northbridges
- * AND
- * for any PCI device.
- *
- * This is a workaround fix for
- * AMD-8132's inability to handle MMCFG
- * accesses on Galaxy's PE servers
- * AND
- * to disable MMCFG for any PCI device.
- *
- * If a device is *not* found to have PCIe
- * capability, then assume it is a PCI device.
- */
-
- if (is_amd_northbridge(rdip) == 0 ||
- (ddi_prop_get_int(DDI_DEV_T_ANY, rdip,
- DDI_PROP_DONTPASS, "pcie-capid-pointer",
- PCI_CAP_NEXT_PTR_NULL) == PCI_CAP_NEXT_PTR_NULL)) {
+ /* Check and see if MMCFG is supported */
+ if (!npe_check_and_set_mmcfg(rdip)) {
if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) &&
mp->map_handlep->ah_acc.devacc_attr_access
!= DDI_DEFAULT_ACC) {
@@ -444,6 +428,7 @@ npe_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
return (DDI_SUCCESS);
}
+ pci_rp->pci_size_low = PCIE_CONF_HDR_SIZE;
/* FALLTHROUGH */
case PCI_ADDR_MEM64:
@@ -511,15 +496,8 @@ npe_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
*vaddrp = (caddr_t)offset;
- /*
- * Check for AMD's northbridges, pci devices and
- * devices underneath a pci bridge. This is to setup
- * I/O based config space access.
- */
- if (is_amd_northbridge(rdip) == 0 ||
- (ddi_prop_get_int(DDI_DEV_T_ANY, rdip, DDI_PROP_DONTPASS,
- "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL) ==
- PCI_CAP_NEXT_PTR_NULL)) {
+ /* Check if MMCFG is supported */
+ if (!npe_check_and_set_mmcfg(rdip)) {
int ret;
if ((ret = pci_fm_acc_setup(hp, offset, len)) ==
diff --git a/usr/src/uts/i86pc/io/pciex/npe_misc.c b/usr/src/uts/i86pc/io/pciex/npe_misc.c
index e017bb42d9..85a14b2f53 100644
--- a/usr/src/uts/i86pc/io/pciex/npe_misc.c
+++ b/usr/src/uts/i86pc/io/pciex/npe_misc.c
@@ -36,6 +36,7 @@
#include <sys/acpica.h>
#include <sys/pci_cap.h>
#include <sys/pcie_impl.h>
+#include <sys/x86_archext.h>
#include <io/pciex/pcie_nvidia.h>
#include <io/pciex/pcie_nb5000.h>
@@ -47,6 +48,8 @@ void npe_ck804_fix_aer_ptr(ddi_acc_handle_t cfg_hdl);
int npe_disable_empty_bridges_workaround(dev_info_t *child);
void npe_nvidia_error_mask(ddi_acc_handle_t cfg_hdl);
void npe_intel_error_mask(ddi_acc_handle_t cfg_hdl);
+boolean_t npe_is_child_pci(dev_info_t *dip);
+boolean_t check_and_set_mmcfg(dev_info_t *dip);
/*
* Default ecfga base address
@@ -56,6 +59,43 @@ int64_t npe_default_ecfga_base = 0xE0000000;
extern uint32_t npe_aer_uce_mask;
extern boolean_t pcie_full_scan;
+/* AMD's northbridges vendor-id and device-ids */
+#define AMD_NTBRDIGE_VID 0x1022 /* AMD vendor-id */
+#define AMD_HT_NTBRIDGE_DID 0x1100 /* HT Configuration */
+#define AMD_AM_NTBRIDGE_DID 0x1101 /* Address Map */
+#define AMD_DC_NTBRIDGE_DID 0x1102 /* DRAM Controller */
+#define AMD_MC_NTBRIDGE_DID 0x1103 /* Misc Controller */
+#define AMD_K10_NTBRIDGE_DID_0 0x1200
+#define AMD_K10_NTBRIDGE_DID_1 0x1201
+#define AMD_K10_NTBRIDGE_DID_2 0x1202
+#define AMD_K10_NTBRIDGE_DID_3 0x1203
+#define AMD_K10_NTBRIDGE_DID_4 0x1204
+
+/*
+ * Check if the given device is an AMD northbridge
+ */
+#define IS_BAD_AMD_NTBRIDGE(vid, did) \
+ (((vid) == AMD_NTBRDIGE_VID) && \
+ (((did) == AMD_HT_NTBRIDGE_DID) || \
+ ((did) == AMD_AM_NTBRIDGE_DID) || \
+ ((did) == AMD_DC_NTBRIDGE_DID) || \
+ ((did) == AMD_MC_NTBRIDGE_DID)))
+
+#define IS_K10_AMD_NTBRIDGE(vid, did) \
+ (((vid) == AMD_NTBRDIGE_VID) && \
+ (((did) == AMD_K10_NTBRIDGE_DID_0) || \
+ ((did) == AMD_K10_NTBRIDGE_DID_1) || \
+ ((did) == AMD_K10_NTBRIDGE_DID_2) || \
+ ((did) == AMD_K10_NTBRIDGE_DID_3) || \
+ ((did) == AMD_K10_NTBRIDGE_DID_4)))
+
+#define MSR_AMD_NB_MMIO_CFG_BADDR 0xc0010058
+#define AMD_MMIO_CFG_BADDR_ADDR_MASK 0xFFFFFFF00000ULL
+#define AMD_MMIO_CFG_BADDR_ENA_MASK 0x000000000001ULL
+#define AMD_MMIO_CFG_BADDR_ENA_ON 0x000000000001ULL
+#define AMD_MMIO_CFG_BADDR_ENA_OFF 0x000000000000ULL
+
+
/*
* Query the MCFG table using ACPI. If MCFG is found, setup the
* 'ecfga-base-address' (Enhanced Configuration Access base address)
@@ -185,3 +225,81 @@ npe_intel_error_mask(ddi_acc_handle_t cfg_hdl) {
pcie_set_aer_uce_mask(regs);
}
}
+
+/*
+ * Check's if this child is a PCI device.
+ * Child is a PCI device if:
+ * parent has a dev_type of "pci"
+ * -and-
+ * child does not have a dev_type of "pciex"
+ *
+ * If the parent is not of dev_type "pci", then assume it is "pciex" and all
+ * children should support using PCIe style MMCFG access.
+ *
+ * If parent's dev_type is "pci" and child is "pciex", then also enable using
+ * PCIe style MMCFG access. This covers the case where NPE is "pci" and a PCIe
+ * RP is beneath.
+ */
+boolean_t
+npe_child_is_pci(dev_info_t *dip) {
+ char *dev_type;
+ boolean_t parent_is_pci, child_is_pciex;
+
+ if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_get_parent(dip),
+ DDI_PROP_DONTPASS, "device_type", &dev_type) ==
+ DDI_PROP_SUCCESS) {
+ parent_is_pci = (strcmp(dev_type, "pci") == 0);
+ ddi_prop_free(dev_type);
+ } else {
+ parent_is_pci = B_FALSE;
+ }
+
+ if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+ "device_type", &dev_type) == DDI_PROP_SUCCESS) {
+ child_is_pciex = (strcmp(dev_type, "pciex") == 0);
+ ddi_prop_free(dev_type);
+ } else {
+ child_is_pciex = B_FALSE;
+ }
+
+ return (parent_is_pci && !child_is_pciex);
+}
+
+/*
+ * Checks to see if MMCFG is supported and enables it if necessary.
+ * Returns: TRUE is MMCFG is support, FLASE is not.
+ *
+ * In general if a device sits below a parent who's "dev_type" is "pciex" the
+ * support MMCFG. Otherwise, default back to legacy IOCFG access.
+ *
+ * Enable Legacy PCI config space access for AMD K8 north bridges.
+ * Host bridge: AMD HyperTransport Technology Configuration
+ * Host bridge: AMD Address Map
+ * Host bridge: AMD DRAM Controller
+ * Host bridge: AMD Miscellaneous Control
+ * These devices do not support MMCFG access.
+ *
+ * Enable MMCFG via msr for AMD K10 north bridges
+ */
+boolean_t
+npe_check_and_set_mmcfg(dev_info_t *dip)
+{
+ int vendor_id, device_id;
+ int64_t data;
+
+ vendor_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+ "vendor-id", -1);
+ device_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+ "device-id", -1);
+
+ if (IS_K10_AMD_NTBRIDGE(vendor_id, device_id)) {
+ data = ddi_prop_get_int64(DDI_DEV_T_ANY, dip, 0,
+ "ecfga-base-address", 0);
+ data &= AMD_MMIO_CFG_BADDR_ADDR_MASK;
+ data |= AMD_MMIO_CFG_BADDR_ENA_ON;
+ wrmsr(MSR_AMD_NB_MMIO_CFG_BADDR, data);
+ }
+
+ return !(npe_child_is_pci(dip) ||
+ IS_BAD_AMD_NTBRIDGE(vendor_id, device_id));
+}
diff --git a/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c b/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c
index 08ab16924b..7ca5da0bb4 100644
--- a/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c
+++ b/usr/src/uts/intel/io/hotplug/pcicfg/pcicfg.c
@@ -35,6 +35,7 @@
#include <sys/autoconf.h>
#include <sys/hwconf.h>
#include <sys/pcie.h>
+#include <sys/pci_cap.h>
#include <sys/ddi.h>
#include <sys/sunndi.h>
#include <sys/hotplug/pci/pcicfg.h>
@@ -2859,8 +2860,8 @@ static int
pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
uint8_t pcie_dev)
{
- int ret, cap_id_loc;
- uint16_t val;
+ int ret;
+ uint16_t cap_id_loc, val;
uint32_t wordval;
uint8_t byteval;
@@ -2985,28 +2986,14 @@ pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
return (ret);
}
}
- if ((cap_id_loc = pcicfg_get_cap(config_handle, PCI_CAP_ID_PCIX)) > 0) {
- /* create the pcix-capid-pointer property */
- if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
- "pcix-capid-pointer", cap_id_loc)) != DDI_SUCCESS)
- return (ret);
- }
- if (pcie_dev && (cap_id_loc = pcicfg_get_cap(config_handle,
- PCI_CAP_ID_PCI_E)) > 0) {
- /* create the pcie-capid-pointer property */
- if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
- "pcie-capid-pointer", cap_id_loc)) != DDI_SUCCESS)
- return (ret);
+ (void) PCI_CAP_LOCATE(config_handle, PCI_CAP_ID_PCI_E, &cap_id_loc);
+ if (pcie_dev && cap_id_loc != PCI_CAP_NEXT_PTR_NULL) {
val = pci_config_get16(config_handle, cap_id_loc +
PCIE_PCIECAP) & PCIE_PCIECAP_SLOT_IMPL;
/* if slot implemented, get physical slot number */
if (val) {
wordval = pci_config_get32(config_handle, cap_id_loc +
PCIE_SLOTCAP);
- /* create the slotcap-reg property */
- if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE,
- dip, "pcie-slotcap-reg", wordval)) != DDI_SUCCESS)
- return (ret);
/* create the property only if slotnum set correctly? */
if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
"physical-slot#", PCIE_SLOTCAP_PHY_SLOT_NUM(
@@ -4496,61 +4483,24 @@ debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3,
}
#endif
-/*
- * given a cap_id, return its cap_id location in config space
- */
-static int
-pcicfg_get_cap(ddi_acc_handle_t config_handle, uint8_t cap_id)
-{
- uint8_t curcap;
- uint_t cap_id_loc;
- uint16_t status;
- int location = -1;
-
- /*
- * Need to check the Status register for ECP support first.
- * Also please note that for type 1 devices, the
- * offset could change. Should support type 1 next.
- */
- status = pci_config_get16(config_handle, PCI_CONF_STAT);
- if (!(status & PCI_STAT_CAP)) {
- return (-1);
- }
- cap_id_loc = pci_config_get8(config_handle, PCI_CONF_CAP_PTR);
-
- /* Walk the list of capabilities */
- while (cap_id_loc) {
-
- curcap = pci_config_get8(config_handle, cap_id_loc);
-
- if (curcap == cap_id) {
- location = cap_id_loc;
- break;
- }
- cap_id_loc = pci_config_get8(config_handle,
- cap_id_loc + 1);
- }
- return (location);
-}
-
/*ARGSUSED*/
static uint8_t
pcicfg_get_nslots(dev_info_t *dip, ddi_acc_handle_t handle)
{
- int cap_id_loc;
+ uint16_t cap_id_loc, slot_id_loc;
uint8_t num_slots = 0;
/* just depend on the pcie_cap for now. */
- if ((cap_id_loc = pcicfg_get_cap(handle, PCI_CAP_ID_PCI_E))
- > 0) {
+ (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_id_loc);
+ (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_SLOT_ID, &slot_id_loc);
+ if (cap_id_loc != PCI_CAP_NEXT_PTR_NULL) {
if (pci_config_get8(handle, cap_id_loc +
PCI_CAP_ID_REGS_OFF) &
PCIE_PCIECAP_SLOT_IMPL)
num_slots = 1;
} else /* not a PCIe switch/bridge. Must be a PCI-PCI[-X] bridge */
- if ((cap_id_loc = pcicfg_get_cap(handle, PCI_CAP_ID_SLOT_ID))
- > 0) {
- uint8_t esr_reg = pci_config_get8(handle, cap_id_loc + 2);
+ if (slot_id_loc != PCI_CAP_NEXT_PTR_NULL) {
+ uint8_t esr_reg = pci_config_get8(handle, slot_id_loc + 2);
num_slots = PCI_CAPSLOT_NSLOTS(esr_reg);
}
/* XXX - need to cover PCI-PCIe bridge with n slots */
@@ -4608,10 +4558,11 @@ static int
pcicfg_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
{
int port_type = -1;
- int cap_loc;
+ uint16_t cap_loc;
/* Note: need to look at the port type information here */
- if ((cap_loc = pcicfg_get_cap(handle, PCI_CAP_ID_PCI_E)) > 0)
+ (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_loc);
+ if (cap_loc != PCI_CAP_NEXT_PTR_NULL)
port_type = pci_config_get16(handle,
cap_loc + PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
diff --git a/usr/src/uts/intel/io/pci/pci_boot.c b/usr/src/uts/intel/io/pci/pci_boot.c
index 761c8f9499..05cf1aecdd 100644
--- a/usr/src/uts/intel/io/pci/pci_boot.c
+++ b/usr/src/uts/intel/io/pci/pci_boot.c
@@ -98,12 +98,14 @@ static void process_devfunc(uchar_t, uchar_t, uchar_t, uchar_t,
static void add_compatible(dev_info_t *, ushort_t, ushort_t,
ushort_t, ushort_t, uchar_t, uint_t, int);
static int add_reg_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int, int);
-static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int);
+static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int,
+ ushort_t);
static void add_model_prop(dev_info_t *, uint_t);
static void add_bus_range_prop(int);
static void add_bus_slot_names_prop(int);
static void add_ppb_ranges_prop(int);
static void add_bus_available_prop(int);
+static int get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id);
static void fix_ppb_res(uchar_t, boolean_t);
static void alloc_res_array();
static void create_ioapic_node(int bus, int dev, int fn, ushort_t vendorid,
@@ -591,6 +593,40 @@ get_parbus_mem_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align)
}
/*
+ * given a cap_id, return its cap_id location in config space
+ */
+static int
+get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id)
+{
+ uint8_t curcap, cap_id_loc;
+ uint16_t status;
+ int location = -1;
+
+ /*
+ * Need to check the Status register for ECP support first.
+ * Also please note that for type 1 devices, the
+ * offset could change. Should support type 1 next.
+ */
+ status = pci_getw(bus, dev, func, PCI_CONF_STAT);
+ if (!(status & PCI_STAT_CAP)) {
+ return (-1);
+ }
+ cap_id_loc = pci_getb(bus, dev, func, PCI_CONF_CAP_PTR);
+
+ /* Walk the list of capabilities */
+ while (cap_id_loc && cap_id_loc != (uint8_t)-1) {
+ curcap = pci_getb(bus, dev, func, cap_id_loc);
+
+ if (curcap == cap_id) {
+ location = cap_id_loc;
+ break;
+ }
+ cap_id_loc = pci_getb(bus, dev, func, cap_id_loc + 1);
+ }
+ return (location);
+}
+
+/*
* Assign valid resources to unconfigured pci(e) bridges. We are trying
* to reprogram the bridge when its
* i) SECBUS == SUBBUS ||
@@ -641,9 +677,8 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
/*
* If pcie bridge, check to see if link is enabled
*/
- cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
- if (cap_ptr != PCI_CAP_NEXT_PTR_NULL) {
+ cap_ptr = get_pci_cap(bus, dev, func, PCI_CAP_ID_PCI_E);
+ if (cap_ptr != -1) {
cmd_reg = pci_getw(bus, dev, func,
(uint16_t)cap_ptr + PCIE_LINKCTL);
if (cmd_reg & PCIE_LINKCTL_LINK_DISABLE) {
@@ -1505,7 +1540,7 @@ process_devfunc(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header,
set_devpm_d0(bus, dev, func);
if ((basecl == PCI_CLASS_BRIDGE) && (subcl == PCI_BRIDGE_PCI))
- add_ppb_props(dip, bus, dev, func, pciex);
+ add_ppb_props(dip, bus, dev, func, pciex, is_pci_bridge);
else {
/*
* Record the non-PPB devices on the bus for possible
@@ -2175,7 +2210,7 @@ done:
static void
add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
- int pciex)
+ int pciex, ushort_t is_pci_bridge)
{
char *dev_type;
int i;
@@ -2206,7 +2241,7 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
pci_bus_res[secbus].dip = dip;
pci_bus_res[secbus].par_bus = bus;
- dev_type = pciex ? "pciex" : "pci";
+ dev_type = (pciex && !is_pci_bridge) ? "pciex" : "pci";
/* setup bus number hierarchy */
pci_bus_res[secbus].sub_bus = subbus;
diff --git a/usr/src/uts/intel/io/pciex/pcie_nvidia.c b/usr/src/uts/intel/io/pciex/pcie_nvidia.c
index 23f3993b9f..b419d2dd81 100644
--- a/usr/src/uts/intel/io/pciex/pcie_nvidia.c
+++ b/usr/src/uts/intel/io/pciex/pcie_nvidia.c
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * 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 booting
*/
@@ -67,10 +65,6 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev,
capsp &= PCI_CAP_PTR_MASK;
cap = (*pci_getb_func)(bus, dev, func, capsp);
- if (cap == PCI_CAP_ID_PCIX && cdip)
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
- "pcix-capid-pointer", capsp);
-
if (cap == PCI_CAP_ID_PCI_E) {
#ifdef DEBUG
if (pci_boot_debug)
@@ -86,7 +80,7 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev,
* device is a PCIe2PCI bridge
*/
*is_pci_bridge =
- ((status & PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) ==
+ ((status & PCIE_PCIECAP_DEV_TYPE_MASK) ==
PCIE_PCIECAP_DEV_TYPE_PCIE2PCI) ? 1 : 0;
/*
@@ -100,11 +94,6 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev,
*slot_number =
PCIE_SLOTCAP_PHY_SLOT_NUM(slot_cap);
- if (cdip)
- (void) ndi_prop_update_int(
- DDI_DEV_T_NONE, cdip,
- "pcie-slotcap-reg", slot_cap);
-
/* Is PCI Express HotPlug capability set? */
if (cdip &&
(slot_cap & PCIE_SLOTCAP_HP_CAPABLE)) {
@@ -115,21 +104,6 @@ check_if_device_is_pciex(dev_info_t *cdip, uchar_t bus, uchar_t dev,
}
}
- /*
- * Can only do I/O based config space access at
- * this early stage. Meaning, one cannot access
- * extended config space i.e. > 256 bytes.
- * So, AER cap_id property will be created much later.
- */
- if (cdip) {
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
- "pcie-capid-reg",
- (*pci_getw_func)(bus, dev, func,
- capsp + PCIE_PCIECAP));
- (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
- "pcie-capid-pointer", capsp);
- }
-
found_pciex = B_TRUE;
}
diff --git a/usr/src/uts/intel/io/pciex/pcie_pci.c b/usr/src/uts/intel/io/pciex/pcie_pci.c
index 918460302d..0da90e8b76 100644
--- a/usr/src/uts/intel/io/pciex/pcie_pci.c
+++ b/usr/src/uts/intel/io/pciex/pcie_pci.c
@@ -211,7 +211,6 @@ typedef struct {
kmutex_t pepb_peek_poke_mutex;
boolean_t pepb_no_aer_msi;
ddi_iblock_cookie_t pepb_fm_ibc;
- int port_type;
} pepb_devstate_t;
/* soft state flags */
@@ -245,9 +244,7 @@ static void pepb_uninitchild(dev_info_t *);
static int pepb_initchild(dev_info_t *child);
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);
+static boolean_t pepb_is_pcie_device_type(dev_info_t *dip);
/* interrupt related declarations */
static int pepb_msi_intr_supported(dev_info_t *, int intr_type);
@@ -360,7 +357,7 @@ pepb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
/*
* Make sure the "device_type" property exists.
*/
- if (pepb_pcie_device_type(devi, &pepb->port_type) == DDI_SUCCESS)
+ if (pepb_is_pcie_device_type(devi))
(void) strcpy(device_type, "pciex");
else
(void) strcpy(device_type, "pci");
@@ -547,7 +544,7 @@ pepb_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
case DDI_CTLOPS_PEEK:
case DDI_CTLOPS_POKE:
- if (pepb->port_type != PCIE_PCIECAP_DEV_TYPE_ROOT)
+ if (!PCIE_IS_RP(PCIE_DIP2BUS(dip)))
return (ddi_ctlops(dip, rdip, ctlop, arg, result));
return (pci_peekpoke_check(dip, rdip, ctlop, arg, result,
ddi_ctlops, &pepb->pepb_err_mutex,
@@ -865,29 +862,15 @@ pepb_restore_config_regs(pepb_devstate_t *pepb_p)
}
}
-static int
-pepb_pcie_device_type(dev_info_t *dip, int *port_type)
+static boolean_t
+pepb_is_pcie_device_type(dev_info_t *dip)
{
- ddi_acc_handle_t handle;
-
- if (pci_config_setup(dip, &handle) != DDI_SUCCESS)
- return (DDI_FAILURE);
- *port_type = pepb_pcie_port_type(dip, handle);
- pci_config_teardown(&handle);
-
- /* No PCIe CAP regs, we are not PCIe device_type */
- if (*port_type < 0)
- return (DDI_FAILURE);
+ pcie_bus_t *bus_p = PCIE_DIP2BUS(dip);
- /* check for all PCIe device_types */
- if ((*port_type == PCIE_PCIECAP_DEV_TYPE_UP) ||
- (*port_type == PCIE_PCIECAP_DEV_TYPE_DOWN) ||
- (*port_type == PCIE_PCIECAP_DEV_TYPE_ROOT) ||
- (*port_type == PCIE_PCIECAP_DEV_TYPE_PCI2PCIE))
- return (DDI_SUCCESS);
-
- return (DDI_FAILURE);
+ if (PCIE_IS_SW(bus_p) || PCIE_IS_RP(bus_p) || PCIE_IS_PCI2PCIE(bus_p))
+ return (B_TRUE);
+ return (B_FALSE);
}
/*
@@ -1183,20 +1166,6 @@ pepb_msi_intr_supported(dev_info_t *dip, int intr_type)
return (DDI_SUCCESS);
}
-static int
-pepb_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
-{
- uint_t cap_loc;
-
- /* Need to look at the port type information here */
- cap_loc = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
-
- return (cap_loc == PCI_CAP_NEXT_PTR_NULL ? -1 :
- pci_config_get16(handle, cap_loc + PCIE_PCIECAP) &
- PCIE_PCIECAP_DEV_TYPE_MASK);
-}
-
/*ARGSUSED*/
int
pepb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
@@ -1214,24 +1183,8 @@ pepb_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap,
static int
pepb_check_slot_disabled(dev_info_t *dip)
{
- int rval = 0;
- uint8_t pcie_cap_ptr;
- ddi_acc_handle_t config_handle;
-
- if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS)
- return (rval);
-
- pcie_cap_ptr = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "pcie-capid-pointer", PCI_CAP_NEXT_PTR_NULL);
-
- if (pcie_cap_ptr != PCI_CAP_NEXT_PTR_NULL) {
- if (pci_config_get16(config_handle,
- pcie_cap_ptr + PCIE_LINKCTL) & PCIE_LINKCTL_LINK_DISABLE)
- rval = 1;
- }
-
- pci_config_teardown(&config_handle);
- return (rval);
+ return ((PCIE_CAP_GET(16, PCIE_DIP2BUS(dip), PCIE_LINKCTL) &
+ PCIE_LINKCTL_LINK_DISABLE) ? 1 : 0);
}
static int
@@ -1682,15 +1635,12 @@ static void
pepb_intel_sw_workaround(dev_info_t *dip)
{
uint16_t vid, regw;
- int port_type;
ddi_acc_handle_t cfg_hdl;
if (pepb_intel_workaround_disable)
return;
- (void) pepb_pcie_device_type(dip, &port_type);
- if (!((port_type == PCIE_PCIECAP_DEV_TYPE_UP) ||
- (port_type == PCIE_PCIECAP_DEV_TYPE_DOWN)))
+ if (!PCIE_IS_SW(PCIE_DIP2BUS(dip)))
return;
(void) pci_config_setup(dip, &cfg_hdl);
diff --git a/usr/src/uts/sun4/io/px/px_fm.c b/usr/src/uts/sun4/io/px/px_fm.c
index 65c1d78d29..3e570f16b6 100644
--- a/usr/src/uts/sun4/io/px/px_fm.c
+++ b/usr/src/uts/sun4/io/px/px_fm.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* PX Fault Management Architecture
*/
@@ -37,6 +35,8 @@
#include <sys/membar.h>
#include "px_obj.h"
+extern uint_t px_ranges_phi_mask;
+
#define PX_PCIE_PANIC_BITS \
(PCIE_AER_UCE_DLP | PCIE_AER_UCE_FCP | PCIE_AER_UCE_TO | \
PCIE_AER_UCE_RO | PCIE_AER_UCE_MTLP | PCIE_AER_UCE_ECRC)
@@ -205,6 +205,8 @@ px_fm_acc_setup(ddi_map_req_t *mp, dev_info_t *rdip, pci_regspec_t *rp)
errp->err_cf = px_err_pio_hdl_check;
break;
default:
+ /* Illegal state, remove the handle from cache */
+ ndi_fmc_remove(rdip, ACC_HANDLE, (void *)hp);
break;
}
} else if (mp->map_op == DDI_MO_UNMAP) {
@@ -268,8 +270,8 @@ px_in_addr_range(dev_info_t *dip, px_ranges_t *ranges_p, uint64_t addr)
{
uint64_t addr_low, addr_high;
- addr_low = ((uint64_t)ranges_p->parent_high << 32) |
- (uint64_t)ranges_p->parent_low;
+ addr_low = (uint64_t)(ranges_p->parent_high & px_ranges_phi_mask) << 32;
+ addr_low |= (uint64_t)ranges_p->parent_low;
addr_high = addr_low + ((uint64_t)ranges_p->size_high << 32) +
(uint64_t)ranges_p->size_low;