diff options
author | jhb <jhb@FreeBSD.org> | 2007-02-14 22:36:27 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2007-02-14 22:36:27 +0000 |
commit | 97e6505dc87049a8a5586084815993b702f2987a (patch) | |
tree | e52868a619ef3fdb7dd16949f2fa1ddf6b0b4361 /sys/dev | |
parent | ad38f4e20eb6f0ab76857cf4ad2083b4c4a615e4 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/dev/pci/pci.c | 26 |
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)); |