• Dean Nelson's avatar
    e1000e: don't inadvertently re-set INTX_DISABLE · 36f2407f
    Dean Nelson authored
    Should e1000_test_msi() fail to see an msi interrupt, it attempts to
    fallback to legacy INTx interrupts. But an error in the code may prevent
    this from happening correctly.
    
    Before calling e1000_test_msi_interrupt(), e1000_test_msi() disables SERR
    by clearing the SERR bit from the just read PCI_COMMAND bits as it writes
    them back out.
    
    Upon return from calling e1000_test_msi_interrupt(), it re-enables SERR
    by writing out the version of PCI_COMMAND it had previously read.
    
    The problem with this is that e1000_test_msi_interrupt() calls
    pci_disable_msi(), which eventually ends up in pci_intx(). And because
    pci_intx() was called with enable set to 1, the INTX_DISABLE bit gets
    cleared from PCI_COMMAND, which is what we want. But when we get back to
    e1000_test_msi(), the INTX_DISABLE bit gets inadvertently re-set because
    of the attempt by e1000_test_msi() to re-enable SERR.
    
    The solution is to have e1000_test_msi() re-read the PCI_COMMAND bits as
    part of its attempt to re-enable SERR.
    
    During debugging/testing of this issue I found that not all the systems
    I ran on had the SERR bit set to begin with. And on some of the systems
    the same could be said for the INTX_DISABLE bit. Needless to say these
    latter systems didn't have a problem falling back to legacy INTx
    interrupts with the code as is.
    Signed-off-by: default avatarDean Nelson <dnelson@redhat.com>
    CC: stable@kernel.org
    Tested-by: default avatarEmil Tantilov <emil.s.tantilov@intel.com>
    Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    36f2407f
netdev.c 165 KB