Only set bus tag/handles in activate_resource() methods
John Baldwin
jhb at freebsd.org
Fri Dec 21 13:45:03 PST 2007
This patch (untested) tries to fix an issue on arm I fixed on the
ACPI-using platforms a while back. It fixes the top-level bus drivers to
activate resources (assign bus tags and handles so you can use bus_space_*())
in bus_activate_resource() methods instead of in bus_alloc_resource(). This
is important for any drivers that want do what ACPI does: allocate a resource
and then subdivide it to hand it out to child devices. A driver that does
this can still pass the bus_activate_resource() request up the tree to
actually get bus_space properly set up with this fix.
Note that i80321_pci still has a hack to deal with the variant base address
for the PCI memory region, but the rest of the drivers should be correct now.
Please test, thanks.
--- //depot/vendor/freebsd/src/sys/arm/arm/nexus.c 2007/02/23 12:24:01
+++ //depot/user/jhb/acpipci/arm/arm/nexus.c 2007/03/05 17:04:36
@@ -206,6 +206,8 @@
struct rman *rm;
int needactivate = flags & RF_ACTIVE;
+ flags &= ~RF_ACTIVE;
+
switch (type) {
case SYS_RES_MEMORY:
rm = &mem_rman;
@@ -220,8 +222,6 @@
return 0;
rman_set_rid(rv, *rid);
- rman_set_bustag(rv, (void*)ARM_BUS_SPACE_MEM);
- rman_set_bushandle(rv, rman_get_start(rv));
if (needactivate) {
if (bus_activate_resource(child, type, *rid, rv)) {
@@ -241,7 +241,7 @@
/*
* If this is a memory resource, map it into the kernel.
*/
- if (rman_get_bustag(r) == (void*)ARM_BUS_SPACE_MEM) {
+ if (type == SYS_RES_MEMORY) {
caddr_t vaddr = 0;
u_int32_t paddr;
u_int32_t psize;
@@ -252,6 +252,7 @@
poffs = paddr - trunc_page(paddr);
vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
rman_set_virtual(r, vaddr);
+ rman_set_bustag(r, (void*)ARM_BUS_SPACE_MEM);
rman_set_bushandle(r, (bus_space_handle_t) vaddr);
}
return (rman_activate_resource(r));
--- //depot/vendor/freebsd/src/sys/arm/at91/at91.c 2007/12/19 17:36:50
+++ //depot/user/jhb/acpipci/arm/at91/at91.c 2007/12/20 18:42:26
@@ -511,11 +511,14 @@
struct resource_list_entry *rle;
struct at91_ivar *ivar = device_get_ivars(child);
struct resource_list *rl = &ivar->resources;
+ int needactivate = flags & RF_ACTIVE;
if (device_get_parent(child) != dev)
return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
type, rid, start, end, count, flags));
+ flags &= ~RF_ACTIVE;
+
rle = resource_list_find(rl, type, *rid);
if (rle == NULL)
return (NULL);
@@ -541,8 +544,6 @@
#endif
rle->res = rman_reserve_resource(&sc->sc_mem_rman,
start, end, count, flags, child);
- rman_set_bustag(rle->res, &at91_bs_tag);
- rman_set_bushandle(rle->res, start);
break;
}
if (rle->res) {
@@ -550,6 +551,12 @@
rle->end = rman_get_end(rle->res);
rle->count = count;
rman_set_rid(rle->res, *rid);
+ if (needactivate) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ }
}
return (rle->res);
}
@@ -576,6 +583,11 @@
rle = resource_list_find(rl, type, rid);
if (rle == NULL)
return (EINVAL);
+ if (rman_get_flags(r) & RF_ACTIVE) {
+ int error = bus_deactivate_resource(child, type, rid, r);
+ if (error)
+ return (error);
+ }
rman_release_resource(r);
rle->res = NULL;
return (0);
@@ -615,15 +627,19 @@
#if 0
u_long p;
int error;
+#endif
if (type == SYS_RES_MEMORY) {
+ rman_set_bustag(r, &at91_bs_tag);
+ rman_set_bushandle(r, start);
+#if 0
error = bus_space_map(rman_get_bustag(r),
rman_get_bushandle(r), rman_get_size(r), 0, &p);
if (error)
return (error);
rman_set_bushandle(r, p);
+#endif
}
-#endif
return (rman_activate_resource(r));
}
--- //depot/vendor/freebsd/src/sys/arm/xscale/i80321/i80321_pci.c 2007/09/30 11:08:30
+++ //depot/user/jhb/acpipci/arm/xscale/i80321/i80321_pci.c 2007/12/20 23:43:49
@@ -283,8 +283,7 @@
struct i80321_pci_softc *sc = device_get_softc(bus);
struct resource *rv;
struct rman *rm;
- bus_space_tag_t bt = NULL;
- bus_space_handle_t bh = 0;
+ bus_handle_t bh = 0;
switch (type) {
case SYS_RES_IRQ:
@@ -292,7 +291,6 @@
break;
case SYS_RES_MEMORY:
rm = &sc->sc_mem_rman;
- bt = sc->sc_pcimem;
bh = (start >= 0x80000000 && start < 0x84000000) ? 0x80000000 :
sc->sc_mem;
start &= (0x1000000 - 1);
@@ -300,8 +298,6 @@
break;
case SYS_RES_IOPORT:
rm = &sc->sc_io_rman;
- bt = sc->sc_pciio;
- bh = sc->sc_io;
if (start < sc->sc_io) {
start = start - 0x90000000 + sc->sc_io;
end = end - 0x90000000 + sc->sc_io;
@@ -311,21 +307,22 @@
return (NULL);
}
- 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_IRQ) {
- if (type == SYS_RES_MEMORY)
- bh += (rman_get_start(rv));
- rman_set_bustag(rv, bt);
+ if (type == SYS_RES_MEMORY)
+ /*
+ * XXX: This isn't quite right but we don't have a better way
+ * to pass this on to our activate_resource() routine.
+ */
rman_set_bushandle(rv, bh);
- if (flags & RF_ACTIVE) {
- if (bus_activate_resource(child, type, *rid, rv)) {
- rman_release_resource(rv);
- return (NULL);
- }
- }
+ if (flags & RF_ACTIVE) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
}
return (rv);
}
@@ -334,16 +331,27 @@
i80321_pci_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
+ struct i80321_pci_softc *sc = device_get_softc(bus);
u_long p;
int error;
-
- if (type == SYS_RES_MEMORY) {
- error = bus_space_map(rman_get_bustag(r),
- rman_get_bushandle(r), rman_get_size(r), 0, &p);
+
+ switch (type) {
+ case SYS_RES_MEMORY:
+ /*
+ * XXX: We rely on having the bushandle initially set to the
+ * start of the PCI memio window above.
+ */
+ error = bus_space_map(sc->sc_pcimem, rman_get_bushandle(r) +
+ rman_get_start(r), rman_get_size(r), 0, &p);
if (error)
return (error);
+ rman_set_bustag(r, sc->sc_pcimem);
rman_set_bushandle(r, p);
-
+ break;
+ case SYS_RES_IOPORT:
+ rman_set_bustag(r, sc->sc_pciio);
+ rman_set_bushandle(r, sc->sc_io);
+ break;
}
return (rman_activate_resource(r));
}
--- //depot/vendor/freebsd/src/sys/arm/xscale/i80321/obio.c 2007/07/27 14:57:30
+++ //depot/user/jhb/acpipci/arm/xscale/i80321/obio.c 2007/09/24 17:24:13
@@ -98,8 +98,6 @@
{
struct resource *rv;
struct rman *rm;
- bus_space_tag_t bt = NULL;
- bus_space_handle_t bh = 0;
struct obio_softc *sc = device_get_softc(bus);
switch (type) {
@@ -110,24 +108,24 @@
return (NULL);
case SYS_RES_IOPORT:
rm = &sc->oba_rman;
- bt = sc->oba_st;
- bh = sc->oba_addr;
- start = bh;
+ start = sc->oba_addr;
break;
default:
return (NULL);
}
-
- 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);
- if (type == SYS_RES_IRQ)
- return (rv);
rman_set_rid(rv, *rid);
- rman_set_bustag(rv, bt);
- rman_set_bushandle(rv, bh);
+ if (flags & RF_ACTIVE) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ }
return (rv);
}
@@ -136,8 +134,15 @@
obio_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- return (0);
+ struct obio_softc *sc = device_get_softc(bus);
+
+ if (type == SYS_RES_IOPORT) {
+ rman_set_bustag(r, sc->oba_st);
+ rman_set_bushandle(r, sc->oba_addr);
+ }
+ return (rman_activate_resource(r));
}
+
static device_method_t obio_methods[] = {
DEVMETHOD(device_probe, obio_probe),
DEVMETHOD(device_attach, obio_attach),
--- //depot/vendor/freebsd/src/sys/arm/xscale/i8134x/i81342_pci.c 2007/09/30 11:08:30
+++ //depot/user/jhb/acpipci/arm/xscale/i8134x/i81342_pci.c 2007/12/20 23:44:30
@@ -334,8 +334,7 @@
struct i81342_pci_softc *sc = device_get_softc(bus);
struct resource *rv;
struct rman *rm;
- bus_space_tag_t bt = NULL;
- bus_space_handle_t bh = 0;
+ u_long off;
switch (type) {
case SYS_RES_IRQ:
@@ -343,41 +342,30 @@
break;
case SYS_RES_MEMORY:
rm = &sc->sc_mem_rman;
- bt = &sc->sc_pcimem;
- bh = 0;
break;
case SYS_RES_IOPORT:
rm = &sc->sc_io_rman;
- bt = &sc->sc_pciio;
- bh = sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR :
+ off = sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR :
IOP34X_PCIE_OIOBAR_VADDR;
- start += bh;
- end += bh;
+ start += off;
+ end += off;
break;
default:
return (NULL);
}
- 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_IRQ) {
- if (type == SYS_RES_MEMORY)
- bh += (rman_get_start(rv));
- rman_set_bustag(rv, bt);
- rman_set_bushandle(rv, bh);
- if (flags & RF_ACTIVE) {
- if (bus_activate_resource(child, type, *rid, rv)) {
- rman_release_resource(rv);
- return (NULL);
- }
- }
- }
+ if (flags & RF_ACTIVE) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ }
return (rv);
-
-
- return (NULL);
}
static int
@@ -386,14 +374,23 @@
{
u_long p;
int error;
-
- if (type == SYS_RES_MEMORY) {
- error = bus_space_map(rman_get_bustag(r),
- rman_get_bushandle(r), rman_get_size(r), 0, &p);
+
+ switch (type) {
+ case SYS_RES_MEMORY:
+ error = bus_space_map(&sc->sc_pcimem, rman_get_start(r),
+ rman_get_size(r), 0, &p);
if (error)
return (error);
+ rman_set_bustag(r, &sc->sc_pcimem);
rman_set_bushandle(r, p);
-
+ break;
+ case SYS_RES_IOPORT:
+ rman_set_bus_tag(r, &sc->sc_pciio);
+ if (sc->sc_is_atux)
+ rman_set_bushandle(r, IOP34X_PCIX_OIOBAR_VADDR);
+ else
+ rman_set_bushandle(r, IOP34X_PCIE_OIOBAR_VADDR);
+ break;
}
return (rman_activate_resource(r));
}
--- //depot/vendor/freebsd/src/sys/arm/xscale/i8134x/obio.c 2007/07/27 14:57:30
+++ //depot/user/jhb/acpipci/arm/xscale/i8134x/obio.c 2007/12/20 23:44:30
@@ -93,8 +93,6 @@
{
struct resource *rv;
struct rman *rm;
- bus_space_tag_t bt = NULL;
- bus_space_handle_t bh = 0;
struct obio_softc *sc = device_get_softc(bus);
int unit = device_get_unit(child);
@@ -110,14 +108,11 @@
return (NULL);
case SYS_RES_IOPORT:
rm = &sc->oba_rman;
- bt = sc->oba_st;
if (unit == 0) {
- bh = IOP34X_UART0_VADDR;
- start = bh;
+ start = IOP34X_UART0_VADDR;
end = IOP34X_UART1_VADDR;
} else {
- bh = IOP34X_UART1_VADDR;
- start = bh;
+ start = IOP34X_UART1_VADDR;
end = start + 0x40;
}
break;
@@ -126,15 +121,18 @@
}
- 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);
- if (type == SYS_RES_IRQ)
- return (rv);
rman_set_rid(rv, *rid);
- rman_set_bustag(rv, bt);
- rman_set_bushandle(rv, bh);
-
+ if (flags & RF_ACTIVE) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ }
+
return (rv);
}
@@ -143,8 +141,16 @@
obio_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
- return (0);
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ rman_set_bustag(r, sc->oba_st);
+ rman_set_bushandle(r, rman_get_start(r));
+ break;
+ }
+ return (rman_activate_resource(r));
}
+
static device_method_t obio_methods[] = {
DEVMETHOD(device_probe, obio_probe),
DEVMETHOD(device_attach, obio_attach),
--- //depot/vendor/freebsd/src/sys/arm/xscale/ixp425/ixp425.c 2007/05/29 18:18:31
+++ //depot/user/jhb/acpipci/arm/xscale/ixp425/ixp425.c 2007/09/24 17:24:13
@@ -319,7 +319,7 @@
struct ixp425_softc *sc = device_get_softc(dev);
struct rman *rmanp;
struct resource *rv;
- uint32_t vbase, addr;
+ uint32_t addr;
int irq;
switch (type) {
@@ -329,7 +329,7 @@
if (BUS_READ_IVAR(dev, child, IXP425_IVAR_IRQ, &irq) == 0)
start = end = irq;
rv = rman_reserve_resource(rmanp, start, end, count,
- flags, child);
+ flags & ~RF_ACTIVE, child);
if (rv != NULL)
rman_set_rid(rv, *rid);
break;
@@ -344,21 +344,45 @@
if (getvbase(start, end - start, &vbase))
return NULL;
rv = rman_reserve_resource(rmanp, start, end, count,
- flags, child);
- if (rv != NULL) {
+ flags & ~RF_ACTIVE, child);
+ if (rv != NULL)
rman_set_rid(rv, *rid);
- if (strcmp(device_get_name(child), "uart") == 0)
- rman_set_bustag(rv, &ixp425_a4x_bs_tag);
- else
- rman_set_bustag(rv, sc->sc_iot);
- rman_set_bushandle(rv, vbase);
- }
break;
default:
rv = NULL;
break;
}
- return rv;
+
+ if (rv != NULL && flags & RF_ACTIVE) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+ }
+
+ return (rv);
+}
+
+static int
+ixp425_activate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct ixp425_softc *sc = device_get_softc(dev);
+ int error;
+ uint32_t vbase;
+
+ if (type == SYS_RES_MEMORY) {
+ error = getvbase(rman_get_start(r), rman_get_size(r), &vbase);
+ if (error)
+ return (error);
+ if (strcmp(device_get_name(child), "uart") == 0)
+ rman_set_bustag(rv, &ixp425_a4x_bs_tag);
+ else
+ rman_set_bustag(rv, sc->sc_iot);
+ rman_set_bushandle(rv, vbase);
+ }
+
+ return (rman_activate_resource(r));
}
static int
@@ -409,6 +433,7 @@
DEVMETHOD(bus_read_ivar, ixp425_read_ivar),
DEVMETHOD(bus_alloc_resource, ixp425_alloc_resource),
+ DEVMETHOD(bus_activate_resource, ixp425_activate_resource),
DEVMETHOD(bus_setup_intr, ixp425_setup_intr),
DEVMETHOD(bus_teardown_intr, ixp425_teardown_intr),
--- //depot/vendor/freebsd/src/sys/arm/xscale/ixp425/ixp425_pci.c 2007/09/30 11:08:30
+++ //depot/user/jhb/acpipci/arm/xscale/ixp425/ixp425_pci.c 2007/10/08 16:52:09
@@ -279,12 +279,10 @@
ixppcib_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
- bus_space_tag_t tag;
struct ixppcib_softc *sc = device_get_softc(bus);
struct rman *rmanp;
struct resource *rv;
- tag = NULL; /* shut up stupid gcc */
rv = NULL;
switch (type) {
case SYS_RES_IRQ:
@@ -293,28 +291,25 @@
case SYS_RES_IOPORT:
rmanp = &sc->sc_io_rman;
- tag = &sc->sc_pci_iot;
break;
case SYS_RES_MEMORY:
rmanp = &sc->sc_mem_rman;
- tag = &sc->sc_pci_memt;
break;
default:
return (rv);
}
- rv = rman_reserve_resource(rmanp, start, end, count, flags, child);
- if (rv != NULL) {
- rman_set_rid(rv, *rid);
- if (type == SYS_RES_IOPORT) {
- rman_set_bustag(rv, tag);
- rman_set_bushandle(rv, rman_get_start(rv));
- } else if (type == SYS_RES_MEMORY) {
- rman_set_bustag(rv, tag);
- rman_set_bushandle(rv, rman_get_bushandle(sc->sc_mem) +
- (rman_get_start(rv) - IXP425_PCI_MEM_HWBASE));
+ rv = rman_reserve_resource(rmanp, start, end, count, flags & ~RF_ACTIVE,
+ child);
+ if (rv == NULL)
+ return (NULL);
+ rman_set_rid(rv, *rid);
+ if (flags & RF_ACTIVE) {
+ if (bus_activate_resource(child, type, *rid, rv)) {
+ rman_release_resource(rv);
+ return (NULL);
}
}
@@ -325,9 +320,21 @@
ixppcib_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
+ struct ixppcib_softc *sc = device_get_softc(bus);
- device_printf(bus, "%s called activate_resource\n", device_get_nameunit(child));
- return (ENXIO);
+ switch (type) {
+ case SYS_RES_IOPORT:
+ rman_set_bustag(r, &sc->sc_pci_iot);
+ rman_set_bushandle(r, rman_get_start(r));
+ break;
+ case SYS_RES_MEMORY:
+ rman_set_bustag(r, &sc->sc_pci_memt);
+ rman_set_bushandle(r, rman_get_bushandle(sc->sc_mem) +
+ (rman_get_start(r) - IXP425_PCI_MEM_HWBASE));
+ break;
+ }
+
+ return (rman_activate_resource(r));
}
static int
--
John Baldwin
More information about the freebsd-arm
mailing list