Root/target/linux/cns3xxx/patches-3.3/060-pcie_abort.patch

1--- a/arch/arm/mach-cns3xxx/pcie.c
2+++ b/arch/arm/mach-cns3xxx/pcie.c
3@@ -92,6 +92,78 @@ static void __iomem *cns3xxx_pci_cfg_bas
4     return base + offset;
5 }
6 
7+static inline int check_master_abort(struct pci_bus *bus, unsigned int devfn, int where)
8+{
9+ struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus);
10+
11+ /* check PCI-compatible status register after access */
12+ if (cnspci->linked) {
13+ u32 host_base, sreg, ereg;
14+
15+ host_base = cnspci->cfg_bases[CNS3XXX_HOST_TYPE].virtual;
16+ sreg = __raw_readw(host_base + 0x6) & 0xF900;
17+ ereg = __raw_readl(host_base + 0x104); // Uncorrectable Error Status Reg
18+
19+ if (sreg | ereg) {
20+ /* SREG:
21+ * BIT15 - Detected Parity Error
22+ * BIT14 - Signaled System Error
23+ * BIT13 - Received Master Abort
24+ * BIT12 - Received Target Abort
25+ * BIT11 - Signaled Target Abort
26+ * BIT08 - Master Data Parity Error
27+ *
28+ * EREG:
29+ * BIT20 - Unsupported Request
30+ * BIT19 - ECRC
31+ * BIT18 - Malformed TLP
32+ * BIT17 - Receiver Overflow
33+ * BIT16 - Unexpected Completion
34+ * BIT15 - Completer Abort
35+ * BIT14 - Completion Timeout
36+ * BIT13 - Flow Control Protocol Error
37+ * BIT12 - Poisoned TLP
38+ * BIT04 - Data Link Protocol Error
39+ *
40+ * TODO: see Documentation/pci-error-recovery.txt
41+ * implement error_detected handler
42+ */
43+/*
44+ printk("pci error: %04d:%02x:%02x.%02x sreg=0x%04x ereg=0x%08x", pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), sreg, ereg);
45+ if (sreg & BIT(15)) printk(" <PERR");
46+ if (sreg & BIT(14)) printk(" >SERR");
47+ if (sreg & BIT(13)) printk(" <MABRT");
48+ if (sreg & BIT(12)) printk(" <TABRT");
49+ if (sreg & BIT(11)) printk(" >TABRT");
50+ if (sreg & BIT( 8)) printk(" MPERR");
51+
52+ if (ereg & BIT(20)) printk(" Unsup");
53+ if (ereg & BIT(19)) printk(" ECRC");
54+ if (ereg & BIT(18)) printk(" MTLP");
55+ if (ereg & BIT(17)) printk(" OFLOW");
56+ if (ereg & BIT(16)) printk(" Unex");
57+ if (ereg & BIT(15)) printk(" ABRT");
58+ if (ereg & BIT(14)) printk(" COMPTO");
59+ if (ereg & BIT(13)) printk(" FLOW");
60+ if (ereg & BIT(12)) printk(" PTLP");
61+ if (ereg & BIT( 4)) printk(" DLINK");
62+ printk("\n");
63+*/
64+ pr_debug("%s failed port%d sreg=0x%04x\n", __func__,
65+ cnspci->hw_pci.domain, sreg);
66+
67+ /* make sure the status bits are reset */
68+ __raw_writew(sreg, host_base + 6);
69+ __raw_writel(ereg, host_base + 0x104);
70+ return 1;
71+ }
72+ }
73+ else
74+ return 1;
75+
76+ return 0;
77+}
78+
79 static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
80                    int where, int size, u32 *val)
81 {
82@@ -108,6 +180,11 @@ static int cns3xxx_pci_read_config(struc
83 
84     v = __raw_readl(base);
85 
86+ if (check_master_abort(bus, devfn, where)) {
87+ printk(KERN_ERR "pci error: %04d:%02x:%02x.%02x %02x(%d)= master_abort on read\n", pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
88+ return PCIBIOS_DEVICE_NOT_FOUND;
89+ }
90+
91     if (bus->number == 0 && devfn == 0 &&
92             (where & 0xffc) == PCI_CLASS_REVISION) {
93         /*
94@@ -137,11 +214,19 @@ static int cns3xxx_pci_write_config(stru
95         return PCIBIOS_SUCCESSFUL;
96 
97     v = __raw_readl(base);
98+ if (check_master_abort(bus, devfn, where)) {
99+ printk(KERN_ERR "pci error: %04d:%02x:%02x.%02x %02x(%d)=0x%08x master_abort on read\n", pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
100+ return PCIBIOS_DEVICE_NOT_FOUND;
101+ }
102 
103     v &= ~(mask << shift);
104     v |= (val & mask) << shift;
105 
106     __raw_writel(v, base);
107+ if (check_master_abort(bus, devfn, where)) {
108+ printk(KERN_ERR "pci error: %04d:%02x:%02x.%02x %02x(%d)=0x%08x master_abort on write\n", pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
109+ return PCIBIOS_DEVICE_NOT_FOUND;
110+ }
111 
112     return PCIBIOS_SUCCESSFUL;
113 }
114@@ -360,8 +445,14 @@ static void __init cns3xxx_pcie_hw_init(
115 static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr,
116                       struct pt_regs *regs)
117 {
118+#if 0
119+/* R14_ABORT = PC+4 for XSCALE but not ARM11MPCORE
120+ * ignore imprecise aborts and use PCI-compatible Status register to
121+ * determine errors instead
122+ */
123     if (fsr & (1 << 10))
124         regs->ARM_pc += 4;
125+#endif
126     return 0;
127 }
128 
129

Archive Download this file



interactive