summaryrefslogtreecommitdiff
path: root/ls-ecaps.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2017-04-21 14:31:50 -0500
committerMartin Mares <mj@ucw.cz>2017-04-29 20:05:07 +0200
commita1492b88709ee5a1565d82eee0387a42625caeac (patch)
tree7d879fb7ab8e5fa67a1822a03a1e5eb14650ce60 /ls-ecaps.c
parenta662543285001bc75f60e4957b4e505af82db0b4 (diff)
downloadpciutils-a1492b88709ee5a1565d82eee0387a42625caeac.tar.gz
lspci: Decode AER Root Error Command, Root Error Status, Error Source
Decode the AER Root Error Command, Root Error Status, and Error Source Identification registers. Per PCIe r3.1, sec 7.10, these registers are only available for Root Ports and Root Complex Event Collectors, so we have to check the Device/Port Type from the PCIe capability. The difference in the "lspci -vv" output looks like this (for a Root Port): + RootCmd: CERptEn- NFERptEn- FERptEn- + RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd- + FirstFatal- NonFatalMsg- FatalMsg- IntMsg 0 + ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000 Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'ls-ecaps.c')
-rw-r--r--ls-ecaps.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/ls-ecaps.c b/ls-ecaps.c
index 1847e8e..eae3a3d 100644
--- a/ls-ecaps.c
+++ b/ls-ecaps.c
@@ -90,9 +90,10 @@ cap_dsn(struct device *d, int where)
}
static void
-cap_aer(struct device *d, int where)
+cap_aer(struct device *d, int where, int type)
{
u32 l, l0, l1, l2, l3;
+ u16 w;
printf("Advanced Error Reporting\n");
if (verbose < 2)
@@ -143,6 +144,36 @@ cap_aer(struct device *d, int where)
l2 = get_conf_long(d, where + PCI_ERR_HEADER_LOG + 8);
l3 = get_conf_long(d, where + PCI_ERR_HEADER_LOG + 12);
printf("\t\tHeaderLog: %08x %08x %08x %08x\n", l0, l1, l2, l3);
+
+ if (type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_ROOT_EC)
+ {
+ if (!config_fetch(d, where + PCI_ERR_ROOT_COMMAND, 12))
+ return;
+
+ l = get_conf_long(d, where + PCI_ERR_ROOT_COMMAND);
+ printf("\t\tRootCmd: CERptEn%c NFERptEn%c FERptEn%c\n",
+ FLAG(l, PCI_ERR_ROOT_CMD_COR_EN),
+ FLAG(l, PCI_ERR_ROOT_CMD_NONFATAL_EN),
+ FLAG(l, PCI_ERR_ROOT_CMD_FATAL_EN));
+
+ l = get_conf_long(d, where + PCI_ERR_ROOT_STATUS);
+ printf("\t\tRootSta: CERcvd%c MultCERcvd%c UERcvd%c MultUERcvd%c\n"
+ "\t\t\t FirstFatal%c NonFatalMsg%c FatalMsg%c IntMsg %d\n",
+ FLAG(l, PCI_ERR_ROOT_COR_RCV),
+ FLAG(l, PCI_ERR_ROOT_MULTI_COR_RCV),
+ FLAG(l, PCI_ERR_ROOT_UNCOR_RCV),
+ FLAG(l, PCI_ERR_ROOT_MULTI_UNCOR_RCV),
+ FLAG(l, PCI_ERR_ROOT_FIRST_FATAL),
+ FLAG(l, PCI_ERR_ROOT_NONFATAL_RCV),
+ FLAG(l, PCI_ERR_ROOT_FATAL_RCV),
+ PCI_ERR_MSG_NUM(l));
+
+ w = get_conf_word(d, where + PCI_ERR_ROOT_COR_SRC);
+ printf("\t\tErrorSrc: ERR_COR: %04x ", w);
+
+ w = get_conf_word(d, where + PCI_ERR_ROOT_SRC);
+ printf("ERR_FATAL/NONFATAL: %04x\n", w);
+ }
}
static void cap_dpc(struct device *d, int where)
@@ -678,7 +709,7 @@ cap_ptm(struct device *d, int where)
}
void
-show_ext_caps(struct device *d)
+show_ext_caps(struct device *d, int type)
{
int where = 0x100;
char been_there[0x1000];
@@ -707,7 +738,7 @@ show_ext_caps(struct device *d)
switch (id)
{
case PCI_EXT_CAP_ID_AER:
- cap_aer(d, where);
+ cap_aer(d, where, type);
break;
case PCI_EXT_CAP_ID_DPC:
cap_dpc(d, where);