[PATCH 22/22] aer-inject: support multiple device injection and faking fep

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

 



This patch adds 2 new fields to struct aer_error_inj:

 - fep: to fake First Error Pointer in capability register
 - flags: indicate some option for injection
     AER_INJ_CONTINUE: indicates this is a part of multiple injection
      If set, kernel saves injected data and wait next data instead of
      invoking fake aer_irq, until data without this flag is injected.

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

diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 86265b2..67dc877 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -37,8 +37,12 @@ struct aer_error_inj {
 	u32 header_log2;
 	u32 header_log3;
 	u16 domain;
+	u8 fep;
+	u8 flags;
 };
 
+#define AER_INJ_CONTINUE	1
+
 struct aer_error {
 	struct list_head list;
 	u16 domain;
@@ -48,6 +52,7 @@ struct aer_error {
 
 	u32 uncor_status;
 	u32 cor_status;
+	u32 fep;
 	u32 header_log0;
 	u32 header_log1;
 	u32 header_log2;
@@ -151,6 +156,9 @@ static u32 *find_pci_config_dword(struct aer_error *err, int where,
 		target = &err->cor_status;
 		rw1cs = 1;
 		break;
+	case PCI_ERR_CAP:
+		target = &err->fep;
+		break;
 	case PCI_ERR_HEADER_LOG:
 		target = &err->header_log0;
 		break;
@@ -321,7 +329,7 @@ static int aer_inject(struct aer_error_inj *einj)
 	unsigned long flags;
 	unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
 	int pos_cap_err, rp_pos_cap_err;
-	u32 sever, cor_mask, uncor_mask;
+	u32 sever, capfep, cor_mask, uncor_mask;
 	int ret = 0;
 
 	dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
@@ -339,6 +347,7 @@ static int aer_inject(struct aer_error_inj *einj)
 		goto out_put;
 	}
 	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever);
+	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_CAP, &capfep);
 	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_COR_MASK, &cor_mask);
 	pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_MASK,
 			      &uncor_mask);
@@ -376,6 +385,7 @@ static int aer_inject(struct aer_error_inj *einj)
 	err->header_log1 = einj->header_log1;
 	err->header_log2 = einj->header_log2;
 	err->header_log3 = einj->header_log3;
+	err->fep = (capfep & ~0x1f) | (einj->fep & 0x1f);
 
 	if (einj->cor_status && !(einj->cor_status & ~cor_mask)) {
 		ret = -EINVAL;
@@ -424,6 +434,9 @@ static int aer_inject(struct aer_error_inj *einj)
 	}
 	spin_unlock_irqrestore(&inject_lock, flags);
 
+	if (einj->flags & AER_INJ_CONTINUE)
+		goto out_put;
+
 	ret = pci_bus_set_aer_ops(dev->bus);
 	if (ret)
 		goto out_put;
-- 
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