]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
PCI: add infrastructure for devices with broken INTx masking
authorBjorn Helgaas <bhelgaas@google.com>
Sat, 16 Jun 2012 20:40:22 +0000 (14:40 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Sat, 16 Jun 2012 20:40:22 +0000 (14:40 -0600)
pci_intx_mask_supported() assumes INTx masking is supported if the
PCI_COMMAND_INTX_DISABLE bit is writable.  But when that bit is set,
some devices don't actually mask INTx or update PCI_STATUS_INTERRUPT
as we expect.

This patch adds a way for quirks to identify these broken devices.

[bhelgaas: split out from Chelsio quirk addition]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/pci.c
drivers/pci/quirks.c
include/linux/pci.h

index 447e83472c01558705d0685f7fd6af17a6f8deef..9ae517a683600d342ddecfbefecbb3bf5e081bf6 100644 (file)
@@ -2876,6 +2876,9 @@ bool pci_intx_mask_supported(struct pci_dev *dev)
        bool mask_supported = false;
        u16 orig, new;
 
+       if (dev->broken_intx_masking)
+               return false;
+
        pci_cfg_access_lock(dev);
 
        pci_read_config_word(dev, PCI_COMMAND, &orig);
index 2a75216775410df88e19fd9faa21e0045c16d15d..cc13415416d70889d615b0a597cdaf0cebb174c8 100644 (file)
@@ -2929,6 +2929,16 @@ static void __devinit disable_igfx_irq(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
 
+/*
+ * Some devices may pass our check in pci_intx_mask_supported if
+ * PCI_COMMAND_INTX_DISABLE works though they actually do not properly
+ * support this feature.
+ */
+static void __devinit quirk_broken_intx_masking(struct pci_dev *dev)
+{
+       dev->broken_intx_masking = 1;
+}
+
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
                          struct pci_fixup *end)
 {
index d8c379dba6adbb36ae9df6c18adea304e2c6b45c..40a039f1dffb189626c362959b70b02e6e8b2dd8 100644 (file)
@@ -324,6 +324,7 @@ struct pci_dev {
        unsigned int    is_hotplug_bridge:1;
        unsigned int    __aer_firmware_first_valid:1;
        unsigned int    __aer_firmware_first:1;
+       unsigned int    broken_intx_masking:1;
        pci_dev_flags_t dev_flags;
        atomic_t        enable_cnt;     /* pci_enable_device has been called */