summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorErwin T Tsaur <Erwin.Tsaur@Sun.COM>2008-10-31 13:58:01 -0700
committerErwin T Tsaur <Erwin.Tsaur@Sun.COM>2008-10-31 13:58:01 -0700
commit49fbdd30212f016ddd49c4b5c997b0b827ff0962 (patch)
tree323ce64a26293d267baf34c6c63b4e5c8896af8a /usr/src
parent325e77f4fc68ea7eea21f5e705d3cf89fd3a7e3d (diff)
downloadillumos-gate-49fbdd30212f016ddd49c4b5c997b0b827ff0962.tar.gz
6745976 pcie error handling for adjust for no aer on URs is incorrect.
6725568 PCI extended config space not usable on AMD CPUs 6415305 npe(7) forgot to unmap config space handles ... 6745957 px should use px_ranges_phi_mask for address lookup 6702295 extended-capabilities property missing from leaf device after panic/reboot
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;