diff --git a/sys/amd64/amd64/legacy.c b/sys/amd64/amd64/legacy.c index 8b16d4393c9c..b0bd75666f9d 100644 --- a/sys/amd64/amd64/legacy.c +++ b/sys/amd64/amd64/legacy.c @@ -26,7 +26,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: nexus.c,v 1.10 1999/05/18 20:48:41 peter Exp $ + * $Id: nexus.c,v 1.11 1999/05/30 10:50:57 dfr Exp $ */ /* @@ -75,6 +75,8 @@ static struct rman irq_rman, drq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static void nexus_print_child(device_t, device_t); +static device_t nexus_add_child(device_t bus, int order, const char *name, + int unit); static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int nexus_activate_resource(device_t, device_t, int, int, @@ -99,6 +101,7 @@ static device_method_t nexus_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, nexus_print_child), + DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), @@ -192,9 +195,12 @@ nexus_probe(device_t dev) if (child == 0) panic("nexus_probe apm"); + bus_generic_probe(dev); +#if 0 child = device_add_child(dev, "pcib", 0, 0); if (child == 0) panic("nexus_probe pcib"); +#endif child = device_add_child(dev, "eisa", 0, 0); if (child == 0) @@ -213,6 +219,12 @@ nexus_print_child(device_t bus, device_t child) printf(" on motherboard"); } +static device_t +nexus_add_child(device_t bus, int order, const char *name, int unit) +{ + return device_add_child_ordered(bus, order, name, unit, 0); +} + /* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. diff --git a/sys/amd64/amd64/nexus.c b/sys/amd64/amd64/nexus.c index 8b16d4393c9c..b0bd75666f9d 100644 --- a/sys/amd64/amd64/nexus.c +++ b/sys/amd64/amd64/nexus.c @@ -26,7 +26,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: nexus.c,v 1.10 1999/05/18 20:48:41 peter Exp $ + * $Id: nexus.c,v 1.11 1999/05/30 10:50:57 dfr Exp $ */ /* @@ -75,6 +75,8 @@ static struct rman irq_rman, drq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static void nexus_print_child(device_t, device_t); +static device_t nexus_add_child(device_t bus, int order, const char *name, + int unit); static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int nexus_activate_resource(device_t, device_t, int, int, @@ -99,6 +101,7 @@ static device_method_t nexus_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, nexus_print_child), + DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), @@ -192,9 +195,12 @@ nexus_probe(device_t dev) if (child == 0) panic("nexus_probe apm"); + bus_generic_probe(dev); +#if 0 child = device_add_child(dev, "pcib", 0, 0); if (child == 0) panic("nexus_probe pcib"); +#endif child = device_add_child(dev, "eisa", 0, 0); if (child == 0) @@ -213,6 +219,12 @@ nexus_print_child(device_t bus, device_t child) printf(" on motherboard"); } +static device_t +nexus_add_child(device_t bus, int order, const char *name, int unit) +{ + return device_add_child_ordered(bus, order, name, unit, 0); +} + /* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. diff --git a/sys/amd64/pci/pci_bus.c b/sys/amd64/pci/pci_bus.c index 14ed5258089c..b3253ac68276 100644 --- a/sys/amd64/pci/pci_bus.c +++ b/sys/amd64/pci/pci_bus.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pcibus.c,v 1.41 1997/12/20 09:04:25 se Exp $ + * $Id: pcibus.c,v 1.42 1999/05/18 20:48:43 peter Exp $ * */ @@ -33,6 +33,7 @@ #include #include +#include #include #ifdef PCI_COMPAT @@ -268,13 +269,187 @@ pci_cfgopen(void) static devclass_t pcib_devclass; +static const char * +nexus_pcib_is_host_bridge(pcicfgregs *cfg, + u_int32_t id, u_int8_t class, u_int8_t subclass, + u_int8_t *busnum) +{ + const char *s = "Host to PCI bridge"; + static u_int8_t pxb[4]; /* hack for 450nx */ + + if (class != PCIC_BRIDGE || subclass != PCIS_BRIDGE_HOST) + return NULL; + + *busnum = 0; + + switch (id) { + case 0x12258086: + s = "Intel 824?? host to PCI bridge"; + /* XXX This is a guess */ + *busnum = pci_cfgread(cfg, 0x41, 1); + break; + case 0x71808086: + s = "Intel 82443LX (440 LX) host to PCI bridge"; + break; + case 0x71908086: + s = "Intel 82443BX (440 BX) host to PCI bridge"; + break; + case 0x71928086: + s = "Intel 82443BX host to PCI bridge (AGP disabled)"; + break; + case 0x71a08086: + s = "Intel 82443GX host to PCI bridge"; + break; + case 0x71a18086: + s = "Intel 82443GX host to AGP bridge"; + break; + case 0x71a28086: + s = "Intel 82443GX host to PCI bridge (AGP disabled)"; + break; + case 0x84c48086: + s = "Intel 82454KX/GX (Orion) host to PCI bridge"; + *busnum = pci_cfgread(cfg, 0x4a, 1); + break; + case 0x84ca8086: + /* + * For the 450nx chipset, there is a whole bundle of + * things pretending to be host bridges. The MIOC will + * be seen first and isn't really a pci bridge (the + * actual busses are attached to the PXB's). We need to + * read the registers of the MIOC to figure out the + * bus numbers for the PXB channels. + * + * Since the MIOC doesn't have a pci bus attached, we + * pretend it wasn't there. + */ + pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ + pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ + pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + return NULL; + case 0x84cb8086: + switch (cfg->slot) { + case 0x12: + s = "Intel 82454NX PXB#0, Bus#A"; + *busnum = pxb[0]; + break; + case 0x13: + s = "Intel 82454NX PXB#0, Bus#B"; + *busnum = pxb[1]; + break; + case 0x14: + s = "Intel 82454NX PXB#1, Bus#A"; + *busnum = pxb[2]; + break; + case 0x15: + s = "Intel 82454NX PXB#1, Bus#B"; + *busnum = pxb[3]; + break; + } + break; + + /* SiS -- vendor 0x1039 */ + case 0x04961039: + s = "SiS 85c496"; + break; + case 0x04061039: + s = "SiS 85c501"; + break; + case 0x06011039: + s = "SiS 85c601"; + break; + case 0x55911039: + s = "SiS 5591 host to PCI bridge"; + break; + case 0x00011039: + s = "SiS 5591 host to AGP bridge"; + break; + + /* VLSI -- vendor 0x1004 */ + case 0x00051004: + s = "VLSI 82C592 Host to PCI bridge"; + break; + + /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */ + /* totally. Please let me know if anything wrong. -F */ + /* XXX need info on the MVP3 -- any takers? */ + case 0x05981106: + s = "VIA 82C598MVP (Apollo MVP3) host bridge"; + break; + + /* AcerLabs -- vendor 0x10b9 */ + /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */ + /* id is '10b9" but the register always shows "10b9". -Foxfair */ + case 0x154110b9: + s = "AcerLabs M1541 (Aladdin-V) PCI host bridge"; + break; + + /* OPTi -- vendor 0x1045 */ + case 0xc8221045: + s = "OPTi 82C822 host to PCI Bridge"; + break; + + /* Ross (?) -- vendor 0x1166 */ + case 0x00051166: + s = "Ross (?) host to PCI bridge"; + /* just guessing the secondary bus register number ... */ + *busnum = pci_cfgread(cfg, 0x45, 1); + break; + } + + return s; +} + +/* + * Scan the first pci bus for host-pci bridges and add pcib instances + * to the nexus for each bridge. + */ +static void +nexus_pcib_identify(driver_t *driver, device_t parent) +{ + pcicfgregs probe; + + probe.hose = 0; + probe.bus = 0; + + pci_cfgopen(); + for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { + int pcifunchigh = 0; + for (probe.func = 0; + probe.func <= pcifunchigh; + probe.func++) { + /* + * Read the IDs and class from the device. + */ + u_int32_t id; + u_int8_t class, subclass, busnum; + device_t child; + const char *s; + + id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + if (id == -1) + continue; + class = pci_cfgread(&probe, PCIR_CLASS, 1); + subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + + s = nexus_pcib_is_host_bridge(&probe, id, + class, subclass, + &busnum); + if (s) { + child = BUS_ADD_CHILD(parent, 0, + "pcib", busnum); + device_set_desc(child, s); + } + } + } + +} + static int nexus_pcib_probe(device_t dev) { if (pci_cfgopen() != 0) { - device_set_desc(dev, "PCI host bus adapter"); - - device_add_child(dev, "pci", 0, 0); + device_add_child(dev, "pci", device_get_unit(dev), 0); return 0; } return ENXIO; @@ -282,6 +457,7 @@ nexus_pcib_probe(device_t dev) static device_method_t nexus_pcib_methods[] = { /* Device interface */ + DEVMETHOD(device_identify, nexus_pcib_identify), DEVMETHOD(device_probe, nexus_pcib_probe), DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c index 14ed5258089c..b3253ac68276 100644 --- a/sys/amd64/pci/pci_cfgreg.c +++ b/sys/amd64/pci/pci_cfgreg.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pcibus.c,v 1.41 1997/12/20 09:04:25 se Exp $ + * $Id: pcibus.c,v 1.42 1999/05/18 20:48:43 peter Exp $ * */ @@ -33,6 +33,7 @@ #include #include +#include #include #ifdef PCI_COMPAT @@ -268,13 +269,187 @@ pci_cfgopen(void) static devclass_t pcib_devclass; +static const char * +nexus_pcib_is_host_bridge(pcicfgregs *cfg, + u_int32_t id, u_int8_t class, u_int8_t subclass, + u_int8_t *busnum) +{ + const char *s = "Host to PCI bridge"; + static u_int8_t pxb[4]; /* hack for 450nx */ + + if (class != PCIC_BRIDGE || subclass != PCIS_BRIDGE_HOST) + return NULL; + + *busnum = 0; + + switch (id) { + case 0x12258086: + s = "Intel 824?? host to PCI bridge"; + /* XXX This is a guess */ + *busnum = pci_cfgread(cfg, 0x41, 1); + break; + case 0x71808086: + s = "Intel 82443LX (440 LX) host to PCI bridge"; + break; + case 0x71908086: + s = "Intel 82443BX (440 BX) host to PCI bridge"; + break; + case 0x71928086: + s = "Intel 82443BX host to PCI bridge (AGP disabled)"; + break; + case 0x71a08086: + s = "Intel 82443GX host to PCI bridge"; + break; + case 0x71a18086: + s = "Intel 82443GX host to AGP bridge"; + break; + case 0x71a28086: + s = "Intel 82443GX host to PCI bridge (AGP disabled)"; + break; + case 0x84c48086: + s = "Intel 82454KX/GX (Orion) host to PCI bridge"; + *busnum = pci_cfgread(cfg, 0x4a, 1); + break; + case 0x84ca8086: + /* + * For the 450nx chipset, there is a whole bundle of + * things pretending to be host bridges. The MIOC will + * be seen first and isn't really a pci bridge (the + * actual busses are attached to the PXB's). We need to + * read the registers of the MIOC to figure out the + * bus numbers for the PXB channels. + * + * Since the MIOC doesn't have a pci bus attached, we + * pretend it wasn't there. + */ + pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ + pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ + pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + return NULL; + case 0x84cb8086: + switch (cfg->slot) { + case 0x12: + s = "Intel 82454NX PXB#0, Bus#A"; + *busnum = pxb[0]; + break; + case 0x13: + s = "Intel 82454NX PXB#0, Bus#B"; + *busnum = pxb[1]; + break; + case 0x14: + s = "Intel 82454NX PXB#1, Bus#A"; + *busnum = pxb[2]; + break; + case 0x15: + s = "Intel 82454NX PXB#1, Bus#B"; + *busnum = pxb[3]; + break; + } + break; + + /* SiS -- vendor 0x1039 */ + case 0x04961039: + s = "SiS 85c496"; + break; + case 0x04061039: + s = "SiS 85c501"; + break; + case 0x06011039: + s = "SiS 85c601"; + break; + case 0x55911039: + s = "SiS 5591 host to PCI bridge"; + break; + case 0x00011039: + s = "SiS 5591 host to AGP bridge"; + break; + + /* VLSI -- vendor 0x1004 */ + case 0x00051004: + s = "VLSI 82C592 Host to PCI bridge"; + break; + + /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */ + /* totally. Please let me know if anything wrong. -F */ + /* XXX need info on the MVP3 -- any takers? */ + case 0x05981106: + s = "VIA 82C598MVP (Apollo MVP3) host bridge"; + break; + + /* AcerLabs -- vendor 0x10b9 */ + /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */ + /* id is '10b9" but the register always shows "10b9". -Foxfair */ + case 0x154110b9: + s = "AcerLabs M1541 (Aladdin-V) PCI host bridge"; + break; + + /* OPTi -- vendor 0x1045 */ + case 0xc8221045: + s = "OPTi 82C822 host to PCI Bridge"; + break; + + /* Ross (?) -- vendor 0x1166 */ + case 0x00051166: + s = "Ross (?) host to PCI bridge"; + /* just guessing the secondary bus register number ... */ + *busnum = pci_cfgread(cfg, 0x45, 1); + break; + } + + return s; +} + +/* + * Scan the first pci bus for host-pci bridges and add pcib instances + * to the nexus for each bridge. + */ +static void +nexus_pcib_identify(driver_t *driver, device_t parent) +{ + pcicfgregs probe; + + probe.hose = 0; + probe.bus = 0; + + pci_cfgopen(); + for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { + int pcifunchigh = 0; + for (probe.func = 0; + probe.func <= pcifunchigh; + probe.func++) { + /* + * Read the IDs and class from the device. + */ + u_int32_t id; + u_int8_t class, subclass, busnum; + device_t child; + const char *s; + + id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + if (id == -1) + continue; + class = pci_cfgread(&probe, PCIR_CLASS, 1); + subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + + s = nexus_pcib_is_host_bridge(&probe, id, + class, subclass, + &busnum); + if (s) { + child = BUS_ADD_CHILD(parent, 0, + "pcib", busnum); + device_set_desc(child, s); + } + } + } + +} + static int nexus_pcib_probe(device_t dev) { if (pci_cfgopen() != 0) { - device_set_desc(dev, "PCI host bus adapter"); - - device_add_child(dev, "pci", 0, 0); + device_add_child(dev, "pci", device_get_unit(dev), 0); return 0; } return ENXIO; @@ -282,6 +457,7 @@ nexus_pcib_probe(device_t dev) static device_method_t nexus_pcib_methods[] = { /* Device interface */ + DEVMETHOD(device_identify, nexus_pcib_identify), DEVMETHOD(device_probe, nexus_pcib_probe), DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), diff --git a/sys/i386/i386/legacy.c b/sys/i386/i386/legacy.c index 8b16d4393c9c..b0bd75666f9d 100644 --- a/sys/i386/i386/legacy.c +++ b/sys/i386/i386/legacy.c @@ -26,7 +26,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: nexus.c,v 1.10 1999/05/18 20:48:41 peter Exp $ + * $Id: nexus.c,v 1.11 1999/05/30 10:50:57 dfr Exp $ */ /* @@ -75,6 +75,8 @@ static struct rman irq_rman, drq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static void nexus_print_child(device_t, device_t); +static device_t nexus_add_child(device_t bus, int order, const char *name, + int unit); static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int nexus_activate_resource(device_t, device_t, int, int, @@ -99,6 +101,7 @@ static device_method_t nexus_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, nexus_print_child), + DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), @@ -192,9 +195,12 @@ nexus_probe(device_t dev) if (child == 0) panic("nexus_probe apm"); + bus_generic_probe(dev); +#if 0 child = device_add_child(dev, "pcib", 0, 0); if (child == 0) panic("nexus_probe pcib"); +#endif child = device_add_child(dev, "eisa", 0, 0); if (child == 0) @@ -213,6 +219,12 @@ nexus_print_child(device_t bus, device_t child) printf(" on motherboard"); } +static device_t +nexus_add_child(device_t bus, int order, const char *name, int unit) +{ + return device_add_child_ordered(bus, order, name, unit, 0); +} + /* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. diff --git a/sys/i386/i386/nexus.c b/sys/i386/i386/nexus.c index 8b16d4393c9c..b0bd75666f9d 100644 --- a/sys/i386/i386/nexus.c +++ b/sys/i386/i386/nexus.c @@ -26,7 +26,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: nexus.c,v 1.10 1999/05/18 20:48:41 peter Exp $ + * $Id: nexus.c,v 1.11 1999/05/30 10:50:57 dfr Exp $ */ /* @@ -75,6 +75,8 @@ static struct rman irq_rman, drq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static void nexus_print_child(device_t, device_t); +static device_t nexus_add_child(device_t bus, int order, const char *name, + int unit); static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int nexus_activate_resource(device_t, device_t, int, int, @@ -99,6 +101,7 @@ static device_method_t nexus_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, nexus_print_child), + DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), @@ -192,9 +195,12 @@ nexus_probe(device_t dev) if (child == 0) panic("nexus_probe apm"); + bus_generic_probe(dev); +#if 0 child = device_add_child(dev, "pcib", 0, 0); if (child == 0) panic("nexus_probe pcib"); +#endif child = device_add_child(dev, "eisa", 0, 0); if (child == 0) @@ -213,6 +219,12 @@ nexus_print_child(device_t bus, device_t child) printf(" on motherboard"); } +static device_t +nexus_add_child(device_t bus, int order, const char *name, int unit) +{ + return device_add_child_ordered(bus, order, name, unit, 0); +} + /* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. diff --git a/sys/i386/isa/pcibus.c b/sys/i386/isa/pcibus.c index 14ed5258089c..b3253ac68276 100644 --- a/sys/i386/isa/pcibus.c +++ b/sys/i386/isa/pcibus.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pcibus.c,v 1.41 1997/12/20 09:04:25 se Exp $ + * $Id: pcibus.c,v 1.42 1999/05/18 20:48:43 peter Exp $ * */ @@ -33,6 +33,7 @@ #include #include +#include #include #ifdef PCI_COMPAT @@ -268,13 +269,187 @@ pci_cfgopen(void) static devclass_t pcib_devclass; +static const char * +nexus_pcib_is_host_bridge(pcicfgregs *cfg, + u_int32_t id, u_int8_t class, u_int8_t subclass, + u_int8_t *busnum) +{ + const char *s = "Host to PCI bridge"; + static u_int8_t pxb[4]; /* hack for 450nx */ + + if (class != PCIC_BRIDGE || subclass != PCIS_BRIDGE_HOST) + return NULL; + + *busnum = 0; + + switch (id) { + case 0x12258086: + s = "Intel 824?? host to PCI bridge"; + /* XXX This is a guess */ + *busnum = pci_cfgread(cfg, 0x41, 1); + break; + case 0x71808086: + s = "Intel 82443LX (440 LX) host to PCI bridge"; + break; + case 0x71908086: + s = "Intel 82443BX (440 BX) host to PCI bridge"; + break; + case 0x71928086: + s = "Intel 82443BX host to PCI bridge (AGP disabled)"; + break; + case 0x71a08086: + s = "Intel 82443GX host to PCI bridge"; + break; + case 0x71a18086: + s = "Intel 82443GX host to AGP bridge"; + break; + case 0x71a28086: + s = "Intel 82443GX host to PCI bridge (AGP disabled)"; + break; + case 0x84c48086: + s = "Intel 82454KX/GX (Orion) host to PCI bridge"; + *busnum = pci_cfgread(cfg, 0x4a, 1); + break; + case 0x84ca8086: + /* + * For the 450nx chipset, there is a whole bundle of + * things pretending to be host bridges. The MIOC will + * be seen first and isn't really a pci bridge (the + * actual busses are attached to the PXB's). We need to + * read the registers of the MIOC to figure out the + * bus numbers for the PXB channels. + * + * Since the MIOC doesn't have a pci bus attached, we + * pretend it wasn't there. + */ + pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ + pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ + pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + return NULL; + case 0x84cb8086: + switch (cfg->slot) { + case 0x12: + s = "Intel 82454NX PXB#0, Bus#A"; + *busnum = pxb[0]; + break; + case 0x13: + s = "Intel 82454NX PXB#0, Bus#B"; + *busnum = pxb[1]; + break; + case 0x14: + s = "Intel 82454NX PXB#1, Bus#A"; + *busnum = pxb[2]; + break; + case 0x15: + s = "Intel 82454NX PXB#1, Bus#B"; + *busnum = pxb[3]; + break; + } + break; + + /* SiS -- vendor 0x1039 */ + case 0x04961039: + s = "SiS 85c496"; + break; + case 0x04061039: + s = "SiS 85c501"; + break; + case 0x06011039: + s = "SiS 85c601"; + break; + case 0x55911039: + s = "SiS 5591 host to PCI bridge"; + break; + case 0x00011039: + s = "SiS 5591 host to AGP bridge"; + break; + + /* VLSI -- vendor 0x1004 */ + case 0x00051004: + s = "VLSI 82C592 Host to PCI bridge"; + break; + + /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */ + /* totally. Please let me know if anything wrong. -F */ + /* XXX need info on the MVP3 -- any takers? */ + case 0x05981106: + s = "VIA 82C598MVP (Apollo MVP3) host bridge"; + break; + + /* AcerLabs -- vendor 0x10b9 */ + /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */ + /* id is '10b9" but the register always shows "10b9". -Foxfair */ + case 0x154110b9: + s = "AcerLabs M1541 (Aladdin-V) PCI host bridge"; + break; + + /* OPTi -- vendor 0x1045 */ + case 0xc8221045: + s = "OPTi 82C822 host to PCI Bridge"; + break; + + /* Ross (?) -- vendor 0x1166 */ + case 0x00051166: + s = "Ross (?) host to PCI bridge"; + /* just guessing the secondary bus register number ... */ + *busnum = pci_cfgread(cfg, 0x45, 1); + break; + } + + return s; +} + +/* + * Scan the first pci bus for host-pci bridges and add pcib instances + * to the nexus for each bridge. + */ +static void +nexus_pcib_identify(driver_t *driver, device_t parent) +{ + pcicfgregs probe; + + probe.hose = 0; + probe.bus = 0; + + pci_cfgopen(); + for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { + int pcifunchigh = 0; + for (probe.func = 0; + probe.func <= pcifunchigh; + probe.func++) { + /* + * Read the IDs and class from the device. + */ + u_int32_t id; + u_int8_t class, subclass, busnum; + device_t child; + const char *s; + + id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + if (id == -1) + continue; + class = pci_cfgread(&probe, PCIR_CLASS, 1); + subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + + s = nexus_pcib_is_host_bridge(&probe, id, + class, subclass, + &busnum); + if (s) { + child = BUS_ADD_CHILD(parent, 0, + "pcib", busnum); + device_set_desc(child, s); + } + } + } + +} + static int nexus_pcib_probe(device_t dev) { if (pci_cfgopen() != 0) { - device_set_desc(dev, "PCI host bus adapter"); - - device_add_child(dev, "pci", 0, 0); + device_add_child(dev, "pci", device_get_unit(dev), 0); return 0; } return ENXIO; @@ -282,6 +457,7 @@ nexus_pcib_probe(device_t dev) static device_method_t nexus_pcib_methods[] = { /* Device interface */ + DEVMETHOD(device_identify, nexus_pcib_identify), DEVMETHOD(device_probe, nexus_pcib_probe), DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), diff --git a/sys/i386/pci/pci_bus.c b/sys/i386/pci/pci_bus.c index 14ed5258089c..b3253ac68276 100644 --- a/sys/i386/pci/pci_bus.c +++ b/sys/i386/pci/pci_bus.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pcibus.c,v 1.41 1997/12/20 09:04:25 se Exp $ + * $Id: pcibus.c,v 1.42 1999/05/18 20:48:43 peter Exp $ * */ @@ -33,6 +33,7 @@ #include #include +#include #include #ifdef PCI_COMPAT @@ -268,13 +269,187 @@ pci_cfgopen(void) static devclass_t pcib_devclass; +static const char * +nexus_pcib_is_host_bridge(pcicfgregs *cfg, + u_int32_t id, u_int8_t class, u_int8_t subclass, + u_int8_t *busnum) +{ + const char *s = "Host to PCI bridge"; + static u_int8_t pxb[4]; /* hack for 450nx */ + + if (class != PCIC_BRIDGE || subclass != PCIS_BRIDGE_HOST) + return NULL; + + *busnum = 0; + + switch (id) { + case 0x12258086: + s = "Intel 824?? host to PCI bridge"; + /* XXX This is a guess */ + *busnum = pci_cfgread(cfg, 0x41, 1); + break; + case 0x71808086: + s = "Intel 82443LX (440 LX) host to PCI bridge"; + break; + case 0x71908086: + s = "Intel 82443BX (440 BX) host to PCI bridge"; + break; + case 0x71928086: + s = "Intel 82443BX host to PCI bridge (AGP disabled)"; + break; + case 0x71a08086: + s = "Intel 82443GX host to PCI bridge"; + break; + case 0x71a18086: + s = "Intel 82443GX host to AGP bridge"; + break; + case 0x71a28086: + s = "Intel 82443GX host to PCI bridge (AGP disabled)"; + break; + case 0x84c48086: + s = "Intel 82454KX/GX (Orion) host to PCI bridge"; + *busnum = pci_cfgread(cfg, 0x4a, 1); + break; + case 0x84ca8086: + /* + * For the 450nx chipset, there is a whole bundle of + * things pretending to be host bridges. The MIOC will + * be seen first and isn't really a pci bridge (the + * actual busses are attached to the PXB's). We need to + * read the registers of the MIOC to figure out the + * bus numbers for the PXB channels. + * + * Since the MIOC doesn't have a pci bus attached, we + * pretend it wasn't there. + */ + pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ + pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ + pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + return NULL; + case 0x84cb8086: + switch (cfg->slot) { + case 0x12: + s = "Intel 82454NX PXB#0, Bus#A"; + *busnum = pxb[0]; + break; + case 0x13: + s = "Intel 82454NX PXB#0, Bus#B"; + *busnum = pxb[1]; + break; + case 0x14: + s = "Intel 82454NX PXB#1, Bus#A"; + *busnum = pxb[2]; + break; + case 0x15: + s = "Intel 82454NX PXB#1, Bus#B"; + *busnum = pxb[3]; + break; + } + break; + + /* SiS -- vendor 0x1039 */ + case 0x04961039: + s = "SiS 85c496"; + break; + case 0x04061039: + s = "SiS 85c501"; + break; + case 0x06011039: + s = "SiS 85c601"; + break; + case 0x55911039: + s = "SiS 5591 host to PCI bridge"; + break; + case 0x00011039: + s = "SiS 5591 host to AGP bridge"; + break; + + /* VLSI -- vendor 0x1004 */ + case 0x00051004: + s = "VLSI 82C592 Host to PCI bridge"; + break; + + /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */ + /* totally. Please let me know if anything wrong. -F */ + /* XXX need info on the MVP3 -- any takers? */ + case 0x05981106: + s = "VIA 82C598MVP (Apollo MVP3) host bridge"; + break; + + /* AcerLabs -- vendor 0x10b9 */ + /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */ + /* id is '10b9" but the register always shows "10b9". -Foxfair */ + case 0x154110b9: + s = "AcerLabs M1541 (Aladdin-V) PCI host bridge"; + break; + + /* OPTi -- vendor 0x1045 */ + case 0xc8221045: + s = "OPTi 82C822 host to PCI Bridge"; + break; + + /* Ross (?) -- vendor 0x1166 */ + case 0x00051166: + s = "Ross (?) host to PCI bridge"; + /* just guessing the secondary bus register number ... */ + *busnum = pci_cfgread(cfg, 0x45, 1); + break; + } + + return s; +} + +/* + * Scan the first pci bus for host-pci bridges and add pcib instances + * to the nexus for each bridge. + */ +static void +nexus_pcib_identify(driver_t *driver, device_t parent) +{ + pcicfgregs probe; + + probe.hose = 0; + probe.bus = 0; + + pci_cfgopen(); + for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { + int pcifunchigh = 0; + for (probe.func = 0; + probe.func <= pcifunchigh; + probe.func++) { + /* + * Read the IDs and class from the device. + */ + u_int32_t id; + u_int8_t class, subclass, busnum; + device_t child; + const char *s; + + id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + if (id == -1) + continue; + class = pci_cfgread(&probe, PCIR_CLASS, 1); + subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + + s = nexus_pcib_is_host_bridge(&probe, id, + class, subclass, + &busnum); + if (s) { + child = BUS_ADD_CHILD(parent, 0, + "pcib", busnum); + device_set_desc(child, s); + } + } + } + +} + static int nexus_pcib_probe(device_t dev) { if (pci_cfgopen() != 0) { - device_set_desc(dev, "PCI host bus adapter"); - - device_add_child(dev, "pci", 0, 0); + device_add_child(dev, "pci", device_get_unit(dev), 0); return 0; } return ENXIO; @@ -282,6 +457,7 @@ nexus_pcib_probe(device_t dev) static device_method_t nexus_pcib_methods[] = { /* Device interface */ + DEVMETHOD(device_identify, nexus_pcib_identify), DEVMETHOD(device_probe, nexus_pcib_probe), DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c index 14ed5258089c..b3253ac68276 100644 --- a/sys/i386/pci/pci_cfgreg.c +++ b/sys/i386/pci/pci_cfgreg.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pcibus.c,v 1.41 1997/12/20 09:04:25 se Exp $ + * $Id: pcibus.c,v 1.42 1999/05/18 20:48:43 peter Exp $ * */ @@ -33,6 +33,7 @@ #include #include +#include #include #ifdef PCI_COMPAT @@ -268,13 +269,187 @@ pci_cfgopen(void) static devclass_t pcib_devclass; +static const char * +nexus_pcib_is_host_bridge(pcicfgregs *cfg, + u_int32_t id, u_int8_t class, u_int8_t subclass, + u_int8_t *busnum) +{ + const char *s = "Host to PCI bridge"; + static u_int8_t pxb[4]; /* hack for 450nx */ + + if (class != PCIC_BRIDGE || subclass != PCIS_BRIDGE_HOST) + return NULL; + + *busnum = 0; + + switch (id) { + case 0x12258086: + s = "Intel 824?? host to PCI bridge"; + /* XXX This is a guess */ + *busnum = pci_cfgread(cfg, 0x41, 1); + break; + case 0x71808086: + s = "Intel 82443LX (440 LX) host to PCI bridge"; + break; + case 0x71908086: + s = "Intel 82443BX (440 BX) host to PCI bridge"; + break; + case 0x71928086: + s = "Intel 82443BX host to PCI bridge (AGP disabled)"; + break; + case 0x71a08086: + s = "Intel 82443GX host to PCI bridge"; + break; + case 0x71a18086: + s = "Intel 82443GX host to AGP bridge"; + break; + case 0x71a28086: + s = "Intel 82443GX host to PCI bridge (AGP disabled)"; + break; + case 0x84c48086: + s = "Intel 82454KX/GX (Orion) host to PCI bridge"; + *busnum = pci_cfgread(cfg, 0x4a, 1); + break; + case 0x84ca8086: + /* + * For the 450nx chipset, there is a whole bundle of + * things pretending to be host bridges. The MIOC will + * be seen first and isn't really a pci bridge (the + * actual busses are attached to the PXB's). We need to + * read the registers of the MIOC to figure out the + * bus numbers for the PXB channels. + * + * Since the MIOC doesn't have a pci bus attached, we + * pretend it wasn't there. + */ + pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ + pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ + pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + return NULL; + case 0x84cb8086: + switch (cfg->slot) { + case 0x12: + s = "Intel 82454NX PXB#0, Bus#A"; + *busnum = pxb[0]; + break; + case 0x13: + s = "Intel 82454NX PXB#0, Bus#B"; + *busnum = pxb[1]; + break; + case 0x14: + s = "Intel 82454NX PXB#1, Bus#A"; + *busnum = pxb[2]; + break; + case 0x15: + s = "Intel 82454NX PXB#1, Bus#B"; + *busnum = pxb[3]; + break; + } + break; + + /* SiS -- vendor 0x1039 */ + case 0x04961039: + s = "SiS 85c496"; + break; + case 0x04061039: + s = "SiS 85c501"; + break; + case 0x06011039: + s = "SiS 85c601"; + break; + case 0x55911039: + s = "SiS 5591 host to PCI bridge"; + break; + case 0x00011039: + s = "SiS 5591 host to AGP bridge"; + break; + + /* VLSI -- vendor 0x1004 */ + case 0x00051004: + s = "VLSI 82C592 Host to PCI bridge"; + break; + + /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */ + /* totally. Please let me know if anything wrong. -F */ + /* XXX need info on the MVP3 -- any takers? */ + case 0x05981106: + s = "VIA 82C598MVP (Apollo MVP3) host bridge"; + break; + + /* AcerLabs -- vendor 0x10b9 */ + /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */ + /* id is '10b9" but the register always shows "10b9". -Foxfair */ + case 0x154110b9: + s = "AcerLabs M1541 (Aladdin-V) PCI host bridge"; + break; + + /* OPTi -- vendor 0x1045 */ + case 0xc8221045: + s = "OPTi 82C822 host to PCI Bridge"; + break; + + /* Ross (?) -- vendor 0x1166 */ + case 0x00051166: + s = "Ross (?) host to PCI bridge"; + /* just guessing the secondary bus register number ... */ + *busnum = pci_cfgread(cfg, 0x45, 1); + break; + } + + return s; +} + +/* + * Scan the first pci bus for host-pci bridges and add pcib instances + * to the nexus for each bridge. + */ +static void +nexus_pcib_identify(driver_t *driver, device_t parent) +{ + pcicfgregs probe; + + probe.hose = 0; + probe.bus = 0; + + pci_cfgopen(); + for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { + int pcifunchigh = 0; + for (probe.func = 0; + probe.func <= pcifunchigh; + probe.func++) { + /* + * Read the IDs and class from the device. + */ + u_int32_t id; + u_int8_t class, subclass, busnum; + device_t child; + const char *s; + + id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + if (id == -1) + continue; + class = pci_cfgread(&probe, PCIR_CLASS, 1); + subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + + s = nexus_pcib_is_host_bridge(&probe, id, + class, subclass, + &busnum); + if (s) { + child = BUS_ADD_CHILD(parent, 0, + "pcib", busnum); + device_set_desc(child, s); + } + } + } + +} + static int nexus_pcib_probe(device_t dev) { if (pci_cfgopen() != 0) { - device_set_desc(dev, "PCI host bus adapter"); - - device_add_child(dev, "pci", 0, 0); + device_add_child(dev, "pci", device_get_unit(dev), 0); return 0; } return ENXIO; @@ -282,6 +457,7 @@ nexus_pcib_probe(device_t dev) static device_method_t nexus_pcib_methods[] = { /* Device interface */ + DEVMETHOD(device_identify, nexus_pcib_identify), DEVMETHOD(device_probe, nexus_pcib_probe), DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), diff --git a/sys/i386/pci/pci_pir.c b/sys/i386/pci/pci_pir.c index 14ed5258089c..b3253ac68276 100644 --- a/sys/i386/pci/pci_pir.c +++ b/sys/i386/pci/pci_pir.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: pcibus.c,v 1.41 1997/12/20 09:04:25 se Exp $ + * $Id: pcibus.c,v 1.42 1999/05/18 20:48:43 peter Exp $ * */ @@ -33,6 +33,7 @@ #include #include +#include #include #ifdef PCI_COMPAT @@ -268,13 +269,187 @@ pci_cfgopen(void) static devclass_t pcib_devclass; +static const char * +nexus_pcib_is_host_bridge(pcicfgregs *cfg, + u_int32_t id, u_int8_t class, u_int8_t subclass, + u_int8_t *busnum) +{ + const char *s = "Host to PCI bridge"; + static u_int8_t pxb[4]; /* hack for 450nx */ + + if (class != PCIC_BRIDGE || subclass != PCIS_BRIDGE_HOST) + return NULL; + + *busnum = 0; + + switch (id) { + case 0x12258086: + s = "Intel 824?? host to PCI bridge"; + /* XXX This is a guess */ + *busnum = pci_cfgread(cfg, 0x41, 1); + break; + case 0x71808086: + s = "Intel 82443LX (440 LX) host to PCI bridge"; + break; + case 0x71908086: + s = "Intel 82443BX (440 BX) host to PCI bridge"; + break; + case 0x71928086: + s = "Intel 82443BX host to PCI bridge (AGP disabled)"; + break; + case 0x71a08086: + s = "Intel 82443GX host to PCI bridge"; + break; + case 0x71a18086: + s = "Intel 82443GX host to AGP bridge"; + break; + case 0x71a28086: + s = "Intel 82443GX host to PCI bridge (AGP disabled)"; + break; + case 0x84c48086: + s = "Intel 82454KX/GX (Orion) host to PCI bridge"; + *busnum = pci_cfgread(cfg, 0x4a, 1); + break; + case 0x84ca8086: + /* + * For the 450nx chipset, there is a whole bundle of + * things pretending to be host bridges. The MIOC will + * be seen first and isn't really a pci bridge (the + * actual busses are attached to the PXB's). We need to + * read the registers of the MIOC to figure out the + * bus numbers for the PXB channels. + * + * Since the MIOC doesn't have a pci bus attached, we + * pretend it wasn't there. + */ + pxb[0] = pci_cfgread(cfg, 0xd0, 1); /* BUSNO[0] */ + pxb[1] = pci_cfgread(cfg, 0xd1, 1) + 1; /* SUBA[0]+1 */ + pxb[2] = pci_cfgread(cfg, 0xd3, 1); /* BUSNO[1] */ + pxb[3] = pci_cfgread(cfg, 0xd4, 1) + 1; /* SUBA[1]+1 */ + return NULL; + case 0x84cb8086: + switch (cfg->slot) { + case 0x12: + s = "Intel 82454NX PXB#0, Bus#A"; + *busnum = pxb[0]; + break; + case 0x13: + s = "Intel 82454NX PXB#0, Bus#B"; + *busnum = pxb[1]; + break; + case 0x14: + s = "Intel 82454NX PXB#1, Bus#A"; + *busnum = pxb[2]; + break; + case 0x15: + s = "Intel 82454NX PXB#1, Bus#B"; + *busnum = pxb[3]; + break; + } + break; + + /* SiS -- vendor 0x1039 */ + case 0x04961039: + s = "SiS 85c496"; + break; + case 0x04061039: + s = "SiS 85c501"; + break; + case 0x06011039: + s = "SiS 85c601"; + break; + case 0x55911039: + s = "SiS 5591 host to PCI bridge"; + break; + case 0x00011039: + s = "SiS 5591 host to AGP bridge"; + break; + + /* VLSI -- vendor 0x1004 */ + case 0x00051004: + s = "VLSI 82C592 Host to PCI bridge"; + break; + + /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */ + /* totally. Please let me know if anything wrong. -F */ + /* XXX need info on the MVP3 -- any takers? */ + case 0x05981106: + s = "VIA 82C598MVP (Apollo MVP3) host bridge"; + break; + + /* AcerLabs -- vendor 0x10b9 */ + /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */ + /* id is '10b9" but the register always shows "10b9". -Foxfair */ + case 0x154110b9: + s = "AcerLabs M1541 (Aladdin-V) PCI host bridge"; + break; + + /* OPTi -- vendor 0x1045 */ + case 0xc8221045: + s = "OPTi 82C822 host to PCI Bridge"; + break; + + /* Ross (?) -- vendor 0x1166 */ + case 0x00051166: + s = "Ross (?) host to PCI bridge"; + /* just guessing the secondary bus register number ... */ + *busnum = pci_cfgread(cfg, 0x45, 1); + break; + } + + return s; +} + +/* + * Scan the first pci bus for host-pci bridges and add pcib instances + * to the nexus for each bridge. + */ +static void +nexus_pcib_identify(driver_t *driver, device_t parent) +{ + pcicfgregs probe; + + probe.hose = 0; + probe.bus = 0; + + pci_cfgopen(); + for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { + int pcifunchigh = 0; + for (probe.func = 0; + probe.func <= pcifunchigh; + probe.func++) { + /* + * Read the IDs and class from the device. + */ + u_int32_t id; + u_int8_t class, subclass, busnum; + device_t child; + const char *s; + + id = pci_cfgread(&probe, PCIR_DEVVENDOR, 4); + if (id == -1) + continue; + class = pci_cfgread(&probe, PCIR_CLASS, 1); + subclass = pci_cfgread(&probe, PCIR_SUBCLASS, 1); + + s = nexus_pcib_is_host_bridge(&probe, id, + class, subclass, + &busnum); + if (s) { + child = BUS_ADD_CHILD(parent, 0, + "pcib", busnum); + device_set_desc(child, s); + } + } + } + +} + static int nexus_pcib_probe(device_t dev) { if (pci_cfgopen() != 0) { - device_set_desc(dev, "PCI host bus adapter"); - - device_add_child(dev, "pci", 0, 0); + device_add_child(dev, "pci", device_get_unit(dev), 0); return 0; } return ENXIO; @@ -282,6 +457,7 @@ nexus_pcib_probe(device_t dev) static device_method_t nexus_pcib_methods[] = { /* Device interface */ + DEVMETHOD(device_identify, nexus_pcib_identify), DEVMETHOD(device_probe, nexus_pcib_probe), DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), diff --git a/sys/pci/pcisupport.c b/sys/pci/pcisupport.c index ab29e544a98b..1808c3bf35e5 100644 --- a/sys/pci/pcisupport.c +++ b/sys/pci/pcisupport.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pcisupport.c,v 1.121 1999/06/16 12:26:40 billf Exp $ +** $Id: pcisupport.c,v 1.122 1999/06/24 04:06:26 jlemon Exp $ ** ** Device driver for DEC/INTEL PCI chipsets. ** @@ -75,19 +75,6 @@ struct condmsg { const char *text; }; -/* - * XXX Both fixbushigh_orion() and fixbushigh_i1225() are bogus in that way, - * that they store the highest bus number to scan in this device's config - * data, though it is about PCI buses attached to the CPU independently! - * The same goes for fixbushigh_450nx. - */ - -static void -fixbushigh_orion(device_t dev) -{ - pci_set_secondarybus(dev, pci_read_config(dev, 0x4a, 1)); - pci_set_subordinatebus(dev, pci_read_config(dev, 0x4b, 1)); -} static void fixbushigh_i1225(device_t dev) @@ -101,81 +88,6 @@ fixbushigh_i1225(device_t dev) } } - -/* - * This reads the PCI config space for the 82451NX MIOC in the 450NX - * chipset to determine the PCI bus configuration. - * - * Assuming the BIOS has set up the MIOC properly, this will correctly - * report the number of PCI busses in the system. - * - * A small problem is that the Host to PCI bridge control is in the MIOC, - * while the host-pci bridges are separate PCI devices. So it really - * isn't easily possible to set up the subordinatebus mappings as the - * 82454NX PCI expander bridges are probed, although that makes the - * most sense. - */ -static void -fixbushigh_450nx(device_t dev) -{ - int subordinatebus; - unsigned long devmap; - - /* - * Read the DEVMAP field, so we know which fields to check. - * If the Host-PCI bridge isn't marked as present by the BIOS, - * we have to assume it doesn't exist. - * If this doesn't find all the PCI busses, complain to the - * BIOS vendor. There is nothing more we can do. - */ - devmap = pci_read_config(dev, 0xd6, 2) & 0x3c; - if (!devmap) - panic("450NX MIOC: No host to PCI bridges marked present.\n"); - /* - * Since the buses are configured in order, we just have to - * find the highest bus, and use those numbers. - */ - if (devmap & 0x20) { /* B1 */ - subordinatebus = pci_read_config(dev, 0xd5, 1); - } else if (devmap & 0x10) { /* A1 */ - subordinatebus = pci_read_config(dev, 0xd4, 1); - } else if (devmap & 0x8) { /* B0 */ - subordinatebus = pci_read_config(dev, 0xd2, 1); - } else /* if (devmap & 0x4) */ { /* A0 */ - subordinatebus = pci_read_config(dev, 0xd1, 1); - } - if (subordinatebus == 255) { - printf("fixbushigh_450nx: bogus highest PCI bus %d", - subordinatebus); -#ifdef NBUS - subordinatebus = NBUS - 2; -#else - subordinatebus = 10; -#endif - printf(", reduced to %d\n", subordinatebus); - } - - if (bootverbose) - printf("fixbushigh_450nx: subordinatebus is %d\n", - subordinatebus); - - pci_set_secondarybus(dev, subordinatebus); - pci_set_subordinatebus(dev, subordinatebus); -} - -static void -fixbushigh_Ross(device_t dev) -{ - int secondarybus; - - /* just guessing the secondary bus register number ... */ - secondarybus = pci_read_config(dev, 0x45, 1); - if (secondarybus != 0 && secondarybus != 0xff) { - pci_set_secondarybus(dev, secondarybus); - pci_set_subordinatebus(dev, secondarybus); - } -} - static void fixwsc_natoma(device_t dev) { @@ -806,6 +718,8 @@ pcib_match(device_t dev) return ("Intel 82443LX (440 LX) PCI-PCI (AGP) bridge"); case 0x71918086: return ("Intel 82443BX (440 BX) PCI-PCI (AGP) bridge"); + case 0x71A18086: + return ("Intel 82443GX (440 GX) PCI-PCI (AGP) bridge"); case 0x84cb8086: return ("Intel 82454NX PCI Expander Bridge"); case 0x124b8086: @@ -834,11 +748,6 @@ pcib_match(device_t dev) return ("IBM 82351 PCI-PCI bridge"); case 0x00011011: return ("DEC 21050 PCI-PCI bridge"); - - /* Ross (?) -- vendor 0x1166 */ - case 0x00051166: - fixbushigh_Ross(dev); - return ("Ross (?) host to PCI bridge"); }; if (pci_get_class(dev) == PCIC_BRIDGE @@ -1100,10 +1009,8 @@ chip_match(device_t dev) case 0x71a28086: return ("Intel 82443GX host to PCI bridge (AGP disabled)"); case 0x84c48086: - fixbushigh_orion(dev); return ("Intel 82454KX/GX (Orion) host to PCI bridge"); case 0x84ca8086: - fixbushigh_450nx(dev); return ("Intel 82451NX Memory and I/O controller"); case 0x04868086: return ("Intel 82425EX PCI system controller"); @@ -1259,6 +1166,15 @@ static int chip_probe(device_t dev) if (desc == NULL) desc = ide_pci_match(dev); if (desc) { + if (pci_get_class(dev) == PCIC_BRIDGE + && pci_get_subclass(dev) == PCIS_BRIDGE_HOST) { + /* + * Suppress printing this device since the nexus + * has already described it. + */ + device_quiet(dev); + } + device_set_desc_copy(dev, desc); return -100; /* Low match priority */ }