浏览代码

PCI: pcie, aer: report multiple/first error on a device

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>
Hidetoshi Seto 15 年之前
父节点
当前提交
e7a0d92b19
共有 3 个文件被更改,包括 10 次插入5 次删除
  1. 1 0
      drivers/pci/pcie/aer/aerdrv.h
  2. 5 1
      drivers/pci/pcie/aer/aerdrv_core.c
  3. 4 4
      drivers/pci/pcie/aer/aerdrv_errprint.c

+ 1 - 0
drivers/pci/pcie/aer/aerdrv.h

@@ -61,6 +61,7 @@ struct aer_err_info {
 	u16 id;
 	u16 id;
 	int severity;			/* 0:NONFATAL | 1:FATAL | 2:COR */
 	int severity;			/* 0:NONFATAL | 1:FATAL | 2:COR */
 	int flags;
 	int flags;
+	int first;
 	unsigned int status;		/* COR/UNCOR Error Status */
 	unsigned int status;		/* COR/UNCOR Error Status */
 	unsigned int mask;		/* COR/UNCOR Error Mask */
 	unsigned int mask;		/* COR/UNCOR Error Mask */
 	struct header_log_regs tlp;	/* TLP Header */
 	struct header_log_regs tlp;	/* TLP Header */

+ 5 - 1
drivers/pci/pcie/aer/aerdrv_core.c

@@ -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)
 static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
 {
 {
-	int pos;
+	int pos, temp;
 
 
 	info->status = 0;
 	info->status = 0;
 	info->flags &= ~AER_TLP_HEADER_VALID_FLAG;
 	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))
 		if (!(info->status & ~info->mask))
 			return AER_UNSUCCESS;
 			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) {
 		if (info->status & AER_LOG_TLP_MASKS) {
 			info->flags |= AER_TLP_HEADER_VALID_FLAG;
 			info->flags |= AER_TLP_HEADER_VALID_FLAG;
 			pci_read_config_dword(dev,
 			pci_read_config_dword(dev,

+ 4 - 4
drivers/pci/pcie/aer/aerdrv_errprint.c

@@ -169,11 +169,11 @@ static void aer_print_error_source(struct aer_err_info *info)
 			errmsg = aer_uncorrectable_error_string[i];
 			errmsg = aer_uncorrectable_error_string[i];
 
 
 		if (errmsg)
 		if (errmsg)
-			AER_PR(info, "%s\t:\n", errmsg);
+			AER_PR(info, "%s\t: %s\n", errmsg,
+				info->first == i ? "First" : "");
 		else
 		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" : "");
 	}
 	}
 }
 }