@@ -1608,6 +1608,20 @@ static void aer_disable_irq(struct pci_dev *pdev)
16081608 pci_write_config_dword (pdev , aer + PCI_ERR_ROOT_COMMAND , reg32 );
16091609}
16101610
1611+ static int clear_status_iter (struct pci_dev * dev , void * data )
1612+ {
1613+ u16 devctl ;
1614+
1615+ /* Skip if pci_enable_pcie_error_reporting() hasn't been called yet */
1616+ pcie_capability_read_word (dev , PCI_EXP_DEVCTL , & devctl );
1617+ if (!(devctl & PCI_EXP_AER_FLAGS ))
1618+ return 0 ;
1619+
1620+ pci_aer_clear_status (dev );
1621+ pcie_clear_device_status (dev );
1622+ return 0 ;
1623+ }
1624+
16111625/**
16121626 * aer_enable_rootport - enable Root Port's interrupts when receiving messages
16131627 * @rpc: pointer to a Root Port data structure
@@ -1629,9 +1643,19 @@ static void aer_enable_rootport(struct aer_rpc *rpc)
16291643 pcie_capability_clear_word (pdev , PCI_EXP_RTCTL ,
16301644 SYSTEM_ERROR_INTR_ON_MESG_MASK );
16311645
1632- /* Clear error status */
1646+ /* Clear error status of this Root Port or RCEC */
16331647 pci_read_config_dword (pdev , aer + PCI_ERR_ROOT_STATUS , & reg32 );
16341648 pci_write_config_dword (pdev , aer + PCI_ERR_ROOT_STATUS , reg32 );
1649+
1650+ /* Clear error status of agents reporting to this Root Port or RCEC */
1651+ if (reg32 & AER_ERR_STATUS_MASK ) {
1652+ if (pci_pcie_type (pdev ) == PCI_EXP_TYPE_RC_EC )
1653+ pcie_walk_rcec (pdev , clear_status_iter , NULL );
1654+ else if (pdev -> subordinate )
1655+ pci_walk_bus (pdev -> subordinate , clear_status_iter ,
1656+ NULL );
1657+ }
1658+
16351659 pci_read_config_dword (pdev , aer + PCI_ERR_COR_STATUS , & reg32 );
16361660 pci_write_config_dword (pdev , aer + PCI_ERR_COR_STATUS , reg32 );
16371661 pci_read_config_dword (pdev , aer + PCI_ERR_UNCOR_STATUS , & reg32 );
0 commit comments