1/*- 2 * Copyright (c) 1994,1995 Stefan Esser, Wolfgang StanglMeier 3 * Copyright (c) 2000 Michael Smith <msmith@freebsd.org> 4 * Copyright (c) 2000 BSDi 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * |
30 * $FreeBSD: head/sys/dev/pci/pci_pci.c 102441 2002-08-26 15:57:08Z jhb $ |
31 */ 32 33/* 34 * PCI:PCI bridge support. 35 */ 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/kernel.h> 40#include <sys/bus.h> 41 42#include <machine/resource.h> 43 44#include <pci/pcivar.h> 45#include <pci/pcireg.h> |
46#include <pci/pcib_private.h> |
47 48#include "pcib_if.h" 49#include "opt_pci.h" 50 |
51static int pcib_probe(device_t dev); 52static int pcib_attach(device_t dev); |
53static int pcib_route_interrupt(device_t pcib, device_t dev, int pin); 54 55static device_method_t pcib_methods[] = { 56 /* Device interface */ 57 DEVMETHOD(device_probe, pcib_probe), 58 DEVMETHOD(device_attach, pcib_attach), 59 DEVMETHOD(device_shutdown, bus_generic_shutdown), 60 DEVMETHOD(device_suspend, bus_generic_suspend), --- 20 unchanged lines hidden (view full) --- 81}; 82 83static driver_t pcib_driver = { 84 "pcib", 85 pcib_methods, 86 sizeof(struct pcib_softc), 87}; 88 |
89devclass_t pcib_devclass; |
90 91DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0); 92 93/* 94 * Generic device interface 95 */ 96static int 97pcib_probe(device_t dev) 98{ 99 if ((pci_get_class(dev) == PCIC_BRIDGE) && 100 (pci_get_subclass(dev) == PCIS_BRIDGE_PCI)) { 101 device_set_desc(dev, "PCI-PCI bridge"); 102 return(-10000); 103 } 104 return(ENXIO); 105} 106 |
107void 108pcib_attach_common(device_t dev) |
109{ 110 struct pcib_softc *sc; |
111 u_int8_t iolow; 112 113 sc = device_get_softc(dev); 114 sc->dev = dev; 115 116 /* 117 * Get current bridge configuration. 118 */ --- 68 unchanged lines hidden (view full) --- 187 */ 188 189 /* 190 * XXX If the subordinate bus number is less than the secondary bus number, 191 * we should pick a better value. One sensible alternative would be to 192 * pick 255; the only tradeoff here is that configuration transactions 193 * would be more widely routed than absolutely necessary. 194 */ |
195} |
196 |
197static int 198pcib_attach(device_t dev) 199{ 200 struct pcib_softc *sc; 201 device_t child; 202 203 pcib_attach_common(dev); 204 sc = device_get_softc(dev); |
205 if (sc->secbus != 0) { 206 child = device_add_child(dev, "pci", -1); 207 if (child != NULL) 208 return(bus_generic_attach(dev)); 209 } 210 211 /* no secondary bus; we should have fixed this */ 212 return(0); 213} 214 |
215int |
216pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 217{ 218 struct pcib_softc *sc = device_get_softc(dev); 219 220 switch (which) { 221 case PCIB_IVAR_BUS: 222 *result = sc->secbus; 223 return(0); 224 } 225 return(ENOENT); 226} 227 |
228int |
229pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 230{ 231 struct pcib_softc *sc = device_get_softc(dev); 232 233 switch (which) { 234 case PCIB_IVAR_BUS: 235 sc->secbus = value; 236 break; --- 24 unchanged lines hidden (view full) --- 261 return (0); 262 return (1); 263} 264 265/* 266 * We have to trap resource allocation requests and ensure that the bridge 267 * is set up to, or capable of handling them. 268 */ |
269struct resource * |
270pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, 271 u_long start, u_long end, u_long count, u_int flags) 272{ 273 struct pcib_softc *sc = device_get_softc(dev); 274 275 /* 276 * If this is a "default" allocation against this rid, we can't work 277 * out where it's coming from (we should actually never see these) so we --- 92 unchanged lines hidden (view full) --- 370 * Bridge is OK decoding this resource, so pass it up. 371 */ 372 return(bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags)); 373} 374 375/* 376 * PCIB interface. 377 */ |
378int |
379pcib_maxslots(device_t dev) 380{ 381 return(PCI_SLOTMAX); 382} 383 384/* 385 * Since we are a child of a PCI bus, its parent must support the pcib interface. 386 */ |
387u_int32_t |
388pcib_read_config(device_t dev, int b, int s, int f, int reg, int width) 389{ 390 return(PCIB_READ_CONFIG(device_get_parent(device_get_parent(dev)), b, s, f, reg, width)); 391} 392 |
393void |
394pcib_write_config(device_t dev, int b, int s, int f, int reg, u_int32_t val, int width) 395{ 396 PCIB_WRITE_CONFIG(device_get_parent(device_get_parent(dev)), b, s, f, reg, val, width); 397} 398 399/* 400 * Route an interrupt across a PCI bridge. 401 */ --- 32 unchanged lines hidden --- |