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; ofw_regs = macio_get_regs(dev); /* * The offset for the register bank is in the first ofw register, * with the base address coming from the parent macio bus (but * accessible via the ata-macio child) */ if (type == SYS_RES_IOPORT) { switch (*rid) { case ATA_IOADDR_RID: myrid = 0; start = ofw_regs[0]; end = start + (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); break; case ATA_ALTADDR_RID: myrid = 0; start = ofw_regs[0] + 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); break; case ATA_BMADDR_RID: /* looks difficult to support DBDMA in FreeBSD... */ break; } return (res); } else if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) { /* * Pass this on to the parent, using the IRQ from the * ATA pseudo-bus resource */ res = bus_generic_rl_alloc_resource(device_get_parent(dev), dev, SYS_RES_IRQ, 0, 0, ~0, 1, flags); return (res); } else { return (NULL); } }
struct resource * atkbdc_isa_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { atkbdc_softc_t *sc; sc = *(atkbdc_softc_t **)device_get_softc(dev); if (type == SYS_RES_IRQ && *rid == KBDC_RID_KBD && sc->irq != NULL) return (sc->irq); return (bus_generic_rl_alloc_resource(dev, child, type, rid, start, end, count, flags)); }
static struct resource * chipc_alloc_resource(device_t dev, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { struct chipc_softc *sc; struct chipc_region *cr; struct resource_list_entry *rle; struct resource *rv; struct rman *rm; int error; bool passthrough, isdefault; sc = device_get_softc(dev); passthrough = (device_get_parent(child) != dev); isdefault = RMAN_IS_DEFAULT_RANGE(start, end); rle = NULL; /* Fetch the resource manager, delegate request if necessary */ rm = chipc_get_rman(sc, type); if (rm == NULL) { /* Requested resource type is delegated to our parent */ rv = bus_generic_rl_alloc_resource(dev, child, type, rid, start, end, count, flags); return (rv); } /* Populate defaults */ if (!passthrough && isdefault) { /* Fetch the resource list entry. */ rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child), type, *rid); if (rle == NULL) { device_printf(dev, "default resource %#x type %d for child %s " "not found\n", *rid, type, device_get_nameunit(child)); return (NULL); } if (rle->res != NULL) { device_printf(dev, "resource entry %#x type %d for child %s is busy " "[%d]\n", *rid, type, device_get_nameunit(child), rman_get_flags(rle->res)); return (NULL); } start = rle->start; end = rle->end; count = ulmax(count, rle->count); } /* Locate a mapping region */ if ((cr = chipc_find_region(sc, start, end)) == NULL) { /* Resource requests outside our shared port regions can be * delegated to our parent. */ rv = bus_generic_rl_alloc_resource(dev, child, type, rid, start, end, count, flags); return (rv); } /* Try to retain a region reference */ if ((error = chipc_retain_region(sc, cr, RF_ALLOCATED))) return (NULL); /* Make our rman reservation */ rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, child); if (rv == NULL) { chipc_release_region(sc, cr, RF_ALLOCATED); return (NULL); } rman_set_rid(rv, *rid); /* Activate */ if (flags & RF_ACTIVE) { error = bus_activate_resource(child, type, *rid, rv); if (error) { device_printf(dev, "failed to activate entry %#x type %d for " "child %s: %d\n", *rid, type, device_get_nameunit(child), error); chipc_release_region(sc, cr, RF_ALLOCATED); rman_release_resource(rv); return (NULL); } } /* Update child's resource list entry */ if (rle != NULL) { rle->res = rv; rle->start = rman_get_start(rv); rle->end = rman_get_end(rv); rle->count = rman_get_size(rv); } return (rv); }