hostb_pci.c revision 302408
1260684Skaiw/*
2260684Skaiw * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3260684Skaiw * All rights reserved.
4260684Skaiw *
5260684Skaiw * Redistribution and use in source and binary forms, with or without
6260684Skaiw * modification, are permitted provided that the following conditions
7260684Skaiw * are met:
8260684Skaiw * 1. Redistributions of source code must retain the above copyright
9260684Skaiw *    notice unmodified, this list of conditions, and the following
10260684Skaiw *    disclaimer.
11260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright
12260684Skaiw *    notice, this list of conditions and the following disclaimer in the
13260684Skaiw *    documentation and/or other materials provided with the distribution.
14260684Skaiw *
15260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16260684Skaiw * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17260684Skaiw * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18260684Skaiw * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19260684Skaiw * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20260684Skaiw * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21260684Skaiw * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22260684Skaiw * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23260684Skaiw * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24260684Skaiw * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25260684Skaiw */
26260684Skaiw
27260684Skaiw#include <sys/cdefs.h>
28260684Skaiw__FBSDID("$FreeBSD: stable/11/sys/dev/pci/hostb_pci.c 298955 2016-05-03 03:41:25Z pfg $");
29260684Skaiw
30260684Skaiw#include <sys/param.h>
31260684Skaiw#include <sys/bus.h>
32260684Skaiw#include <sys/kernel.h>
33260684Skaiw#include <sys/module.h>
34260684Skaiw
35260684Skaiw#include <dev/pci/pcivar.h>
36300311Semaste#include <dev/pci/pcireg.h>
37260684Skaiw
38260684Skaiw/*
39260684Skaiw * Provide a device to "eat" the host->pci bridge devices that show up
40260684Skaiw * on PCI busses and stop them showing up twice on the probes.  This also
41260684Skaiw * stops them showing up as 'none' in pciconf -l.  If the host bridge
42260684Skaiw * provides an AGP capability then we create a child agp device for the
43260684Skaiw * agp GART driver to attach to.
44260684Skaiw */
45260684Skaiwstatic int
46260684Skaiwpci_hostb_probe(device_t dev)
47260684Skaiw{
48260684Skaiw	u_int32_t id;
49260684Skaiw
50260684Skaiw	id = pci_get_devid(dev);
51260684Skaiw
52260684Skaiw	switch (id) {
53260684Skaiw
54260684Skaiw	/* VIA VT82C596 Power Management Function */
55260684Skaiw	case 0x30501106:
56260684Skaiw		return (ENXIO);
57260684Skaiw
58260684Skaiw	default:
59260684Skaiw		break;
60260684Skaiw	}
61260684Skaiw
62260684Skaiw	if (pci_get_class(dev) == PCIC_BRIDGE &&
63260684Skaiw	    pci_get_subclass(dev) == PCIS_BRIDGE_HOST) {
64260684Skaiw		device_set_desc(dev, "Host to PCI bridge");
65260684Skaiw		device_quiet(dev);
66260684Skaiw		return (-10000);
67300311Semaste	}
68260684Skaiw	return (ENXIO);
69260684Skaiw}
70260684Skaiw
71260684Skaiwstatic int
72260684Skaiwpci_hostb_attach(device_t dev)
73260684Skaiw{
74260684Skaiw
75260684Skaiw	bus_generic_probe(dev);
76260684Skaiw
77260684Skaiw	/*
78260684Skaiw	 * If AGP capabilities are present on this device, then create
79260684Skaiw	 * an AGP child.
80260684Skaiw	 */
81260684Skaiw	if (pci_find_cap(dev, PCIY_AGP, NULL) == 0)
82260684Skaiw		device_add_child(dev, "agp", -1);
83260684Skaiw	bus_generic_attach(dev);
84260684Skaiw	return (0);
85260684Skaiw}
86260684Skaiw
87260684Skaiw/* Bus interface. */
88260684Skaiw
89260684Skaiwstatic int
90260684Skaiwpci_hostb_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
91260684Skaiw{
92260684Skaiw
93260684Skaiw	return (BUS_READ_IVAR(device_get_parent(dev), dev, which, result));
94260684Skaiw}
95260684Skaiw
96260684Skaiwstatic int
97260684Skaiwpci_hostb_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
98260684Skaiw{
99260684Skaiw
100260684Skaiw	return (EINVAL);
101260684Skaiw}
102260684Skaiw
103260684Skaiwstatic struct resource *
104260684Skaiwpci_hostb_alloc_resource(device_t dev, device_t child, int type, int *rid,
105260684Skaiw    rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
106260684Skaiw{
107260684Skaiw
108260684Skaiw	return (bus_alloc_resource(dev, type, rid, start, end, count, flags));
109260684Skaiw}
110260684Skaiw
111276371Semastestatic int
112260684Skaiwpci_hostb_release_resource(device_t dev, device_t child, int type, int rid,
113260684Skaiw    struct resource *r)
114260684Skaiw{
115260684Skaiw
116260684Skaiw	return (bus_release_resource(dev, type, rid, r));
117260684Skaiw}
118260684Skaiw
119260684Skaiw/* PCI interface. */
120260684Skaiw
121260684Skaiwstatic uint32_t
122260684Skaiwpci_hostb_read_config(device_t dev, device_t child, int reg, int width)
123260684Skaiw{
124260684Skaiw
125260684Skaiw	return (pci_read_config(dev, reg, width));
126260684Skaiw}
127260684Skaiw
128260684Skaiwstatic void
129260684Skaiwpci_hostb_write_config(device_t dev, device_t child, int reg,
130260684Skaiw    uint32_t val, int width)
131260684Skaiw{
132260684Skaiw
133260684Skaiw	pci_write_config(dev, reg, val, width);
134260684Skaiw}
135260684Skaiw
136260684Skaiwstatic int
137260684Skaiwpci_hostb_enable_busmaster(device_t dev, device_t child)
138260684Skaiw{
139260684Skaiw
140260684Skaiw	device_printf(dev, "child %s requested pci_enable_busmaster\n",
141260684Skaiw	    device_get_nameunit(child));
142260684Skaiw	return (pci_enable_busmaster(dev));
143260684Skaiw}
144260684Skaiw
145260684Skaiwstatic int
146260684Skaiwpci_hostb_disable_busmaster(device_t dev, device_t child)
147260684Skaiw{
148260684Skaiw
149260684Skaiw	device_printf(dev, "child %s requested pci_disable_busmaster\n",
150260684Skaiw	    device_get_nameunit(child));
151260684Skaiw	return (pci_disable_busmaster(dev));
152260684Skaiw}
153260684Skaiw
154260684Skaiwstatic int
155260684Skaiwpci_hostb_enable_io(device_t dev, device_t child, int space)
156260684Skaiw{
157260684Skaiw
158260684Skaiw	device_printf(dev, "child %s requested pci_enable_io\n",
159260684Skaiw	    device_get_nameunit(child));
160260684Skaiw	return (pci_enable_io(dev, space));
161260684Skaiw}
162260684Skaiw
163260684Skaiwstatic int
164260684Skaiwpci_hostb_disable_io(device_t dev, device_t child, int space)
165260684Skaiw{
166260684Skaiw
167260684Skaiw	device_printf(dev, "child %s requested pci_disable_io\n",
168260684Skaiw	    device_get_nameunit(child));
169260684Skaiw	return (pci_disable_io(dev, space));
170260684Skaiw}
171260684Skaiw
172260684Skaiwstatic int
173260684Skaiwpci_hostb_set_powerstate(device_t dev, device_t child, int state)
174260684Skaiw{
175260684Skaiw
176260684Skaiw	device_printf(dev, "child %s requested pci_set_powerstate\n",
177260684Skaiw	    device_get_nameunit(child));
178260684Skaiw	return (pci_set_powerstate(dev, state));
179260684Skaiw}
180260684Skaiw
181260684Skaiwstatic int
182260684Skaiwpci_hostb_get_powerstate(device_t dev, device_t child)
183260684Skaiw{
184260684Skaiw
185260684Skaiw	device_printf(dev, "child %s requested pci_get_powerstate\n",
186260684Skaiw	    device_get_nameunit(child));
187260684Skaiw	return (pci_get_powerstate(dev));
188260684Skaiw}
189260684Skaiw
190260684Skaiwstatic int
191260684Skaiwpci_hostb_assign_interrupt(device_t dev, device_t child)
192260684Skaiw{
193276371Semaste
194260684Skaiw	device_printf(dev, "child %s requested pci_assign_interrupt\n",
195260684Skaiw	    device_get_nameunit(child));
196260684Skaiw	return (PCI_ASSIGN_INTERRUPT(device_get_parent(dev), dev));
197260684Skaiw}
198260684Skaiw
199260684Skaiwstatic int
200260684Skaiwpci_hostb_find_cap(device_t dev, device_t child, int capability,
201260684Skaiw    int *capreg)
202276371Semaste{
203260684Skaiw
204260684Skaiw	return (pci_find_cap(dev, capability, capreg));
205276371Semaste}
206260684Skaiw
207260684Skaiwstatic int
208260684Skaiwpci_hostb_find_extcap(device_t dev, device_t child, int capability,
209260684Skaiw    int *capreg)
210260684Skaiw{
211260684Skaiw
212260684Skaiw	return (pci_find_extcap(dev, capability, capreg));
213260684Skaiw}
214260684Skaiw
215260684Skaiwstatic int
216260684Skaiwpci_hostb_find_htcap(device_t dev, device_t child, int capability,
217260684Skaiw    int *capreg)
218260684Skaiw{
219260684Skaiw
220260684Skaiw	return (pci_find_htcap(dev, capability, capreg));
221260684Skaiw}
222260684Skaiw
223260684Skaiwstatic device_method_t pci_hostb_methods[] = {
224260684Skaiw	/* Device interface */
225260684Skaiw	DEVMETHOD(device_probe,		pci_hostb_probe),
226260684Skaiw	DEVMETHOD(device_attach,	pci_hostb_attach),
227260684Skaiw	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
228260684Skaiw	DEVMETHOD(device_suspend,	bus_generic_suspend),
229260684Skaiw	DEVMETHOD(device_resume,	bus_generic_resume),
230260684Skaiw
231260684Skaiw	/* Bus interface */
232260684Skaiw	DEVMETHOD(bus_read_ivar,	pci_hostb_read_ivar),
233260684Skaiw	DEVMETHOD(bus_write_ivar,	pci_hostb_write_ivar),
234260684Skaiw	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
235260684Skaiw	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
236260684Skaiw
237260684Skaiw	DEVMETHOD(bus_alloc_resource,	pci_hostb_alloc_resource),
238260684Skaiw	DEVMETHOD(bus_release_resource,	pci_hostb_release_resource),
239260684Skaiw	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
240260684Skaiw	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
241260684Skaiw
242260684Skaiw	/* PCI interface */
243260684Skaiw	DEVMETHOD(pci_read_config,	pci_hostb_read_config),
244260684Skaiw	DEVMETHOD(pci_write_config,	pci_hostb_write_config),
245260684Skaiw	DEVMETHOD(pci_enable_busmaster,	pci_hostb_enable_busmaster),
246260684Skaiw	DEVMETHOD(pci_disable_busmaster, pci_hostb_disable_busmaster),
247260684Skaiw	DEVMETHOD(pci_enable_io,	pci_hostb_enable_io),
248260684Skaiw	DEVMETHOD(pci_disable_io,	pci_hostb_disable_io),
249260684Skaiw	DEVMETHOD(pci_get_powerstate,	pci_hostb_get_powerstate),
250276371Semaste	DEVMETHOD(pci_set_powerstate,	pci_hostb_set_powerstate),
251260684Skaiw	DEVMETHOD(pci_assign_interrupt,	pci_hostb_assign_interrupt),
252260684Skaiw	DEVMETHOD(pci_find_cap,		pci_hostb_find_cap),
253260684Skaiw	DEVMETHOD(pci_find_extcap,	pci_hostb_find_extcap),
254260684Skaiw	DEVMETHOD(pci_find_htcap,	pci_hostb_find_htcap),
255276371Semaste
256260684Skaiw	{ 0, 0 }
257260684Skaiw};
258260684Skaiw
259260684Skaiwstatic driver_t pci_hostb_driver = {
260260684Skaiw	"hostb",
261260684Skaiw	pci_hostb_methods,
262260684Skaiw	1,
263260684Skaiw};
264260684Skaiw
265260684Skaiwstatic devclass_t pci_hostb_devclass;
266260684Skaiw
267260684SkaiwDRIVER_MODULE(hostb, pci, pci_hostb_driver, pci_hostb_devclass, 0, 0);
268260684Skaiw