xref: /freebsd/sys/x86/pci/pci_bus.c (revision d6b6639713e65ebb7982ddbc864e468328acdc8f)
11368987aSJohn Baldwin /*-
2ebf5747bSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3ebf5747bSPedro F. Giffuni  *
41368987aSJohn Baldwin  * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
51368987aSJohn Baldwin  * All rights reserved.
61368987aSJohn Baldwin  *
71368987aSJohn Baldwin  * Redistribution and use in source and binary forms, with or without
81368987aSJohn Baldwin  * modification, are permitted provided that the following conditions
91368987aSJohn Baldwin  * are met:
101368987aSJohn Baldwin  * 1. Redistributions of source code must retain the above copyright
111368987aSJohn Baldwin  *    notice unmodified, this list of conditions, and the following
121368987aSJohn Baldwin  *    disclaimer.
131368987aSJohn Baldwin  * 2. Redistributions in binary form must reproduce the above copyright
141368987aSJohn Baldwin  *    notice, this list of conditions and the following disclaimer in the
151368987aSJohn Baldwin  *    documentation and/or other materials provided with the distribution.
161368987aSJohn Baldwin  *
171368987aSJohn Baldwin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
181368987aSJohn Baldwin  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
191368987aSJohn Baldwin  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
201368987aSJohn Baldwin  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
211368987aSJohn Baldwin  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
221368987aSJohn Baldwin  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231368987aSJohn Baldwin  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241368987aSJohn Baldwin  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251368987aSJohn Baldwin  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
261368987aSJohn Baldwin  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271368987aSJohn Baldwin  */
281368987aSJohn Baldwin 
291368987aSJohn Baldwin #include <sys/cdefs.h>
301368987aSJohn Baldwin __FBSDID("$FreeBSD$");
311368987aSJohn Baldwin 
321368987aSJohn Baldwin #include "opt_cpu.h"
331368987aSJohn Baldwin 
341368987aSJohn Baldwin #include <sys/param.h>
351368987aSJohn Baldwin #include <sys/systm.h>
361368987aSJohn Baldwin #include <sys/bus.h>
371368987aSJohn Baldwin #include <sys/kernel.h>
381368987aSJohn Baldwin #include <sys/malloc.h>
391368987aSJohn Baldwin #include <sys/module.h>
401368987aSJohn Baldwin #include <sys/rman.h>
411368987aSJohn Baldwin #include <sys/sysctl.h>
421368987aSJohn Baldwin 
431368987aSJohn Baldwin #include <dev/pci/pcivar.h>
441368987aSJohn Baldwin #include <dev/pci/pcireg.h>
451368987aSJohn Baldwin #include <dev/pci/pcib_private.h>
461368987aSJohn Baldwin #include <isa/isavar.h>
471368987aSJohn Baldwin #ifdef CPU_ELAN
481368987aSJohn Baldwin #include <machine/md_var.h>
491368987aSJohn Baldwin #endif
50435803f3SJohn Baldwin #include <x86/legacyvar.h>
511368987aSJohn Baldwin #include <machine/pci_cfgreg.h>
521368987aSJohn Baldwin #include <machine/resource.h>
531368987aSJohn Baldwin 
541368987aSJohn Baldwin #include "pcib_if.h"
551368987aSJohn Baldwin 
561368987aSJohn Baldwin int
571368987aSJohn Baldwin legacy_pcib_maxslots(device_t dev)
581368987aSJohn Baldwin {
591368987aSJohn Baldwin 	return 31;
601368987aSJohn Baldwin }
611368987aSJohn Baldwin 
621368987aSJohn Baldwin /* read configuration space register */
631368987aSJohn Baldwin 
641368987aSJohn Baldwin uint32_t
651368987aSJohn Baldwin legacy_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
661368987aSJohn Baldwin 			u_int reg, int bytes)
671368987aSJohn Baldwin {
681368987aSJohn Baldwin 	return(pci_cfgregread(bus, slot, func, reg, bytes));
691368987aSJohn Baldwin }
701368987aSJohn Baldwin 
711368987aSJohn Baldwin /* write configuration space register */
721368987aSJohn Baldwin 
731368987aSJohn Baldwin void
741368987aSJohn Baldwin legacy_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func,
751368987aSJohn Baldwin 			 u_int reg, uint32_t data, int bytes)
761368987aSJohn Baldwin {
771368987aSJohn Baldwin 	pci_cfgregwrite(bus, slot, func, reg, data, bytes);
781368987aSJohn Baldwin }
791368987aSJohn Baldwin 
801368987aSJohn Baldwin /* route interrupt */
811368987aSJohn Baldwin 
821368987aSJohn Baldwin static int
831368987aSJohn Baldwin legacy_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
841368987aSJohn Baldwin {
851368987aSJohn Baldwin 
861368987aSJohn Baldwin #ifdef __HAVE_PIR
871368987aSJohn Baldwin 	return (pci_pir_route_interrupt(pci_get_bus(dev), pci_get_slot(dev),
881368987aSJohn Baldwin 	    pci_get_function(dev), pin));
891368987aSJohn Baldwin #else
901368987aSJohn Baldwin 	/* No routing possible */
911368987aSJohn Baldwin 	return (PCI_INVALID_IRQ);
921368987aSJohn Baldwin #endif
931368987aSJohn Baldwin }
941368987aSJohn Baldwin 
951368987aSJohn Baldwin /* Pass MSI requests up to the nexus. */
961368987aSJohn Baldwin 
9784ca9aadSJohn Baldwin int
981368987aSJohn Baldwin legacy_pcib_alloc_msi(device_t pcib, device_t dev, int count, int maxcount,
991368987aSJohn Baldwin     int *irqs)
1001368987aSJohn Baldwin {
1011368987aSJohn Baldwin 	device_t bus;
1021368987aSJohn Baldwin 
1031368987aSJohn Baldwin 	bus = device_get_parent(pcib);
1041368987aSJohn Baldwin 	return (PCIB_ALLOC_MSI(device_get_parent(bus), dev, count, maxcount,
1051368987aSJohn Baldwin 	    irqs));
1061368987aSJohn Baldwin }
1071368987aSJohn Baldwin 
10884ca9aadSJohn Baldwin int
1091368987aSJohn Baldwin legacy_pcib_alloc_msix(device_t pcib, device_t dev, int *irq)
1101368987aSJohn Baldwin {
1111368987aSJohn Baldwin 	device_t bus;
1121368987aSJohn Baldwin 
1131368987aSJohn Baldwin 	bus = device_get_parent(pcib);
1141368987aSJohn Baldwin 	return (PCIB_ALLOC_MSIX(device_get_parent(bus), dev, irq));
1151368987aSJohn Baldwin }
1161368987aSJohn Baldwin 
1170d95597cSJohn Baldwin int
1181368987aSJohn Baldwin legacy_pcib_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
1191368987aSJohn Baldwin     uint32_t *data)
1201368987aSJohn Baldwin {
1210d95597cSJohn Baldwin 	device_t bus, hostb;
1220d95597cSJohn Baldwin 	int error, func, slot;
1231368987aSJohn Baldwin 
1241368987aSJohn Baldwin 	bus = device_get_parent(pcib);
1250d95597cSJohn Baldwin 	error = PCIB_MAP_MSI(device_get_parent(bus), dev, irq, addr, data);
1260d95597cSJohn Baldwin 	if (error)
1270d95597cSJohn Baldwin 		return (error);
1280d95597cSJohn Baldwin 
1290d95597cSJohn Baldwin 	slot = legacy_get_pcislot(pcib);
1300d95597cSJohn Baldwin 	func = legacy_get_pcifunc(pcib);
1310d95597cSJohn Baldwin 	if (slot == -1 || func == -1)
1320d95597cSJohn Baldwin 		return (0);
1330d95597cSJohn Baldwin 	hostb = pci_find_bsf(0, slot, func);
1340d95597cSJohn Baldwin 	KASSERT(hostb != NULL, ("%s: missing hostb for 0:%d:%d", __func__,
1350d95597cSJohn Baldwin 	    slot, func));
1360d95597cSJohn Baldwin 	pci_ht_map_msi(hostb, *addr);
1370d95597cSJohn Baldwin 	return (0);
1381368987aSJohn Baldwin }
1391368987aSJohn Baldwin 
1401368987aSJohn Baldwin static const char *
1411368987aSJohn Baldwin legacy_pcib_is_host_bridge(int bus, int slot, int func,
1421368987aSJohn Baldwin 			  uint32_t id, uint8_t class, uint8_t subclass,
1431368987aSJohn Baldwin 			  uint8_t *busnum)
1441368987aSJohn Baldwin {
1451368987aSJohn Baldwin #ifdef __i386__
1461368987aSJohn Baldwin 	const char *s = NULL;
1471368987aSJohn Baldwin 	static uint8_t pxb[4];	/* hack for 450nx */
1481368987aSJohn Baldwin 
1491368987aSJohn Baldwin 	*busnum = 0;
1501368987aSJohn Baldwin 
1511368987aSJohn Baldwin 	switch (id) {
1521368987aSJohn Baldwin 	case 0x12258086:
1531368987aSJohn Baldwin 		s = "Intel 824?? host to PCI bridge";
1541368987aSJohn Baldwin 		/* XXX This is a guess */
1551368987aSJohn Baldwin 		/* *busnum = legacy_pcib_read_config(0, bus, slot, func, 0x41, 1); */
1561368987aSJohn Baldwin 		*busnum = bus;
1571368987aSJohn Baldwin 		break;
1581368987aSJohn Baldwin 	case 0x71208086:
1591368987aSJohn Baldwin 		s = "Intel 82810 (i810 GMCH) Host To Hub bridge";
1601368987aSJohn Baldwin 		break;
1611368987aSJohn Baldwin 	case 0x71228086:
1621368987aSJohn Baldwin 		s = "Intel 82810-DC100 (i810-DC100 GMCH) Host To Hub bridge";
1631368987aSJohn Baldwin 		break;
1641368987aSJohn Baldwin 	case 0x71248086:
1651368987aSJohn Baldwin 		s = "Intel 82810E (i810E GMCH) Host To Hub bridge";
1661368987aSJohn Baldwin 		break;
1671368987aSJohn Baldwin 	case 0x11308086:
1681368987aSJohn Baldwin 		s = "Intel 82815 (i815 GMCH) Host To Hub bridge";
1691368987aSJohn Baldwin 		break;
1701368987aSJohn Baldwin 	case 0x71808086:
1711368987aSJohn Baldwin 		s = "Intel 82443LX (440 LX) host to PCI bridge";
1721368987aSJohn Baldwin 		break;
1731368987aSJohn Baldwin 	case 0x71908086:
1741368987aSJohn Baldwin 		s = "Intel 82443BX (440 BX) host to PCI bridge";
1751368987aSJohn Baldwin 		break;
1761368987aSJohn Baldwin 	case 0x71928086:
1771368987aSJohn Baldwin 		s = "Intel 82443BX host to PCI bridge (AGP disabled)";
1781368987aSJohn Baldwin 		break;
1791368987aSJohn Baldwin 	case 0x71948086:
1801368987aSJohn Baldwin 		s = "Intel 82443MX host to PCI bridge";
1811368987aSJohn Baldwin 		break;
1821368987aSJohn Baldwin 	case 0x71a08086:
1831368987aSJohn Baldwin 		s = "Intel 82443GX host to PCI bridge";
1841368987aSJohn Baldwin 		break;
1851368987aSJohn Baldwin 	case 0x71a18086:
1861368987aSJohn Baldwin 		s = "Intel 82443GX host to AGP bridge";
1871368987aSJohn Baldwin 		break;
1881368987aSJohn Baldwin 	case 0x71a28086:
1891368987aSJohn Baldwin 		s = "Intel 82443GX host to PCI bridge (AGP disabled)";
1901368987aSJohn Baldwin 		break;
1911368987aSJohn Baldwin 	case 0x84c48086:
1921368987aSJohn Baldwin 		s = "Intel 82454KX/GX (Orion) host to PCI bridge";
1931368987aSJohn Baldwin 		*busnum = legacy_pcib_read_config(0, bus, slot, func, 0x4a, 1);
1941368987aSJohn Baldwin 		break;
1951368987aSJohn Baldwin 	case 0x84ca8086:
1961368987aSJohn Baldwin 		/*
1971368987aSJohn Baldwin 		 * For the 450nx chipset, there is a whole bundle of
1981368987aSJohn Baldwin 		 * things pretending to be host bridges. The MIOC will
1991368987aSJohn Baldwin 		 * be seen first and isn't really a pci bridge (the
200db4fcadfSConrad Meyer 		 * actual buses are attached to the PXB's). We need to
2011368987aSJohn Baldwin 		 * read the registers of the MIOC to figure out the
2021368987aSJohn Baldwin 		 * bus numbers for the PXB channels.
2031368987aSJohn Baldwin 		 *
2041368987aSJohn Baldwin 		 * Since the MIOC doesn't have a pci bus attached, we
2051368987aSJohn Baldwin 		 * pretend it wasn't there.
2061368987aSJohn Baldwin 		 */
2071368987aSJohn Baldwin 		pxb[0] = legacy_pcib_read_config(0, bus, slot, func,
2081368987aSJohn Baldwin 						0xd0, 1); /* BUSNO[0] */
2091368987aSJohn Baldwin 		pxb[1] = legacy_pcib_read_config(0, bus, slot, func,
2101368987aSJohn Baldwin 						0xd1, 1) + 1;	/* SUBA[0]+1 */
2111368987aSJohn Baldwin 		pxb[2] = legacy_pcib_read_config(0, bus, slot, func,
2121368987aSJohn Baldwin 						0xd3, 1); /* BUSNO[1] */
2131368987aSJohn Baldwin 		pxb[3] = legacy_pcib_read_config(0, bus, slot, func,
2141368987aSJohn Baldwin 						0xd4, 1) + 1;	/* SUBA[1]+1 */
2151368987aSJohn Baldwin 		return NULL;
2161368987aSJohn Baldwin 	case 0x84cb8086:
2171368987aSJohn Baldwin 		switch (slot) {
2181368987aSJohn Baldwin 		case 0x12:
2191368987aSJohn Baldwin 			s = "Intel 82454NX PXB#0, Bus#A";
2201368987aSJohn Baldwin 			*busnum = pxb[0];
2211368987aSJohn Baldwin 			break;
2221368987aSJohn Baldwin 		case 0x13:
2231368987aSJohn Baldwin 			s = "Intel 82454NX PXB#0, Bus#B";
2241368987aSJohn Baldwin 			*busnum = pxb[1];
2251368987aSJohn Baldwin 			break;
2261368987aSJohn Baldwin 		case 0x14:
2271368987aSJohn Baldwin 			s = "Intel 82454NX PXB#1, Bus#A";
2281368987aSJohn Baldwin 			*busnum = pxb[2];
2291368987aSJohn Baldwin 			break;
2301368987aSJohn Baldwin 		case 0x15:
2311368987aSJohn Baldwin 			s = "Intel 82454NX PXB#1, Bus#B";
2321368987aSJohn Baldwin 			*busnum = pxb[3];
2331368987aSJohn Baldwin 			break;
2341368987aSJohn Baldwin 		}
2351368987aSJohn Baldwin 		break;
2361368987aSJohn Baldwin 	case 0x1A308086:
2371368987aSJohn Baldwin 		s = "Intel 82845 Host to PCI bridge";
2381368987aSJohn Baldwin 		break;
2391368987aSJohn Baldwin 
2401368987aSJohn Baldwin 		/* AMD -- vendor 0x1022 */
2411368987aSJohn Baldwin 	case 0x30001022:
2421368987aSJohn Baldwin 		s = "AMD Elan SC520 host to PCI bridge";
2431368987aSJohn Baldwin #ifdef CPU_ELAN
2441368987aSJohn Baldwin 		init_AMD_Elan_sc520();
2451368987aSJohn Baldwin #else
2461368987aSJohn Baldwin 		printf(
2471368987aSJohn Baldwin "*** WARNING: missing CPU_ELAN -- timekeeping may be wrong\n");
2481368987aSJohn Baldwin #endif
2491368987aSJohn Baldwin 		break;
2501368987aSJohn Baldwin 	case 0x70061022:
2511368987aSJohn Baldwin 		s = "AMD-751 host to PCI bridge";
2521368987aSJohn Baldwin 		break;
2531368987aSJohn Baldwin 	case 0x700e1022:
2541368987aSJohn Baldwin 		s = "AMD-761 host to PCI bridge";
2551368987aSJohn Baldwin 		break;
2561368987aSJohn Baldwin 
2571368987aSJohn Baldwin 		/* SiS -- vendor 0x1039 */
2581368987aSJohn Baldwin 	case 0x04961039:
2591368987aSJohn Baldwin 		s = "SiS 85c496";
2601368987aSJohn Baldwin 		break;
2611368987aSJohn Baldwin 	case 0x04061039:
2621368987aSJohn Baldwin 		s = "SiS 85c501";
2631368987aSJohn Baldwin 		break;
2641368987aSJohn Baldwin 	case 0x06011039:
2651368987aSJohn Baldwin 		s = "SiS 85c601";
2661368987aSJohn Baldwin 		break;
2671368987aSJohn Baldwin 	case 0x55911039:
2681368987aSJohn Baldwin 		s = "SiS 5591 host to PCI bridge";
2691368987aSJohn Baldwin 		break;
2701368987aSJohn Baldwin 	case 0x00011039:
2711368987aSJohn Baldwin 		s = "SiS 5591 host to AGP bridge";
2721368987aSJohn Baldwin 		break;
2731368987aSJohn Baldwin 
2741368987aSJohn Baldwin 		/* VLSI -- vendor 0x1004 */
2751368987aSJohn Baldwin 	case 0x00051004:
2761368987aSJohn Baldwin 		s = "VLSI 82C592 Host to PCI bridge";
2771368987aSJohn Baldwin 		break;
2781368987aSJohn Baldwin 
2791368987aSJohn Baldwin 		/* XXX Here is MVP3, I got the datasheet but NO M/B to test it  */
2801368987aSJohn Baldwin 		/* totally. Please let me know if anything wrong.            -F */
2811368987aSJohn Baldwin 		/* XXX need info on the MVP3 -- any takers? */
2821368987aSJohn Baldwin 	case 0x05981106:
2831368987aSJohn Baldwin 		s = "VIA 82C598MVP (Apollo MVP3) host bridge";
2841368987aSJohn Baldwin 		break;
2851368987aSJohn Baldwin 
2861368987aSJohn Baldwin 		/* AcerLabs -- vendor 0x10b9 */
2871368987aSJohn Baldwin 		/* Funny : The datasheet told me vendor id is "10b8",sub-vendor */
2881368987aSJohn Baldwin 		/* id is '10b9" but the register always shows "10b9". -Foxfair  */
2891368987aSJohn Baldwin 	case 0x154110b9:
2901368987aSJohn Baldwin 		s = "AcerLabs M1541 (Aladdin-V) PCI host bridge";
2911368987aSJohn Baldwin 		break;
2921368987aSJohn Baldwin 
2931368987aSJohn Baldwin 		/* OPTi -- vendor 0x1045 */
2941368987aSJohn Baldwin 	case 0xc7011045:
2951368987aSJohn Baldwin 		s = "OPTi 82C700 host to PCI bridge";
2961368987aSJohn Baldwin 		break;
2971368987aSJohn Baldwin 	case 0xc8221045:
2981368987aSJohn Baldwin 		s = "OPTi 82C822 host to PCI Bridge";
2991368987aSJohn Baldwin 		break;
3001368987aSJohn Baldwin 
3011368987aSJohn Baldwin 		/* ServerWorks -- vendor 0x1166 */
3021368987aSJohn Baldwin 	case 0x00051166:
3031368987aSJohn Baldwin 		s = "ServerWorks NB6536 2.0HE host to PCI bridge";
3041368987aSJohn Baldwin 		*busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1);
3051368987aSJohn Baldwin 		break;
3061368987aSJohn Baldwin 
3071368987aSJohn Baldwin 	case 0x00061166:
3081368987aSJohn Baldwin 		/* FALLTHROUGH */
3091368987aSJohn Baldwin 	case 0x00081166:
3101368987aSJohn Baldwin 		/* FALLTHROUGH */
3111368987aSJohn Baldwin 	case 0x02011166:
3121368987aSJohn Baldwin 		/* FALLTHROUGH */
3131368987aSJohn Baldwin 	case 0x010f1014: /* IBM re-badged ServerWorks chipset */
3141368987aSJohn Baldwin 		s = "ServerWorks host to PCI bridge";
3151368987aSJohn Baldwin 		*busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1);
3161368987aSJohn Baldwin 		break;
3171368987aSJohn Baldwin 
3181368987aSJohn Baldwin 	case 0x00091166:
3191368987aSJohn Baldwin 		s = "ServerWorks NB6635 3.0LE host to PCI bridge";
3201368987aSJohn Baldwin 		*busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1);
3211368987aSJohn Baldwin 		break;
3221368987aSJohn Baldwin 
3231368987aSJohn Baldwin 	case 0x00101166:
3241368987aSJohn Baldwin 		s = "ServerWorks CIOB30 host to PCI bridge";
3251368987aSJohn Baldwin 		*busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1);
3261368987aSJohn Baldwin 		break;
3271368987aSJohn Baldwin 
3281368987aSJohn Baldwin 	case 0x00111166:
3291368987aSJohn Baldwin 		/* FALLTHROUGH */
3301368987aSJohn Baldwin 	case 0x03021014: /* IBM re-badged ServerWorks chipset */
3311368987aSJohn Baldwin 		s = "ServerWorks CMIC-HE host to PCI-X bridge";
3321368987aSJohn Baldwin 		*busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1);
3331368987aSJohn Baldwin 		break;
3341368987aSJohn Baldwin 
3351368987aSJohn Baldwin 		/* XXX unknown chipset, but working */
3361368987aSJohn Baldwin 	case 0x00171166:
3371368987aSJohn Baldwin 		/* FALLTHROUGH */
3381368987aSJohn Baldwin 	case 0x01011166:
3391368987aSJohn Baldwin 	case 0x01101166:
3401368987aSJohn Baldwin 	case 0x02251166:
3411368987aSJohn Baldwin 		s = "ServerWorks host to PCI bridge(unknown chipset)";
3421368987aSJohn Baldwin 		*busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1);
3431368987aSJohn Baldwin 		break;
3441368987aSJohn Baldwin 
3451368987aSJohn Baldwin 		/* Compaq/HP -- vendor 0x0e11 */
3461368987aSJohn Baldwin 	case 0x60100e11:
3471368987aSJohn Baldwin 		s = "Compaq/HP Model 6010 HotPlug PCI Bridge";
3481368987aSJohn Baldwin 		*busnum = legacy_pcib_read_config(0, bus, slot, func, 0xc8, 1);
3491368987aSJohn Baldwin 		break;
3501368987aSJohn Baldwin 
3511368987aSJohn Baldwin 		/* Integrated Micro Solutions -- vendor 0x10e0 */
3521368987aSJohn Baldwin 	case 0x884910e0:
3531368987aSJohn Baldwin 		s = "Integrated Micro Solutions VL Bridge";
3541368987aSJohn Baldwin 		break;
3551368987aSJohn Baldwin 
3561368987aSJohn Baldwin 	default:
3571368987aSJohn Baldwin 		if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST)
3581368987aSJohn Baldwin 			s = "Host to PCI bridge";
3591368987aSJohn Baldwin 		break;
3601368987aSJohn Baldwin 	}
3611368987aSJohn Baldwin 
3621368987aSJohn Baldwin 	return s;
3631368987aSJohn Baldwin #else
3641368987aSJohn Baldwin 	const char *s = NULL;
3651368987aSJohn Baldwin 
3661368987aSJohn Baldwin 	*busnum = 0;
3671368987aSJohn Baldwin 	if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST)
3681368987aSJohn Baldwin 		s = "Host to PCI bridge";
3691368987aSJohn Baldwin 	return s;
3701368987aSJohn Baldwin #endif
3711368987aSJohn Baldwin }
3721368987aSJohn Baldwin 
3731368987aSJohn Baldwin /*
3741368987aSJohn Baldwin  * Scan the first pci bus for host-pci bridges and add pcib instances
3751368987aSJohn Baldwin  * to the nexus for each bridge.
3761368987aSJohn Baldwin  */
3771368987aSJohn Baldwin static void
3781368987aSJohn Baldwin legacy_pcib_identify(driver_t *driver, device_t parent)
3791368987aSJohn Baldwin {
3801368987aSJohn Baldwin 	int bus, slot, func;
3811368987aSJohn Baldwin 	uint8_t  hdrtype;
3821368987aSJohn Baldwin 	int found = 0;
3831368987aSJohn Baldwin 	int pcifunchigh;
3841368987aSJohn Baldwin 	int found824xx = 0;
3851368987aSJohn Baldwin 	int found_orion = 0;
3861368987aSJohn Baldwin 	device_t child;
3871368987aSJohn Baldwin 	devclass_t pci_devclass;
3881368987aSJohn Baldwin 
3891368987aSJohn Baldwin 	if (pci_cfgregopen() == 0)
3901368987aSJohn Baldwin 		return;
3911368987aSJohn Baldwin 	/*
3921368987aSJohn Baldwin 	 * Check to see if we haven't already had a PCI bus added
3931368987aSJohn Baldwin 	 * via some other means.  If we have, bail since otherwise
3941368987aSJohn Baldwin 	 * we're going to end up duplicating it.
3951368987aSJohn Baldwin 	 */
3961368987aSJohn Baldwin 	if ((pci_devclass = devclass_find("pci")) &&
3971368987aSJohn Baldwin 		devclass_get_device(pci_devclass, 0))
3981368987aSJohn Baldwin 		return;
3991368987aSJohn Baldwin 
4001368987aSJohn Baldwin 
4011368987aSJohn Baldwin 	bus = 0;
4021368987aSJohn Baldwin  retry:
4031368987aSJohn Baldwin 	for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
4041368987aSJohn Baldwin 		func = 0;
4051368987aSJohn Baldwin 		hdrtype = legacy_pcib_read_config(0, bus, slot, func,
4061368987aSJohn Baldwin 						 PCIR_HDRTYPE, 1);
4071368987aSJohn Baldwin 		/*
4081368987aSJohn Baldwin 		 * When enumerating bus devices, the standard says that
4091368987aSJohn Baldwin 		 * one should check the header type and ignore the slots whose
4101368987aSJohn Baldwin 		 * header types that the software doesn't know about.  We use
4111368987aSJohn Baldwin 		 * this to filter out devices.
4121368987aSJohn Baldwin 		 */
4131368987aSJohn Baldwin 		if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
4141368987aSJohn Baldwin 			continue;
4151368987aSJohn Baldwin 		if ((hdrtype & PCIM_MFDEV) &&
4161368987aSJohn Baldwin 		    (!found_orion || hdrtype != 0xff))
4171368987aSJohn Baldwin 			pcifunchigh = PCI_FUNCMAX;
4181368987aSJohn Baldwin 		else
4191368987aSJohn Baldwin 			pcifunchigh = 0;
4201368987aSJohn Baldwin 		for (func = 0; func <= pcifunchigh; func++) {
4211368987aSJohn Baldwin 			/*
4221368987aSJohn Baldwin 			 * Read the IDs and class from the device.
4231368987aSJohn Baldwin 			 */
4241368987aSJohn Baldwin 			uint32_t id;
4251368987aSJohn Baldwin 			uint8_t class, subclass, busnum;
4261368987aSJohn Baldwin 			const char *s;
4271368987aSJohn Baldwin 			device_t *devs;
4281368987aSJohn Baldwin 			int ndevs, i;
4291368987aSJohn Baldwin 
4301368987aSJohn Baldwin 			id = legacy_pcib_read_config(0, bus, slot, func,
4311368987aSJohn Baldwin 						    PCIR_DEVVENDOR, 4);
4321368987aSJohn Baldwin 			if (id == -1)
4331368987aSJohn Baldwin 				continue;
4341368987aSJohn Baldwin 			class = legacy_pcib_read_config(0, bus, slot, func,
4351368987aSJohn Baldwin 						       PCIR_CLASS, 1);
4361368987aSJohn Baldwin 			subclass = legacy_pcib_read_config(0, bus, slot, func,
4371368987aSJohn Baldwin 							  PCIR_SUBCLASS, 1);
4381368987aSJohn Baldwin 
4391368987aSJohn Baldwin 			s = legacy_pcib_is_host_bridge(bus, slot, func,
4401368987aSJohn Baldwin 						      id, class, subclass,
4411368987aSJohn Baldwin 						      &busnum);
4421368987aSJohn Baldwin 			if (s == NULL)
4431368987aSJohn Baldwin 				continue;
4441368987aSJohn Baldwin 
4451368987aSJohn Baldwin 			/*
4461368987aSJohn Baldwin 			 * Check to see if the physical bus has already
4471368987aSJohn Baldwin 			 * been seen.  Eg: hybrid 32 and 64 bit host
4481368987aSJohn Baldwin 			 * bridges to the same logical bus.
4491368987aSJohn Baldwin 			 */
4501368987aSJohn Baldwin 			if (device_get_children(parent, &devs, &ndevs) == 0) {
4511368987aSJohn Baldwin 				for (i = 0; s != NULL && i < ndevs; i++) {
4521368987aSJohn Baldwin 					if (strcmp(device_get_name(devs[i]),
4531368987aSJohn Baldwin 					    "pcib") != 0)
4541368987aSJohn Baldwin 						continue;
4551368987aSJohn Baldwin 					if (legacy_get_pcibus(devs[i]) == busnum)
4561368987aSJohn Baldwin 						s = NULL;
4571368987aSJohn Baldwin 				}
4581368987aSJohn Baldwin 				free(devs, M_TEMP);
4591368987aSJohn Baldwin 			}
4601368987aSJohn Baldwin 
4611368987aSJohn Baldwin 			if (s == NULL)
4621368987aSJohn Baldwin 				continue;
4631368987aSJohn Baldwin 			/*
4641368987aSJohn Baldwin 			 * Add at priority 100 to make sure we
4651368987aSJohn Baldwin 			 * go after any motherboard resources
4661368987aSJohn Baldwin 			 */
4671368987aSJohn Baldwin 			child = BUS_ADD_CHILD(parent, 100,
4681368987aSJohn Baldwin 					      "pcib", busnum);
4691368987aSJohn Baldwin 			device_set_desc(child, s);
4701368987aSJohn Baldwin 			legacy_set_pcibus(child, busnum);
4710d95597cSJohn Baldwin 			legacy_set_pcislot(child, slot);
4720d95597cSJohn Baldwin 			legacy_set_pcifunc(child, func);
4731368987aSJohn Baldwin 
4741368987aSJohn Baldwin 			found = 1;
4751368987aSJohn Baldwin 			if (id == 0x12258086)
4761368987aSJohn Baldwin 				found824xx = 1;
4771368987aSJohn Baldwin 			if (id == 0x84c48086)
4781368987aSJohn Baldwin 				found_orion = 1;
4791368987aSJohn Baldwin 		}
4801368987aSJohn Baldwin 	}
4811368987aSJohn Baldwin 	if (found824xx && bus == 0) {
4821368987aSJohn Baldwin 		bus++;
4831368987aSJohn Baldwin 		goto retry;
4841368987aSJohn Baldwin 	}
4851368987aSJohn Baldwin 
4861368987aSJohn Baldwin 	/*
4871368987aSJohn Baldwin 	 * Make sure we add at least one bridge since some old
4881368987aSJohn Baldwin 	 * hardware doesn't actually have a host-pci bridge device.
4891368987aSJohn Baldwin 	 * Note that pci_cfgregopen() thinks we have PCI devices..
4901368987aSJohn Baldwin 	 */
4911368987aSJohn Baldwin 	if (!found) {
4921368987aSJohn Baldwin 		if (bootverbose)
4931368987aSJohn Baldwin 			printf(
4941368987aSJohn Baldwin 	"legacy_pcib_identify: no bridge found, adding pcib0 anyway\n");
4951368987aSJohn Baldwin 		child = BUS_ADD_CHILD(parent, 100, "pcib", 0);
4961368987aSJohn Baldwin 		legacy_set_pcibus(child, 0);
4971368987aSJohn Baldwin 	}
4981368987aSJohn Baldwin }
4991368987aSJohn Baldwin 
5001368987aSJohn Baldwin static int
5011368987aSJohn Baldwin legacy_pcib_probe(device_t dev)
5021368987aSJohn Baldwin {
5031368987aSJohn Baldwin 
5041368987aSJohn Baldwin 	if (pci_cfgregopen() == 0)
5051368987aSJohn Baldwin 		return ENXIO;
5061368987aSJohn Baldwin 	return -100;
5071368987aSJohn Baldwin }
5081368987aSJohn Baldwin 
5091368987aSJohn Baldwin static int
5101368987aSJohn Baldwin legacy_pcib_attach(device_t dev)
5111368987aSJohn Baldwin {
5121368987aSJohn Baldwin #ifdef __HAVE_PIR
5131368987aSJohn Baldwin 	device_t pir;
5141368987aSJohn Baldwin #endif
5151368987aSJohn Baldwin 	int bus;
5161368987aSJohn Baldwin 
5171368987aSJohn Baldwin 	bus = pcib_get_bus(dev);
5181368987aSJohn Baldwin #ifdef __HAVE_PIR
5191368987aSJohn Baldwin 	/*
5201368987aSJohn Baldwin 	 * Look for a PCI BIOS interrupt routing table as that will be
5211368987aSJohn Baldwin 	 * our method of routing interrupts if we have one.
5221368987aSJohn Baldwin 	 */
5231368987aSJohn Baldwin 	if (pci_pir_probe(bus, 0)) {
5241368987aSJohn Baldwin 		pir = BUS_ADD_CHILD(device_get_parent(dev), 0, "pir", 0);
5251368987aSJohn Baldwin 		if (pir != NULL)
5261368987aSJohn Baldwin 			device_probe_and_attach(pir);
5271368987aSJohn Baldwin 	}
5281368987aSJohn Baldwin #endif
52918c72666SZbigniew Bodek 	device_add_child(dev, "pci", -1);
5301368987aSJohn Baldwin 	return bus_generic_attach(dev);
5311368987aSJohn Baldwin }
5321368987aSJohn Baldwin 
5331368987aSJohn Baldwin int
5341368987aSJohn Baldwin legacy_pcib_read_ivar(device_t dev, device_t child, int which,
5351368987aSJohn Baldwin     uintptr_t *result)
5361368987aSJohn Baldwin {
5371368987aSJohn Baldwin 
5381368987aSJohn Baldwin 	switch (which) {
5391368987aSJohn Baldwin 	case  PCIB_IVAR_DOMAIN:
5401368987aSJohn Baldwin 		*result = 0;
5411368987aSJohn Baldwin 		return 0;
5421368987aSJohn Baldwin 	case  PCIB_IVAR_BUS:
5431368987aSJohn Baldwin 		*result = legacy_get_pcibus(dev);
5441368987aSJohn Baldwin 		return 0;
5451368987aSJohn Baldwin 	}
5461368987aSJohn Baldwin 	return ENOENT;
5471368987aSJohn Baldwin }
5481368987aSJohn Baldwin 
5491368987aSJohn Baldwin int
5501368987aSJohn Baldwin legacy_pcib_write_ivar(device_t dev, device_t child, int which,
5511368987aSJohn Baldwin     uintptr_t value)
5521368987aSJohn Baldwin {
5531368987aSJohn Baldwin 
5541368987aSJohn Baldwin 	switch (which) {
5551368987aSJohn Baldwin 	case  PCIB_IVAR_DOMAIN:
5561368987aSJohn Baldwin 		return EINVAL;
5571368987aSJohn Baldwin 	case  PCIB_IVAR_BUS:
5581368987aSJohn Baldwin 		legacy_set_pcibus(dev, value);
5591368987aSJohn Baldwin 		return 0;
5601368987aSJohn Baldwin 	}
5611368987aSJohn Baldwin 	return ENOENT;
5621368987aSJohn Baldwin }
5631368987aSJohn Baldwin 
5641368987aSJohn Baldwin /*
5651368987aSJohn Baldwin  * Helper routine for x86 Host-PCI bridge driver resource allocation.
5661368987aSJohn Baldwin  * This is used to adjust the start address of wildcard allocation
5671368987aSJohn Baldwin  * requests to avoid low addresses that are known to be problematic.
5681368987aSJohn Baldwin  *
5691368987aSJohn Baldwin  * If no memory preference is given, use upper 32MB slot most BIOSes
5701368987aSJohn Baldwin  * use for their memory window.  This is typically only used on older
571db4fcadfSConrad Meyer  * laptops that don't have PCI buses behind a PCI bridge, so assuming
5721368987aSJohn Baldwin  * > 32MB is likely OK.
5731368987aSJohn Baldwin  *
5741368987aSJohn Baldwin  * However, this can cause problems for other chipsets, so we make
5751368987aSJohn Baldwin  * this tunable by hw.pci.host_mem_start.
5761368987aSJohn Baldwin  */
5771368987aSJohn Baldwin SYSCTL_DECL(_hw_pci);
5781368987aSJohn Baldwin 
5791368987aSJohn Baldwin static unsigned long host_mem_start = 0x80000000;
5801368987aSJohn Baldwin SYSCTL_ULONG(_hw_pci, OID_AUTO, host_mem_start, CTLFLAG_RDTUN, &host_mem_start,
5811368987aSJohn Baldwin     0, "Limit the host bridge memory to being above this address.");
5821368987aSJohn Baldwin 
5832dd1bdf1SJustin Hibbits rman_res_t
5842dd1bdf1SJustin Hibbits hostb_alloc_start(int type, rman_res_t start, rman_res_t end, rman_res_t count)
5851368987aSJohn Baldwin {
5861368987aSJohn Baldwin 
5871368987aSJohn Baldwin 	if (start + count - 1 != end) {
5881368987aSJohn Baldwin 		if (type == SYS_RES_MEMORY && start < host_mem_start)
5891368987aSJohn Baldwin 			start = host_mem_start;
5901368987aSJohn Baldwin 		if (type == SYS_RES_IOPORT && start < 0x1000)
5911368987aSJohn Baldwin 			start = 0x1000;
5921368987aSJohn Baldwin 	}
5931368987aSJohn Baldwin 	return (start);
5941368987aSJohn Baldwin }
5951368987aSJohn Baldwin 
5961368987aSJohn Baldwin struct resource *
5971368987aSJohn Baldwin legacy_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
5982dd1bdf1SJustin Hibbits     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
5991368987aSJohn Baldwin {
6001368987aSJohn Baldwin 
6014edef187SJohn Baldwin #if defined(NEW_PCIB) && defined(PCI_RES_BUS)
6024edef187SJohn Baldwin 	if (type == PCI_RES_BUS)
6034edef187SJohn Baldwin 		return (pci_domain_alloc_bus(0, child, rid, start, end, count,
6044edef187SJohn Baldwin 		    flags));
6054edef187SJohn Baldwin #endif
6061368987aSJohn Baldwin 	start = hostb_alloc_start(type, start, end, count);
6071368987aSJohn Baldwin 	return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
6081368987aSJohn Baldwin 	    count, flags));
6091368987aSJohn Baldwin }
6101368987aSJohn Baldwin 
6114edef187SJohn Baldwin #if defined(NEW_PCIB) && defined(PCI_RES_BUS)
6124edef187SJohn Baldwin int
6134edef187SJohn Baldwin legacy_pcib_adjust_resource(device_t dev, device_t child, int type,
6142dd1bdf1SJustin Hibbits     struct resource *r, rman_res_t start, rman_res_t end)
6154edef187SJohn Baldwin {
6164edef187SJohn Baldwin 
6174edef187SJohn Baldwin 	if (type == PCI_RES_BUS)
6184edef187SJohn Baldwin 		return (pci_domain_adjust_bus(0, child, r, start, end));
6194edef187SJohn Baldwin 	return (bus_generic_adjust_resource(dev, child, type, r, start, end));
6204edef187SJohn Baldwin }
6214edef187SJohn Baldwin 
6224edef187SJohn Baldwin int
6234edef187SJohn Baldwin legacy_pcib_release_resource(device_t dev, device_t child, int type, int rid,
6244edef187SJohn Baldwin     struct resource *r)
6254edef187SJohn Baldwin {
6264edef187SJohn Baldwin 
6274edef187SJohn Baldwin 	if (type == PCI_RES_BUS)
6284edef187SJohn Baldwin 		return (pci_domain_release_bus(0, child, rid, r));
6294edef187SJohn Baldwin 	return (bus_generic_release_resource(dev, child, type, rid, r));
6304edef187SJohn Baldwin }
6314edef187SJohn Baldwin #endif
6324edef187SJohn Baldwin 
6331368987aSJohn Baldwin static device_method_t legacy_pcib_methods[] = {
6341368987aSJohn Baldwin 	/* Device interface */
6351368987aSJohn Baldwin 	DEVMETHOD(device_identify,	legacy_pcib_identify),
6361368987aSJohn Baldwin 	DEVMETHOD(device_probe,		legacy_pcib_probe),
6371368987aSJohn Baldwin 	DEVMETHOD(device_attach,	legacy_pcib_attach),
6381368987aSJohn Baldwin 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
6391368987aSJohn Baldwin 	DEVMETHOD(device_suspend,	bus_generic_suspend),
6401368987aSJohn Baldwin 	DEVMETHOD(device_resume,	bus_generic_resume),
6411368987aSJohn Baldwin 
6421368987aSJohn Baldwin 	/* Bus interface */
6431368987aSJohn Baldwin 	DEVMETHOD(bus_read_ivar,	legacy_pcib_read_ivar),
6441368987aSJohn Baldwin 	DEVMETHOD(bus_write_ivar,	legacy_pcib_write_ivar),
6451368987aSJohn Baldwin 	DEVMETHOD(bus_alloc_resource,	legacy_pcib_alloc_resource),
6464edef187SJohn Baldwin #if defined(NEW_PCIB) && defined(PCI_RES_BUS)
6474edef187SJohn Baldwin 	DEVMETHOD(bus_adjust_resource,	legacy_pcib_adjust_resource),
6484edef187SJohn Baldwin 	DEVMETHOD(bus_release_resource,	legacy_pcib_release_resource),
6494edef187SJohn Baldwin #else
6501368987aSJohn Baldwin 	DEVMETHOD(bus_adjust_resource,	bus_generic_adjust_resource),
6511368987aSJohn Baldwin 	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
6524edef187SJohn Baldwin #endif
6531368987aSJohn Baldwin 	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
6541368987aSJohn Baldwin 	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
6551368987aSJohn Baldwin 	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
6561368987aSJohn Baldwin 	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
6571368987aSJohn Baldwin 
6581368987aSJohn Baldwin 	/* pcib interface */
6591368987aSJohn Baldwin 	DEVMETHOD(pcib_maxslots,	legacy_pcib_maxslots),
6601368987aSJohn Baldwin 	DEVMETHOD(pcib_read_config,	legacy_pcib_read_config),
6611368987aSJohn Baldwin 	DEVMETHOD(pcib_write_config,	legacy_pcib_write_config),
6621368987aSJohn Baldwin 	DEVMETHOD(pcib_route_interrupt,	legacy_pcib_route_interrupt),
6631368987aSJohn Baldwin 	DEVMETHOD(pcib_alloc_msi,	legacy_pcib_alloc_msi),
6641368987aSJohn Baldwin 	DEVMETHOD(pcib_release_msi,	pcib_release_msi),
6651368987aSJohn Baldwin 	DEVMETHOD(pcib_alloc_msix,	legacy_pcib_alloc_msix),
6661368987aSJohn Baldwin 	DEVMETHOD(pcib_release_msix,	pcib_release_msix),
6671368987aSJohn Baldwin 	DEVMETHOD(pcib_map_msi,		legacy_pcib_map_msi),
66828586889SWarner Losh 	DEVMETHOD(pcib_request_feature,	pcib_request_feature_allow),
6691368987aSJohn Baldwin 
6704b7ec270SMarius Strobl 	DEVMETHOD_END
6711368987aSJohn Baldwin };
6721368987aSJohn Baldwin 
6731368987aSJohn Baldwin static devclass_t hostb_devclass;
6741368987aSJohn Baldwin 
6751368987aSJohn Baldwin DEFINE_CLASS_0(pcib, legacy_pcib_driver, legacy_pcib_methods, 1);
6761368987aSJohn Baldwin DRIVER_MODULE(pcib, legacy, legacy_pcib_driver, hostb_devclass, 0, 0);
6771368987aSJohn Baldwin 
6781368987aSJohn Baldwin 
6791368987aSJohn Baldwin /*
6801368987aSJohn Baldwin  * Install placeholder to claim the resources owned by the
6811368987aSJohn Baldwin  * PCI bus interface.  This could be used to extract the
6821368987aSJohn Baldwin  * config space registers in the extreme case where the PnP
6831368987aSJohn Baldwin  * ID is available and the PCI BIOS isn't, but for now we just
6841368987aSJohn Baldwin  * eat the PnP ID and do nothing else.
6851368987aSJohn Baldwin  *
686*d6b66397SWarner Losh  * we silence this probe, as it will generally confuse people.
6871368987aSJohn Baldwin  */
6881368987aSJohn Baldwin static struct isa_pnp_id pcibus_pnp_ids[] = {
6891368987aSJohn Baldwin 	{ 0x030ad041 /* PNP0A03 */, "PCI Bus" },
6901368987aSJohn Baldwin 	{ 0x080ad041 /* PNP0A08 */, "PCIe Bus" },
6911368987aSJohn Baldwin 	{ 0 }
6921368987aSJohn Baldwin };
6931368987aSJohn Baldwin 
6941368987aSJohn Baldwin static int
6951368987aSJohn Baldwin pcibus_pnp_probe(device_t dev)
6961368987aSJohn Baldwin {
6971368987aSJohn Baldwin 	int result;
6981368987aSJohn Baldwin 
6991368987aSJohn Baldwin 	if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, pcibus_pnp_ids)) <= 0)
7001368987aSJohn Baldwin 		device_quiet(dev);
7011368987aSJohn Baldwin 	return(result);
7021368987aSJohn Baldwin }
7031368987aSJohn Baldwin 
7041368987aSJohn Baldwin static int
7051368987aSJohn Baldwin pcibus_pnp_attach(device_t dev)
7061368987aSJohn Baldwin {
7071368987aSJohn Baldwin 	return(0);
7081368987aSJohn Baldwin }
7091368987aSJohn Baldwin 
7101368987aSJohn Baldwin static device_method_t pcibus_pnp_methods[] = {
7111368987aSJohn Baldwin 	/* Device interface */
7121368987aSJohn Baldwin 	DEVMETHOD(device_probe,		pcibus_pnp_probe),
7131368987aSJohn Baldwin 	DEVMETHOD(device_attach,	pcibus_pnp_attach),
7141368987aSJohn Baldwin 	DEVMETHOD(device_detach,	bus_generic_detach),
7151368987aSJohn Baldwin 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
7161368987aSJohn Baldwin 	DEVMETHOD(device_suspend,	bus_generic_suspend),
7171368987aSJohn Baldwin 	DEVMETHOD(device_resume,	bus_generic_resume),
7181368987aSJohn Baldwin 	{ 0, 0 }
7191368987aSJohn Baldwin };
7201368987aSJohn Baldwin 
7211368987aSJohn Baldwin static devclass_t pcibus_pnp_devclass;
7221368987aSJohn Baldwin 
7231368987aSJohn Baldwin DEFINE_CLASS_0(pcibus_pnp, pcibus_pnp_driver, pcibus_pnp_methods, 1);
7241368987aSJohn Baldwin DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0);
7251368987aSJohn Baldwin 
7261368987aSJohn Baldwin #ifdef __HAVE_PIR
7271368987aSJohn Baldwin /*
728db4fcadfSConrad Meyer  * Provide a PCI-PCI bridge driver for PCI buses behind PCI-PCI bridges
7291368987aSJohn Baldwin  * that appear in the PCIBIOS Interrupt Routing Table to use the routing
7301368987aSJohn Baldwin  * table for interrupt routing when possible.
7311368987aSJohn Baldwin  */
7321368987aSJohn Baldwin static int	pcibios_pcib_probe(device_t bus);
7331368987aSJohn Baldwin 
7341368987aSJohn Baldwin static device_method_t pcibios_pcib_pci_methods[] = {
7351368987aSJohn Baldwin 	/* Device interface */
7361368987aSJohn Baldwin 	DEVMETHOD(device_probe,		pcibios_pcib_probe),
7371368987aSJohn Baldwin 
7381368987aSJohn Baldwin 	/* pcib interface */
7391368987aSJohn Baldwin 	DEVMETHOD(pcib_route_interrupt,	legacy_pcib_route_interrupt),
7401368987aSJohn Baldwin 
7411368987aSJohn Baldwin 	{0, 0}
7421368987aSJohn Baldwin };
7431368987aSJohn Baldwin 
7441368987aSJohn Baldwin static devclass_t pcib_devclass;
7451368987aSJohn Baldwin 
7461368987aSJohn Baldwin DEFINE_CLASS_1(pcib, pcibios_pcib_driver, pcibios_pcib_pci_methods,
7471368987aSJohn Baldwin     sizeof(struct pcib_softc), pcib_driver);
7481368987aSJohn Baldwin DRIVER_MODULE(pcibios_pcib, pci, pcibios_pcib_driver, pcib_devclass, 0, 0);
749*d6b66397SWarner Losh ISA_PNP_INFO(pcibus_pnp_ids);
7501368987aSJohn Baldwin 
7511368987aSJohn Baldwin static int
7521368987aSJohn Baldwin pcibios_pcib_probe(device_t dev)
7531368987aSJohn Baldwin {
7541368987aSJohn Baldwin 	int bus;
7551368987aSJohn Baldwin 
7561368987aSJohn Baldwin 	if ((pci_get_class(dev) != PCIC_BRIDGE) ||
7571368987aSJohn Baldwin 	    (pci_get_subclass(dev) != PCIS_BRIDGE_PCI))
7581368987aSJohn Baldwin 		return (ENXIO);
7591368987aSJohn Baldwin 	bus = pci_read_config(dev, PCIR_SECBUS_1, 1);
7601368987aSJohn Baldwin 	if (bus == 0)
7611368987aSJohn Baldwin 		return (ENXIO);
7621368987aSJohn Baldwin 	if (!pci_pir_probe(bus, 1))
7631368987aSJohn Baldwin 		return (ENXIO);
7641368987aSJohn Baldwin 	device_set_desc(dev, "PCIBIOS PCI-PCI bridge");
7651368987aSJohn Baldwin 	return (-2000);
7661368987aSJohn Baldwin }
7671368987aSJohn Baldwin #endif
768