diff options
author | benno <benno@FreeBSD.org> | 2003-01-30 11:28:29 +0000 |
---|---|---|
committer | benno <benno@FreeBSD.org> | 2003-01-30 11:28:29 +0000 |
commit | cd92290e8c2bc2039d8a1a472e4d42887f371374 (patch) | |
tree | 7b695d7b8ce12002a7349ccc8f1ac49d380ada3f /sys/powerpc/powermac | |
parent | 63f9ad87909a7752f8eef1f5749481d4a4c6d174 (diff) | |
download | FreeBSD-src-cd92290e8c2bc2039d8a1a472e4d42887f371374.zip FreeBSD-src-cd92290e8c2bc2039d8a1a472e4d42887f371374.tar.gz |
Rework of how memory resources are discovered and dealt with in macio.
- Store the OpenFirmware "reg" property in the macio ivars.
- Use a struct to define the structure of a "reg" property entry.
- Discover all memory ranges, not just the first.
- In ata_macio, manage our own range and hand out our own allocations using
bus_space_subregion.
- Fix bus_space_subregion to handle subregions of sparse maps.
Diffstat (limited to 'sys/powerpc/powermac')
-rw-r--r-- | sys/powerpc/powermac/ata_macio.c | 107 | ||||
-rw-r--r-- | sys/powerpc/powermac/macio.c | 100 | ||||
-rw-r--r-- | sys/powerpc/powermac/maciovar.h | 17 |
3 files changed, 159 insertions, 65 deletions
diff --git a/sys/powerpc/powermac/ata_macio.c b/sys/powerpc/powermac/ata_macio.c index c192e2e..cc2e7fb 100644 --- a/sys/powerpc/powermac/ata_macio.c +++ b/sys/powerpc/powermac/ata_macio.c @@ -46,6 +46,14 @@ #include <dev/ofw/openfirm.h> #include <powerpc/powermac/maciovar.h> +struct ata_macio_softc { + struct resource *sc_memres; + int sc_memrid; + bus_space_tag_t sc_bt; + bus_space_handle_t sc_bh; + struct rman sc_mem_rman; +}; + /* * Define the macio ata bus attachment. This creates a pseudo-bus that * the ATA device can be attached to @@ -81,7 +89,7 @@ static device_method_t ata_macio_methods[] = { static driver_t ata_macio_driver = { "atamacio", ata_macio_methods, - 0, + sizeof(struct ata_macio_softc), }; static devclass_t ata_macio_devclass; @@ -98,7 +106,7 @@ ata_macio_probe(device_t dev) return (ENXIO); /* Print keylargo/pangea ??? */ - device_set_desc(dev, "Mac-IO ATA Controller"); + device_set_desc(dev, "MacIO ATA Controller"); return (0); } @@ -106,6 +114,31 @@ ata_macio_probe(device_t dev) static int ata_macio_attach(device_t dev) { + struct ata_macio_softc *sc; + + sc = device_get_softc(dev); + + sc->sc_memrid = 0; + sc->sc_memres = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->sc_memrid, + 0, ~1, 1, RF_ACTIVE | PPC_BUS_SPARSE4); + if (sc->sc_memres == NULL) { + device_printf(dev, "could not allocate memory\n"); + return (ENXIO); + } + + sc->sc_bt = rman_get_bustag(sc->sc_memres); + sc->sc_bh = rman_get_bushandle(sc->sc_memres); + + sc->sc_mem_rman.rm_type = RMAN_ARRAY; + sc->sc_mem_rman.rm_descr = device_get_nameunit(dev); + if (rman_init(&sc->sc_mem_rman) != 0) { + device_printf(dev, "failed to init memory rman\n"); + bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_memrid, + sc->sc_memres); + return (ENXIO); + } + rman_manage_region(&sc->sc_mem_rman, 0, rman_get_size(sc->sc_memres)); + /* * Add a single child per controller. Should be able * to add two @@ -135,11 +168,13 @@ struct resource * ata_macio_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - struct resource *res = NULL; - int myrid; - u_int *ofw_regs; + struct ata_macio_softc *sc; + struct resource *res; + int myrid; + bus_space_handle_t bh; - ofw_regs = macio_get_regs(dev); + sc = device_get_softc(dev); + res = NULL; /* * The offset for the register bank is in the first ofw register, @@ -149,25 +184,42 @@ ata_macio_alloc_resource(device_t dev, device_t child, int type, int *rid, if (type == SYS_RES_IOPORT) { switch (*rid) { case ATA_IOADDR_RID: - myrid = 0; - start = ofw_regs[0]; - end = start + (ATA_IOSIZE << 4) - 1; + start = 0; + end = (ATA_IOSIZE << 4) - 1; count = ATA_IOSIZE << 4; - res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, - SYS_RES_IOPORT, &myrid, - start, end, count, - PPC_BUS_SPARSE4 | flags); + res = rman_reserve_resource(&sc->sc_mem_rman, start, + end, count, flags | PPC_BUS_SPARSE4, child); + if (res == NULL) { + device_printf(dev, "rman_reserve failed\n"); + return (NULL); + } + + rman_set_bustag(res, sc->sc_bt); + bus_space_subregion(sc->sc_bt, sc->sc_bh, + rman_get_start(res), rman_get_size(res), &bh); + rman_set_bushandle(res, bh); + rman_set_rid(res, ATA_IOADDR_RID); + break; case ATA_ALTADDR_RID: - myrid = 0; - start = ofw_regs[0] + ATA_MACIO_ALTOFFSET; + start = ATA_MACIO_ALTOFFSET; end = start + (ATA_ALTIOSIZE << 4) - 1; count = ATA_ALTIOSIZE << 4; - res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, - SYS_RES_IOPORT, &myrid, - start, end, count, - PPC_BUS_SPARSE4 | flags); + + res = rman_reserve_resource(&sc->sc_mem_rman, start, + end, count, flags | PPC_BUS_SPARSE4, child); + if (res == NULL) { + device_printf(dev, "rman_reserve failed\n"); + return (NULL); + } + + rman_set_bustag(res, sc->sc_bt); + bus_space_subregion(sc->sc_bt, sc->sc_bh, + rman_get_start(res), rman_get_size(res), &bh); + rman_set_bushandle(res, bh); + rman_set_rid(res, ATA_ALTADDR_RID); + break; case ATA_BMADDR_RID: @@ -196,8 +248,15 @@ static int ata_macio_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { - printf("macio: release resource\n"); - return (0); + + if (type == SYS_RES_IRQ) + return (bus_release_resource(device_get_parent(dev), type, + rid, r)); + + if (type == SYS_RES_IOPORT || type == SYS_RES_MEMORY) + return (rman_release_resource(r)); + + return (ENXIO); } @@ -242,12 +301,14 @@ ata_macio_locknoop(struct ata_channel *ch, int type) static int ata_macio_sub_probe(device_t dev) { - struct ata_channel *ch = device_get_softc(dev); + struct ata_channel *ch; + + ch = device_get_softc(dev); ch->unit = 0; ch->flags = ATA_USE_16BIT; ch->intr_func = ata_macio_intrnoop; ch->lock_func = ata_macio_locknoop; - return ata_probe(dev); + return (ata_probe(dev)); } diff --git a/sys/powerpc/powermac/macio.c b/sys/powerpc/powermac/macio.c index 6445602..f41a66c 100644 --- a/sys/powerpc/powermac/macio.c +++ b/sys/powerpc/powermac/macio.c @@ -110,7 +110,6 @@ devclass_t macio_devclass; DRIVER_MODULE(macio, pci, macio_pci_driver, macio_devclass, 0, 0); - /* * PCI ID search table */ @@ -189,25 +188,20 @@ macio_add_intr(phandle_t devnode, struct macio_devinfo *dinfo) static void macio_add_reg(phandle_t devnode, struct macio_devinfo *dinfo) { - u_int size; - u_int start; - u_int end; - - size = OF_getprop(devnode, "reg", dinfo->mdi_reg, - sizeof(dinfo->mdi_reg)); + struct macio_reg *reg; + int i, nreg; + + nreg = OF_getprop_alloc(devnode, "reg", sizeof(*reg), (void **)®); + if (nreg == -1) + return; + + dinfo->mdi_nregs = nreg; + dinfo->mdi_regs = reg; - if (size != -1) { - - /* - * Only do a single range for the moment... - */ - dinfo->mdi_nregs = 1; - start = dinfo->mdi_reg[0]; - end = start + dinfo->mdi_reg[1] - 1; - resource_list_add_next(&dinfo->mdi_resources, SYS_RES_MEMORY, - start, end, end - start + 1); - } else { - dinfo->mdi_nregs = -1; + for (i = 0; i < nreg; i++) { + resource_list_add(&dinfo->mdi_resources, SYS_RES_MEMORY, i, + reg[i].mr_base, reg[i].mr_base + reg[i].mr_size, + reg[i].mr_size); } } @@ -263,7 +257,7 @@ macio_attach(device_t dev) sc->sc_size = MACIO_REG_SIZE; sc->sc_mem_rman.rm_type = RMAN_ARRAY; - sc->sc_mem_rman.rm_descr = "IOBus Device Memory"; + sc->sc_mem_rman.rm_descr = "MacIO Device Memory"; if (rman_init(&sc->sc_mem_rman) != 0) { device_printf(dev, "failed to init mem range resources\n"); @@ -340,14 +334,18 @@ macio_print_child(device_t dev, device_t child) static void macio_probe_nomatch(device_t dev, device_t child) { - u_int *regs; + struct macio_devinfo *dinfo; + struct resource_list *rl; if (bootverbose) { - regs = macio_get_regs(child); + dinfo = device_get_ivars(child); + rl = &dinfo->mdi_resources; device_printf(dev, "<%s, %s>", macio_get_devtype(child), - macio_get_name(child)); - printf("at offset 0x%x (no driver attached)\n", regs[0]); + macio_get_name(child)); + resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx"); + resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); + printf(" (no driver attached)\n"); } } @@ -374,7 +372,7 @@ macio_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) *result = dinfo->mdi_nregs; break; case MACIO_IVAR_REGS: - *result = (uintptr_t) &dinfo->mdi_reg[0]; + *result = dinfo->mdi_regs; break; default: return (ENOENT); @@ -395,12 +393,14 @@ static struct resource * macio_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - struct macio_softc *sc; - int needactivate; - struct resource *rv; - struct rman *rm; - bus_space_tag_t tagval; - struct macio_devinfo *dinfo; + struct macio_softc *sc; + int needactivate; + struct resource *rv; + struct rman *rm; + bus_space_tag_t tagval; + u_long adjstart, adjend, adjcount; + struct macio_devinfo *dinfo; + struct resource_list_entry *rle; sc = device_get_softc(bus); dinfo = device_get_ivars(child); @@ -411,25 +411,55 @@ macio_alloc_resource(device_t bus, device_t child, int type, int *rid, switch (type) { case SYS_RES_MEMORY: case SYS_RES_IOPORT: + rle = resource_list_find(&dinfo->mdi_resources, SYS_RES_MEMORY, + *rid); + if (rle == NULL) { + device_printf(bus, "no rle for %s memory %d\n", + device_get_nameunit(child), *rid); + return (NULL); + } + + if (start < rle->start) + adjstart = rle->start; + else if (start > rle->end) + adjstart = rle->end; + else + adjstart = start; + + if (end < rle->start) + adjend = rle->start; + else if (end > rle->end) + adjend = rle->end; + else + adjend = end; + + adjcount = adjend - adjstart; + rm = &sc->sc_mem_rman; + tagval = PPC_BUS_SPACE_MEM; if (flags & PPC_BUS_SPARSE4) tagval |= 4; + break; + case SYS_RES_IRQ: return (resource_list_alloc(&dinfo->mdi_resources, bus, child, type, rid, start, end, count, flags)); break; + default: device_printf(bus, "unknown resource request from %s\n", device_get_nameunit(child)); return (NULL); } - rv = rman_reserve_resource(rm, start, end, count, flags, child); + rv = rman_reserve_resource(rm, adjstart, adjend, adjcount, flags, + child); if (rv == NULL) { - device_printf(bus, "failed to reserve resource for %s\n", - device_get_nameunit(child)); + device_printf(bus, + "failed to reserve resource %#lx - %#lx (%#lx) for %s\n", + adjstart, adjend, adjcount, device_get_nameunit(child)); return (NULL); } @@ -446,7 +476,7 @@ macio_alloc_resource(device_t bus, device_t child, int type, int *rid, } } - return (rv); + return (rv); } diff --git a/sys/powerpc/powermac/maciovar.h b/sys/powerpc/powermac/maciovar.h index 7882bca..c3e1427 100644 --- a/sys/powerpc/powermac/maciovar.h +++ b/sys/powerpc/powermac/maciovar.h @@ -49,16 +49,11 @@ MACIO_ACCESSOR(node, NODE, phandle_t) MACIO_ACCESSOR(name, NAME, char *) MACIO_ACCESSOR(devtype, DEVTYPE, char *) MACIO_ACCESSOR(nregs, NREGS, u_int) -MACIO_ACCESSOR(regs, REGS, u_int *) +MACIO_ACCESSOR(regs, REGS, struct macio_reg *) #undef MACIO_ACCESSOR /* - * Upper limit on OpenFirmware reg array - */ -#define MACIO_MAXREG 16 - -/* * The addr space size * XXX it would be better if this could be determined by querying the * PCI device, but there isn't an access method for this @@ -76,6 +71,14 @@ struct macio_softc { }; /* + * Format of a macio reg property entry. + */ +struct macio_reg { + u_int32_t mr_base; + u_int32_t mr_size; +}; + +/* * Per macio device structure. */ struct macio_devinfo { @@ -86,7 +89,7 @@ struct macio_devinfo { int mdi_ninterrupts; int mdi_base; int mdi_nregs; - u_int mdi_reg[MACIO_MAXREG]; + struct macio_reg *mdi_regs; struct resource_list mdi_resources; }; |