summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2011-10-02 23:22:38 +0000
committermarius <marius@FreeBSD.org>2011-10-02 23:22:38 +0000
commitb730263346b617e3949a799cd7cbbaec0a0faaba (patch)
tree8a3ccb0c4cbe92ab406722848f03d20132c1e280 /sys/sparc64
parent2dc050638298978fc3e396cc2d0206c599dc8c46 (diff)
downloadFreeBSD-src-b730263346b617e3949a799cd7cbbaec0a0faaba.zip
FreeBSD-src-b730263346b617e3949a799cd7cbbaec0a0faaba.tar.gz
Make sparc64 compatible with NEW_PCIB and enable it:
- Implement bus_adjust_resource() methods as far as necessary and in non-PCI bridge drivers as far as feasible without rototilling them. - As NEW_PCIB does a layering violation by activating resources at layers above pci(4) without previously bubbling up their allocation there, move the assignment of bus tags and handles from the bus_alloc_resource() to the bus_activate_resource() methods like at least the other NEW_PCIB enabled architectures do. This is somewhat unfortunate as previously sparc64 (ab)used resource activation to indicate whether SYS_RES_MEMORY resources should be mapped into KVA, which is only necessary if their going to be accessed via the pointer returned from rman_get_virtual() but not for bus_space(9) as the later always uses physical access on sparc64. Besides wasting KVA if we always map in SYS_RES_MEMORY resources, a driver also may deliberately not map them in if the firmware already has done so, possibly in a special way. So in order to still allow a driver to decide whether a SYS_RES_MEMORY resource should be mapped into KVA we let it indicate that by calling bus_space_map(9) with BUS_SPACE_MAP_LINEAR as actually documented in the bus_space(9) page. This is implemented by allocating a separate bus tag per SYS_RES_MEMORY resource and passing the resource via the previously unused bus tag cookie so we later on can call rman_set_virtual() in sparc64_bus_mem_map(). As a side effect this now also allows to actually indicate that a SYS_RES_MEMORY resource should be mapped in as cacheable and/or read-only via BUS_SPACE_MAP_CACHEABLE and BUS_SPACE_MAP_READONLY respectively. - Do some minor cleanup like taking advantage of rman_init_from_resource(), factor out the common part of bus tag allocation into a newly added sparc64_alloc_bus_tag(), hook up some missing newbus methods and replace some homegrown versions with the generic counterparts etc. - While at it, let apb_attach() (which can't use the generic NEW_PCIB code as APB bridges just don't have the base and limit registers implemented) regarding the config space registers cached in pcib_softc and the SYSCTL reporting nodes set up.
Diffstat (limited to 'sys/sparc64')
-rw-r--r--sys/sparc64/central/central.c11
-rw-r--r--sys/sparc64/conf/DEFAULTS2
-rw-r--r--sys/sparc64/ebus/ebus.c102
-rw-r--r--sys/sparc64/fhc/fhc.c11
-rw-r--r--sys/sparc64/include/bus.h23
-rw-r--r--sys/sparc64/include/bus_private.h12
-rw-r--r--sys/sparc64/pci/apb.c62
-rw-r--r--sys/sparc64/pci/fire.c159
-rw-r--r--sys/sparc64/pci/firevar.h1
-rw-r--r--sys/sparc64/pci/ofw_pcib_subr.c1
-rw-r--r--sys/sparc64/pci/psycho.c159
-rw-r--r--sys/sparc64/pci/psychovar.h1
-rw-r--r--sys/sparc64/pci/sbbc.c60
-rw-r--r--sys/sparc64/pci/schizo.c165
-rw-r--r--sys/sparc64/pci/schizovar.h1
-rw-r--r--sys/sparc64/sbus/dma_sbus.c1
-rw-r--r--sys/sparc64/sbus/sbus.c158
-rw-r--r--sys/sparc64/sparc64/bus_machdep.c75
-rw-r--r--sys/sparc64/sparc64/nexus.c110
-rw-r--r--sys/sparc64/sparc64/upa.c15
20 files changed, 630 insertions, 499 deletions
diff --git a/sys/sparc64/central/central.c b/sys/sparc64/central/central.c
index 777660f..e418a8b 100644
--- a/sys/sparc64/central/central.c
+++ b/sys/sparc64/central/central.c
@@ -60,6 +60,7 @@ static device_attach_t central_attach;
static bus_print_child_t central_print_child;
static bus_probe_nomatch_t central_probe_nomatch;
static bus_alloc_resource_t central_alloc_resource;
+static bus_adjust_resource_t central_adjust_resource;
static bus_get_resource_list_t central_get_resource_list;
static ofw_bus_get_devinfo_t central_get_devinfo;
@@ -79,6 +80,7 @@ static device_method_t central_methods[] = {
DEVMETHOD(bus_alloc_resource, central_alloc_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, central_adjust_resource),
DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
@@ -180,6 +182,15 @@ central_attach(device_t dev)
}
static int
+central_adjust_resource(device_t bus __unused, device_t child __unused,
+ int type __unused, struct resource *r __unused, u_long start __unused,
+ u_long end __unused)
+{
+
+ return (ENXIO);
+}
+
+static int
central_print_child(device_t dev, device_t child)
{
int rv;
diff --git a/sys/sparc64/conf/DEFAULTS b/sys/sparc64/conf/DEFAULTS
index 38b2408..de7b253 100644
--- a/sys/sparc64/conf/DEFAULTS
+++ b/sys/sparc64/conf/DEFAULTS
@@ -19,3 +19,5 @@ options GEOM_PART_VTOC8
# Let sunkbd emulate an AT keyboard by default.
options SUNKBD_EMULATE_ATKBD
+
+#options NEW_PCIB
diff --git a/sys/sparc64/ebus/ebus.c b/sys/sparc64/ebus/ebus.c
index 317cdfa..42bac06 100644
--- a/sys/sparc64/ebus/ebus.c
+++ b/sys/sparc64/ebus/ebus.c
@@ -136,6 +136,8 @@ static device_attach_t ebus_pci_attach;
static bus_print_child_t ebus_print_child;
static bus_probe_nomatch_t ebus_probe_nomatch;
static bus_alloc_resource_t ebus_alloc_resource;
+static bus_activate_resource_t ebus_activate_resource;
+static bus_adjust_resource_t ebus_adjust_resource;
static bus_release_resource_t ebus_release_resource;
static bus_setup_intr_t ebus_setup_intr;
static bus_get_resource_list_t ebus_get_resource_list;
@@ -161,8 +163,9 @@ static device_method_t ebus_nexus_methods[] = {
DEVMETHOD(bus_print_child, ebus_print_child),
DEVMETHOD(bus_probe_nomatch, ebus_probe_nomatch),
DEVMETHOD(bus_alloc_resource, ebus_alloc_resource),
- DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_activate_resource, ebus_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, ebus_adjust_resource),
DEVMETHOD(bus_release_resource, ebus_release_resource),
DEVMETHOD(bus_setup_intr, ebus_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
@@ -342,16 +345,10 @@ ebus_pci_attach(device_t dev)
eri->eri_res = res;
eri->eri_rman.rm_type = RMAN_ARRAY;
eri->eri_rman.rm_descr = "EBus range";
- if (rman_init(&eri->eri_rman) != 0) {
+ if (rman_init_from_resource(&eri->eri_rman, res) != 0) {
printf("%s: failed to initialize rman!", __func__);
goto fail;
}
- if (rman_manage_region(&eri->eri_rman, rman_get_start(res),
- rman_get_end(res)) != 0) {
- printf("%s: failed to register region!", __func__);
- rman_fini(&eri->eri_rman);
- goto fail;
- }
}
return (ebus_attach(dev, sc, node));
@@ -423,12 +420,10 @@ ebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
struct resource_list *rl;
struct resource_list_entry *rle = NULL;
struct resource *res;
- struct ebus_rinfo *ri;
+ struct ebus_rinfo *eri;
struct ebus_nexus_ranges *enr;
- bus_space_tag_t bt;
- bus_space_handle_t bh;
uint64_t cend, cstart, offset;
- int i, isdefault, passthrough, ridx, rv;
+ int i, isdefault, passthrough, ridx;
isdefault = (start == 0UL && end == ~0UL);
passthrough = (device_get_parent(child) != bus);
@@ -459,23 +454,17 @@ ebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
*/
(void)ofw_isa_range_map(sc->sc_range, sc->sc_nrange,
&start, &end, &ridx);
- ri = &sc->sc_rinfo[ridx];
- res = rman_reserve_resource(&ri->eri_rman, start, end,
- count, flags, child);
+ eri = &sc->sc_rinfo[ridx];
+ res = rman_reserve_resource(&eri->eri_rman, start,
+ end, count, flags & ~RF_ACTIVE, child);
if (res == NULL)
return (NULL);
rman_set_rid(res, *rid);
- bt = rman_get_bustag(ri->eri_res);
- rman_set_bustag(res, bt);
- rv = bus_space_subregion(bt,
- rman_get_bushandle(ri->eri_res),
- rman_get_start(res) - rman_get_start(ri->eri_res),
- count, &bh);
- if (rv != 0) {
+ if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(
+ child, type, *rid, res) != 0) {
rman_release_resource(res);
return (NULL);
}
- rman_set_bushandle(res, bh);
} else {
/* Map EBus ranges to nexus ranges. */
for (i = 0; i < sc->sc_nrange; i++) {
@@ -496,7 +485,6 @@ ebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
break;
}
}
-
}
if (!passthrough)
rle->res = res;
@@ -509,6 +497,48 @@ ebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
}
static int
+ebus_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *res)
+{
+ struct ebus_softc *sc;
+ struct ebus_rinfo *eri;
+ bus_space_tag_t bt;
+ bus_space_handle_t bh;
+ int i, rv;
+
+ sc = device_get_softc(bus);
+ if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) {
+ for (i = 0; i < sc->sc_nrange; i++) {
+ eri = &sc->sc_rinfo[i];
+ if (rman_is_region_manager(res, &eri->eri_rman) != 0) {
+ bt = rman_get_bustag(eri->eri_res);
+ rv = bus_space_subregion(bt,
+ rman_get_bushandle(eri->eri_res),
+ rman_get_start(res) -
+ rman_get_start(eri->eri_res),
+ rman_get_size(res), &bh);
+ if (rv != 0)
+ return (rv);
+ rman_set_bustag(res, bt);
+ rman_set_bushandle(res, bh);
+ return (rman_activate_resource(res));
+ }
+ }
+ return (EINVAL);
+ }
+ return (bus_generic_activate_resource(bus, child, type, rid, res));
+}
+
+static int
+ebus_adjust_resource(device_t bus __unused, device_t child __unused,
+ int type __unused, struct resource *res __unused, u_long start __unused,
+ u_long end __unused)
+{
+
+ return (ENXIO);
+}
+
+static int
ebus_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)
{
@@ -519,13 +549,15 @@ ebus_release_resource(device_t bus, device_t child, int type, int rid,
passthrough = (device_get_parent(child) != bus);
rl = BUS_GET_RESOURCE_LIST(bus, child);
- switch (type) {
- case SYS_RES_MEMORY:
- sc = device_get_softc(bus);
- if ((sc->sc_flags & EBUS_PCI) == 0)
- return (resource_list_release(rl, bus, child, type,
- rid, res));
- if ((rv = rman_release_resource(res)) != 0)
+ sc = device_get_softc(bus);
+ if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) {
+ if ((rman_get_flags(res) & RF_ACTIVE) != 0 ){
+ rv = bus_deactivate_resource(child, type, rid, res);
+ if (rv != 0)
+ return (rv);
+ }
+ rv = rman_release_resource(res);
+ if (rv != 0)
return (rv);
if (!passthrough) {
rle = resource_list_find(rl, type, rid);
@@ -535,13 +567,9 @@ ebus_release_resource(device_t bus, device_t child, int type, int rid,
("%s: resource entry is not busy", __func__));
rle->res = NULL;
}
- break;
- case SYS_RES_IRQ:
- return (resource_list_release(rl, bus, child, type, rid, res));
- default:
- panic("%s: unsupported resource type %d", __func__, type);
+ return (0);
}
- return (0);
+ return (resource_list_release(rl, bus, child, type, rid, res));
}
static int
diff --git a/sys/sparc64/fhc/fhc.c b/sys/sparc64/fhc/fhc.c
index 2b15e5e..0200bb1 100644
--- a/sys/sparc64/fhc/fhc.c
+++ b/sys/sparc64/fhc/fhc.c
@@ -69,6 +69,7 @@ static bus_print_child_t fhc_print_child;
static bus_probe_nomatch_t fhc_probe_nomatch;
static bus_setup_intr_t fhc_setup_intr;
static bus_alloc_resource_t fhc_alloc_resource;
+static bus_adjust_resource_t fhc_adjust_resource;
static bus_get_resource_list_t fhc_get_resource_list;
static ofw_bus_get_devinfo_t fhc_get_devinfo;
@@ -93,6 +94,7 @@ static device_method_t fhc_methods[] = {
DEVMETHOD(bus_alloc_resource, fhc_alloc_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, fhc_adjust_resource),
DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
DEVMETHOD(bus_setup_intr, fhc_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
@@ -475,6 +477,15 @@ fhc_alloc_resource(device_t bus, device_t child, int type, int *rid,
return (res);
}
+static int
+fhc_adjust_resource(device_t bus __unused, device_t child __unused,
+ int type __unused, struct resource *r __unused, u_long start __unused,
+ u_long end __unused)
+{
+
+ return (ENXIO);
+}
+
static struct resource_list *
fhc_get_resource_list(device_t bus, device_t child)
{
diff --git a/sys/sparc64/include/bus.h b/sys/sparc64/include/bus.h
index 75e5989..c641a25 100644
--- a/sys/sparc64/include/bus.h
+++ b/sys/sparc64/include/bus.h
@@ -122,32 +122,15 @@ static int bus_space_subregion(bus_space_tag_t, bus_space_handle_t,
/*
* Map a region of device bus space into CPU virtual address space.
*/
-
-static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
- bus_size_t size, int flags, bus_space_handle_t *bshp);
-
-static __inline int
-bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
- bus_size_t size __unused, int flags __unused, bus_space_handle_t *bshp)
-{
-
- *bshp = addr;
- return (0);
-}
+int bus_space_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size,
+ int flags, bus_space_handle_t *handlep);
/*
* Unmap a region of device bus space.
*/
-static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
+void bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t size);
-static __inline void
-bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
- bus_size_t size __unused)
-{
-
-}
-
/* This macro finds the first "upstream" implementation of method `f' */
#define _BS_CALL(t,f) \
while (t->f == NULL) \
diff --git a/sys/sparc64/include/bus_private.h b/sys/sparc64/include/bus_private.h
index fb6f8d3..bccd229 100644
--- a/sys/sparc64/include/bus_private.h
+++ b/sys/sparc64/include/bus_private.h
@@ -36,10 +36,14 @@
/*
* Helpers
*/
-int sparc64_bus_mem_map(bus_space_tag_t, bus_space_handle_t, bus_size_t,
- int, vm_offset_t, void **);
-int sparc64_bus_mem_unmap(void *, bus_size_t);
-bus_space_handle_t sparc64_fake_bustag(int, bus_addr_t, struct bus_space_tag *);
+int sparc64_bus_mem_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size,
+ int flags, vm_offset_t vaddr, bus_space_handle_t *hp);
+int sparc64_bus_mem_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
+ bus_size_t size);
+bus_space_tag_t sparc64_alloc_bus_tag(void *cookie,
+ struct bus_space_tag *ptag, int type, void *barrier);
+bus_space_handle_t sparc64_fake_bustag(int space, bus_addr_t addr,
+ struct bus_space_tag *ptag);
struct bus_dmamap_res {
struct resource *dr_res;
diff --git a/sys/sparc64/pci/apb.c b/sys/sparc64/pci/apb.c
index 87f1821..7d42b7b 100644
--- a/sys/sparc64/pci/apb.c
+++ b/sys/sparc64/pci/apb.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/rman.h>
+#include <sys/sysctl.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/openfirm.h>
@@ -77,6 +78,7 @@ struct apb_softc {
static device_probe_t apb_probe;
static device_attach_t apb_attach;
static bus_alloc_resource_t apb_alloc_resource;
+static bus_adjust_resource_t apb_adjust_resource;
static device_method_t apb_methods[] = {
/* Device interface */
@@ -85,6 +87,8 @@ static device_method_t apb_methods[] = {
/* Bus interface */
DEVMETHOD(bus_alloc_resource, apb_alloc_resource),
+ DEVMETHOD(bus_adjust_resource, apb_adjust_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
/* pcib interface */
DEVMETHOD(pcib_route_interrupt, ofw_pcib_gen_route_interrupt),
@@ -158,6 +162,8 @@ static int
apb_attach(device_t dev)
{
struct apb_softc *sc;
+ struct sysctl_ctx_list *sctx;
+ struct sysctl_oid *soid;
sc = device_get_softc(dev);
@@ -165,12 +171,41 @@ apb_attach(device_t dev)
* Get current bridge configuration.
*/
sc->sc_bsc.ops_pcib_sc.domain = pci_get_domain(dev);
+ sc->sc_bsc.ops_pcib_sc.secstat =
+ pci_read_config(dev, PCIR_SECSTAT_1, 2);
+ sc->sc_bsc.ops_pcib_sc.command =
+ pci_read_config(dev, PCIR_COMMAND, 2);
+ sc->sc_bsc.ops_pcib_sc.pribus =
+ pci_read_config(dev, PCIR_PRIBUS_1, 1);
sc->sc_bsc.ops_pcib_sc.secbus =
pci_read_config(dev, PCIR_SECBUS_1, 1);
sc->sc_bsc.ops_pcib_sc.subbus =
pci_read_config(dev, PCIR_SUBBUS_1, 1);
+ sc->sc_bsc.ops_pcib_sc.bridgectl =
+ pci_read_config(dev, PCIR_BRIDGECTL_1, 2);
+ sc->sc_bsc.ops_pcib_sc.seclat =
+ pci_read_config(dev, PCIR_SECLAT_1, 1);
sc->sc_iomap = pci_read_config(dev, APBR_IOMAP, 1);
sc->sc_memmap = pci_read_config(dev, APBR_MEMMAP, 1);
+
+ /*
+ * Setup SYSCTL reporting nodes.
+ */
+ sctx = device_get_sysctl_ctx(dev);
+ soid = device_get_sysctl_tree(dev);
+ SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "domain",
+ CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.domain, 0,
+ "Domain number");
+ SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "pribus",
+ CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.pribus, 0,
+ "Primary bus number");
+ SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "secbus",
+ CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.secbus, 0,
+ "Secondary bus number");
+ SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "subbus",
+ CTLFLAG_RD, &sc->sc_bsc.ops_pcib_sc.subbus, 0,
+ "Subordinate bus number");
+
ofw_pcib_gen_setup(dev);
if (bootverbose) {
@@ -233,9 +268,9 @@ apb_alloc_resource(device_t dev, device_t child, int type, int *rid,
"%s requested decoded I/O range 0x%lx-0x%lx\n",
device_get_nameunit(child), start, end);
break;
-
case SYS_RES_MEMORY:
- if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start, end)) {
+ if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start,
+ end)) {
device_printf(dev, "device %s requested unsupported "
"memory range 0x%lx-0x%lx\n",
device_get_nameunit(child), start, end);
@@ -246,9 +281,6 @@ apb_alloc_resource(device_t dev, device_t child, int type, int *rid,
"%s requested decoded memory range 0x%lx-0x%lx\n",
device_get_nameunit(child), start, end);
break;
-
- default:
- break;
}
passup:
@@ -258,3 +290,23 @@ apb_alloc_resource(device_t dev, device_t child, int type, int *rid,
return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
count, flags));
}
+
+static int
+apb_adjust_resource(device_t dev, device_t child, int type,
+ struct resource *r, u_long start, u_long end)
+{
+ struct apb_softc *sc;
+
+ sc = device_get_softc(dev);
+ switch (type) {
+ case SYS_RES_IOPORT:
+ if (!apb_checkrange(sc->sc_iomap, APB_IO_SCALE, start, end))
+ return (ENXIO);
+ break;
+ case SYS_RES_MEMORY:
+ if (!apb_checkrange(sc->sc_memmap, APB_MEM_SCALE, start, end))
+ return (ENXIO);
+ break;
+ }
+ return (bus_generic_adjust_resource(dev, child, type, r, start, end));
+}
diff --git a/sys/sparc64/pci/fire.c b/sys/sparc64/pci/fire.c
index 0402896..5a1e08a 100644
--- a/sys/sparc64/pci/fire.c
+++ b/sys/sparc64/pci/fire.c
@@ -85,7 +85,6 @@ __FBSDID("$FreeBSD$");
struct fire_msiqarg;
-static bus_space_tag_t fire_alloc_bus_tag(struct fire_softc *sc, int type);
static const struct fire_desc *fire_get_desc(device_t dev);
static void fire_dmamap_sync(bus_dma_tag_t dt __unused, bus_dmamap_t map,
bus_dmasync_op_t op);
@@ -113,11 +112,11 @@ static driver_filter_t fire_xcb;
* Methods
*/
static bus_activate_resource_t fire_activate_resource;
+static bus_adjust_resource_t fire_adjust_resource;
static pcib_alloc_msi_t fire_alloc_msi;
static pcib_alloc_msix_t fire_alloc_msix;
static bus_alloc_resource_t fire_alloc_resource;
static device_attach_t fire_attach;
-static bus_deactivate_resource_t fire_deactivate_resource;
static bus_get_dma_tag_t fire_get_dma_tag;
static ofw_bus_get_node_t fire_get_node;
static pcib_map_msi_t fire_map_msi;
@@ -127,7 +126,6 @@ static pcib_read_config_t fire_read_config;
static bus_read_ivar_t fire_read_ivar;
static pcib_release_msi_t fire_release_msi;
static pcib_release_msix_t fire_release_msix;
-static bus_release_resource_t fire_release_resource;
static pcib_route_interrupt_t fire_route_interrupt;
static bus_setup_intr_t fire_setup_intr;
static bus_teardown_intr_t fire_teardown_intr;
@@ -147,9 +145,10 @@ static device_method_t fire_methods[] = {
DEVMETHOD(bus_setup_intr, fire_setup_intr),
DEVMETHOD(bus_teardown_intr, fire_teardown_intr),
DEVMETHOD(bus_alloc_resource, fire_alloc_resource),
- DEVMETHOD(bus_activate_resource, fire_activate_resource),
- DEVMETHOD(bus_deactivate_resource, fire_deactivate_resource),
- DEVMETHOD(bus_release_resource, fire_release_resource),
+ DEVMETHOD(bus_activate_resource, fire_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, fire_adjust_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_get_dma_tag, fire_get_dma_tag),
/* pcib interface */
@@ -757,13 +756,19 @@ fire_attach(device_t dev)
free(range, M_OFWPROP);
/* Allocate our tags. */
- sc->sc_pci_memt = fire_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE);
- sc->sc_pci_iot = fire_alloc_bus_tag(sc, PCI_IO_BUS_SPACE);
- sc->sc_pci_cfgt = fire_alloc_bus_tag(sc, PCI_CONFIG_BUS_SPACE);
+ sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
+ sc->sc_mem_res[FIRE_PCI]), PCI_IO_BUS_SPACE, NULL);
+ if (sc->sc_pci_iot == NULL)
+ panic("%s: could not allocate PCI I/O tag", __func__);
+ sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
+ sc->sc_mem_res[FIRE_PCI]), PCI_CONFIG_BUS_SPACE, NULL);
+ if (sc->sc_pci_cfgt == NULL)
+ panic("%s: could not allocate PCI configuration space tag",
+ __func__);
if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
sc->sc_is.is_pmaxaddr, ~0, NULL, NULL, sc->sc_is.is_pmaxaddr,
0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0)
- panic("%s: bus_dma_tag_create failed", __func__);
+ panic("%s: could not create PCI DMA tag", __func__);
/* Customize the tag. */
sc->sc_pci_dmat->dt_cookie = &sc->sc_is;
sc->sc_pci_dmat->dt_mt = &sc->sc_dma_methods;
@@ -2015,14 +2020,10 @@ fire_alloc_resource(device_t bus, device_t child, int type, int *rid,
struct fire_softc *sc;
struct resource *rv;
struct rman *rm;
- bus_space_tag_t bt;
- bus_space_handle_t bh;
- int needactivate = flags & RF_ACTIVE;
-
- flags &= ~RF_ACTIVE;
sc = device_get_softc(bus);
- if (type == SYS_RES_IRQ) {
+ switch (type) {
+ case SYS_RES_IRQ:
/*
* XXX: Don't accept blank ranges for now, only single
* interrupts. The other case should not happen with
@@ -2034,38 +2035,28 @@ fire_alloc_resource(device_t bus, device_t child, int type, int *rid,
panic("%s: XXX: interrupt range", __func__);
if (*rid == 0)
start = end = INTMAP_VEC(sc->sc_ign, end);
- return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
- type, rid, start, end, count, flags));
- }
- switch (type) {
+ return (bus_generic_alloc_resource(bus, child, type, rid,
+ start, end, count, flags));
case SYS_RES_MEMORY:
rm = &sc->sc_pci_mem_rman;
- bt = sc->sc_pci_memt;
- bh = sc->sc_pci_bh[OFW_PCI_CS_MEM32];
break;
case SYS_RES_IOPORT:
rm = &sc->sc_pci_io_rman;
- bt = sc->sc_pci_iot;
- bh = sc->sc_pci_bh[OFW_PCI_CS_IO];
break;
default:
return (NULL);
- /* NOTREACHED */
}
- rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
+ child);
if (rv == NULL)
return (NULL);
rman_set_rid(rv, *rid);
- bh += rman_get_start(rv);
- rman_set_bustag(rv, bt);
- rman_set_bushandle(rv, bh);
-
- if (needactivate) {
- if (bus_activate_resource(child, type, *rid, rv)) {
- rman_release_resource(rv);
- return (NULL);
- }
+
+ if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
+ *rid, rv) != 0) {
+ rman_release_resource(rv);
+ return (NULL);
}
return (rv);
}
@@ -2074,56 +2065,56 @@ static int
fire_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- void *p;
- int error;
+ struct fire_softc *sc;
+ struct bus_space_tag *tag;
- if (type == SYS_RES_IRQ)
- return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child,
- type, rid, r));
- if (type == SYS_RES_MEMORY) {
- /*
- * Need to memory-map the device space, as some drivers
- * depend on the virtual address being set and usable.
- */
- error = sparc64_bus_mem_map(rman_get_bustag(r),
- rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);
- if (error != 0)
- return (error);
- rman_set_virtual(r, p);
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (bus_generic_activate_resource(bus, child, type, rid,
+ r));
+ case SYS_RES_MEMORY:
+ tag = sparc64_alloc_bus_tag(r, rman_get_bustag(
+ sc->sc_mem_res[FIRE_PCI]), PCI_MEMORY_BUS_SPACE, NULL);
+ if (tag == NULL)
+ return (ENOMEM);
+ rman_set_bustag(r, tag);
+ rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] +
+ rman_get_start(r));
+ break;
+ case SYS_RES_IOPORT:
+ rman_set_bustag(r, sc->sc_pci_iot);
+ rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] +
+ rman_get_start(r));
+ break;
}
return (rman_activate_resource(r));
}
static int
-fire_deactivate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
+fire_adjust_resource(device_t bus, device_t child, int type,
+ struct resource *r, u_long start, u_long end)
{
+ struct fire_softc *sc;
+ struct rman *rm;
- if (type == SYS_RES_IRQ)
- return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child,
- type, rid, r));
- if (type == SYS_RES_MEMORY) {
- sparc64_bus_mem_unmap(rman_get_virtual(r), rman_get_size(r));
- rman_set_virtual(r, NULL);
- }
- return (rman_deactivate_resource(r));
-}
-
-static int
-fire_release_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- int error;
-
- if (type == SYS_RES_IRQ)
- return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
- type, rid, r));
- if (rman_get_flags(r) & RF_ACTIVE) {
- error = bus_deactivate_resource(child, type, rid, r);
- if (error)
- return (error);
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (bus_generic_adjust_resource(bus, child, type, r,
+ start, end));
+ case SYS_RES_MEMORY:
+ rm = &sc->sc_pci_mem_rman;
+ break;
+ case SYS_RES_IOPORT:
+ rm = &sc->sc_pci_io_rman;
+ break;
+ default:
+ return (EINVAL);
}
- return (rman_release_resource(r));
+ if (rman_is_region_manager(r, rm) == 0)
+ return (EINVAL);
+ return (rman_adjust_resource(r, start, end));
}
static bus_dma_tag_t
@@ -2145,22 +2136,6 @@ fire_get_node(device_t bus, device_t child __unused)
return (sc->sc_node);
}
-static bus_space_tag_t
-fire_alloc_bus_tag(struct fire_softc *sc, int type)
-{
- bus_space_tag_t bt;
-
- bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF,
- M_NOWAIT | M_ZERO);
- if (bt == NULL)
- panic("%s: out of memory", __func__);
-
- bt->bst_cookie = sc;
- bt->bst_parent = rman_get_bustag(sc->sc_mem_res[FIRE_PCI]);
- bt->bst_type = type;
- return (bt);
-}
-
static u_int
fire_get_timecount(struct timecounter *tc)
{
diff --git a/sys/sparc64/pci/firevar.h b/sys/sparc64/pci/firevar.h
index 58ba419..d414c1a 100644
--- a/sys/sparc64/pci/firevar.h
+++ b/sys/sparc64/pci/firevar.h
@@ -47,7 +47,6 @@ struct fire_softc {
bus_space_handle_t sc_pci_bh[FIRE_NRANGE];
bus_space_tag_t sc_pci_cfgt;
bus_space_tag_t sc_pci_iot;
- bus_space_tag_t sc_pci_memt;
bus_dma_tag_t sc_pci_dmat;
device_t sc_dev;
diff --git a/sys/sparc64/pci/ofw_pcib_subr.c b/sys/sparc64/pci/ofw_pcib_subr.c
index 6001023..2ffb32d 100644
--- a/sys/sparc64/pci/ofw_pcib_subr.c
+++ b/sys/sparc64/pci/ofw_pcib_subr.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/rman.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_pci.h>
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c
index 2b81f27..f7b5d4a 100644
--- a/sys/sparc64/pci/psycho.c
+++ b/sys/sparc64/pci/psycho.c
@@ -89,7 +89,6 @@ static void psycho_intr_enable(void *);
static void psycho_intr_disable(void *);
static void psycho_intr_assign(void *);
static void psycho_intr_clear(void *);
-static bus_space_tag_t psycho_alloc_bus_tag(struct psycho_softc *, int);
/* Interrupt handlers */
static driver_filter_t psycho_ue;
@@ -113,8 +112,7 @@ static bus_read_ivar_t psycho_read_ivar;
static bus_setup_intr_t psycho_setup_intr;
static bus_alloc_resource_t psycho_alloc_resource;
static bus_activate_resource_t psycho_activate_resource;
-static bus_deactivate_resource_t psycho_deactivate_resource;
-static bus_release_resource_t psycho_release_resource;
+static bus_adjust_resource_t psycho_adjust_resource;
static bus_get_dma_tag_t psycho_get_dma_tag;
static pcib_maxslots_t psycho_maxslots;
static pcib_read_config_t psycho_read_config;
@@ -137,9 +135,10 @@ static device_method_t psycho_methods[] = {
DEVMETHOD(bus_setup_intr, psycho_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_alloc_resource, psycho_alloc_resource),
- DEVMETHOD(bus_activate_resource, psycho_activate_resource),
- DEVMETHOD(bus_deactivate_resource, psycho_deactivate_resource),
- DEVMETHOD(bus_release_resource, psycho_release_resource),
+ DEVMETHOD(bus_activate_resource, psycho_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, psycho_adjust_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_describe_intr, bus_generic_describe_intr),
DEVMETHOD(bus_get_dma_tag, psycho_get_dma_tag),
@@ -567,13 +566,19 @@ psycho_attach(device_t dev)
}
/* Allocate our tags. */
- sc->sc_pci_memt = psycho_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE);
- sc->sc_pci_iot = psycho_alloc_bus_tag(sc, PCI_IO_BUS_SPACE);
- sc->sc_pci_cfgt = psycho_alloc_bus_tag(sc, PCI_CONFIG_BUS_SPACE);
+ sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
+ sc->sc_mem_res), PCI_IO_BUS_SPACE, NULL);
+ if (sc->sc_pci_iot == NULL)
+ panic("%s: could not allocate PCI I/O tag", __func__);
+ sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
+ sc->sc_mem_res), PCI_CONFIG_BUS_SPACE, NULL);
+ if (sc->sc_pci_cfgt == NULL)
+ panic("%s: could not allocate PCI configuration space tag",
+ __func__);
if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
sc->sc_is->is_pmaxaddr, ~0, NULL, NULL, sc->sc_is->is_pmaxaddr,
0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0)
- panic("%s: bus_dma_tag_create failed", __func__);
+ panic("%s: could not create PCI DMA tag", __func__);
/* Customize the tag. */
sc->sc_pci_dmat->dt_cookie = sc->sc_is;
sc->sc_pci_dmat->dt_mt = sc->sc_dma_methods;
@@ -1165,14 +1170,10 @@ psycho_alloc_resource(device_t bus, device_t child, int type, int *rid,
struct psycho_softc *sc;
struct resource *rv;
struct rman *rm;
- bus_space_tag_t bt;
- bus_space_handle_t bh;
- int needactivate = flags & RF_ACTIVE;
-
- flags &= ~RF_ACTIVE;
sc = device_get_softc(bus);
- if (type == SYS_RES_IRQ) {
+ switch (type) {
+ case SYS_RES_IRQ:
/*
* XXX: Don't accept blank ranges for now, only single
* interrupts. The other case should not happen with
@@ -1183,38 +1184,28 @@ psycho_alloc_resource(device_t bus, device_t child, int type, int *rid,
if (start != end)
panic("%s: XXX: interrupt range", __func__);
start = end = INTMAP_VEC(sc->sc_ign, end);
- return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
- type, rid, start, end, count, flags));
- }
- switch (type) {
+ return (bus_generic_alloc_resource(bus, child, type, rid,
+ start, end, count, flags));
case SYS_RES_MEMORY:
rm = &sc->sc_pci_mem_rman;
- bt = sc->sc_pci_memt;
- bh = sc->sc_pci_bh[OFW_PCI_CS_MEM32];
break;
case SYS_RES_IOPORT:
rm = &sc->sc_pci_io_rman;
- bt = sc->sc_pci_iot;
- bh = sc->sc_pci_bh[OFW_PCI_CS_IO];
break;
default:
return (NULL);
- /* NOTREACHED */
}
- rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
+ child);
if (rv == NULL)
return (NULL);
rman_set_rid(rv, *rid);
- bh += rman_get_start(rv);
- rman_set_bustag(rv, bt);
- rman_set_bushandle(rv, bh);
-
- if (needactivate) {
- if (bus_activate_resource(child, type, *rid, rv)) {
- rman_release_resource(rv);
- return (NULL);
- }
+
+ if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
+ *rid, rv) != 0) {
+ rman_release_resource(rv);
+ return (NULL);
}
return (rv);
}
@@ -1223,56 +1214,56 @@ static int
psycho_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- void *p;
- int error;
+ struct psycho_softc *sc;
+ struct bus_space_tag *tag;
- if (type == SYS_RES_IRQ)
- return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child,
- type, rid, r));
- if (type == SYS_RES_MEMORY) {
- /*
- * Need to memory-map the device space, as some drivers
- * depend on the virtual address being set and usable.
- */
- error = sparc64_bus_mem_map(rman_get_bustag(r),
- rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);
- if (error != 0)
- return (error);
- rman_set_virtual(r, p);
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (bus_generic_activate_resource(bus, child, type, rid,
+ r));
+ case SYS_RES_MEMORY:
+ tag = sparc64_alloc_bus_tag(r, rman_get_bustag(
+ sc->sc_mem_res), PCI_MEMORY_BUS_SPACE, NULL);
+ if (tag == NULL)
+ return (ENOMEM);
+ rman_set_bustag(r, tag);
+ rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] +
+ rman_get_start(r));
+ break;
+ case SYS_RES_IOPORT:
+ rman_set_bustag(r, sc->sc_pci_iot);
+ rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] +
+ rman_get_start(r));
+ break;
}
return (rman_activate_resource(r));
}
static int
-psycho_deactivate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
+psycho_adjust_resource(device_t bus, device_t child, int type,
+ struct resource *r, u_long start, u_long end)
{
+ struct psycho_softc *sc;
+ struct rman *rm;
- if (type == SYS_RES_IRQ)
- return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child,
- type, rid, r));
- if (type == SYS_RES_MEMORY) {
- sparc64_bus_mem_unmap(rman_get_virtual(r), rman_get_size(r));
- rman_set_virtual(r, NULL);
- }
- return (rman_deactivate_resource(r));
-}
-
-static int
-psycho_release_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- int error;
-
- if (type == SYS_RES_IRQ)
- return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
- type, rid, r));
- if (rman_get_flags(r) & RF_ACTIVE) {
- error = bus_deactivate_resource(child, type, rid, r);
- if (error)
- return (error);
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (bus_generic_adjust_resource(bus, child, type, r,
+ start, end));
+ case SYS_RES_MEMORY:
+ rm = &sc->sc_pci_mem_rman;
+ break;
+ case SYS_RES_IOPORT:
+ rm = &sc->sc_pci_io_rman;
+ break;
+ default:
+ return (EINVAL);
}
- return (rman_release_resource(r));
+ if (rman_is_region_manager(r, rm) == 0)
+ return (EINVAL);
+ return (rman_adjust_resource(r, start, end));
}
static bus_dma_tag_t
@@ -1312,19 +1303,3 @@ psycho_setup_device(device_t bus, device_t child)
PCICTL_WRITE8(sc, PCR_CS, PCICTL_READ8(sc, PCR_CS) &
~PCICTL_ARB_PARK);
}
-
-static bus_space_tag_t
-psycho_alloc_bus_tag(struct psycho_softc *sc, int type)
-{
- bus_space_tag_t bt;
-
- bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF,
- M_NOWAIT | M_ZERO);
- if (bt == NULL)
- panic("%s: out of memory", __func__);
-
- bt->bst_cookie = sc;
- bt->bst_parent = rman_get_bustag(sc->sc_mem_res);
- bt->bst_type = type;
- return (bt);
-}
diff --git a/sys/sparc64/pci/psychovar.h b/sys/sparc64/pci/psychovar.h
index 117b738..5532d16 100644
--- a/sys/sparc64/pci/psychovar.h
+++ b/sys/sparc64/pci/psychovar.h
@@ -65,7 +65,6 @@ struct psycho_softc {
/* Tags for PCI access */
bus_space_tag_t sc_pci_cfgt;
- bus_space_tag_t sc_pci_memt;
bus_space_tag_t sc_pci_iot;
bus_dma_tag_t sc_pci_dmat;
diff --git a/sys/sparc64/pci/sbbc.c b/sys/sparc64/pci/sbbc.c
index be95f05..812b350 100644
--- a/sys/sparc64/pci/sbbc.c
+++ b/sys/sparc64/pci/sbbc.c
@@ -259,6 +259,9 @@ static const char *sbbc_serengeti_set_console_input(char *new);
/*
* SBBC PCI interface
*/
+static bus_activate_resource_t sbbc_bus_activate_resource;
+static bus_adjust_resource_t sbbc_bus_adjust_resource;
+static bus_deactivate_resource_t sbbc_bus_deactivate_resource;
static bus_alloc_resource_t sbbc_bus_alloc_resource;
static bus_release_resource_t sbbc_bus_release_resource;
static bus_get_resource_list_t sbbc_bus_get_resource_list;
@@ -278,9 +281,13 @@ static device_method_t sbbc_pci_methods[] = {
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_alloc_resource, sbbc_bus_alloc_resource),
+ DEVMETHOD(bus_activate_resource,sbbc_bus_activate_resource),
+ DEVMETHOD(bus_deactivate_resource,sbbc_bus_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, sbbc_bus_adjust_resource),
DEVMETHOD(bus_release_resource, sbbc_bus_release_resource),
DEVMETHOD(bus_setup_intr, sbbc_bus_setup_intr),
DEVMETHOD(bus_teardown_intr, sbbc_bus_teardown_intr),
+ DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_get_resource_list, sbbc_bus_get_resource_list),
/* clock interface */
@@ -333,11 +340,8 @@ sbbc_pci_attach(device_t dev)
sc = device_get_softc(dev);
rid = SBBC_PCI_BAR;
- /*
- * Note that we don't activate the resource so it's not mapped twice
- * but only once by the firmware.
- */
- sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0);
+ sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
if (sc->sc_res == NULL) {
device_printf(dev, "failed to allocate resources\n");
return (ENXIO);
@@ -402,24 +406,52 @@ sbbc_bus_alloc_resource(device_t dev, device_t child __unused, int type,
sc = device_get_softc(dev);
switch (type) {
case SYS_RES_IRQ:
- return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type,
- rid, start, end, count, flags));
+ return (bus_generic_alloc_resource(dev, dev, type, rid, start,
+ end, count, flags));
case SYS_RES_MEMORY:
return (sc->sc_res);
default:
return (NULL);
- /* NOTREACHED */
}
}
static int
+sbbc_bus_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *res)
+{
+
+ if (type == SYS_RES_MEMORY)
+ return (0);
+ return (bus_generic_activate_resource(bus, child, type, rid, res));
+}
+
+static int
+sbbc_bus_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *res)
+{
+
+ if (type == SYS_RES_MEMORY)
+ return (0);
+ return (bus_generic_deactivate_resource(bus, child, type, rid, res));
+}
+
+static int
+sbbc_bus_adjust_resource(device_t bus __unused, device_t child __unused,
+ int type __unused, struct resource *res __unused, u_long start __unused,
+ u_long end __unused)
+{
+
+ return (ENXIO);
+}
+
+static int
sbbc_bus_release_resource(device_t dev, device_t child __unused, int type,
int rid, struct resource *res)
{
if (type == SYS_RES_IRQ)
- return (BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
- type, rid, res));
+ return (bus_generic_release_resource(dev, dev, type, rid,
+ res));
return (0);
}
@@ -427,7 +459,7 @@ static struct resource_list *
sbbc_bus_get_resource_list(device_t dev, device_t child __unused)
{
- return (BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev));
+ return (bus_generic_get_resource_list(dev, dev));
}
static int
@@ -436,8 +468,8 @@ sbbc_bus_setup_intr(device_t dev, device_t child __unused,
driver_intr_t *intr, void *arg, void **cookiep)
{
- return (BUS_SETUP_INTR(device_get_parent(dev), dev, res, flags, filt,
- intr, arg, cookiep));
+ return (bus_generic_setup_intr(dev, dev, res, flags, filt, intr, arg,
+ cookiep));
}
static int
@@ -445,7 +477,7 @@ sbbc_bus_teardown_intr(device_t dev, device_t child __unused,
struct resource *res, void *cookie)
{
- return (BUS_TEARDOWN_INTR(device_get_parent(dev), dev, res, cookie));
+ return (bus_generic_teardown_intr(dev, dev, res, cookie));
}
/*
diff --git a/sys/sparc64/pci/schizo.c b/sys/sparc64/pci/schizo.c
index 3d147c8..b0e7545 100644
--- a/sys/sparc64/pci/schizo.c
+++ b/sys/sparc64/pci/schizo.c
@@ -91,7 +91,6 @@ static void schizo_intr_clear(void *);
static int schizo_intr_register(struct schizo_softc *sc, u_int ino);
static int schizo_get_intrmap(struct schizo_softc *, u_int,
bus_addr_t *, bus_addr_t *);
-static bus_space_tag_t schizo_alloc_bus_tag(struct schizo_softc *, int);
static timecounter_get_t schizo_get_timecount;
/* Interrupt handlers */
@@ -113,8 +112,7 @@ static bus_read_ivar_t schizo_read_ivar;
static bus_setup_intr_t schizo_setup_intr;
static bus_alloc_resource_t schizo_alloc_resource;
static bus_activate_resource_t schizo_activate_resource;
-static bus_deactivate_resource_t schizo_deactivate_resource;
-static bus_release_resource_t schizo_release_resource;
+static bus_adjust_resource_t schizo_adjust_resource;
static bus_get_dma_tag_t schizo_get_dma_tag;
static pcib_maxslots_t schizo_maxslots;
static pcib_read_config_t schizo_read_config;
@@ -137,9 +135,10 @@ static device_method_t schizo_methods[] = {
DEVMETHOD(bus_setup_intr, schizo_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_alloc_resource, schizo_alloc_resource),
- DEVMETHOD(bus_activate_resource, schizo_activate_resource),
- DEVMETHOD(bus_deactivate_resource, schizo_deactivate_resource),
- DEVMETHOD(bus_release_resource, schizo_release_resource),
+ DEVMETHOD(bus_activate_resource, schizo_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, schizo_adjust_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_get_dma_tag, schizo_get_dma_tag),
/* pcib interface */
@@ -151,7 +150,7 @@ static device_method_t schizo_methods[] = {
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, schizo_get_node),
- /* ofw_pci interface */
+ /* ofw_pci interface */
DEVMETHOD(ofw_pci_setup_device, schizo_setup_device),
KOBJMETHOD_END
@@ -580,14 +579,20 @@ schizo_attach(device_t dev)
SLIST_INSERT_HEAD(&schizo_softcs, sc, sc_link);
/* Allocate our tags. */
- sc->sc_pci_memt = schizo_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE);
- sc->sc_pci_iot = schizo_alloc_bus_tag(sc, PCI_IO_BUS_SPACE);
- sc->sc_pci_cfgt = schizo_alloc_bus_tag(sc, PCI_CONFIG_BUS_SPACE);
+ sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
+ sc->sc_mem_res[STX_PCI]), PCI_IO_BUS_SPACE, NULL);
+ if (sc->sc_pci_iot == NULL)
+ panic("%s: could not allocate PCI I/O tag", __func__);
+ sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
+ sc->sc_mem_res[STX_PCI]), PCI_CONFIG_BUS_SPACE, NULL);
+ if (sc->sc_pci_cfgt == NULL)
+ panic("%s: could not allocate PCI configuration space tag",
+ __func__);
if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
sc->sc_is.sis_is.is_pmaxaddr, ~0, NULL, NULL,
sc->sc_is.sis_is.is_pmaxaddr, 0xff, 0xffffffff, 0, NULL, NULL,
&sc->sc_pci_dmat) != 0)
- panic("%s: bus_dma_tag_create failed", __func__);
+ panic("%s: could not create PCI DMA tag", __func__);
/* Customize the tag. */
sc->sc_pci_dmat->dt_cookie = &sc->sc_is;
sc->sc_pci_dmat->dt_mt = &sc->sc_dma_methods;
@@ -1161,7 +1166,7 @@ schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op)
if ((op & BUS_DMASYNC_POSTREAD) != 0) {
/*
- * Note that in order to allow this function to be called from
+ * Note that in order to allow this function to be called from
* filters we would need to use a spin mutex for serialization
* but given that these disable interrupts we have to emulate
* one.
@@ -1333,14 +1338,10 @@ schizo_alloc_resource(device_t bus, device_t child, int type, int *rid,
struct schizo_softc *sc;
struct resource *rv;
struct rman *rm;
- bus_space_tag_t bt;
- bus_space_handle_t bh;
- int needactivate = flags & RF_ACTIVE;
-
- flags &= ~RF_ACTIVE;
sc = device_get_softc(bus);
- if (type == SYS_RES_IRQ) {
+ switch (type) {
+ case SYS_RES_IRQ:
/*
* XXX: Don't accept blank ranges for now, only single
* interrupts. The other case should not happen with
@@ -1351,38 +1352,28 @@ schizo_alloc_resource(device_t bus, device_t child, int type, int *rid,
if (start != end)
panic("%s: XXX: interrupt range", __func__);
start = end = INTMAP_VEC(sc->sc_ign, end);
- return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
- type, rid, start, end, count, flags));
- }
- switch (type) {
+ return (bus_generic_alloc_resource(bus, child, type, rid,
+ start, end, count, flags));
case SYS_RES_MEMORY:
rm = &sc->sc_pci_mem_rman;
- bt = sc->sc_pci_memt;
- bh = sc->sc_pci_bh[OFW_PCI_CS_MEM32];
break;
case SYS_RES_IOPORT:
rm = &sc->sc_pci_io_rman;
- bt = sc->sc_pci_iot;
- bh = sc->sc_pci_bh[OFW_PCI_CS_IO];
break;
default:
return (NULL);
- /* NOTREACHED */
}
- rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
+ child);
if (rv == NULL)
return (NULL);
rman_set_rid(rv, *rid);
- bh += rman_get_start(rv);
- rman_set_bustag(rv, bt);
- rman_set_bushandle(rv, bh);
-
- if (needactivate) {
- if (bus_activate_resource(child, type, *rid, rv)) {
- rman_release_resource(rv);
- return (NULL);
- }
+
+ if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
+ *rid, rv) != 0) {
+ rman_release_resource(rv);
+ return (NULL);
}
return (rv);
}
@@ -1391,56 +1382,56 @@ static int
schizo_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- void *p;
- int error;
+ struct schizo_softc *sc;
+ struct bus_space_tag *tag;
- if (type == SYS_RES_IRQ)
- return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child,
- type, rid, r));
- if (type == SYS_RES_MEMORY) {
- /*
- * Need to memory-map the device space, as some drivers
- * depend on the virtual address being set and usable.
- */
- error = sparc64_bus_mem_map(rman_get_bustag(r),
- rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);
- if (error != 0)
- return (error);
- rman_set_virtual(r, p);
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (bus_generic_activate_resource(bus, child, type, rid,
+ r));
+ case SYS_RES_MEMORY:
+ tag = sparc64_alloc_bus_tag(r, rman_get_bustag(
+ sc->sc_mem_res[STX_PCI]), PCI_MEMORY_BUS_SPACE, NULL);
+ if (tag == NULL)
+ return (ENOMEM);
+ rman_set_bustag(r, tag);
+ rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] +
+ rman_get_start(r));
+ break;
+ case SYS_RES_IOPORT:
+ rman_set_bustag(r, sc->sc_pci_iot);
+ rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] +
+ rman_get_start(r));
+ break;
}
return (rman_activate_resource(r));
}
static int
-schizo_deactivate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
+schizo_adjust_resource(device_t bus, device_t child, int type,
+ struct resource *r, u_long start, u_long end)
{
+ struct schizo_softc *sc;
+ struct rman *rm;
- if (type == SYS_RES_IRQ)
- return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child,
- type, rid, r));
- if (type == SYS_RES_MEMORY) {
- sparc64_bus_mem_unmap(rman_get_virtual(r), rman_get_size(r));
- rman_set_virtual(r, NULL);
- }
- return (rman_deactivate_resource(r));
-}
-
-static int
-schizo_release_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
-{
- int error;
-
- if (type == SYS_RES_IRQ)
- return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
- type, rid, r));
- if (rman_get_flags(r) & RF_ACTIVE) {
- error = bus_deactivate_resource(child, type, rid, r);
- if (error)
- return (error);
+ sc = device_get_softc(bus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (bus_generic_adjust_resource(bus, child, type, r,
+ start, end));
+ case SYS_RES_MEMORY:
+ rm = &sc->sc_pci_mem_rman;
+ break;
+ case SYS_RES_IOPORT:
+ rm = &sc->sc_pci_io_rman;
+ break;
+ default:
+ return (EINVAL);
}
- return (rman_release_resource(r));
+ if (rman_is_region_manager(r, rm) == 0)
+ return (EINVAL);
+ return (rman_adjust_resource(r, start, end));
}
static bus_dma_tag_t
@@ -1473,7 +1464,7 @@ schizo_setup_device(device_t bus, device_t child)
/*
* Disable bus parking in order to work around a bus hang caused by
* Casinni/Skyhawk combinations.
- */
+ */
if (OF_getproplen(ofw_bus_get_node(child), "pci-req-removal") >= 0)
SCHIZO_PCI_SET(sc, STX_PCI_CTRL, SCHIZO_PCI_READ_8(sc,
STX_PCI_CTRL) & ~STX_PCI_CTRL_ARB_PARK);
@@ -1498,22 +1489,6 @@ schizo_setup_device(device_t bus, device_t child)
}
}
-static bus_space_tag_t
-schizo_alloc_bus_tag(struct schizo_softc *sc, int type)
-{
- bus_space_tag_t bt;
-
- bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF,
- M_NOWAIT | M_ZERO);
- if (bt == NULL)
- panic("%s: out of memory", __func__);
-
- bt->bst_cookie = sc;
- bt->bst_parent = rman_get_bustag(sc->sc_mem_res[STX_PCI]);
- bt->bst_type = type;
- return (bt);
-}
-
static u_int
schizo_get_timecount(struct timecounter *tc)
{
diff --git a/sys/sparc64/pci/schizovar.h b/sys/sparc64/pci/schizovar.h
index 8e18b58..3fe7cdc 100644
--- a/sys/sparc64/pci/schizovar.h
+++ b/sys/sparc64/pci/schizovar.h
@@ -81,7 +81,6 @@ struct schizo_softc {
bus_space_handle_t sc_pci_bh[STX_NRANGE];
bus_space_tag_t sc_pci_cfgt;
bus_space_tag_t sc_pci_iot;
- bus_space_tag_t sc_pci_memt;
bus_dma_tag_t sc_pci_dmat;
uint32_t sc_stats_dma_ce;
diff --git a/sys/sparc64/sbus/dma_sbus.c b/sys/sparc64/sbus/dma_sbus.c
index 1310f37..2594243 100644
--- a/sys/sparc64/sbus/dma_sbus.c
+++ b/sys/sparc64/sbus/dma_sbus.c
@@ -118,6 +118,7 @@ static device_method_t dma_methods[] = {
DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
diff --git a/sys/sparc64/sbus/sbus.c b/sys/sparc64/sbus/sbus.c
index dbe3859..f9f78da 100644
--- a/sys/sparc64/sbus/sbus.c
+++ b/sys/sparc64/sbus/sbus.c
@@ -108,7 +108,6 @@ struct sbus_rd {
struct sbus_softc {
device_t sc_dev;
bus_dma_tag_t sc_cdmatag;
- bus_space_tag_t sc_cbustag;
int sc_clockfreq; /* clock frequency (in Hz) */
int sc_nrange;
struct sbus_rd *sc_rd;
@@ -137,9 +136,9 @@ static bus_read_ivar_t sbus_read_ivar;
static bus_get_resource_list_t sbus_get_resource_list;
static bus_setup_intr_t sbus_setup_intr;
static bus_alloc_resource_t sbus_alloc_resource;
-static bus_release_resource_t sbus_release_resource;
static bus_activate_resource_t sbus_activate_resource;
-static bus_deactivate_resource_t sbus_deactivate_resource;
+static bus_adjust_resource_t sbus_adjust_resource;
+static bus_release_resource_t sbus_release_resource;
static bus_get_dma_tag_t sbus_get_dma_tag;
static ofw_bus_get_devinfo_t sbus_get_devinfo;
@@ -153,7 +152,6 @@ static void sbus_intr_assign(void *);
static void sbus_intr_clear(void *);
static int sbus_find_intrmap(struct sbus_softc *, u_int, bus_addr_t *,
bus_addr_t *);
-static bus_space_tag_t sbus_alloc_bustag(struct sbus_softc *);
static driver_intr_t sbus_overtemp;
static driver_intr_t sbus_pwrfail;
static int sbus_print_res(struct sbus_devinfo *);
@@ -171,10 +169,11 @@ static device_method_t sbus_methods[] = {
DEVMETHOD(bus_probe_nomatch, sbus_probe_nomatch),
DEVMETHOD(bus_read_ivar, sbus_read_ivar),
DEVMETHOD(bus_alloc_resource, sbus_alloc_resource),
- DEVMETHOD(bus_activate_resource, sbus_activate_resource),
- DEVMETHOD(bus_deactivate_resource, sbus_deactivate_resource),
+ DEVMETHOD(bus_activate_resource, sbus_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, sbus_adjust_resource),
DEVMETHOD(bus_release_resource, sbus_release_resource),
- DEVMETHOD(bus_setup_intr, sbus_setup_intr),
+ DEVMETHOD(bus_setup_intr, sbus_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_get_resource_list, sbus_get_resource_list),
@@ -284,7 +283,6 @@ sbus_attach(device_t dev)
if (OF_getprop(node, "interrupts", &prop, sizeof(prop)) == -1)
panic("%s: cannot get IGN", __func__);
sc->sc_ign = INTIGN(prop);
- sc->sc_cbustag = sbus_alloc_bustag(sc);
/*
* Record clock frequency for synchronous SCSI.
@@ -343,7 +341,6 @@ sbus_attach(device_t dev)
sc->sc_burst =
(SBUS_BURST64_DEF << SBUS_BURST64_SHIFT) | SBUS_BURST_DEF;
-
/* initalise the IOMMU */
/* punch in our copies */
@@ -375,7 +372,7 @@ sbus_attach(device_t dev)
sc->sc_cdmatag->dt_cookie = &sc->sc_is;
sc->sc_cdmatag->dt_mt = &iommu_dma_methods;
- /*
+ /*
* Hunt through all the interrupt mapping regs and register our
* interrupt controller for the corresponding interrupt vectors.
* We do this early in order to be able to catch stray interrupts.
@@ -701,12 +698,12 @@ sbus_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
/*
* Make sure the vector is fully specified and we registered
* our interrupt controller for it.
- */
+ */
vec = rman_get_start(ires);
if (INTIGN(vec) != sc->sc_ign || intr_vectors[vec].iv_ic != &sbus_ic) {
device_printf(dev, "invalid interrupt vector 0x%lx\n", vec);
- return (EINVAL);
- }
+ return (EINVAL);
+ }
return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr,
arg, cookiep));
}
@@ -721,14 +718,12 @@ sbus_alloc_resource(device_t bus, device_t child, int type, int *rid,
struct resource_list *rl;
struct resource_list_entry *rle;
device_t schild;
- bus_space_handle_t bh;
bus_addr_t toffs;
bus_size_t tend;
int i, slot;
- int isdefault, needactivate, passthrough;
+ int isdefault, passthrough;
isdefault = (start == 0UL && end == ~0UL);
- needactivate = flags & RF_ACTIVE;
passthrough = (device_get_parent(child) != bus);
rle = NULL;
sc = device_get_softc(bus);
@@ -751,7 +746,6 @@ sbus_alloc_resource(device_t bus, device_t child, int type, int *rid,
}
}
rm = NULL;
- bh = toffs = tend = 0;
schild = child;
while (device_get_parent(schild) != bus)
schild = device_get_parent(schild);
@@ -768,24 +762,21 @@ sbus_alloc_resource(device_t bus, device_t child, int type, int *rid,
toffs = start - sc->sc_rd[i].rd_coffset;
tend = end - sc->sc_rd[i].rd_coffset;
rm = &sc->sc_rd[i].rd_rman;
- bh = sc->sc_rd[i].rd_bushandle;
break;
}
if (rm == NULL)
return (NULL);
- flags &= ~RF_ACTIVE;
- rv = rman_reserve_resource(rm, toffs, tend, count, flags,
- child);
+
+ rv = rman_reserve_resource(rm, toffs, tend, count, flags &
+ ~RF_ACTIVE, child);
if (rv == NULL)
return (NULL);
rman_set_rid(rv, *rid);
- rman_set_bustag(rv, sc->sc_cbustag);
- rman_set_bushandle(rv, bh + rman_get_start(rv));
- if (needactivate) {
- if (bus_activate_resource(child, type, *rid, rv)) {
- rman_release_resource(rv);
- return (NULL);
- }
+
+ if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child,
+ type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
}
if (!passthrough)
rle->res = rv;
@@ -799,41 +790,53 @@ static int
sbus_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- void *p;
- int error;
+ struct sbus_softc *sc;
+ struct bus_space_tag *tag;
+ int i;
- if (type == SYS_RES_IRQ) {
- return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus),
- child, type, rid, r));
- }
- if (type == SYS_RES_MEMORY) {
- /*
- * Need to memory-map the device space, as some drivers
- * depend on the virtual address being set and usable.
- */
- error = sparc64_bus_mem_map(rman_get_bustag(r),
- rman_get_bushandle(r), rman_get_size(r), 0, 0, &p);
- if (error != 0)
- return (error);
- rman_set_virtual(r, p);
+ switch (type) {
+ case SYS_RES_IRQ:
+ return (bus_generic_activate_resource(bus, child, type, rid,
+ r));
+ case SYS_RES_MEMORY:
+ sc = device_get_softc(bus);
+ for (i = 0; i < sc->sc_nrange; i++) {
+ if (rman_is_region_manager(r,
+ &sc->sc_rd[i].rd_rman) != 0) {
+ tag = sparc64_alloc_bus_tag(r,
+ rman_get_bustag(sc->sc_sysio_res),
+ SBUS_BUS_SPACE, NULL);
+ if (tag == NULL)
+ return (ENOMEM);
+ rman_set_bustag(r, tag);
+ rman_set_bushandle(r,
+ sc->sc_rd[i].rd_bushandle +
+ rman_get_start(r));
+ return (rman_activate_resource(r));
+ }
+ }
+ /* FALLTHROUGH */
+ default:
+ return (EINVAL);
}
- return (rman_activate_resource(r));
}
static int
-sbus_deactivate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
+sbus_adjust_resource(device_t bus, device_t child, int type,
+ struct resource *r, u_long start, u_long end)
{
+ struct sbus_softc *sc;
+ int i;
- if (type == SYS_RES_IRQ) {
- return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus),
- child, type, rid, r));
- }
if (type == SYS_RES_MEMORY) {
- sparc64_bus_mem_unmap(rman_get_virtual(r), rman_get_size(r));
- rman_set_virtual(r, NULL);
+ sc = device_get_softc(bus);
+ for (i = 0; i < sc->sc_nrange; i++)
+ if (rman_is_region_manager(r,
+ &sc->sc_rd[i].rd_rman) != 0)
+ return (rman_adjust_resource(r, start, end));
+ return (EINVAL);
}
- return (rman_deactivate_resource(r));
+ return (bus_generic_adjust_resource(bus, child, type, r, start, end));
}
static int
@@ -846,23 +849,26 @@ sbus_release_resource(device_t bus, device_t child, int type, int rid,
passthrough = (device_get_parent(child) != bus);
rl = BUS_GET_RESOURCE_LIST(bus, child);
- if (type == SYS_RES_IRQ)
- return (resource_list_release(rl, bus, child, type, rid, r));
- if ((rman_get_flags(r) & RF_ACTIVE) != 0) {
- error = bus_deactivate_resource(child, type, rid, r);
+ if (type == SYS_RES_MEMORY) {
+ if ((rman_get_flags(r) & RF_ACTIVE) != 0) {
+ error = bus_deactivate_resource(child, type, rid, r);
+ if (error)
+ return (error);
+ }
+ error = rman_release_resource(r);
if (error != 0)
return (error);
+ if (!passthrough) {
+ rle = resource_list_find(rl, type, rid);
+ KASSERT(rle != NULL,
+ ("%s: resource entry not found!", __func__));
+ KASSERT(rle->res != NULL,
+ ("%s: resource entry is not busy", __func__));
+ rle->res = NULL;
+ }
+ return (0);
}
- error = rman_release_resource(r);
- if (error != 0 || passthrough)
- return (error);
- rle = resource_list_find(rl, type, rid);
- if (rle == NULL)
- panic("%s: cannot find resource", __func__);
- if (rle->res == NULL)
- panic("%s: resource entry is not busy", __func__);
- rle->res = NULL;
- return (0);
+ return (resource_list_release(rl, bus, child, type, rid, r));
}
static bus_dma_tag_t
@@ -918,22 +924,6 @@ sbus_pwrfail(void *arg)
shutdown_nice(0);
}
-static bus_space_tag_t
-sbus_alloc_bustag(struct sbus_softc *sc)
-{
- bus_space_tag_t sbt;
-
- sbt = (bus_space_tag_t)malloc(sizeof(struct bus_space_tag), M_DEVBUF,
- M_NOWAIT | M_ZERO);
- if (sbt == NULL)
- panic("%s: out of memory", __func__);
-
- sbt->bst_cookie = sc;
- sbt->bst_parent = rman_get_bustag(sc->sc_sysio_res);
- sbt->bst_type = SBUS_BUS_SPACE;
- return (sbt);
-}
-
static int
sbus_print_res(struct sbus_devinfo *sdi)
{
diff --git a/sys/sparc64/sparc64/bus_machdep.c b/sys/sparc64/sparc64/bus_machdep.c
index 3e8748f..4667e44 100644
--- a/sys/sparc64/sparc64/bus_machdep.c
+++ b/sys/sparc64/sparc64/bus_machdep.c
@@ -101,6 +101,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/rman.h>
#include <sys/smp.h>
#include <sys/systm.h>
#include <sys/uio.h>
@@ -665,7 +666,7 @@ nexus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
contigfree(vaddr, dmat->dt_maxsize, M_DEVBUF);
}
-struct bus_dma_methods nexus_dma_methods = {
+static struct bus_dma_methods nexus_dma_methods = {
nexus_dmamap_create,
nexus_dmamap_destroy,
nexus_dmamap_load,
@@ -703,22 +704,43 @@ struct bus_dma_tag nexus_dmatag = {
* Helpers to map/unmap bus memory
*/
int
-sparc64_bus_mem_map(bus_space_tag_t tag, bus_space_handle_t handle,
- bus_size_t size, int flags, vm_offset_t vaddr, void **hp)
+bus_space_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size,
+ int flags, bus_space_handle_t *handlep)
+{
+
+ return (sparc64_bus_mem_map(tag, address, size, flags, 0, handlep));
+}
+
+int
+sparc64_bus_mem_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size,
+ int flags, vm_offset_t vaddr, bus_space_handle_t *hp)
{
- vm_offset_t addr;
vm_offset_t sva;
vm_offset_t va;
vm_paddr_t pa;
vm_size_t vsz;
u_long pm_flags;
- addr = (vm_offset_t)handle;
+ /*
+ * Given that we use physical access for bus_space(9) there's no need
+ * need to map anything in unless BUS_SPACE_MAP_LINEAR is requested.
+ */
+ if ((flags & BUS_SPACE_MAP_LINEAR) == 0) {
+ *hp = addr;
+ return (0);
+ }
+
+ if (tag->bst_cookie == NULL) {
+ printf("%s: resource cookie not set\n", __func__);
+ return (EINVAL);
+ }
+
size = round_page(size);
if (size == 0) {
printf("%s: zero size\n", __func__);
return (EINVAL);
}
+
switch (tag->bst_type) {
case PCI_CONFIG_BUS_SPACE:
case PCI_IO_BUS_SPACE:
@@ -730,7 +752,7 @@ sparc64_bus_mem_map(bus_space_tag_t tag, bus_space_handle_t handle,
break;
}
- if (!(flags & BUS_SPACE_MAP_CACHEABLE))
+ if ((flags & BUS_SPACE_MAP_CACHEABLE) == 0)
pm_flags |= TD_E;
if (vaddr != 0L)
@@ -740,9 +762,6 @@ sparc64_bus_mem_map(bus_space_tag_t tag, bus_space_handle_t handle,
panic("%s: cannot allocate virtual memory", __func__);
}
- /* Preserve page offset. */
- *hp = (void *)(sva | ((u_long)addr & PAGE_MASK));
-
pa = trunc_page(addr);
if ((flags & BUS_SPACE_MAP_READONLY) == 0)
pm_flags |= TD_W;
@@ -755,17 +774,32 @@ sparc64_bus_mem_map(bus_space_tag_t tag, bus_space_handle_t handle,
pa += PAGE_SIZE;
} while ((vsz -= PAGE_SIZE) > 0);
tlb_range_demap(kernel_pmap, sva, sva + size - 1);
+
+ /* Note: we preserve the page offset. */
+ rman_set_virtual(tag->bst_cookie, (void *)(sva | (addr & PAGE_MASK)));
return (0);
}
+void
+bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
+ bus_size_t size)
+{
+
+ sparc64_bus_mem_unmap(tag, handle, size);
+}
+
int
-sparc64_bus_mem_unmap(void *bh, bus_size_t size)
+sparc64_bus_mem_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
+ bus_size_t size)
{
vm_offset_t sva;
vm_offset_t va;
vm_offset_t endva;
- sva = trunc_page((vm_offset_t)bh);
+ if (tag->bst_cookie == NULL ||
+ (sva = (vm_offset_t)rman_get_virtual(tag->bst_cookie)) == 0)
+ return (0);
+ sva = trunc_page(sva);
endva = sva + round_page(size);
for (va = sva; va < endva; va += PAGE_SIZE)
pmap_kremove_flags(va);
@@ -791,6 +825,25 @@ sparc64_fake_bustag(int space, bus_addr_t addr, struct bus_space_tag *ptag)
}
/*
+ * Allocate a bus tag.
+ */
+bus_space_tag_t
+sparc64_alloc_bus_tag(void *cookie, struct bus_space_tag *ptag, int type,
+ void *barrier)
+{
+ bus_space_tag_t bt;
+
+ bt = malloc(sizeof(struct bus_space_tag), M_DEVBUF, M_NOWAIT);
+ if (bt == NULL)
+ return (NULL);
+ bt->bst_cookie = cookie;
+ bt->bst_parent = ptag;
+ bt->bst_type = type;
+ bt->bst_bus_barrier = barrier;
+ return (bt);
+}
+
+/*
* Base bus space handlers.
*/
diff --git a/sys/sparc64/sparc64/nexus.c b/sys/sparc64/sparc64/nexus.c
index 4c1379e..041f2ff 100644
--- a/sys/sparc64/sparc64/nexus.c
+++ b/sys/sparc64/sparc64/nexus.c
@@ -90,6 +90,7 @@ static bus_teardown_intr_t nexus_teardown_intr;
static bus_alloc_resource_t nexus_alloc_resource;
static bus_activate_resource_t nexus_activate_resource;
static bus_deactivate_resource_t nexus_deactivate_resource;
+static bus_adjust_resource_t nexus_adjust_resource;
static bus_release_resource_t nexus_release_resource;
static bus_get_resource_list_t nexus_get_resource_list;
#ifdef SMP
@@ -122,6 +123,7 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
DEVMETHOD(bus_activate_resource, nexus_activate_resource),
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, nexus_adjust_resource),
DEVMETHOD(bus_release_resource, nexus_release_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
@@ -277,22 +279,22 @@ nexus_add_child(device_t dev, u_int order, const char *name, int unit)
}
static int
-nexus_print_child(device_t dev, device_t child)
+nexus_print_child(device_t bus, device_t child)
{
int rv;
- rv = bus_print_child_header(dev, child);
+ rv = bus_print_child_header(bus, child);
rv += nexus_print_res(device_get_ivars(child));
- rv += bus_print_child_footer(dev, child);
+ rv += bus_print_child_footer(bus, child);
return (rv);
}
static void
-nexus_probe_nomatch(device_t dev, device_t child)
+nexus_probe_nomatch(device_t bus, device_t child)
{
const char *type;
- device_printf(dev, "<%s>", ofw_bus_get_name(child));
+ device_printf(bus, "<%s>", ofw_bus_get_name(child));
nexus_print_res(device_get_ivars(child));
type = ofw_bus_get_type(child);
printf(" type %s (no driver attached)\n",
@@ -300,23 +302,24 @@ nexus_probe_nomatch(device_t dev, device_t child)
}
static int
-nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
- driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
+nexus_setup_intr(device_t bus __unused, device_t child, struct resource *r,
+ int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
+ void **cookiep)
{
int error;
- if (res == NULL)
+ if (r == NULL)
panic("%s: NULL interrupt resource!", __func__);
- if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
+ if ((rman_get_flags(r) & RF_SHAREABLE) == 0)
flags |= INTR_EXCL;
/* We depend here on rman_activate_resource() being idempotent. */
- error = rman_activate_resource(res);
+ error = rman_activate_resource(r);
if (error)
return (error);
- error = inthand_add(device_get_nameunit(child), rman_get_start(res),
+ error = inthand_add(device_get_nameunit(child), rman_get_start(r),
filt, intr, arg, flags, cookiep);
/*
@@ -328,7 +331,8 @@ nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
}
static int
-nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
+nexus_teardown_intr(device_t bus __unused, device_t child __unused,
+ struct resource *r, void *ih)
{
inthand_remove(rman_get_start(r), ih);
@@ -337,7 +341,8 @@ nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
#ifdef SMP
static int
-nexus_bind_intr(device_t dev, device_t child, struct resource *r, int cpu)
+nexus_bind_intr(device_t bus __unused, device_t child __unused,
+ struct resource *r, int cpu)
{
return (intr_bind(rman_get_start(r), cpu));
@@ -345,8 +350,8 @@ nexus_bind_intr(device_t dev, device_t child, struct resource *r, int cpu)
#endif
static int
-nexus_describe_intr(device_t dev, device_t child, struct resource *r,
- void *cookie, const char *descr)
+nexus_describe_intr(device_t bus __unused, device_t child __unused,
+ struct resource *r, void *cookie, const char *descr)
{
return (intr_describe(rman_get_start(r), cookie, descr));
@@ -361,10 +366,9 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
struct resource *rv;
struct resource_list_entry *rle;
device_t nexus;
- int isdefault, needactivate, passthrough;
+ int isdefault, passthrough;
isdefault = (start == 0UL && end == ~0UL);
- needactivate = flags & RF_ACTIVE;
passthrough = (device_get_parent(child) != bus);
nexus = bus;
while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0)
@@ -397,21 +401,16 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
return (NULL);
}
- flags &= ~RF_ACTIVE;
- rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
+ child);
if (rv == NULL)
return (NULL);
rman_set_rid(rv, *rid);
- if (type == SYS_RES_MEMORY) {
- rman_set_bustag(rv, &nexus_bustag);
- rman_set_bushandle(rv, rman_get_start(rv));
- }
- if (needactivate) {
- if (bus_activate_resource(child, type, *rid, rv) != 0) {
- rman_release_resource(rv);
- return (NULL);
- }
+ if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
+ *rid, rv) != 0) {
+ rman_release_resource(rv);
+ return (NULL);
}
if (!passthrough) {
@@ -425,30 +424,61 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
}
static int
-nexus_activate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
+nexus_activate_resource(device_t bus __unused, device_t child __unused,
+ int type, int rid __unused, struct resource *r)
{
- /* Not much to be done yet... */
+ if (type == SYS_RES_MEMORY) {
+ rman_set_bustag(r, &nexus_bustag);
+ rman_set_bushandle(r, rman_get_start(r));
+ }
return (rman_activate_resource(r));
}
static int
-nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
+nexus_deactivate_resource(device_t bus __unused, device_t child __unused,
+ int type __unused, int rid __unused, struct resource *r)
{
- /* Not much to be done yet... */
return (rman_deactivate_resource(r));
}
static int
-nexus_release_resource(device_t bus, device_t child, int type, int rid,
- struct resource *r)
+nexus_adjust_resource(device_t bus, device_t child __unused, int type,
+ struct resource *r, u_long start, u_long end)
+{
+ struct nexus_softc *sc;
+ struct rman *rm;
+ device_t nexus;
+
+ nexus = bus;
+ while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0)
+ nexus = device_get_parent(nexus);
+ sc = device_get_softc(nexus);
+ switch (type) {
+ case SYS_RES_IRQ:
+ rm = &sc->sc_intr_rman;
+ break;
+ case SYS_RES_MEMORY:
+ rm = &sc->sc_mem_rman;
+ break;
+ default:
+ return (EINVAL);
+ }
+ if (rm == NULL)
+ return (ENXIO);
+ if (rman_is_region_manager(r, rm) == 0)
+ return (EINVAL);
+ return (rman_adjust_resource(r, start, end));
+}
+
+static int
+nexus_release_resource(device_t bus __unused, device_t child, int type,
+ int rid, struct resource *r)
{
int error;
- if (rman_get_flags(r) & RF_ACTIVE) {
+ if ((rman_get_flags(r) & RF_ACTIVE) != 0) {
error = bus_deactivate_resource(child, type, rid, r);
if (error)
return (error);
@@ -457,7 +487,7 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
}
static struct resource_list *
-nexus_get_resource_list(device_t dev, device_t child)
+nexus_get_resource_list(device_t bus __unused, device_t child)
{
struct nexus_devinfo *ndi;
@@ -466,14 +496,14 @@ nexus_get_resource_list(device_t dev, device_t child)
}
static bus_dma_tag_t
-nexus_get_dma_tag(device_t bus, device_t child)
+nexus_get_dma_tag(device_t bus __unused, device_t child __unused)
{
return (&nexus_dmatag);
}
static const struct ofw_bus_devinfo *
-nexus_get_devinfo(device_t dev, device_t child)
+nexus_get_devinfo(device_t bus __unused, device_t child)
{
struct nexus_devinfo *ndi;
diff --git a/sys/sparc64/sparc64/upa.c b/sys/sparc64/sparc64/upa.c
index ecb11a2..1891de1 100644
--- a/sys/sparc64/sparc64/upa.c
+++ b/sys/sparc64/sparc64/upa.c
@@ -99,10 +99,11 @@ struct upa_softc {
static device_probe_t upa_probe;
static device_attach_t upa_attach;
-static bus_alloc_resource_t upa_alloc_resource;
-static bus_setup_intr_t upa_setup_intr;
static bus_print_child_t upa_print_child;
static bus_probe_nomatch_t upa_probe_nomatch;
+static bus_alloc_resource_t upa_alloc_resource;
+static bus_adjust_resource_t upa_adjust_resource;
+static bus_setup_intr_t upa_setup_intr;
static bus_get_resource_list_t upa_get_resource_list;
static ofw_bus_get_devinfo_t upa_get_devinfo;
@@ -130,6 +131,7 @@ static device_method_t upa_methods[] = {
DEVMETHOD(bus_alloc_resource, upa_alloc_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_adjust_resource, upa_adjust_resource),
DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
DEVMETHOD(bus_setup_intr, upa_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
@@ -506,6 +508,15 @@ upa_setup_intr(device_t dev, device_t child, struct resource *ires, int flags,
arg, cookiep));
}
+static int
+upa_adjust_resource(device_t bus __unused, device_t child __unused,
+ int type __unused, struct resource *r __unused, u_long start __unused,
+ u_long end __unused)
+{
+
+ return (ENXIO);
+}
+
static struct resource_list *
upa_get_resource_list(device_t dev, device_t child)
{
OpenPOWER on IntegriCloud