Disable INTx when enabling MSI/MSIX

This addresses interrupt storms that were noticed after enabling MSI
in drm.  I think this is due to a loose interpretation of the PCI 2.3
spec, which states that a function using MSI is prohibitted from using
INTx.  It appears that some vendors interpretted that to mean that they
should handle it in hardware, while others felt it was the drivers
responsibility.

This fix will also likely resolve interrupt storm related issues with
devices other than drm.

Reviewed by:	jhb@
MFC after:	3 days
This commit is contained in:
Robert Noland 2009-03-02 19:00:41 +00:00
parent 65067cc8b0
commit 5884a846e7
2 changed files with 5 additions and 0 deletions

View file

@ -2864,6 +2864,8 @@ pci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
}
mte->mte_handlers++;
}
/* Disable INTx if we are using MSI/MSIX */
pci_set_command_bit(dev, child, PCIM_CMD_INTxDIS);
bad:
if (error) {
(void)bus_generic_teardown_intr(dev, child, irq,
@ -2918,6 +2920,8 @@ pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
if (mte->mte_handlers == 0)
pci_mask_msix(child, rid - 1);
}
/* Restore INTx capability for MSI/MSIX */
pci_clear_command_bit(dev, child, PCIM_CMD_INTxDIS);
}
error = bus_generic_teardown_intr(dev, child, irq, cookie);
if (device_get_parent(child) == dev && rid > 0)

View file

@ -60,6 +60,7 @@
#define PCIM_CMD_PERRESPEN 0x0040
#define PCIM_CMD_SERRESPEN 0x0100
#define PCIM_CMD_BACKTOBACK 0x0200
#define PCIM_CMD_INTxDIS 0x0400
#define PCIR_STATUS 0x06
#define PCIM_STATUS_CAPPRESENT 0x0010
#define PCIM_STATUS_66CAPABLE 0x0020