sky2: handle advanced error recovery config issues
The PCI AER support may not work for a couple of reasons. It may not be configured into the kernel or there may be a BIOS bug that prevents MMCONFIG from working. If MMCONFIG doesn't work then the PCI registers that control AER will not be accessible via pci_read_config functions; luckly there is another window to access PCI space in the device, so use that. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
ab1a145638
commit
cf06ffb4df
2 changed files with 30 additions and 7 deletions
|
@ -2435,13 +2435,26 @@ static void sky2_hw_intr(struct sky2_hw *hw)
|
|||
|
||||
if (status & Y2_IS_PCI_EXP) {
|
||||
/* PCI-Express uncorrectable Error occurred */
|
||||
int pos = pci_find_aer_capability(hw->pdev);
|
||||
int aer = pci_find_aer_capability(hw->pdev);
|
||||
u32 err;
|
||||
|
||||
pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &err);
|
||||
if (aer) {
|
||||
pci_read_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS,
|
||||
&err);
|
||||
pci_cleanup_aer_uncorrect_error_status(pdev);
|
||||
} else {
|
||||
/* Either AER not configured, or not working
|
||||
* because of bad MMCONFIG, so just do recover
|
||||
* manually.
|
||||
*/
|
||||
err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS);
|
||||
sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
|
||||
0xfffffffful);
|
||||
}
|
||||
|
||||
if (net_ratelimit())
|
||||
dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
|
||||
pci_cleanup_aer_uncorrect_error_status(pdev);
|
||||
|
||||
}
|
||||
|
||||
if (status & Y2_HWE_L1_MASK)
|
||||
|
@ -2799,9 +2812,18 @@ static void sky2_reset(struct sky2_hw *hw)
|
|||
|
||||
cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
|
||||
if (cap) {
|
||||
/* Check for advanced error reporting */
|
||||
pci_cleanup_aer_uncorrect_error_status(pdev);
|
||||
pci_cleanup_aer_correct_error_status(pdev);
|
||||
if (pci_find_aer_capability(pdev)) {
|
||||
/* Check for advanced error reporting */
|
||||
pci_cleanup_aer_uncorrect_error_status(pdev);
|
||||
pci_cleanup_aer_correct_error_status(pdev);
|
||||
} else {
|
||||
dev_warn(&pdev->dev,
|
||||
"PCI Express Advanced Error Reporting"
|
||||
" not configured or MMCONFIG problem?\n");
|
||||
|
||||
sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS,
|
||||
0xfffffffful);
|
||||
}
|
||||
|
||||
/* If error bit is stuck on ignore it */
|
||||
if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
|
||||
|
|
|
@ -247,7 +247,8 @@ enum csr_regs {
|
|||
B3_PA_CTRL = 0x01f0,
|
||||
B3_PA_TEST = 0x01f2,
|
||||
|
||||
Y2_CFG_SPC = 0x1c00,
|
||||
Y2_CFG_SPC = 0x1c00, /* PCI config space region */
|
||||
Y2_CFG_AER = 0x1d00, /* PCI Advanced Error Report region */
|
||||
};
|
||||
|
||||
/* B0_CTST 16 bit Control/Status register */
|
||||
|
|
Loading…
Reference in a new issue