-/* $OpenBSD: pci.c,v 1.5 1996/11/28 23:28:09 niklas Exp $ */
-/* $NetBSD: pci.c,v 1.24 1996/10/21 22:56:55 thorpej Exp $ */
+/* $OpenBSD: pci.c,v 1.6 1997/01/24 19:34:15 niklas Exp $ */
+/* $NetBSD: pci.c,v 1.26 1996/12/05 01:25:30 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Christopher G. Demetriou. All rights reserved.
int pciprint __P((void *, const char *));
int pcisubmatch __P((struct device *, void *, void *));
+/*
+ * Callback so that ISA/EISA bridges can attach their child busses
+ * after PCI configuration is done.
+ *
+ * This works because:
+ * (1) there can be at most one ISA/EISA bridge per PCI bus, and
+ * (2) any ISA/EISA bridges must be attached to primary PCI
+ * busses (i.e. bus zero).
+ *
+ * That boils down to: there can only be one of these outstanding
+ * at a time, it is cleared when configuring PCI bus 0 before any
+ * subdevices have been found, and it is run after all subdevices
+ * of PCI bus 0 have been found.
+ *
+ * This is needed because there are some (legacy) PCI devices which
+ * can show up as ISA/EISA devices as well (the prime example of which
+ * are VGA controllers). If you attach ISA from a PCI-ISA/EISA bridge,
+ * and the bridge is seen before the video board is, the board can show
+ * up as an ISA device, and that can (bogusly) complicate the PCI device's
+ * attach code, or make the PCI device not be properly attached at all.
+ */
+static void (*pci_isa_bridge_callback) __P((void *));
+static void *pci_isa_bridge_callback_arg;
+
int
pcimatch(parent, match, aux)
struct device *parent;
bus = pba->pba_bus;
maxndevs = pci_bus_maxdevs(pc, bus);
+ if (bus == 0)
+ pci_isa_bridge_callback = NULL;
+
for (device = 0; device < maxndevs; device++) {
pcitag_t tag;
pcireg_t id, class, intr, bhlcr;
config_found_sm(self, &pa, pciprint, pcisubmatch);
}
}
+
+ if (bus == 0 && pci_isa_bridge_callback != NULL)
+ (*pci_isa_bridge_callback)(pci_isa_bridge_callback_arg);
}
int
return 0;
}
+
+void
+set_pci_isa_bridge_callback(fn, arg)
+ void (*fn) __P((void *));
+ void *arg;
+{
+
+ if (pci_isa_bridge_callback != NULL)
+ panic("set_pci_isa_bridge_callback");
+ pci_isa_bridge_callback = fn;
+ pci_isa_bridge_callback_arg = arg;
+}
-/* $OpenBSD: pcivar.h,v 1.9 1996/11/28 23:28:14 niklas Exp $ */
-/* $NetBSD: pcivar.h,v 1.16 1996/10/21 22:56:57 thorpej Exp $ */
+/* $OpenBSD: pcivar.h,v 1.10 1997/01/24 19:34:16 niklas Exp $ */
+/* $NetBSD: pcivar.h,v 1.18 1996/12/01 21:02:18 leo Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
/*
* Machine-dependent definitions.
*/
-#if (alpha + i386 != 1)
+#if (alpha + atari + i386 != 1)
ERROR: COMPILING FOR UNSUPPORTED MACHINE, OR MORE THAN ONE.
#endif
#if alpha
#include <alpha/pci/pci_machdep.h>
#endif
+#if atari
+#include <atari/pci/pci_machdep.h>
+#endif
#if i386
#include <i386/pci/pci_machdep.h>
#endif
* Helper functions for autoconfiguration.
*/
void pci_devinfo __P((pcireg_t, pcireg_t, int, char *));
+void set_pci_isa_bridge_callback __P((void (*)(void *), void *));
#endif /* _DEV_PCI_PCIVAR_H_ */