124042910SMarcin Wojtas /*-
224042910SMarcin Wojtas * Copyright (c) 2011 Nathan Whitehorn
324042910SMarcin Wojtas * All rights reserved.
424042910SMarcin Wojtas *
524042910SMarcin Wojtas * Redistribution and use in source and binary forms, with or without
624042910SMarcin Wojtas * modification, are permitted provided that the following conditions
724042910SMarcin Wojtas * are met:
824042910SMarcin Wojtas * 1. Redistributions of source code must retain the above copyright
924042910SMarcin Wojtas * notice, this list of conditions and the following disclaimer.
1024042910SMarcin Wojtas * 2. Redistributions in binary form must reproduce the above copyright
1124042910SMarcin Wojtas * notice, this list of conditions and the following disclaimer in the
1224042910SMarcin Wojtas * documentation and/or other materials provided with the distribution.
1324042910SMarcin Wojtas *
1424042910SMarcin Wojtas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1524042910SMarcin Wojtas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1624042910SMarcin Wojtas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1724042910SMarcin Wojtas * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1824042910SMarcin Wojtas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1924042910SMarcin Wojtas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2024042910SMarcin Wojtas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2124042910SMarcin Wojtas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2224042910SMarcin Wojtas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2324042910SMarcin Wojtas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2424042910SMarcin Wojtas * SUCH DAMAGE.
2524042910SMarcin Wojtas */
2624042910SMarcin Wojtas
2724042910SMarcin Wojtas #include <sys/param.h>
2824042910SMarcin Wojtas #include <sys/systm.h>
2924042910SMarcin Wojtas #include <sys/module.h>
3024042910SMarcin Wojtas #include <sys/bus.h>
3124042910SMarcin Wojtas #include <sys/conf.h>
3224042910SMarcin Wojtas #include <sys/kernel.h>
3324042910SMarcin Wojtas #include <sys/rman.h>
3424042910SMarcin Wojtas
3524042910SMarcin Wojtas #include <dev/ofw/openfirm.h>
3624042910SMarcin Wojtas #include <dev/ofw/ofw_pci.h>
3724042910SMarcin Wojtas #include <dev/ofw/ofw_bus.h>
3824042910SMarcin Wojtas #include <dev/ofw/ofw_bus_subr.h>
3924042910SMarcin Wojtas #include <dev/ofw/ofwpci.h>
4024042910SMarcin Wojtas
4124042910SMarcin Wojtas #include <dev/pci/pcivar.h>
4224042910SMarcin Wojtas #include <dev/pci/pcireg.h>
4324042910SMarcin Wojtas #include <dev/pci/pcib_private.h>
4424042910SMarcin Wojtas
4524042910SMarcin Wojtas #include <machine/bus.h>
4624042910SMarcin Wojtas #include <machine/md_var.h>
4724042910SMarcin Wojtas #include <machine/resource.h>
4824042910SMarcin Wojtas
4924042910SMarcin Wojtas #include <vm/vm.h>
5024042910SMarcin Wojtas #include <vm/pmap.h>
5124042910SMarcin Wojtas
5224042910SMarcin Wojtas #include "pcib_if.h"
5324042910SMarcin Wojtas
5424042910SMarcin Wojtas /*
5524042910SMarcin Wojtas * If it is necessary to set another value of this for
5624042910SMarcin Wojtas * some platforms it should be set at fdt.h file
5724042910SMarcin Wojtas */
5824042910SMarcin Wojtas #ifndef PCI_MAP_INTR
5924042910SMarcin Wojtas #define PCI_MAP_INTR 4
6024042910SMarcin Wojtas #endif
6124042910SMarcin Wojtas
6224042910SMarcin Wojtas #define PCI_INTR_PINS 4
6324042910SMarcin Wojtas
6424042910SMarcin Wojtas /*
6524042910SMarcin Wojtas * bus interface.
6624042910SMarcin Wojtas */
670b60d7a6SJohn Baldwin static struct rman *ofw_pcib_get_rman(device_t, int, u_int);
6824042910SMarcin Wojtas static struct resource * ofw_pcib_alloc_resource(device_t, device_t,
6924042910SMarcin Wojtas int, int *, rman_res_t, rman_res_t, rman_res_t, u_int);
709dbf5b0eSJohn Baldwin static int ofw_pcib_release_resource(device_t, device_t, struct resource *);
712baed46eSJohn Baldwin static int ofw_pcib_activate_resource(device_t, device_t, struct resource *);
722baed46eSJohn Baldwin static int ofw_pcib_deactivate_resource(device_t, device_t, struct resource *);
73fef01f04SJohn Baldwin static int ofw_pcib_adjust_resource(device_t, device_t,
7424042910SMarcin Wojtas struct resource *, rman_res_t, rman_res_t);
75d77f2092SJohn Baldwin static int ofw_pcib_map_resource(device_t, device_t, struct resource *,
760b60d7a6SJohn Baldwin struct resource_map_request *, struct resource_map *);
77d77f2092SJohn Baldwin static int ofw_pcib_unmap_resource(device_t, device_t, struct resource *,
780b60d7a6SJohn Baldwin struct resource_map *);
7924042910SMarcin Wojtas static int ofw_pcib_translate_resource(device_t bus, int type,
8024042910SMarcin Wojtas rman_res_t start, rman_res_t *newstart);
8124042910SMarcin Wojtas
8224042910SMarcin Wojtas #ifdef __powerpc__
8324042910SMarcin Wojtas static bus_space_tag_t ofw_pcib_bus_get_bus_tag(device_t, device_t);
8424042910SMarcin Wojtas #endif
8524042910SMarcin Wojtas
8624042910SMarcin Wojtas /*
8724042910SMarcin Wojtas * pcib interface
8824042910SMarcin Wojtas */
8924042910SMarcin Wojtas static int ofw_pcib_maxslots(device_t);
9024042910SMarcin Wojtas
9124042910SMarcin Wojtas /*
9224042910SMarcin Wojtas * ofw_bus interface
9324042910SMarcin Wojtas */
9424042910SMarcin Wojtas static phandle_t ofw_pcib_get_node(device_t, device_t);
9524042910SMarcin Wojtas
9624042910SMarcin Wojtas /*
9724042910SMarcin Wojtas * local methods
9824042910SMarcin Wojtas */
9924042910SMarcin Wojtas static int ofw_pcib_fill_ranges(phandle_t, struct ofw_pci_range *);
10024042910SMarcin Wojtas
10124042910SMarcin Wojtas /*
10224042910SMarcin Wojtas * Driver methods.
10324042910SMarcin Wojtas */
10424042910SMarcin Wojtas static device_method_t ofw_pcib_methods[] = {
10524042910SMarcin Wojtas /* Device interface */
10624042910SMarcin Wojtas DEVMETHOD(device_attach, ofw_pcib_attach),
10724042910SMarcin Wojtas
10824042910SMarcin Wojtas /* Bus interface */
10924042910SMarcin Wojtas DEVMETHOD(bus_print_child, bus_generic_print_child),
11024042910SMarcin Wojtas DEVMETHOD(bus_read_ivar, ofw_pcib_read_ivar),
11124042910SMarcin Wojtas DEVMETHOD(bus_write_ivar, ofw_pcib_write_ivar),
11224042910SMarcin Wojtas DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
11324042910SMarcin Wojtas DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
1140b60d7a6SJohn Baldwin DEVMETHOD(bus_get_rman, ofw_pcib_get_rman),
11524042910SMarcin Wojtas DEVMETHOD(bus_alloc_resource, ofw_pcib_alloc_resource),
11624042910SMarcin Wojtas DEVMETHOD(bus_release_resource, ofw_pcib_release_resource),
11724042910SMarcin Wojtas DEVMETHOD(bus_activate_resource, ofw_pcib_activate_resource),
11824042910SMarcin Wojtas DEVMETHOD(bus_deactivate_resource, ofw_pcib_deactivate_resource),
11924042910SMarcin Wojtas DEVMETHOD(bus_adjust_resource, ofw_pcib_adjust_resource),
1200b60d7a6SJohn Baldwin DEVMETHOD(bus_map_resource, ofw_pcib_map_resource),
1210b60d7a6SJohn Baldwin DEVMETHOD(bus_unmap_resource, ofw_pcib_unmap_resource),
12224042910SMarcin Wojtas DEVMETHOD(bus_translate_resource, ofw_pcib_translate_resource),
12324042910SMarcin Wojtas #ifdef __powerpc__
12424042910SMarcin Wojtas DEVMETHOD(bus_get_bus_tag, ofw_pcib_bus_get_bus_tag),
12524042910SMarcin Wojtas #endif
12624042910SMarcin Wojtas
12724042910SMarcin Wojtas /* pcib interface */
12824042910SMarcin Wojtas DEVMETHOD(pcib_maxslots, ofw_pcib_maxslots),
12924042910SMarcin Wojtas DEVMETHOD(pcib_route_interrupt, ofw_pcib_route_interrupt),
13024042910SMarcin Wojtas DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),
13124042910SMarcin Wojtas
13224042910SMarcin Wojtas /* ofw_bus interface */
13324042910SMarcin Wojtas DEVMETHOD(ofw_bus_get_node, ofw_pcib_get_node),
13424042910SMarcin Wojtas
13524042910SMarcin Wojtas DEVMETHOD_END
13624042910SMarcin Wojtas };
13724042910SMarcin Wojtas
13824042910SMarcin Wojtas DEFINE_CLASS_0(ofw_pcib, ofw_pcib_driver, ofw_pcib_methods, 0);
13924042910SMarcin Wojtas
14024042910SMarcin Wojtas int
ofw_pcib_init(device_t dev)14124042910SMarcin Wojtas ofw_pcib_init(device_t dev)
14224042910SMarcin Wojtas {
14324042910SMarcin Wojtas struct ofw_pci_softc *sc;
14424042910SMarcin Wojtas phandle_t node;
14524042910SMarcin Wojtas u_int32_t busrange[2];
14624042910SMarcin Wojtas struct ofw_pci_range *rp;
14724042910SMarcin Wojtas int i, error;
14824042910SMarcin Wojtas struct ofw_pci_cell_info *cell_info;
14924042910SMarcin Wojtas
15024042910SMarcin Wojtas node = ofw_bus_get_node(dev);
15124042910SMarcin Wojtas sc = device_get_softc(dev);
15224042910SMarcin Wojtas sc->sc_initialized = 1;
15324042910SMarcin Wojtas sc->sc_range = NULL;
15424042910SMarcin Wojtas sc->sc_pci_domain = device_get_unit(dev);
15524042910SMarcin Wojtas
15624042910SMarcin Wojtas cell_info = (struct ofw_pci_cell_info *)malloc(sizeof(*cell_info),
15724042910SMarcin Wojtas M_DEVBUF, M_WAITOK | M_ZERO);
15824042910SMarcin Wojtas
15924042910SMarcin Wojtas sc->sc_cell_info = cell_info;
16024042910SMarcin Wojtas
16124042910SMarcin Wojtas if (OF_getencprop(node, "bus-range", busrange, sizeof(busrange)) != 8)
16224042910SMarcin Wojtas busrange[0] = 0;
16324042910SMarcin Wojtas
16424042910SMarcin Wojtas sc->sc_dev = dev;
16524042910SMarcin Wojtas sc->sc_node = node;
16624042910SMarcin Wojtas sc->sc_bus = busrange[0];
16724042910SMarcin Wojtas
16824042910SMarcin Wojtas if (sc->sc_quirks & OFW_PCI_QUIRK_RANGES_ON_CHILDREN) {
16924042910SMarcin Wojtas phandle_t c;
17024042910SMarcin Wojtas int n, i;
17124042910SMarcin Wojtas
17224042910SMarcin Wojtas sc->sc_nrange = 0;
17324042910SMarcin Wojtas for (c = OF_child(node); c != 0; c = OF_peer(c)) {
17424042910SMarcin Wojtas n = ofw_pcib_nranges(c, cell_info);
17524042910SMarcin Wojtas if (n > 0)
17624042910SMarcin Wojtas sc->sc_nrange += n;
17724042910SMarcin Wojtas }
17824042910SMarcin Wojtas if (sc->sc_nrange == 0) {
17924042910SMarcin Wojtas error = ENXIO;
18024042910SMarcin Wojtas goto out;
18124042910SMarcin Wojtas }
18224042910SMarcin Wojtas sc->sc_range = malloc(sc->sc_nrange * sizeof(sc->sc_range[0]),
18324042910SMarcin Wojtas M_DEVBUF, M_WAITOK);
18424042910SMarcin Wojtas i = 0;
18524042910SMarcin Wojtas for (c = OF_child(node); c != 0; c = OF_peer(c)) {
18624042910SMarcin Wojtas n = ofw_pcib_fill_ranges(c, &sc->sc_range[i]);
18724042910SMarcin Wojtas if (n > 0)
18824042910SMarcin Wojtas i += n;
18924042910SMarcin Wojtas }
19024042910SMarcin Wojtas KASSERT(i == sc->sc_nrange, ("range count mismatch"));
19124042910SMarcin Wojtas } else {
19224042910SMarcin Wojtas sc->sc_nrange = ofw_pcib_nranges(node, cell_info);
19324042910SMarcin Wojtas if (sc->sc_nrange <= 0) {
19424042910SMarcin Wojtas device_printf(dev, "could not getranges\n");
19524042910SMarcin Wojtas error = ENXIO;
19624042910SMarcin Wojtas goto out;
19724042910SMarcin Wojtas }
19824042910SMarcin Wojtas sc->sc_range = malloc(sc->sc_nrange * sizeof(sc->sc_range[0]),
19924042910SMarcin Wojtas M_DEVBUF, M_WAITOK);
20024042910SMarcin Wojtas ofw_pcib_fill_ranges(node, sc->sc_range);
20124042910SMarcin Wojtas }
20224042910SMarcin Wojtas
20324042910SMarcin Wojtas sc->sc_io_rman.rm_type = RMAN_ARRAY;
20424042910SMarcin Wojtas sc->sc_io_rman.rm_descr = "PCI I/O Ports";
20524042910SMarcin Wojtas error = rman_init(&sc->sc_io_rman);
20624042910SMarcin Wojtas if (error != 0) {
20724042910SMarcin Wojtas device_printf(dev, "rman_init() failed. error = %d\n", error);
20824042910SMarcin Wojtas goto out;
20924042910SMarcin Wojtas }
21024042910SMarcin Wojtas
21124042910SMarcin Wojtas sc->sc_mem_rman.rm_type = RMAN_ARRAY;
21224042910SMarcin Wojtas sc->sc_mem_rman.rm_descr = "PCI Non Prefetchable Memory";
21324042910SMarcin Wojtas error = rman_init(&sc->sc_mem_rman);
21424042910SMarcin Wojtas if (error != 0) {
21524042910SMarcin Wojtas device_printf(dev, "rman_init() failed. error = %d\n", error);
216b1e93132SAndrew Turner goto out_mem_rman;
21724042910SMarcin Wojtas }
21824042910SMarcin Wojtas
21924042910SMarcin Wojtas sc->sc_pmem_rman.rm_type = RMAN_ARRAY;
22024042910SMarcin Wojtas sc->sc_pmem_rman.rm_descr = "PCI Prefetchable Memory";
22124042910SMarcin Wojtas error = rman_init(&sc->sc_pmem_rman);
22224042910SMarcin Wojtas if (error != 0) {
22324042910SMarcin Wojtas device_printf(dev, "rman_init() failed. error = %d\n", error);
224b1e93132SAndrew Turner goto out_pmem_rman;
22524042910SMarcin Wojtas }
22624042910SMarcin Wojtas
22724042910SMarcin Wojtas for (i = 0; i < sc->sc_nrange; i++) {
22824042910SMarcin Wojtas error = 0;
22924042910SMarcin Wojtas rp = sc->sc_range + i;
23024042910SMarcin Wojtas
23124042910SMarcin Wojtas if (sc->sc_range_mask & ((uint64_t)1 << i))
23224042910SMarcin Wojtas continue;
23324042910SMarcin Wojtas switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
23424042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_CONFIG:
23524042910SMarcin Wojtas break;
23624042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_IO:
23724042910SMarcin Wojtas error = rman_manage_region(&sc->sc_io_rman, rp->pci,
23824042910SMarcin Wojtas rp->pci + rp->size - 1);
23924042910SMarcin Wojtas break;
24024042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_MEM32:
24124042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_MEM64:
24224042910SMarcin Wojtas if (rp->pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) {
24324042910SMarcin Wojtas sc->sc_have_pmem = 1;
24424042910SMarcin Wojtas error = rman_manage_region(&sc->sc_pmem_rman,
24524042910SMarcin Wojtas rp->pci, rp->pci + rp->size - 1);
24624042910SMarcin Wojtas } else {
24724042910SMarcin Wojtas error = rman_manage_region(&sc->sc_mem_rman,
24824042910SMarcin Wojtas rp->pci, rp->pci + rp->size - 1);
24924042910SMarcin Wojtas }
25024042910SMarcin Wojtas break;
25124042910SMarcin Wojtas }
25224042910SMarcin Wojtas
25324042910SMarcin Wojtas if (error != 0) {
25424042910SMarcin Wojtas device_printf(dev,
25524042910SMarcin Wojtas "rman_manage_region(%x, %#jx, %#jx) failed. "
25624042910SMarcin Wojtas "error = %d\n", rp->pci_hi &
25724042910SMarcin Wojtas OFW_PCI_PHYS_HI_SPACEMASK, rp->pci,
25824042910SMarcin Wojtas rp->pci + rp->size - 1, error);
259b1e93132SAndrew Turner goto out_full;
26024042910SMarcin Wojtas }
26124042910SMarcin Wojtas }
26224042910SMarcin Wojtas
26324042910SMarcin Wojtas ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t));
26424042910SMarcin Wojtas return (0);
26524042910SMarcin Wojtas
266b1e93132SAndrew Turner out_full:
267b1e93132SAndrew Turner rman_fini(&sc->sc_pmem_rman);
268b1e93132SAndrew Turner out_pmem_rman:
269b1e93132SAndrew Turner rman_fini(&sc->sc_mem_rman);
270b1e93132SAndrew Turner out_mem_rman:
271b1e93132SAndrew Turner rman_fini(&sc->sc_io_rman);
27224042910SMarcin Wojtas out:
273b1e93132SAndrew Turner free(sc->sc_cell_info, M_DEVBUF);
274b1e93132SAndrew Turner free(sc->sc_range, M_DEVBUF);
275b1e93132SAndrew Turner
276b1e93132SAndrew Turner return (error);
277b1e93132SAndrew Turner }
278b1e93132SAndrew Turner
279b1e93132SAndrew Turner void
ofw_pcib_fini(device_t dev)280b1e93132SAndrew Turner ofw_pcib_fini(device_t dev)
281b1e93132SAndrew Turner {
282b1e93132SAndrew Turner struct ofw_pci_softc *sc;
283b1e93132SAndrew Turner
284b1e93132SAndrew Turner sc = device_get_softc(dev);
285b1e93132SAndrew Turner free(sc->sc_cell_info, M_DEVBUF);
28624042910SMarcin Wojtas free(sc->sc_range, M_DEVBUF);
28724042910SMarcin Wojtas rman_fini(&sc->sc_io_rman);
28824042910SMarcin Wojtas rman_fini(&sc->sc_mem_rman);
28924042910SMarcin Wojtas rman_fini(&sc->sc_pmem_rman);
29024042910SMarcin Wojtas }
29124042910SMarcin Wojtas
29224042910SMarcin Wojtas int
ofw_pcib_attach(device_t dev)29324042910SMarcin Wojtas ofw_pcib_attach(device_t dev)
29424042910SMarcin Wojtas {
29524042910SMarcin Wojtas struct ofw_pci_softc *sc;
29624042910SMarcin Wojtas int error;
29724042910SMarcin Wojtas
29824042910SMarcin Wojtas sc = device_get_softc(dev);
29924042910SMarcin Wojtas if (!sc->sc_initialized) {
30024042910SMarcin Wojtas error = ofw_pcib_init(dev);
30124042910SMarcin Wojtas if (error != 0)
30224042910SMarcin Wojtas return (error);
30324042910SMarcin Wojtas }
30424042910SMarcin Wojtas
3055b56413dSWarner Losh device_add_child(dev, "pci", DEVICE_UNIT_ANY);
306*18250ec6SJohn Baldwin bus_attach_children(dev);
307*18250ec6SJohn Baldwin return (0);
30824042910SMarcin Wojtas }
30924042910SMarcin Wojtas
31024042910SMarcin Wojtas static int
ofw_pcib_maxslots(device_t dev)31124042910SMarcin Wojtas ofw_pcib_maxslots(device_t dev)
31224042910SMarcin Wojtas {
31324042910SMarcin Wojtas
31424042910SMarcin Wojtas return (PCI_SLOTMAX);
31524042910SMarcin Wojtas }
31624042910SMarcin Wojtas
31724042910SMarcin Wojtas int
ofw_pcib_route_interrupt(device_t bus,device_t dev,int pin)31824042910SMarcin Wojtas ofw_pcib_route_interrupt(device_t bus, device_t dev, int pin)
31924042910SMarcin Wojtas {
32024042910SMarcin Wojtas struct ofw_pci_softc *sc;
32124042910SMarcin Wojtas struct ofw_pci_register reg;
32224042910SMarcin Wojtas uint32_t pintr, mintr[PCI_MAP_INTR];
32324042910SMarcin Wojtas int intrcells;
32424042910SMarcin Wojtas phandle_t iparent;
32524042910SMarcin Wojtas
32624042910SMarcin Wojtas sc = device_get_softc(bus);
32724042910SMarcin Wojtas pintr = pin;
32824042910SMarcin Wojtas
32924042910SMarcin Wojtas /* Fabricate imap information in case this isn't an OFW device */
33024042910SMarcin Wojtas bzero(®, sizeof(reg));
33124042910SMarcin Wojtas reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) |
33224042910SMarcin Wojtas (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
33324042910SMarcin Wojtas (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
33424042910SMarcin Wojtas
33524042910SMarcin Wojtas intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev),
33624042910SMarcin Wojtas &sc->sc_pci_iinfo, ®, sizeof(reg), &pintr, sizeof(pintr),
33724042910SMarcin Wojtas mintr, sizeof(mintr), &iparent);
33824042910SMarcin Wojtas if (intrcells != 0) {
33924042910SMarcin Wojtas pintr = ofw_bus_map_intr(dev, iparent, intrcells, mintr);
34024042910SMarcin Wojtas return (pintr);
34124042910SMarcin Wojtas }
34224042910SMarcin Wojtas
34324042910SMarcin Wojtas /*
34424042910SMarcin Wojtas * Maybe it's a real interrupt, not an intpin
34524042910SMarcin Wojtas */
34624042910SMarcin Wojtas if (pin > PCI_INTR_PINS)
34724042910SMarcin Wojtas return (pin);
34824042910SMarcin Wojtas
34924042910SMarcin Wojtas device_printf(bus, "could not route pin %d for device %d.%d\n",
35024042910SMarcin Wojtas pin, pci_get_slot(dev), pci_get_function(dev));
35124042910SMarcin Wojtas return (PCI_INVALID_IRQ);
35224042910SMarcin Wojtas }
35324042910SMarcin Wojtas
35424042910SMarcin Wojtas int
ofw_pcib_read_ivar(device_t dev,device_t child,int which,uintptr_t * result)35524042910SMarcin Wojtas ofw_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
35624042910SMarcin Wojtas {
35724042910SMarcin Wojtas struct ofw_pci_softc *sc;
35824042910SMarcin Wojtas
35924042910SMarcin Wojtas sc = device_get_softc(dev);
36024042910SMarcin Wojtas
36124042910SMarcin Wojtas switch (which) {
36224042910SMarcin Wojtas case PCIB_IVAR_DOMAIN:
36324042910SMarcin Wojtas *result = sc->sc_pci_domain;
36424042910SMarcin Wojtas return (0);
36524042910SMarcin Wojtas case PCIB_IVAR_BUS:
36624042910SMarcin Wojtas *result = sc->sc_bus;
36724042910SMarcin Wojtas return (0);
36824042910SMarcin Wojtas default:
36924042910SMarcin Wojtas break;
37024042910SMarcin Wojtas }
37124042910SMarcin Wojtas
37224042910SMarcin Wojtas return (ENOENT);
37324042910SMarcin Wojtas }
37424042910SMarcin Wojtas
37524042910SMarcin Wojtas int
ofw_pcib_write_ivar(device_t dev,device_t child,int which,uintptr_t value)37624042910SMarcin Wojtas ofw_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
37724042910SMarcin Wojtas {
37824042910SMarcin Wojtas struct ofw_pci_softc *sc;
37924042910SMarcin Wojtas
38024042910SMarcin Wojtas sc = device_get_softc(dev);
38124042910SMarcin Wojtas
38224042910SMarcin Wojtas switch (which) {
38324042910SMarcin Wojtas case PCIB_IVAR_BUS:
38424042910SMarcin Wojtas sc->sc_bus = value;
38524042910SMarcin Wojtas return (0);
38624042910SMarcin Wojtas default:
38724042910SMarcin Wojtas break;
38824042910SMarcin Wojtas }
38924042910SMarcin Wojtas
39024042910SMarcin Wojtas return (ENOENT);
39124042910SMarcin Wojtas }
39224042910SMarcin Wojtas
39324042910SMarcin Wojtas int
ofw_pcib_nranges(phandle_t node,struct ofw_pci_cell_info * info)39424042910SMarcin Wojtas ofw_pcib_nranges(phandle_t node, struct ofw_pci_cell_info *info)
39524042910SMarcin Wojtas {
39624042910SMarcin Wojtas ssize_t nbase_ranges;
39724042910SMarcin Wojtas
39824042910SMarcin Wojtas if (info == NULL)
39924042910SMarcin Wojtas return (-1);
40024042910SMarcin Wojtas
40124042910SMarcin Wojtas info->host_address_cells = 1;
40224042910SMarcin Wojtas info->size_cells = 2;
40324042910SMarcin Wojtas info->pci_address_cell = 3;
40424042910SMarcin Wojtas
40524042910SMarcin Wojtas OF_getencprop(OF_parent(node), "#address-cells",
40624042910SMarcin Wojtas &(info->host_address_cells), sizeof(info->host_address_cells));
40724042910SMarcin Wojtas OF_getencprop(node, "#address-cells",
40824042910SMarcin Wojtas &(info->pci_address_cell), sizeof(info->pci_address_cell));
40924042910SMarcin Wojtas OF_getencprop(node, "#size-cells", &(info->size_cells),
41024042910SMarcin Wojtas sizeof(info->size_cells));
41124042910SMarcin Wojtas
41224042910SMarcin Wojtas nbase_ranges = OF_getproplen(node, "ranges");
41324042910SMarcin Wojtas if (nbase_ranges <= 0)
41424042910SMarcin Wojtas return (-1);
41524042910SMarcin Wojtas
41624042910SMarcin Wojtas return (nbase_ranges / sizeof(cell_t) /
41724042910SMarcin Wojtas (info->pci_address_cell + info->host_address_cells +
41824042910SMarcin Wojtas info->size_cells));
41924042910SMarcin Wojtas }
42024042910SMarcin Wojtas
42124042910SMarcin Wojtas static struct resource *
ofw_pcib_alloc_resource(device_t bus,device_t child,int type,int * rid,rman_res_t start,rman_res_t end,rman_res_t count,u_int flags)42224042910SMarcin Wojtas ofw_pcib_alloc_resource(device_t bus, device_t child, int type, int *rid,
42324042910SMarcin Wojtas rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
42424042910SMarcin Wojtas {
42524042910SMarcin Wojtas struct ofw_pci_softc *sc;
42624042910SMarcin Wojtas
42724042910SMarcin Wojtas sc = device_get_softc(bus);
4280b60d7a6SJohn Baldwin switch (type) {
4290b60d7a6SJohn Baldwin case PCI_RES_BUS:
4300b60d7a6SJohn Baldwin return (pci_domain_alloc_bus(sc->sc_pci_domain, child, rid,
4310b60d7a6SJohn Baldwin start, end, count, flags));
4320b60d7a6SJohn Baldwin case SYS_RES_MEMORY:
4330b60d7a6SJohn Baldwin case SYS_RES_IOPORT:
4340b60d7a6SJohn Baldwin return (bus_generic_rman_alloc_resource(bus, child, type, rid,
4350b60d7a6SJohn Baldwin start, end, count, flags));
4360b60d7a6SJohn Baldwin default:
43724042910SMarcin Wojtas return (bus_generic_alloc_resource(bus, child, type, rid,
4380b60d7a6SJohn Baldwin start, end, count, flags));
43924042910SMarcin Wojtas }
44024042910SMarcin Wojtas }
44124042910SMarcin Wojtas
44224042910SMarcin Wojtas static int
ofw_pcib_release_resource(device_t bus,device_t child,struct resource * res)4439dbf5b0eSJohn Baldwin ofw_pcib_release_resource(device_t bus, device_t child, struct resource *res)
44424042910SMarcin Wojtas {
44524042910SMarcin Wojtas struct ofw_pci_softc *sc;
44624042910SMarcin Wojtas
44724042910SMarcin Wojtas sc = device_get_softc(bus);
4489dbf5b0eSJohn Baldwin switch (rman_get_type(res)) {
4490b60d7a6SJohn Baldwin case PCI_RES_BUS:
4509dbf5b0eSJohn Baldwin return (pci_domain_release_bus(sc->sc_pci_domain, child, res));
4510b60d7a6SJohn Baldwin case SYS_RES_MEMORY:
4520b60d7a6SJohn Baldwin case SYS_RES_IOPORT:
4539dbf5b0eSJohn Baldwin return (bus_generic_rman_release_resource(bus, child, res));
4540b60d7a6SJohn Baldwin default:
4559dbf5b0eSJohn Baldwin return (bus_generic_release_resource(bus, child, res));
45624042910SMarcin Wojtas }
45724042910SMarcin Wojtas }
45824042910SMarcin Wojtas
45924042910SMarcin Wojtas static int
ofw_pcib_translate_resource(device_t bus,int type,rman_res_t start,rman_res_t * newstart)46024042910SMarcin Wojtas ofw_pcib_translate_resource(device_t bus, int type, rman_res_t start,
46124042910SMarcin Wojtas rman_res_t *newstart)
46224042910SMarcin Wojtas {
46324042910SMarcin Wojtas struct ofw_pci_softc *sc;
46424042910SMarcin Wojtas struct ofw_pci_range *rp;
46524042910SMarcin Wojtas int space;
46624042910SMarcin Wojtas
46724042910SMarcin Wojtas sc = device_get_softc(bus);
46824042910SMarcin Wojtas
46924042910SMarcin Wojtas /*
47024042910SMarcin Wojtas * Map this through the ranges list
47124042910SMarcin Wojtas */
47224042910SMarcin Wojtas for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange &&
47324042910SMarcin Wojtas rp->pci_hi != 0; rp++) {
47424042910SMarcin Wojtas if (start < rp->pci || start >= rp->pci + rp->size)
47524042910SMarcin Wojtas continue;
47624042910SMarcin Wojtas
47724042910SMarcin Wojtas switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
47824042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_IO:
47924042910SMarcin Wojtas space = SYS_RES_IOPORT;
48024042910SMarcin Wojtas break;
48124042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_MEM32:
48224042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_MEM64:
48324042910SMarcin Wojtas space = SYS_RES_MEMORY;
48424042910SMarcin Wojtas break;
48524042910SMarcin Wojtas default:
48624042910SMarcin Wojtas space = -1;
48724042910SMarcin Wojtas }
48824042910SMarcin Wojtas
48924042910SMarcin Wojtas if (type == space) {
49024042910SMarcin Wojtas start += (rp->host - rp->pci);
49124042910SMarcin Wojtas *newstart = start;
49224042910SMarcin Wojtas return (0);
49324042910SMarcin Wojtas }
4941fb99e97SMark Johnston }
4951fb99e97SMark Johnston return (ENOENT);
4961fb99e97SMark Johnston }
49724042910SMarcin Wojtas
49824042910SMarcin Wojtas static int
ofw_pcib_activate_resource(device_t bus,device_t child,struct resource * res)4992baed46eSJohn Baldwin ofw_pcib_activate_resource(device_t bus, device_t child, struct resource *res)
50024042910SMarcin Wojtas {
50124042910SMarcin Wojtas struct ofw_pci_softc *sc;
50224042910SMarcin Wojtas
50324042910SMarcin Wojtas sc = device_get_softc(bus);
5042baed46eSJohn Baldwin switch (rman_get_type(res)) {
5050b60d7a6SJohn Baldwin case PCI_RES_BUS:
5062baed46eSJohn Baldwin return (pci_domain_activate_bus(sc->sc_pci_domain, child, res));
5070b60d7a6SJohn Baldwin case SYS_RES_MEMORY:
5080b60d7a6SJohn Baldwin case SYS_RES_IOPORT:
5092baed46eSJohn Baldwin return (bus_generic_rman_activate_resource(bus, child, res));
5100b60d7a6SJohn Baldwin default:
5112baed46eSJohn Baldwin return (bus_generic_activate_resource(bus, child, res));
51224042910SMarcin Wojtas }
5130b60d7a6SJohn Baldwin }
51424042910SMarcin Wojtas
5150b60d7a6SJohn Baldwin static int
ofw_pcib_map_resource(device_t dev,device_t child,struct resource * r,struct resource_map_request * argsp,struct resource_map * map)516d77f2092SJohn Baldwin ofw_pcib_map_resource(device_t dev, device_t child, struct resource *r,
517d77f2092SJohn Baldwin struct resource_map_request *argsp, struct resource_map *map)
5180b60d7a6SJohn Baldwin {
5190b60d7a6SJohn Baldwin struct resource_map_request args;
5200b60d7a6SJohn Baldwin struct ofw_pci_softc *sc;
5210b60d7a6SJohn Baldwin struct ofw_pci_range *rp;
5220b60d7a6SJohn Baldwin rman_res_t length, start;
5230b60d7a6SJohn Baldwin int error, space;
5240b60d7a6SJohn Baldwin
5250b60d7a6SJohn Baldwin /* Resources must be active to be mapped. */
5260b60d7a6SJohn Baldwin if (!(rman_get_flags(r) & RF_ACTIVE))
5270b60d7a6SJohn Baldwin return (ENXIO);
5280b60d7a6SJohn Baldwin
529d77f2092SJohn Baldwin switch (rman_get_type(r)) {
5300b60d7a6SJohn Baldwin case SYS_RES_MEMORY:
5310b60d7a6SJohn Baldwin case SYS_RES_IOPORT:
5320b60d7a6SJohn Baldwin break;
5330b60d7a6SJohn Baldwin default:
5340b60d7a6SJohn Baldwin return (EINVAL);
5350b60d7a6SJohn Baldwin }
5360b60d7a6SJohn Baldwin
5370b60d7a6SJohn Baldwin resource_init_map_request(&args);
5380b60d7a6SJohn Baldwin error = resource_validate_map_request(r, argsp, &args, &start, &length);
5390b60d7a6SJohn Baldwin if (error)
5400b60d7a6SJohn Baldwin return (error);
54124042910SMarcin Wojtas
54224042910SMarcin Wojtas /*
54324042910SMarcin Wojtas * Map this through the ranges list
54424042910SMarcin Wojtas */
5450b60d7a6SJohn Baldwin sc = device_get_softc(dev);
54624042910SMarcin Wojtas for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange &&
54724042910SMarcin Wojtas rp->pci_hi != 0; rp++) {
54824042910SMarcin Wojtas if (start < rp->pci || start >= rp->pci + rp->size)
54924042910SMarcin Wojtas continue;
55024042910SMarcin Wojtas
55124042910SMarcin Wojtas switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
55224042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_IO:
55324042910SMarcin Wojtas space = SYS_RES_IOPORT;
55424042910SMarcin Wojtas break;
55524042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_MEM32:
55624042910SMarcin Wojtas case OFW_PCI_PHYS_HI_SPACE_MEM64:
55724042910SMarcin Wojtas space = SYS_RES_MEMORY;
55824042910SMarcin Wojtas break;
55924042910SMarcin Wojtas default:
56024042910SMarcin Wojtas space = -1;
56124042910SMarcin Wojtas }
56224042910SMarcin Wojtas
563d77f2092SJohn Baldwin if (rman_get_type(r) == space) {
56424042910SMarcin Wojtas start += (rp->host - rp->pci);
56524042910SMarcin Wojtas break;
56624042910SMarcin Wojtas }
56724042910SMarcin Wojtas }
56824042910SMarcin Wojtas
56924042910SMarcin Wojtas if (bootverbose)
5700b60d7a6SJohn Baldwin printf("ofw_pci mapdev: start %jx, len %jd\n", start, length);
57124042910SMarcin Wojtas
5720b60d7a6SJohn Baldwin map->r_bustag = BUS_GET_BUS_TAG(child, child);
5730b60d7a6SJohn Baldwin if (map->r_bustag == NULL)
57424042910SMarcin Wojtas return (ENOMEM);
57524042910SMarcin Wojtas
5760b60d7a6SJohn Baldwin error = bus_space_map(map->r_bustag, start, length, 0,
5770b60d7a6SJohn Baldwin &map->r_bushandle);
5780b60d7a6SJohn Baldwin if (error != 0)
5790b60d7a6SJohn Baldwin return (error);
58024042910SMarcin Wojtas
5810b60d7a6SJohn Baldwin /* XXX for powerpc only? */
5820b60d7a6SJohn Baldwin map->r_vaddr = (void *)map->r_bushandle;
5830b60d7a6SJohn Baldwin map->r_size = length;
5840b60d7a6SJohn Baldwin return (0);
5850b60d7a6SJohn Baldwin }
58624042910SMarcin Wojtas
5870b60d7a6SJohn Baldwin static int
ofw_pcib_unmap_resource(device_t dev,device_t child,struct resource * r,struct resource_map * map)588d77f2092SJohn Baldwin ofw_pcib_unmap_resource(device_t dev, device_t child, struct resource *r,
589d77f2092SJohn Baldwin struct resource_map *map)
5900b60d7a6SJohn Baldwin {
591d77f2092SJohn Baldwin switch (rman_get_type(r)) {
5920b60d7a6SJohn Baldwin case SYS_RES_MEMORY:
5930b60d7a6SJohn Baldwin case SYS_RES_IOPORT:
5940b60d7a6SJohn Baldwin bus_space_unmap(map->r_bustag, map->r_bushandle, map->r_size);
5950b60d7a6SJohn Baldwin return (0);
5960b60d7a6SJohn Baldwin default:
5970b60d7a6SJohn Baldwin return (EINVAL);
5980b60d7a6SJohn Baldwin }
59924042910SMarcin Wojtas }
60024042910SMarcin Wojtas
60124042910SMarcin Wojtas #ifdef __powerpc__
60224042910SMarcin Wojtas static bus_space_tag_t
ofw_pcib_bus_get_bus_tag(device_t bus,device_t child)60324042910SMarcin Wojtas ofw_pcib_bus_get_bus_tag(device_t bus, device_t child)
60424042910SMarcin Wojtas {
60524042910SMarcin Wojtas
60624042910SMarcin Wojtas return (&bs_le_tag);
60724042910SMarcin Wojtas }
60824042910SMarcin Wojtas #endif
60924042910SMarcin Wojtas
61024042910SMarcin Wojtas static int
ofw_pcib_deactivate_resource(device_t bus,device_t child,struct resource * res)6112baed46eSJohn Baldwin ofw_pcib_deactivate_resource(device_t bus, device_t child, struct resource *res)
61224042910SMarcin Wojtas {
6130b60d7a6SJohn Baldwin struct ofw_pci_softc *sc;
61424042910SMarcin Wojtas
6150b60d7a6SJohn Baldwin sc = device_get_softc(bus);
6162baed46eSJohn Baldwin switch (rman_get_type(res)) {
6170b60d7a6SJohn Baldwin case PCI_RES_BUS:
6182baed46eSJohn Baldwin return (pci_domain_deactivate_bus(sc->sc_pci_domain, child,
6190b60d7a6SJohn Baldwin res));
6200b60d7a6SJohn Baldwin case SYS_RES_MEMORY:
6210b60d7a6SJohn Baldwin case SYS_RES_IOPORT:
6222baed46eSJohn Baldwin return (bus_generic_rman_deactivate_resource(bus, child, res));
6230b60d7a6SJohn Baldwin default:
6242baed46eSJohn Baldwin return (bus_generic_deactivate_resource(bus, child, res));
62524042910SMarcin Wojtas }
62624042910SMarcin Wojtas }
62724042910SMarcin Wojtas
62824042910SMarcin Wojtas static int
ofw_pcib_adjust_resource(device_t bus,device_t child,struct resource * res,rman_res_t start,rman_res_t end)629fef01f04SJohn Baldwin ofw_pcib_adjust_resource(device_t bus, device_t child,
63024042910SMarcin Wojtas struct resource *res, rman_res_t start, rman_res_t end)
63124042910SMarcin Wojtas {
63224042910SMarcin Wojtas struct ofw_pci_softc *sc;
63324042910SMarcin Wojtas
63424042910SMarcin Wojtas sc = device_get_softc(bus);
635fef01f04SJohn Baldwin switch (rman_get_type(res)) {
6360b60d7a6SJohn Baldwin case PCI_RES_BUS:
63724042910SMarcin Wojtas return (pci_domain_adjust_bus(sc->sc_pci_domain, child, res,
63824042910SMarcin Wojtas start, end));
6390b60d7a6SJohn Baldwin case SYS_RES_MEMORY:
6400b60d7a6SJohn Baldwin case SYS_RES_IOPORT:
641fef01f04SJohn Baldwin return (bus_generic_rman_adjust_resource(bus, child, res,
6420b60d7a6SJohn Baldwin start, end));
6430b60d7a6SJohn Baldwin default:
644fef01f04SJohn Baldwin return (bus_generic_adjust_resource(bus, child, res, start,
645fef01f04SJohn Baldwin end));
64624042910SMarcin Wojtas }
64724042910SMarcin Wojtas }
64824042910SMarcin Wojtas
64924042910SMarcin Wojtas static phandle_t
ofw_pcib_get_node(device_t bus,device_t dev)65024042910SMarcin Wojtas ofw_pcib_get_node(device_t bus, device_t dev)
65124042910SMarcin Wojtas {
65224042910SMarcin Wojtas struct ofw_pci_softc *sc;
65324042910SMarcin Wojtas
65424042910SMarcin Wojtas sc = device_get_softc(bus);
65524042910SMarcin Wojtas /* We only have one child, the PCI bus, which needs our own node. */
65624042910SMarcin Wojtas
65724042910SMarcin Wojtas return (sc->sc_node);
65824042910SMarcin Wojtas }
65924042910SMarcin Wojtas
66024042910SMarcin Wojtas static int
ofw_pcib_fill_ranges(phandle_t node,struct ofw_pci_range * ranges)66124042910SMarcin Wojtas ofw_pcib_fill_ranges(phandle_t node, struct ofw_pci_range *ranges)
66224042910SMarcin Wojtas {
66324042910SMarcin Wojtas int host_address_cells = 1, pci_address_cells = 3, size_cells = 2;
66424042910SMarcin Wojtas cell_t *base_ranges;
66524042910SMarcin Wojtas ssize_t nbase_ranges;
66624042910SMarcin Wojtas int nranges;
66724042910SMarcin Wojtas int i, j, k;
66824042910SMarcin Wojtas
66924042910SMarcin Wojtas OF_getencprop(OF_parent(node), "#address-cells", &host_address_cells,
67024042910SMarcin Wojtas sizeof(host_address_cells));
67124042910SMarcin Wojtas OF_getencprop(node, "#address-cells", &pci_address_cells,
67224042910SMarcin Wojtas sizeof(pci_address_cells));
67324042910SMarcin Wojtas OF_getencprop(node, "#size-cells", &size_cells, sizeof(size_cells));
67424042910SMarcin Wojtas
67524042910SMarcin Wojtas nbase_ranges = OF_getproplen(node, "ranges");
67624042910SMarcin Wojtas if (nbase_ranges <= 0)
67724042910SMarcin Wojtas return (-1);
67824042910SMarcin Wojtas nranges = nbase_ranges / sizeof(cell_t) /
67924042910SMarcin Wojtas (pci_address_cells + host_address_cells + size_cells);
68024042910SMarcin Wojtas
68124042910SMarcin Wojtas base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
68224042910SMarcin Wojtas OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
68324042910SMarcin Wojtas
68424042910SMarcin Wojtas for (i = 0, j = 0; i < nranges; i++) {
68524042910SMarcin Wojtas ranges[i].pci_hi = base_ranges[j++];
68624042910SMarcin Wojtas ranges[i].pci = 0;
68724042910SMarcin Wojtas for (k = 0; k < pci_address_cells - 1; k++) {
68824042910SMarcin Wojtas ranges[i].pci <<= 32;
68924042910SMarcin Wojtas ranges[i].pci |= base_ranges[j++];
69024042910SMarcin Wojtas }
69124042910SMarcin Wojtas ranges[i].host = 0;
69224042910SMarcin Wojtas for (k = 0; k < host_address_cells; k++) {
69324042910SMarcin Wojtas ranges[i].host <<= 32;
69424042910SMarcin Wojtas ranges[i].host |= base_ranges[j++];
69524042910SMarcin Wojtas }
69624042910SMarcin Wojtas ranges[i].size = 0;
69724042910SMarcin Wojtas for (k = 0; k < size_cells; k++) {
69824042910SMarcin Wojtas ranges[i].size <<= 32;
69924042910SMarcin Wojtas ranges[i].size |= base_ranges[j++];
70024042910SMarcin Wojtas }
70124042910SMarcin Wojtas }
70224042910SMarcin Wojtas
70324042910SMarcin Wojtas free(base_ranges, M_DEVBUF);
70424042910SMarcin Wojtas return (nranges);
70524042910SMarcin Wojtas }
70624042910SMarcin Wojtas
70724042910SMarcin Wojtas static struct rman *
ofw_pcib_get_rman(device_t bus,int type,u_int flags)7080b60d7a6SJohn Baldwin ofw_pcib_get_rman(device_t bus, int type, u_int flags)
70924042910SMarcin Wojtas {
7100b60d7a6SJohn Baldwin struct ofw_pci_softc *sc;
71124042910SMarcin Wojtas
7120b60d7a6SJohn Baldwin sc = device_get_softc(bus);
71324042910SMarcin Wojtas switch (type) {
71424042910SMarcin Wojtas case SYS_RES_IOPORT:
71524042910SMarcin Wojtas return (&sc->sc_io_rman);
71624042910SMarcin Wojtas case SYS_RES_MEMORY:
71724042910SMarcin Wojtas if (sc->sc_have_pmem && (flags & RF_PREFETCHABLE))
71824042910SMarcin Wojtas return (&sc->sc_pmem_rman);
71924042910SMarcin Wojtas else
72024042910SMarcin Wojtas return (&sc->sc_mem_rman);
72124042910SMarcin Wojtas default:
72224042910SMarcin Wojtas break;
72324042910SMarcin Wojtas }
72424042910SMarcin Wojtas
72524042910SMarcin Wojtas return (NULL);
72624042910SMarcin Wojtas }
727