summaryrefslogtreecommitdiffstats
path: root/sys/amd64/pci
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2001-08-21 03:10:55 +0000
committerpeter <peter@FreeBSD.org>2001-08-21 03:10:55 +0000
commita6fa1409cbc02046d100fc143d019e076e5ca3e0 (patch)
treeca5e78a7629795acc383adf7359d25c41c82255c /sys/amd64/pci
parent4694b279a2481f10ddcc8cd86ff0e76951aadbb3 (diff)
downloadFreeBSD-src-a6fa1409cbc02046d100fc143d019e076e5ca3e0.zip
FreeBSD-src-a6fa1409cbc02046d100fc143d019e076e5ca3e0.tar.gz
Detect a certain type of PCIBIOS brain damage. For some reason,
some bios vendors took it apon themselves to "censor" the host->pci bridges from PCIBIOS callers, even when the caller explicitly asks for them. This includes certain Compaq machines (eg: DL360) and some laptops. If we detect this, shut down pcibios and revert to using IO port bashing. Under -current, apcica does a better job anyway.
Diffstat (limited to 'sys/amd64/pci')
-rw-r--r--sys/amd64/pci/pci_bus.c18
-rw-r--r--sys/amd64/pci/pci_cfgreg.c13
2 files changed, 31 insertions, 0 deletions
diff --git a/sys/amd64/pci/pci_bus.c b/sys/amd64/pci/pci_bus.c
index dfd4967..b01cc2d 100644
--- a/sys/amd64/pci/pci_bus.c
+++ b/sys/amd64/pci/pci_bus.c
@@ -268,6 +268,7 @@ nexus_pcib_identify(driver_t *driver, device_t parent)
int pcifunchigh;
int found824xx = 0;
int found_orion = 0;
+ int found_pcibios_flaming_death = 0;
device_t child;
devclass_t pci_devclass;
@@ -359,6 +360,23 @@ nexus_pcib_identify(driver_t *driver, device_t parent)
}
/*
+ * This is just freaking brilliant! Some BIOS writers have
+ * decided that we must be forcibly prevented from using
+ * PCIBIOS to query the host->pci bridges. If you try and
+ * access configuration registers, it pretends there is
+ * no pci device at that bus:device:function address.
+ */
+ if (!found && pci_pcibios_active() && !found_pcibios_flaming_death) {
+ /* retry with the old mechanism, or fail */
+ if (pci_kill_pcibios() == 0)
+ return;
+ printf("nexus_pcib_identify: found broken PCIBIOS - disabling it and retrying.\n");
+ printf("nexus_pcib_identify: it is bogusly censoring host->pci bridges.\n");
+ found_pcibios_flaming_death = 1;
+ goto retry;
+ }
+
+ /*
* Make sure we add at least one bridge since some old
* hardware doesn't actually have a host-pci bridge device.
* Note that pci_cfgregopen() thinks we have PCI devices..
diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c
index 7b73486..3538969 100644
--- a/sys/amd64/pci/pci_cfgreg.c
+++ b/sys/amd64/pci/pci_cfgreg.c
@@ -71,6 +71,19 @@ static int pcireg_cfgopen(void);
static struct PIR_table *pci_route_table;
static int pci_route_count;
+int
+pci_pcibios_active(void)
+{
+ return usebios;
+}
+
+int
+pci_kill_pcibios(void)
+{
+ usebios = 0;
+ return pcireg_cfgopen() != 0;
+}
+
/*
* Initialise access to PCI configuration space
*/
OpenPOWER on IntegriCloud