aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorRobert Noland <rnoland@FreeBSD.org>2009-03-02 19:00:41 +0000
committerRobert Noland <rnoland@FreeBSD.org>2009-03-02 19:00:41 +0000
commit5884a846e72db83a4b5fa452c51ab3409923face (patch)
tree34e309d229993a18a27654764c3f79708bdbbf56 /sys/dev/pci
parent65067cc8b020a2a55018319816f8c6c2d9bcee18 (diff)
downloadsrc-5884a846e72db83a4b5fa452c51ab3409923face.tar.gz
src-5884a846e72db83a4b5fa452c51ab3409923face.zip
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
Notes
Notes: svn path=/head/; revision=189285
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/pci.c4
-rw-r--r--sys/dev/pci/pcireg.h1
2 files changed, 5 insertions, 0 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 8f1e51fb121c..c3a6441d6dc0 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -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)
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index 0b83584f3f5d..04e0f35fcb8d 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -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