[PATCH 06/22] aerdrv: rework aer_isr_one_error()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Divide tricky for-loop into readable if-blocks.

The logic to set multi_error_valid (to force walking pci bus
hierarchy to find 2nd~ error devices) is changed too, to check
MULTI_{,_UN}COR_RCV bit individually and to force walk only when
it is required.

And rework setting e_info->severity for uncorrectable, not to use
magic numbers.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@xxxxxxxxxxxxxx>
---
 drivers/pci/pcie/aer/aerdrv_core.c |   49 +++++++++++++++++++----------------
 1 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 6fd8f55..b1965b0 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -217,7 +217,7 @@ found:
 /**
  * find_source_device - search through device hierarchy for source device
  * @parent: pointer to Root Port pci_dev data structure
- * @e_info: including detailed error information such like id
+ * @e_info: scratched but includes detailed error information such like id
  *
  * Return 1 if found, otherwise 0.
  *
@@ -229,6 +229,9 @@ static int find_source_device(struct pci_dev *parent,
 	struct pci_dev *dev = parent;
 	int result;
 
+	/* Must reset before use, other than id, severity, multi_error_valid */
+	e_info->error_dev_num = 0;
+
 	/* Is Root Port an agent that sends error message? */
 	result = find_device_iter(dev, e_info);
 	if (result)
@@ -744,11 +747,10 @@ static void aer_isr_one_error(struct pcie_device *p_device,
 		struct aer_err_source *e_src)
 {
 	struct aer_err_info *e_info;
-	int i;
 
 	/* struct aer_err_info might be big, so we allocate it with slab */
 	e_info = kmalloc(sizeof(struct aer_err_info), GFP_KERNEL);
-	if (e_info == NULL) {
+	if (!e_info) {
 		dev_printk(KERN_DEBUG, &p_device->port->dev,
 			"Can't allocate mem when processing AER errors\n");
 		return;
@@ -758,25 +760,28 @@ static void aer_isr_one_error(struct pcie_device *p_device,
 	 * There is a possibility that both correctable error and
 	 * uncorrectable error being logged. Report correctable error first.
 	 */
-	for (i = 1; i & ROOT_ERR_STATUS_MASKS ; i <<= 2) {
-		if (i > 4)
-			break;
-		if (!(e_src->status & i))
-			continue;
-
-		memset(e_info, 0, sizeof(struct aer_err_info));
-
-		/* Init comprehensive error information */
-		if (i & PCI_ERR_ROOT_COR_RCV) {
-			e_info->id = ERR_COR_ID(e_src->id);
-			e_info->severity = AER_CORRECTABLE;
-		} else {
-			e_info->id = ERR_UNCOR_ID(e_src->id);
-			e_info->severity = ((e_src->status >> 6) & 1);
-		}
-		if (e_src->status &
-			(PCI_ERR_ROOT_MULTI_COR_RCV |
-			 PCI_ERR_ROOT_MULTI_UNCOR_RCV))
+	if (e_src->status & PCI_ERR_ROOT_COR_RCV) {
+		e_info->id = ERR_COR_ID(e_src->id);
+		e_info->severity = AER_CORRECTABLE;
+
+		if (e_src->status & PCI_ERR_ROOT_MULTI_COR_RCV)
+			e_info->multi_error_valid = 1;
+
+		aer_print_port_info(p_device->port, e_info);
+
+		if (find_source_device(p_device->port, e_info))
+			aer_process_err_devices(p_device, e_info);
+	}
+
+	if (e_src->status & PCI_ERR_ROOT_UNCOR_RCV) {
+		e_info->id = ERR_UNCOR_ID(e_src->id);
+
+		if (e_src->status & PCI_ERR_ROOT_FATAL_RCV)
+			e_info->severity = AER_FATAL;
+		else
+			e_info->severity = AER_NONFATAL;
+
+		if (e_src->status & PCI_ERR_ROOT_MULTI_UNCOR_RCV)
 			e_info->multi_error_valid = 1;
 
 		aer_print_port_info(p_device->port, e_info);
-- 
1.7.0.4


--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux