summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2015-12-27 17:51:10 +0000
committermarius <marius@FreeBSD.org>2015-12-27 17:51:10 +0000
commit14a25019d63edd9c451e5dfd43607d28b042d919 (patch)
tree9a9013b86216cf1d28b2e073130537b90bd15866
parentb65a25360bf453761bef728656d2499296150eb6 (diff)
downloadFreeBSD-src-14a25019d63edd9c451e5dfd43607d28b042d919.zip
FreeBSD-src-14a25019d63edd9c451e5dfd43607d28b042d919.tar.gz
MFC: r287767
- Sanity check that the parent ranges given in the "ranges" property of PCI-EBus-bridges actually match the BARs as specified in and required by [1, p. 113 f.]. Doing so earlier would have simplified diagnosing a bug in QEMU/OpenBIOS getting the mapping of child addresses wrong, which still needs to be fixed there. In theory, we could try to change the BARs accordingly if we hit this problem. However, at least with real machines changing the decoding likely won't work, especially if the PCI-EBus-bridge is beneath an APB one. So implementing such functionality generally is rather pointless. - Actually change the allocation type of EBus resources if they change from SYS_RES_MEMORY to SYS_RES_IOPORT when mapping them to PCI ranges in ebus_alloc_resource() and passing them up to bus_activate_resource(9). This may happen with the QEMU/OpenBIOS PCI-EBus-bridge but not real ones. Still, this is only cleans up the code and the result of resource allocation and activation is unchanged. - Change the remainder of printf(9) to device_printf(9) calls and canonicalize their wording. Peripheral Component Interconnect Input Output Controller, Part No.: 802-7837-01, Sun Microelectronics, March 1997 [1]
-rw-r--r--sys/sparc64/ebus/ebus.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/sys/sparc64/ebus/ebus.c b/sys/sparc64/ebus/ebus.c
index 93ad342..0967c5d 100644
--- a/sys/sparc64/ebus/ebus.c
+++ b/sys/sparc64/ebus/ebus.c
@@ -69,7 +69,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
-
#include <sys/rman.h>
#include <dev/ofw/ofw_bus.h>
@@ -294,7 +293,7 @@ ebus_nexus_attach(device_t dev)
sc->sc_nrange = OF_getprop_alloc(node, "ranges",
sizeof(struct ebus_nexus_ranges), &sc->sc_range);
if (sc->sc_nrange == -1) {
- printf("%s: could not get ranges property\n", __func__);
+ device_printf(dev, "could not get ranges property\n");
return (ENXIO);
}
return (ebus_attach(dev, sc, node));
@@ -306,6 +305,7 @@ ebus_pci_attach(device_t dev)
struct ebus_softc *sc;
struct ebus_rinfo *eri;
struct resource *res;
+ struct isa_ranges *range;
phandle_t node;
int i, rnum, rid;
@@ -322,7 +322,7 @@ ebus_pci_attach(device_t dev)
sc->sc_nrange = OF_getprop_alloc(node, "ranges",
sizeof(struct isa_ranges), &sc->sc_range);
if (sc->sc_nrange == -1) {
- printf("%s: could not get ranges property\n", __func__);
+ device_printf(dev, "could not get ranges property\n");
return (ENXIO);
}
@@ -332,21 +332,34 @@ ebus_pci_attach(device_t dev)
/* For every range, there must be a matching resource. */
for (rnum = 0; rnum < sc->sc_nrange; rnum++) {
eri = &sc->sc_rinfo[rnum];
- eri->eri_rtype = ofw_isa_range_restype(
- &((struct isa_ranges *)sc->sc_range)[rnum]);
+ range = &((struct isa_ranges *)sc->sc_range)[rnum];
+ eri->eri_rtype = ofw_isa_range_restype(range);
rid = PCIR_BAR(rnum);
res = bus_alloc_resource_any(dev, eri->eri_rtype, &rid,
RF_ACTIVE);
if (res == NULL) {
- printf("%s: failed to allocate range resource!\n",
- __func__);
+ device_printf(dev,
+ "could not allocate range resource %d\n", rnum);
+ goto fail;
+ }
+ if (rman_get_start(res) != ISA_RANGE_PHYS(range)) {
+ device_printf(dev,
+ "mismatch in start of range %d (0x%lx/0x%lx)\n",
+ rnum, rman_get_start(res), ISA_RANGE_PHYS(range));
+ goto fail;
+ }
+ if (rman_get_size(res) != range->size) {
+ device_printf(dev,
+ "mismatch in size of range %d (0x%lx/0x%x)\n",
+ rnum, rman_get_size(res), range->size);
goto fail;
}
eri->eri_res = res;
eri->eri_rman.rm_type = RMAN_ARRAY;
eri->eri_rman.rm_descr = "EBus range";
if (rman_init_from_resource(&eri->eri_rman, res) != 0) {
- printf("%s: failed to initialize rman!", __func__);
+ device_printf(dev,
+ "could not initialize rman for range %d", rnum);
goto fail;
}
}
@@ -452,7 +465,7 @@ ebus_alloc_resource(device_t bus, device_t child, int type, int *rid,
* Map EBus ranges to PCI ranges. This may include
* changing the allocation type.
*/
- (void)ofw_isa_range_map(sc->sc_range, sc->sc_nrange,
+ type = ofw_isa_range_map(sc->sc_range, sc->sc_nrange,
&start, &end, &ridx);
eri = &sc->sc_rinfo[ridx];
res = rman_reserve_resource(&eri->eri_rman, start,
@@ -507,7 +520,7 @@ ebus_activate_resource(device_t bus, device_t child, int type, int rid,
int i, rv;
sc = device_get_softc(bus);
- if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) {
+ if ((sc->sc_flags & EBUS_PCI) != 0 && type != SYS_RES_IRQ) {
for (i = 0; i < sc->sc_nrange; i++) {
eri = &sc->sc_rinfo[i];
if (rman_is_region_manager(res, &eri->eri_rman) != 0) {
@@ -550,7 +563,7 @@ 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);
sc = device_get_softc(bus);
- if ((sc->sc_flags & EBUS_PCI) != 0 && type == SYS_RES_MEMORY) {
+ if ((sc->sc_flags & EBUS_PCI) != 0 && type != SYS_RES_IRQ) {
if ((rman_get_flags(res) & RF_ACTIVE) != 0 ){
rv = bus_deactivate_resource(child, type, rid, res);
if (rv != 0)
OpenPOWER on IntegriCloud