Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/i386/pci Search the entire device-space of bus 0 if...
details: https://anonhg.NetBSD.org/src/rev/a37e84d9a123
branches: trunk
changeset: 509976:a37e84d9a123
user: kanaoka <kanaoka%NetBSD.org@localhost>
date: Wed May 16 08:10:36 2001 +0000
description:
Search the entire device-space of bus 0 if the router device
address is set to 000:00:0, and the compatible router entry
is undefined.
Patch PR port-i386/12880 by Dave Sainty <dave%dtsp.co.nz@localhost>.
diffstat:
sys/arch/i386/pci/pci_intr_fixup.c | 60 ++++++++++++++++++++++++++++++++++---
1 files changed, 55 insertions(+), 5 deletions(-)
diffs (90 lines):
diff -r fa35a5075934 -r a37e84d9a123 sys/arch/i386/pci/pci_intr_fixup.c
--- a/sys/arch/i386/pci/pci_intr_fixup.c Wed May 16 07:53:54 2001 +0000
+++ b/sys/arch/i386/pci/pci_intr_fixup.c Wed May 16 08:10:36 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_intr_fixup.c,v 1.12 2001/04/19 17:32:40 uch Exp $ */
+/* $NetBSD: pci_intr_fixup.c,v 1.13 2001/05/16 08:10:36 kanaoka Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -716,8 +716,21 @@
* specified by the PIR Table, and use the compat ID,
* if present. Otherwise, we have to look for the router
* ourselves (the PCI-ISA bridge).
+ *
+ * A number of buggy BIOS implementations leave the router
+ * entry as 000:00:0, which is typically not the correct
+ * device/function. If the router device address is set to
+ * this value, and the compatible router entry is undefined
+ * (zero is the correct value to indicate undefined), then we
+ * work on the basis it is most likely an error, and search
+ * the entire device-space of bus 0 (but obviously starting
+ * with 000:00:0, in case that really is the right one).
*/
- if (pcibios_pir_header.signature != 0) {
+ if (pcibios_pir_header.signature != 0 &&
+ (pcibios_pir_header.router_bus != 0 ||
+ PIR_DEVFUNC_DEVICE(pcibios_pir_header.router_devfunc) != 0 ||
+ PIR_DEVFUNC_FUNCTION(pcibios_pir_header.router_devfunc) != 0 ||
+ pcibios_pir_header.compat_router != 0)) {
icutag = pci_make_tag(pc, pcibios_pir_header.router_bus,
PIR_DEVFUNC_DEVICE(pcibios_pir_header.router_devfunc),
PIR_DEVFUNC_FUNCTION(pcibios_pir_header.router_devfunc));
@@ -740,6 +753,10 @@
* router.
*/
for (device = 0; device < maxdevs; device++) {
+ const struct pci_quirkdata *qd;
+ int function, nfuncs;
+ pcireg_t bhlcr;
+
icutag = pci_make_tag(pc, 0, device, 0);
icuid = pci_conf_read(pc, icutag, PCI_ID_REG);
@@ -750,10 +767,43 @@
if (PCI_VENDOR(icuid) == 0)
continue;
- piit = pciintr_icu_lookup(icuid);
- if (piit != NULL)
- break;
+ qd = pci_lookup_quirkdata(PCI_VENDOR(icuid),
+ PCI_PRODUCT(icuid));
+
+ bhlcr = pci_conf_read(pc, icutag, PCI_BHLC_REG);
+ if (PCI_HDRTYPE_MULTIFN(bhlcr) ||
+ (qd != NULL &&
+ (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0))
+ nfuncs = 8;
+ else
+ nfuncs = 1;
+
+ for (function = 0; function < nfuncs; function++) {
+ icutag = pci_make_tag(pc, 0, device, function);
+ icuid = pci_conf_read(pc, icutag, PCI_ID_REG);
+
+ /* Invalid vendor ID value? */
+ if (PCI_VENDOR(icuid) == PCI_VENDOR_INVALID)
+ continue;
+ /* Not invalid, but we've done this ~forever */
+ if (PCI_VENDOR(icuid) == 0)
+ continue;
+
+ piit = pciintr_icu_lookup(icuid);
+ if (piit != NULL)
+ goto found;
+ }
}
+
+ /*
+ * Invalidate the ICU ID. If we failed to find the
+ * interrupt router (piit == NULL) we don't want to
+ * display a spurious device address below containing
+ * the product information of the last device we
+ * looked at.
+ */
+ icuid = 0;
+found:
}
if (piit == NULL) {
Home |
Main Index |
Thread Index |
Old Index