PCI: pcie, aer: report multiple/first error on a device
authorHidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Mon, 7 Sep 2009 08:13:42 +0000 (17:13 +0900)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Wed, 9 Sep 2009 20:49:26 +0000 (13:49 -0700)
Multiple bits might be set in the Uncorrectable Error Status
register.  But aer_print_error_source() only report a error of
the lowest bit set in the error status register.

So print strings for all bits unmasked and set.

And check First Error Pointer to mark the error occured first.
This FEP is not valid when the corresponing bit of the Uncorrectable
Error Status register is not set, or unimplemented or undefined.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
drivers/pci/pcie/aer/aerdrv.h
drivers/pci/pcie/aer/aerdrv_core.c
drivers/pci/pcie/aer/aerdrv_errprint.c

index 0db530db943913bc8d38a34af17283e9f1e72983..436bf79e2739c7cca265b3fbed4e62aa2fa8f0cb 100644 (file)
@@ -61,6 +61,7 @@ struct aer_err_info {
        u16 id;
        int severity;                   /* 0:NONFATAL | 1:FATAL | 2:COR */
        int flags;
+       int first;
        unsigned int status;            /* COR/UNCOR Error Status */
        unsigned int mask;              /* COR/UNCOR Error Mask */
        struct header_log_regs tlp;     /* TLP Header */
index 38b3933200caa23fb751ab4ba534193c843fabe7..9ba1602aebff91cb1d97e8abf54c89d85423e9c6 100644 (file)
@@ -698,7 +698,7 @@ static struct aer_err_source *get_e_source(struct aer_rpc *rpc)
 
 static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
 {
-       int pos;
+       int pos, temp;
 
        info->status = 0;
        info->flags &= ~AER_TLP_HEADER_VALID_FLAG;
@@ -727,6 +727,10 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
                if (!(info->status & ~info->mask))
                        return AER_UNSUCCESS;
 
+               /* Get First Error Pointer */
+               pci_read_config_dword(dev, pos + PCI_ERR_CAP, &temp);
+               info->first = PCI_ERR_CAP_FEP(temp);
+
                if (info->status & AER_LOG_TLP_MASKS) {
                        info->flags |= AER_TLP_HEADER_VALID_FLAG;
                        pci_read_config_dword(dev,
index 41bd1c753ace6c0a99937b6843d6a56d484fef74..0bb91e28d5fee30b91f82c6e015d06a3c262a981 100644 (file)
@@ -169,11 +169,11 @@ static void aer_print_error_source(struct aer_err_info *info)
                        errmsg = aer_uncorrectable_error_string[i];
 
                if (errmsg)
-                       AER_PR(info, "%s\t:\n", errmsg);
+                       AER_PR(info, "%s\t: %s\n", errmsg,
+                               info->first == i ? "First" : "");
                else
-                       AER_PR(info, "Unknown Error Bit %2d  \t:\n", i);
-
-               break;
+                       AER_PR(info, "Unknown Error Bit %2d  \t: %s\n",
+                               i, info->first == i ? "First" : "");
        }
 }