Provide a routine so that ISA/EISA bridges can set up a callback so

that their child busses can be attached after the PCI bus
autoconfiguration for their parent bus 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 (or something like it) 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.

This could be done with machine-dependent code, but as more ports
add support for PCI (and PCI-ISA/EISA bridges) more will need it.
The i386 port could (perhaps should) be converted to use it as well.
This commit is contained in:
cgd 1996-11-23 21:58:16 +00:00
parent f1482e61d8
commit 828f1f3aa1
2 changed files with 45 additions and 2 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pci.c,v 1.24 1996/10/21 22:56:55 thorpej Exp $ */
/* $NetBSD: pci.c,v 1.25 1996/11/23 21:58:16 cgd Exp $ */
/*
* Copyright (c) 1995, 1996 Christopher G. Demetriou. All rights reserved.
@ -55,6 +55,30 @@ struct cfdriver pci_cd = {
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;
@ -101,6 +125,9 @@ pciattach(parent, self, aux)
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;
@ -157,6 +184,9 @@ pciattach(parent, self, aux)
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
@ -292,3 +322,15 @@ pci_mem_find(pc, pcitag, reg, membasep, memsizep, cacheablep)
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;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pcivar.h,v 1.16 1996/10/21 22:56:57 thorpej Exp $ */
/* $NetBSD: pcivar.h,v 1.17 1996/11/23 21:58:17 cgd Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -137,5 +137,6 @@ int pci_mem_find __P((pci_chipset_tag_t, pcitag_t, int, bus_addr_t *,
* 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_ */