xref: /dflybsd-src/sys/bus/pci/hostb_pci.c (revision 6589c7619ebe1d6df15a9228bd3db866fe36e4bc)
14d28e78fSSepherosa Ziehau /*
24d28e78fSSepherosa Ziehau  * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
34d28e78fSSepherosa Ziehau  * All rights reserved.
44d28e78fSSepherosa Ziehau  *
54d28e78fSSepherosa Ziehau  * Redistribution and use in source and binary forms, with or without
64d28e78fSSepherosa Ziehau  * modification, are permitted provided that the following conditions
74d28e78fSSepherosa Ziehau  * are met:
84d28e78fSSepherosa Ziehau  * 1. Redistributions of source code must retain the above copyright
94d28e78fSSepherosa Ziehau  *    notice unmodified, this list of conditions, and the following
104d28e78fSSepherosa Ziehau  *    disclaimer.
114d28e78fSSepherosa Ziehau  * 2. Redistributions in binary form must reproduce the above copyright
124d28e78fSSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer in the
134d28e78fSSepherosa Ziehau  *    documentation and/or other materials provided with the distribution.
144d28e78fSSepherosa Ziehau  *
154d28e78fSSepherosa Ziehau  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
164d28e78fSSepherosa Ziehau  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
174d28e78fSSepherosa Ziehau  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
184d28e78fSSepherosa Ziehau  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
194d28e78fSSepherosa Ziehau  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
204d28e78fSSepherosa Ziehau  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
214d28e78fSSepherosa Ziehau  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
224d28e78fSSepherosa Ziehau  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
234d28e78fSSepherosa Ziehau  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
244d28e78fSSepherosa Ziehau  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2583c1faaaSSascha Wildner  *
2683c1faaaSSascha Wildner  * $FreeBSD: src/sys/dev/pci/hostb_pci.c,v 1.1.8.1 2009/04/15 03:14:26 kensmith Exp $
274d28e78fSSepherosa Ziehau  */
284d28e78fSSepherosa Ziehau 
294d28e78fSSepherosa Ziehau #include <sys/param.h>
304d28e78fSSepherosa Ziehau #include <sys/bus.h>
314d28e78fSSepherosa Ziehau #include <sys/kernel.h>
324d28e78fSSepherosa Ziehau #include <sys/module.h>
334d28e78fSSepherosa Ziehau 
344d28e78fSSepherosa Ziehau #include <sys/types.h>
354d28e78fSSepherosa Ziehau #include <sys/systm.h>
364d28e78fSSepherosa Ziehau 
374d28e78fSSepherosa Ziehau #include <bus/pci/pcivar.h>
384d28e78fSSepherosa Ziehau #include <bus/pci/pcireg.h>
394d28e78fSSepherosa Ziehau 
404d28e78fSSepherosa Ziehau /*
414d28e78fSSepherosa Ziehau  * Provide a device to "eat" the host->pci bridge devices that show up
424d28e78fSSepherosa Ziehau  * on PCI busses and stop them showing up twice on the probes.  This also
434d28e78fSSepherosa Ziehau  * stops them showing up as 'none' in pciconf -l.  If the host bridge
444d28e78fSSepherosa Ziehau  * provides an AGP capability then we create a child agp device for the
454d28e78fSSepherosa Ziehau  * agp GART driver to attach to.
464d28e78fSSepherosa Ziehau  */
474d28e78fSSepherosa Ziehau static int
pci_hostb_probe(device_t dev)484d28e78fSSepherosa Ziehau pci_hostb_probe(device_t dev)
494d28e78fSSepherosa Ziehau {
504d28e78fSSepherosa Ziehau 	u_int32_t id;
514d28e78fSSepherosa Ziehau 	id = pci_get_devid(dev);
524d28e78fSSepherosa Ziehau 
534d28e78fSSepherosa Ziehau 	switch (id) {
544d28e78fSSepherosa Ziehau 
554d28e78fSSepherosa Ziehau 	/* VIA VT82C596 Power Managment Function */
564d28e78fSSepherosa Ziehau 	case 0x30501106:
574d28e78fSSepherosa Ziehau 		return (ENXIO);
584d28e78fSSepherosa Ziehau 
594d28e78fSSepherosa Ziehau 	default:
604d28e78fSSepherosa Ziehau 		break;
614d28e78fSSepherosa Ziehau 	}
624d28e78fSSepherosa Ziehau 
634d28e78fSSepherosa Ziehau 	if (pci_get_class(dev) == PCIC_BRIDGE &&
644d28e78fSSepherosa Ziehau 	    pci_get_subclass(dev) == PCIS_BRIDGE_HOST) {
654d28e78fSSepherosa Ziehau 		device_set_desc(dev, "Host to PCI bridge");
664d28e78fSSepherosa Ziehau 		device_quiet(dev);
674d28e78fSSepherosa Ziehau 		return (-10000);
684d28e78fSSepherosa Ziehau 	}
694d28e78fSSepherosa Ziehau 	return (ENXIO);
704d28e78fSSepherosa Ziehau }
714d28e78fSSepherosa Ziehau 
724d28e78fSSepherosa Ziehau static int
pci_hostb_attach(device_t dev)734d28e78fSSepherosa Ziehau pci_hostb_attach(device_t dev)
744d28e78fSSepherosa Ziehau {
754d28e78fSSepherosa Ziehau 
764d28e78fSSepherosa Ziehau 	bus_generic_probe(dev);
774d28e78fSSepherosa Ziehau 
784d28e78fSSepherosa Ziehau 	/*
794d28e78fSSepherosa Ziehau 	 * If AGP capabilities are present on this device, then create
804d28e78fSSepherosa Ziehau 	 * an AGP child.
814d28e78fSSepherosa Ziehau 	 */
824d28e78fSSepherosa Ziehau 	if (pci_find_extcap(dev, PCIY_AGP, NULL) == 0)
834d28e78fSSepherosa Ziehau 		device_add_child(dev, "agp", -1);
844d28e78fSSepherosa Ziehau 	bus_generic_attach(dev);
854d28e78fSSepherosa Ziehau 	return (0);
864d28e78fSSepherosa Ziehau }
874d28e78fSSepherosa Ziehau 
884d28e78fSSepherosa Ziehau /* Bus interface. */
894d28e78fSSepherosa Ziehau 
904d28e78fSSepherosa Ziehau static int
pci_hostb_read_ivar(device_t dev,device_t child,int which,uintptr_t * result)914d28e78fSSepherosa Ziehau pci_hostb_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
924d28e78fSSepherosa Ziehau {
934d28e78fSSepherosa Ziehau 
944d28e78fSSepherosa Ziehau 	return (BUS_READ_IVAR(device_get_parent(dev), dev, which, result));
954d28e78fSSepherosa Ziehau }
964d28e78fSSepherosa Ziehau 
974d28e78fSSepherosa Ziehau static int
pci_hostb_write_ivar(device_t dev,device_t child,int which,uintptr_t value)984d28e78fSSepherosa Ziehau pci_hostb_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
994d28e78fSSepherosa Ziehau {
1004d28e78fSSepherosa Ziehau 
1014d28e78fSSepherosa Ziehau 	return (EINVAL);
1024d28e78fSSepherosa Ziehau }
1034d28e78fSSepherosa Ziehau 
1044d28e78fSSepherosa Ziehau static struct resource *
pci_hostb_alloc_resource(device_t dev,device_t child,int type,int * rid,u_long start,u_long end,u_long count,u_int flags,int cpuid __unused)1054d28e78fSSepherosa Ziehau pci_hostb_alloc_resource(device_t dev, device_t child, int type, int *rid,
1064f7fe8c7SSepherosa Ziehau     u_long start, u_long end, u_long count, u_int flags, int cpuid __unused)
1074d28e78fSSepherosa Ziehau {
1084d28e78fSSepherosa Ziehau 
1094d28e78fSSepherosa Ziehau 	return (bus_alloc_resource(dev, type, rid, start, end, count, flags));
1104d28e78fSSepherosa Ziehau }
1114d28e78fSSepherosa Ziehau 
1124d28e78fSSepherosa Ziehau static int
pci_hostb_release_resource(device_t dev,device_t child,int type,int rid,struct resource * r)1134d28e78fSSepherosa Ziehau pci_hostb_release_resource(device_t dev, device_t child, int type, int rid,
1144d28e78fSSepherosa Ziehau     struct resource *r)
1154d28e78fSSepherosa Ziehau {
1164d28e78fSSepherosa Ziehau 
1174d28e78fSSepherosa Ziehau 	return (bus_release_resource(dev, type, rid, r));
1184d28e78fSSepherosa Ziehau }
1194d28e78fSSepherosa Ziehau 
1204d28e78fSSepherosa Ziehau /* PCI interface. */
1214d28e78fSSepherosa Ziehau 
1224d28e78fSSepherosa Ziehau static uint32_t
pci_hostb_read_config(device_t dev,device_t child,int reg,int width)1234d28e78fSSepherosa Ziehau pci_hostb_read_config(device_t dev, device_t child, int reg, int width)
1244d28e78fSSepherosa Ziehau {
1254d28e78fSSepherosa Ziehau 
1264d28e78fSSepherosa Ziehau 	return (pci_read_config(dev, reg, width));
1274d28e78fSSepherosa Ziehau }
1284d28e78fSSepherosa Ziehau 
1294d28e78fSSepherosa Ziehau static void
pci_hostb_write_config(device_t dev,device_t child,int reg,uint32_t val,int width)1304d28e78fSSepherosa Ziehau pci_hostb_write_config(device_t dev, device_t child, int reg,
1314d28e78fSSepherosa Ziehau     uint32_t val, int width)
1324d28e78fSSepherosa Ziehau {
1334d28e78fSSepherosa Ziehau 
1344d28e78fSSepherosa Ziehau 	pci_write_config(dev, reg, val, width);
1354d28e78fSSepherosa Ziehau }
1364d28e78fSSepherosa Ziehau 
1374d28e78fSSepherosa Ziehau static int
pci_hostb_enable_busmaster(device_t dev,device_t child)1384d28e78fSSepherosa Ziehau pci_hostb_enable_busmaster(device_t dev, device_t child)
1394d28e78fSSepherosa Ziehau {
1404d28e78fSSepherosa Ziehau 
1414d28e78fSSepherosa Ziehau 	device_printf(dev, "child %s requested pci_enable_busmaster\n",
1424d28e78fSSepherosa Ziehau 	    device_get_nameunit(child));
1434d28e78fSSepherosa Ziehau 	return (pci_enable_busmaster(dev));
1444d28e78fSSepherosa Ziehau }
1454d28e78fSSepherosa Ziehau 
1464d28e78fSSepherosa Ziehau static int
pci_hostb_disable_busmaster(device_t dev,device_t child)1474d28e78fSSepherosa Ziehau pci_hostb_disable_busmaster(device_t dev, device_t child)
1484d28e78fSSepherosa Ziehau {
1494d28e78fSSepherosa Ziehau 
1504d28e78fSSepherosa Ziehau 	device_printf(dev, "child %s requested pci_disable_busmaster\n",
1514d28e78fSSepherosa Ziehau 	    device_get_nameunit(child));
1524d28e78fSSepherosa Ziehau 	return (pci_disable_busmaster(dev));
1534d28e78fSSepherosa Ziehau }
1544d28e78fSSepherosa Ziehau 
1554d28e78fSSepherosa Ziehau static int
pci_hostb_enable_io(device_t dev,device_t child,int space)1564d28e78fSSepherosa Ziehau pci_hostb_enable_io(device_t dev, device_t child, int space)
1574d28e78fSSepherosa Ziehau {
1584d28e78fSSepherosa Ziehau 
1594d28e78fSSepherosa Ziehau 	device_printf(dev, "child %s requested pci_enable_io\n",
1604d28e78fSSepherosa Ziehau 	    device_get_nameunit(child));
1614d28e78fSSepherosa Ziehau 	return (pci_enable_io(dev, space));
1624d28e78fSSepherosa Ziehau }
1634d28e78fSSepherosa Ziehau 
1644d28e78fSSepherosa Ziehau static int
pci_hostb_disable_io(device_t dev,device_t child,int space)1654d28e78fSSepherosa Ziehau pci_hostb_disable_io(device_t dev, device_t child, int space)
1664d28e78fSSepherosa Ziehau {
1674d28e78fSSepherosa Ziehau 
1684d28e78fSSepherosa Ziehau 	device_printf(dev, "child %s requested pci_disable_io\n",
1694d28e78fSSepherosa Ziehau 	    device_get_nameunit(child));
1704d28e78fSSepherosa Ziehau 	return (pci_disable_io(dev, space));
1714d28e78fSSepherosa Ziehau }
1724d28e78fSSepherosa Ziehau 
1734d28e78fSSepherosa Ziehau static int
pci_hostb_set_powerstate(device_t dev,device_t child,int state)1744d28e78fSSepherosa Ziehau pci_hostb_set_powerstate(device_t dev, device_t child, int state)
1754d28e78fSSepherosa Ziehau {
1764d28e78fSSepherosa Ziehau 
1774d28e78fSSepherosa Ziehau 	device_printf(dev, "child %s requested pci_set_powerstate\n",
1784d28e78fSSepherosa Ziehau 	    device_get_nameunit(child));
1794d28e78fSSepherosa Ziehau 	return (pci_set_powerstate(dev, state));
1804d28e78fSSepherosa Ziehau }
1814d28e78fSSepherosa Ziehau 
1824d28e78fSSepherosa Ziehau static int
pci_hostb_get_powerstate(device_t dev,device_t child)1834d28e78fSSepherosa Ziehau pci_hostb_get_powerstate(device_t dev, device_t child)
1844d28e78fSSepherosa Ziehau {
1854d28e78fSSepherosa Ziehau 
1864d28e78fSSepherosa Ziehau 	device_printf(dev, "child %s requested pci_get_powerstate\n",
1874d28e78fSSepherosa Ziehau 	    device_get_nameunit(child));
1884d28e78fSSepherosa Ziehau 	return (pci_get_powerstate(dev));
1894d28e78fSSepherosa Ziehau }
1904d28e78fSSepherosa Ziehau 
1914d28e78fSSepherosa Ziehau static int
pci_hostb_assign_interrupt(device_t dev,device_t child)1924d28e78fSSepherosa Ziehau pci_hostb_assign_interrupt(device_t dev, device_t child)
1934d28e78fSSepherosa Ziehau {
1944d28e78fSSepherosa Ziehau 
1954d28e78fSSepherosa Ziehau 	device_printf(dev, "child %s requested pci_assign_interrupt\n",
1964d28e78fSSepherosa Ziehau 	    device_get_nameunit(child));
1974d28e78fSSepherosa Ziehau 	return (PCI_ASSIGN_INTERRUPT(device_get_parent(dev), dev));
1984d28e78fSSepherosa Ziehau }
1994d28e78fSSepherosa Ziehau 
2004d28e78fSSepherosa Ziehau static int
pci_hostb_find_extcap(device_t dev,device_t child,int capability,int * capreg)2014d28e78fSSepherosa Ziehau pci_hostb_find_extcap(device_t dev, device_t child, int capability,
2024d28e78fSSepherosa Ziehau     int *capreg)
2034d28e78fSSepherosa Ziehau {
2044d28e78fSSepherosa Ziehau 
2054d28e78fSSepherosa Ziehau 	return (pci_find_extcap(dev, capability, capreg));
2064d28e78fSSepherosa Ziehau }
2074d28e78fSSepherosa Ziehau 
2084d28e78fSSepherosa Ziehau static device_method_t pci_hostb_methods[] = {
2094d28e78fSSepherosa Ziehau 	/* Device interface */
2104d28e78fSSepherosa Ziehau 	DEVMETHOD(device_probe,		pci_hostb_probe),
2114d28e78fSSepherosa Ziehau 	DEVMETHOD(device_attach,	pci_hostb_attach),
2124d28e78fSSepherosa Ziehau 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
2134d28e78fSSepherosa Ziehau 	DEVMETHOD(device_suspend,	bus_generic_suspend),
2144d28e78fSSepherosa Ziehau 	DEVMETHOD(device_resume,	bus_generic_resume),
2154d28e78fSSepherosa Ziehau 
2164d28e78fSSepherosa Ziehau 	/* Bus interface */
2174d28e78fSSepherosa Ziehau 	DEVMETHOD(bus_read_ivar,	pci_hostb_read_ivar),
2184d28e78fSSepherosa Ziehau 	DEVMETHOD(bus_write_ivar,	pci_hostb_write_ivar),
2194d28e78fSSepherosa Ziehau 	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
2204d28e78fSSepherosa Ziehau 	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
2214d28e78fSSepherosa Ziehau 
2224d28e78fSSepherosa Ziehau 	DEVMETHOD(bus_alloc_resource,	pci_hostb_alloc_resource),
2234d28e78fSSepherosa Ziehau 	DEVMETHOD(bus_release_resource,	pci_hostb_release_resource),
2244d28e78fSSepherosa Ziehau 	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
2254d28e78fSSepherosa Ziehau 	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
2264d28e78fSSepherosa Ziehau 
2274d28e78fSSepherosa Ziehau 	/* PCI interface */
2284d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_read_config,	pci_hostb_read_config),
2294d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_write_config,	pci_hostb_write_config),
2304d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_enable_busmaster,	pci_hostb_enable_busmaster),
2314d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_disable_busmaster, pci_hostb_disable_busmaster),
2324d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_enable_io,	pci_hostb_enable_io),
2334d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_disable_io,	pci_hostb_disable_io),
2344d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_get_powerstate,	pci_hostb_get_powerstate),
2354d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_set_powerstate,	pci_hostb_set_powerstate),
2364d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_assign_interrupt,	pci_hostb_assign_interrupt),
2374d28e78fSSepherosa Ziehau 	DEVMETHOD(pci_find_extcap,	pci_hostb_find_extcap),
2384d28e78fSSepherosa Ziehau 
239*d3c9c58eSSascha Wildner 	DEVMETHOD_END
2404d28e78fSSepherosa Ziehau };
2414d28e78fSSepherosa Ziehau 
2424d28e78fSSepherosa Ziehau static driver_t pci_hostb_driver = {
2434d28e78fSSepherosa Ziehau 	"hostb",
2444d28e78fSSepherosa Ziehau 	pci_hostb_methods,
2454d28e78fSSepherosa Ziehau 	1,
2464d28e78fSSepherosa Ziehau };
2474d28e78fSSepherosa Ziehau 
2484d28e78fSSepherosa Ziehau static devclass_t pci_hostb_devclass;
2494d28e78fSSepherosa Ziehau 
250aa2b9d05SSascha Wildner DRIVER_MODULE(hostb, pci, pci_hostb_driver, pci_hostb_devclass, NULL, NULL);
251