summaryrefslogtreecommitdiffstats
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-02-14 22:36:27 +0000
committerjhb <jhb@FreeBSD.org>2007-02-14 22:36:27 +0000
commit97e6505dc87049a8a5586084815993b702f2987a (patch)
treee52868a619ef3fdb7dd16949f2fa1ddf6b0b4361 /sys/dev/pci
parentad38f4e20eb6f0ab76857cf4ad2083b4c4a615e4 (diff)
downloadFreeBSD-src-97e6505dc87049a8a5586084815993b702f2987a.zip
FreeBSD-src-97e6505dc87049a8a5586084815993b702f2987a.tar.gz
Adjust the global MSI blacklisting strategy so we don't have to explicitly
blacklist a bunch of old chipsets. If a system contains a PCI-PCI bridge that supports PCI-X, assume the chipset supports PCI-X. If a system contains a PCI-express root port, assume the chipset supports PCI-express. If the chipset doesn't support either PCI-X or PCI-express, then blacklist it by default. We should now only need to explicitly blacklist PCI-X or PCI-express chipsets that don't properly handle MSI.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/pci.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 494a9b5..fae9ba2 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -217,6 +217,7 @@ struct pci_quirk pci_quirks[] = {
struct devlist pci_devq;
uint32_t pci_generation;
uint32_t pci_numdevs = 0;
+static int pcie_chipset, pcix_chipset;
/* sysctl vars */
SYSCTL_NODE(_hw, OID_AUTO, pci, CTLFLAG_RD, 0, "PCI bus tuning parameters");
@@ -586,6 +587,27 @@ pci_read_extcap(device_t pcib, pcicfgregs *cfg)
cfg->subdevice = val >> 16;
}
break;
+ case PCIY_PCIX: /* PCI-X */
+ /*
+ * Assume we have a PCI-X chipset if we have
+ * at least one PCI-PCI bridge with a PCI-X
+ * capability. Note that some systems with
+ * PCI-express or HT chipsets might match on
+ * this check as well.
+ */
+ if ((cfg->hdrtype & PCIM_HDRTYPE) == 1)
+ pcix_chipset = 1;
+ break;
+ case PCIY_EXPRESS: /* PCI-express */
+ /*
+ * Assume we have a PCI-express chipset if we have
+ * at least one PCI-express root port.
+ */
+ val = REG(ptr + PCIR_EXPRESS_FLAGS, 2);
+ if ((val & PCIM_EXP_FLAGS_TYPE) ==
+ PCIM_EXP_TYPE_ROOT_PORT)
+ pcie_chipset = 1;
+ break;
default:
break;
}
@@ -1404,6 +1426,10 @@ pci_msi_blacklisted(void)
if (!pci_honor_msi_blacklist)
return (0);
+ /* Blacklist all non-PCI-express and non-PCI-X chipsets. */
+ if (!(pcie_chipset || pcix_chipset))
+ return (1);
+
dev = pci_find_bsf(0, 0, 0);
if (dev != NULL)
return (pci_msi_device_blacklisted(dev));
OpenPOWER on IntegriCloud