static struct resource * ixp425_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 ixp425_softc *sc = device_get_softc(dev); struct rman *rmanp; struct resource *rv; uint32_t vbase, addr; int irq; switch (type) { case SYS_RES_IRQ: rmanp = &sc->sc_irq_rman; /* override per hints */ if (BUS_READ_IVAR(dev, child, IXP425_IVAR_IRQ, &irq) == 0) start = end = irq; rv = rman_reserve_resource(rmanp, start, end, count, flags, child); if (rv != NULL) rman_set_rid(rv, *rid); break; case SYS_RES_MEMORY: rmanp = &sc->sc_mem_rman; /* override per hints */ if (BUS_READ_IVAR(dev, child, IXP425_IVAR_ADDR, &addr) == 0) { start = addr; end = start + 0x1000; /* XXX */ } if (getvbase(start, end - start, &vbase) != 0) { /* likely means above table needs to be updated */ device_printf(dev, "%s: no mapping for 0x%lx:0x%lx\n", __func__, start, end-start); return NULL; } rv = rman_reserve_resource(rmanp, start, end, count, flags, 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; }
static struct resource * ofwbus_alloc_resource(device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { struct ofwbus_softc *sc; struct rman *rm; struct resource *rv; struct resource_list_entry *rle; int isdefault, passthrough; isdefault = RMAN_IS_DEFAULT_RANGE(start, end); passthrough = (device_get_parent(child) != bus); sc = device_get_softc(bus); rle = NULL; if (!passthrough && isdefault) { rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child), type, *rid); if (rle == NULL) { if (bootverbose) device_printf(bus, "no default resources for " "rid = %d, type = %d\n", *rid, type); return (NULL); } start = rle->start; count = ulmax(count, rle->count); end = ulmax(rle->end, start + count - 1); } switch (type) { case SYS_RES_IRQ: rm = &sc->sc_intr_rman; break; case SYS_RES_MEMORY: rm = &sc->sc_mem_rman; break; default: return (NULL); } rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, child); if (rv == NULL) return (NULL); rman_set_rid(rv, *rid); if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, *rid, rv) != 0) { rman_release_resource(rv); return (NULL); } if (!passthrough && rle != NULL) { rle->res = rv; rle->start = rman_get_start(rv); rle->end = rman_get_end(rv); rle->count = rle->end - rle->start + 1; } return (rv); }
/* * Allocate resources at the behest of a child. This only handles interrupts, * since I/O resources are handled by child busses. */ static struct resource * nexus_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 nexus_softc *sc; struct resource *rv; if (type != SYS_RES_IRQ) { device_printf(bus, "unknown resource request from %s\n", device_get_nameunit(child)); return (NULL); } if (count == 0 || start + count - 1 != end) { device_printf(bus, "invalid IRQ allocation from %s\n", device_get_nameunit(child)); return (NULL); } sc = device_get_softc(bus); rv = rman_reserve_resource(&sc->sc_rman, start, end, count, flags, child); if (rv == NULL) { device_printf(bus, "IRQ allocation failed for %s\n", device_get_nameunit(child)); } else rman_set_rid(rv, *rid); return (rv); }
/* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. * (Exceptions include footbridge.) */ static struct resource * nexus_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 resource *rv; struct rman *rm; int needactivate = flags & RF_ACTIVE; switch (type) { case SYS_RES_MEMORY: case SYS_RES_IOPORT: rm = &mem_rman; break; default: return (0); } rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == 0) return (0); rman_set_rid(rv, *rid); rman_set_bushandle(rv, rman_get_start(rv)); if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { rman_release_resource(rv); return (0); } } return (rv); }
static struct resource * zbpci_alloc_resource(device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { struct resource *res; /* * Handle PCI I/O port resources here and pass everything else to nexus. */ if (type != SYS_RES_IOPORT) { res = bus_generic_alloc_resource(bus, child, type, rid, start, end, count, flags); return (res); } res = rman_reserve_resource(&port_rman, start, end, count, flags, child); if (res == NULL) return (NULL); rman_set_rid(res, *rid); /* Activate the resource is requested */ if (flags & RF_ACTIVE) { if (bus_activate_resource(child, type, *rid, res) != 0) { rman_release_resource(res); return (NULL); } } return (res); }
static struct resource * thunder_pem_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 thunder_pem_softc *sc = device_get_softc(dev); struct rman *rm = NULL; struct resource *res; device_t parent_dev; rm = thunder_pem_rman(sc, type); if (rm == NULL) { /* Find parent device. On ThunderX we know an exact path. */ parent_dev = device_get_parent(device_get_parent(dev)); return (BUS_ALLOC_RESOURCE(parent_dev, dev, type, rid, start, end, count, flags)); } if (!RMAN_IS_DEFAULT_RANGE(start, end)) { /* * We might get PHYS addresses here inherited from EFI. * Convert to PCI if necessary. */ if (range_addr_is_phys(sc->ranges, start, count)) { start = range_addr_phys_to_pci(sc->ranges, start); end = start + count - 1; } } if (bootverbose) { device_printf(dev, "thunder_pem_alloc_resource: start=%#lx, end=%#lx, count=%#lx\n", start, end, count); } res = rman_reserve_resource(rm, start, end, count, flags, child); if (res == NULL) goto fail; rman_set_rid(res, *rid); if (flags & RF_ACTIVE) if (bus_activate_resource(child, type, *rid, res)) { rman_release_resource(res); goto fail; } return (res); fail: if (bootverbose) { device_printf(dev, "%s FAIL: type=%d, rid=%d, " "start=%016lx, end=%016lx, count=%016lx, flags=%x\n", __func__, type, *rid, start, end, count, flags); } return (NULL); }
static struct resource * ofwbus_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 ofwbus_softc *sc; struct rman *rm; struct resource *rv; struct resource_list_entry *rle; int isdefault, passthrough; isdefault = (start == 0UL && end == ~0UL); passthrough = (device_get_parent(child) != bus); sc = device_get_softc(bus); rle = NULL; if (!passthrough && isdefault) { rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child), type, *rid); if (rle == NULL) return (NULL); if (rle->res != NULL) panic("%s: resource entry is busy", __func__); start = rle->start; count = ulmax(count, rle->count); end = ulmax(rle->end, start + count - 1); } switch (type) { case SYS_RES_IRQ: rm = &sc->sc_intr_rman; break; case SYS_RES_MEMORY: rm = &sc->sc_mem_rman; break; default: return (NULL); } rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, child); if (rv == NULL) return (NULL); rman_set_rid(rv, *rid); if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, *rid, rv) != 0) { rman_release_resource(rv); return (NULL); } if (!passthrough && rle != NULL) { rle->res = rv; rle->start = rman_get_start(rv); rle->end = rman_get_end(rv); rle->count = rle->end - rle->start + 1; } return (rv); }
/* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. * (Exceptions include footbridge.) */ static struct resource * nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { struct nexus_device *ndev = DEVTONX(child); struct resource *rv; struct resource_list_entry *rle; struct rman *rm; int needactivate = flags & RF_ACTIVE; /* * If this is an allocation of the "default" range for a given * RID, and we know what the resources for this device are * (ie. they aren't maintained by a child bus), then work out * the start/end values. */ if (RMAN_IS_DEFAULT_RANGE(start, end) && (count == 1)) { if (device_get_parent(child) != bus || ndev == NULL) return(NULL); rle = resource_list_find(&ndev->nx_resources, type, *rid); if (rle == NULL) return(NULL); start = rle->start; end = rle->end; count = rle->count; } switch (type) { case SYS_RES_IRQ: rm = &irq_rman; break; case SYS_RES_MEMORY: case SYS_RES_IOPORT: rm = &mem_rman; break; default: return (NULL); } rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == NULL) return (NULL); rman_set_rid(rv, *rid); rman_set_bushandle(rv, rman_get_start(rv)); if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { rman_release_resource(rv); return (NULL); } } return (rv); }
static struct resource * obio_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 resource *rv; struct rman *rm; bus_space_tag_t bt = 0; bus_space_handle_t bh = 0; struct obio_softc *sc = device_get_softc(bus); switch (type) { case SYS_RES_IRQ: switch (device_get_unit(child)) { case 0: start = end = OCTEON_IRQ_UART0; break; case 1: start = end = OCTEON_IRQ_UART1; break; default: return (NULL); } rm = &sc->oba_irq_rman; break; case SYS_RES_MEMORY: return (NULL); case SYS_RES_IOPORT: rm = &sc->oba_rman; bt = &octeon_uart_tag; bh = CVMX_MIO_UARTX_RBR(device_get_unit(child)); start = bh; break; default: return (NULL); } rv = rman_reserve_resource(rm, start, end, count, flags, 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 (0) { if (bus_activate_resource(child, type, *rid, rv)) { rman_release_resource(rv); return (NULL); } } return (rv); }
static struct resource * wiibus_alloc_resource(device_t bus, device_t child, int type, int *rid, unsigned long start, unsigned long end, unsigned long count, unsigned int flags) { struct wiibus_softc *sc; struct wiibus_devinfo *dinfo; struct resource_list_entry *rle; struct resource *rv; int needactivate; sc = device_get_softc(bus); dinfo = device_get_ivars(child); needactivate = flags & RF_ACTIVE; flags &= ~RF_ACTIVE; switch (type) { case SYS_RES_MEMORY: rle = resource_list_find(&dinfo->di_resources, SYS_RES_MEMORY, *rid); if (rle == NULL) { device_printf(bus, "no res entry for %s memory 0x%x\n", device_get_nameunit(child), *rid); return (NULL); } rv = rman_reserve_resource(&sc->sc_rman, rle->start, rle->end, rle->count, flags, child); if (rv == NULL) { device_printf(bus, "failed to reserve resource for %s\n", device_get_nameunit(child)); return (NULL); } rman_set_rid(rv, *rid); break; case SYS_RES_IRQ: return (resource_list_alloc(&dinfo->di_resources, bus, child, type, rid, start, end, count, flags)); default: device_printf(bus, "unknown resource request from %s\n", device_get_nameunit(child)); return (NULL); } if (needactivate) { if (bus_activate_resource(child, type, *rid, rv) != 0) { device_printf(bus, "failed to activate resource for %s\n", device_get_nameunit(child)); return (NULL); } } return (rv); }
static struct resource * ofw_pci_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 ofw_pci_softc *sc; struct resource *rv; struct rman *rm; int needactivate; needactivate = flags & RF_ACTIVE; flags &= ~RF_ACTIVE; sc = device_get_softc(bus); switch (type) { case SYS_RES_MEMORY: rm = &sc->sc_mem_rman; break; case SYS_RES_IOPORT: rm = &sc->sc_io_rman; break; case SYS_RES_IRQ: return (bus_alloc_resource(bus, type, rid, start, end, count, flags)); 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); if (rv == NULL) { device_printf(bus, "failed to reserve resource for %s\n", device_get_nameunit(child)); return (NULL); } rman_set_rid(rv, *rid); if (needactivate) { if (bus_activate_resource(child, type, *rid, rv) != 0) { device_printf(bus, "failed to activate resource for %s\n", device_get_nameunit(child)); rman_release_resource(rv); return (NULL); } } return (rv); }
static struct resource * i80321_pci_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 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; switch (type) { case SYS_RES_IRQ: rm = &sc->sc_irq_rman; 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); end &= (0x1000000 - 1); 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; } break; default: return (NULL); } rv = rman_reserve_resource(rm, start, end, count, flags, 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); } } } return (rv); }
/** * omap_alloc_resource * * This function will be called when bus_alloc_resource(...) if the memory * region requested is in the range of the managed values set by * rman_manage_region(...) above. * * For SYS_RES_MEMORY resource types the omap_attach() calls rman_manage_region * with the list of pyshical mappings defined in the omap_devmap region map. * However because we are working with physical addresses, we need to convert * the physical to virtual within this function and return the virtual address * in the bus tag field. * */ static struct resource * omap_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 omap_softc *sc = device_get_softc(dev); struct resource_list_entry *rle; struct omap_ivar *ivar = device_get_ivars(child); struct resource_list *rl = &ivar->resources; /* If we aren't the parent pass it onto the actual parent */ if (device_get_parent(child) != dev) { return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); } /* Find the resource in the list */ rle = resource_list_find(rl, type, *rid); if (rle == NULL) return (NULL); if (rle->res) panic("Resource rid %d type %d already in use", *rid, type); if (start == 0UL && end == ~0UL) { start = rle->start; count = ulmax(count, rle->count); end = ulmax(rle->end, start + count - 1); } switch (type) { case SYS_RES_IRQ: rle->res = rman_reserve_resource(&sc->sc_irq_rman, start, end, count, flags, child); break; case SYS_RES_MEMORY: rle->res = rman_reserve_resource(&sc->sc_mem_rman, start, end, count, flags, child); if (rle->res != NULL) { rman_set_bustag(rle->res, &omap_bs_tag); rman_set_bushandle(rle->res, omap_devmap_phys2virt(start)); } break; } if (rle->res) { rle->start = rman_get_start(rle->res); rle->end = rman_get_end(rle->res); rle->count = count; rman_set_rid(rle->res, *rid); } return (rle->res); }
static struct resource * at91_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 at91_softc *sc = device_get_softc(dev); struct resource_list_entry *rle; struct at91_ivar *ivar = device_get_ivars(child); struct resource_list *rl = &ivar->resources; if (device_get_parent(child) != dev) return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); rle = resource_list_find(rl, type, *rid); if (rle == NULL) return (NULL); if (rle->res) panic("Resource rid %d type %d already in use", *rid, type); if (start == 0UL && end == ~0UL) { start = rle->start; count = ulmax(count, rle->count); end = ulmax(rle->end, start + count - 1); } switch (type) { case SYS_RES_IRQ: rle->res = rman_reserve_resource(&sc->sc_irq_rman, start, end, count, flags, child); break; case SYS_RES_MEMORY: #if 0 if (start >= 0x00300000 && start <= 0x003fffff) rle->res = rman_reserve_resource(&sc->sc_usbmem_rman, start, end, count, flags, child); else #endif rle->res = rman_reserve_resource(&sc->sc_mem_rman, start, end, count, flags, child); if (rle->res != NULL) { rman_set_bustag(rle->res, &at91_bs_tag); rman_set_bushandle(rle->res, start); } break; } if (rle->res) { rle->start = rman_get_start(rle->res); rle->end = rman_get_end(rle->res); rle->count = count; rman_set_rid(rle->res, *rid); } return (rle->res); }
static struct resource * sa1110_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 resource *res; res = rman_reserve_resource(&sa11x0_softc->sa11x0_rman, *rid, *rid, count, flags, child); if (res != NULL) rman_set_rid(res, *rid); return (res); }
static struct resource * obio_alloc_resource(device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { 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); switch (type) { case SYS_RES_IRQ: rm = &sc->oba_irq_rman; if (unit == 0) start = end = ICU_INT_UART0; else start = end = ICU_INT_UART1; break; case SYS_RES_MEMORY: return (NULL); case SYS_RES_IOPORT: rm = &sc->oba_rman; bt = sc->oba_st; if (unit == 0) { bh = IOP34X_UART0_VADDR; start = bh; end = IOP34X_UART1_VADDR; } else { bh = IOP34X_UART1_VADDR; start = bh; end = start + 0x40; } break; default: return (NULL); } rv = rman_reserve_resource(rm, start, end, count, flags, 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); return (rv); }
static struct resource * ocpbus_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 ocpbus_softc *sc; struct resource *rv; int error; sc = device_get_softc(dev); switch (type) { case SYS_RES_IRQ: if (start == 0ul && end == ~0ul) { error = ocpbus_get_resource(dev, child, type, *rid, &start, &count); if (error) return (NULL); } rv = rman_reserve_resource(&sc->sc_irq, start, start + count - 1, count, flags, child); if (rv == NULL) return (NULL); break; case SYS_RES_MEMORY: if (start != 0ul || end != ~0ul) return (NULL); error = ocpbus_get_resource(dev, child, type, *rid, &start, &count); if (error) return (NULL); rv = rman_reserve_resource(&sc->sc_mem, start, start + count - 1, count, flags, child); if (rv == NULL) return (NULL); rman_set_bustag(rv, &bs_be_tag); rman_set_bushandle(rv, rman_get_start(rv)); break; default: return (NULL); } rman_set_rid(rv, *rid); return (rv); }
struct resource * pci_host_generic_core_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 generic_pcie_core_softc *sc; struct resource *res; struct rman *rm; sc = device_get_softc(dev); #if defined(NEW_PCIB) && defined(PCI_RES_BUS) if (type == PCI_RES_BUS) { return (pci_domain_alloc_bus(sc->ecam, child, rid, start, end, count, flags)); } #endif rm = generic_pcie_rman(sc, type); if (rm == NULL) return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); if (bootverbose) { device_printf(dev, "rman_reserve_resource: start=%#jx, end=%#jx, count=%#jx\n", start, end, count); } res = rman_reserve_resource(rm, start, end, count, flags, child); if (res == NULL) goto fail; rman_set_rid(res, *rid); if (flags & RF_ACTIVE) if (bus_activate_resource(child, type, *rid, res)) { rman_release_resource(res); goto fail; } return (res); fail: device_printf(dev, "%s FAIL: type=%d, rid=%d, " "start=%016jx, end=%016jx, count=%016jx, flags=%x\n", __func__, type, *rid, start, end, count, flags); return (NULL); }
static struct resource * at91_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 at91_softc *sc = device_get_softc(dev); struct resource_list_entry *rle; struct at91_ivar *ivar = device_get_ivars(child); struct resource_list *rl = &ivar->resources; bus_space_handle_t bsh; if (device_get_parent(child) != dev) return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); rle = resource_list_find(rl, type, *rid); if (rle == NULL) return (NULL); if (rle->res) panic("Resource rid %d type %d already in use", *rid, type); if (start == 0UL && end == ~0UL) { start = rle->start; count = ulmax(count, rle->count); end = ulmax(rle->end, start + count - 1); } switch (type) { case SYS_RES_IRQ: rle->res = rman_reserve_resource(&sc->sc_irq_rman, start, end, count, flags, child); break; case SYS_RES_MEMORY: rle->res = rman_reserve_resource(&sc->sc_mem_rman, start, end, count, flags, child); if (rle->res != NULL) { bus_space_map(arm_base_bs_tag, start, rman_get_size(rle->res), 0, &bsh); rman_set_bustag(rle->res, arm_base_bs_tag); rman_set_bushandle(rle->res, bsh); } break; } if (rle->res) { rle->start = rman_get_start(rle->res); rle->end = rman_get_end(rle->res); rle->count = count; rman_set_rid(rle->res, *rid); } return (rle->res); }
static struct resource * iq80321_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 i80321_softc *sc = device_get_softc(dev); struct resource *rv; if (type == SYS_RES_IRQ) { rv = rman_reserve_resource(&sc->sc_irq_rman, start, end, count, flags, child); if (rv != NULL) rman_set_rid(rv, *rid); return (rv); } return (NULL); }
/* * Allocate a resource on behalf of child. NB: child is usually going to be a * child of one of our descendants, not a direct child of nexus0. * (Exceptions include npx.) */ static struct resource * nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { struct nexus_device *ndev = DEVTONX(child); struct resource *rv; struct resource_list_entry *rle; struct rman *rm; int needactivate = flags & RF_ACTIVE; /* * If this is an allocation of the "default" range for a given * RID, and we know what the resources for this device are * (ie. they aren't maintained by a child bus), then work out * the start/end values. */ if ((start == 0UL) && (end == ~0UL) && (count == 1)) { if (device_get_parent(child) != bus || ndev == NULL) return(NULL); rle = resource_list_find(&ndev->nx_resources, type, *rid); if (rle == NULL) return(NULL); start = rle->start; end = rle->end; count = rle->count; } flags &= ~RF_ACTIVE; rm = nexus_rman(type); if (rm == NULL) return (NULL); rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == 0) return 0; rman_set_rid(rv, *rid); if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { rman_release_resource(rv); return 0; } } return rv; }
static struct resource * obio_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 resource *rv; struct rman *rm; bus_space_tag_t bt = 0; bus_space_handle_t bh = 0; struct obio_softc *sc = device_get_softc(bus); switch (type) { case SYS_RES_IRQ: rm = &sc->oba_irq_rman; break; case SYS_RES_MEMORY: return (NULL); case SYS_RES_IOPORT: rm = &sc->oba_rman; bt = sc->oba_st; bh = sc->oba_addr; start = bh; break; default: return (NULL); } rv = rman_reserve_resource(rm, start, end, count, flags, 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 (0) { if (bus_activate_resource(child, type, *rid, rv)) { rman_release_resource(rv); return (NULL); } } return (rv); }
struct resource * ofw_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { struct ofw_pci_softc *sc; struct resource *rv; struct rman *rm; sc = device_get_softc(bus); switch (type) { case SYS_RES_IRQ: /* * XXX: Don't accept blank ranges for now, only single * interrupts. The other case should not happen with * the MI PCI code ... * XXX: This may return a resource that is out of the * range that was specified. Is this correct ...? */ if (start != end) panic("%s: XXX: interrupt range", __func__); return (bus_generic_alloc_resource(bus, child, type, rid, start, end, count, flags)); case SYS_RES_MEMORY: rm = &sc->sc_pci_mem_rman; break; case SYS_RES_IOPORT: rm = &sc->sc_pci_io_rman; break; default: return (NULL); } rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, child); if (rv == NULL) return (NULL); rman_set_rid(rv, *rid); if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, *rid, rv) != 0) { rman_release_resource(rv); return (NULL); } return (rv); }
static struct resource * siba_pcib_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { #if 1 //device_printf(bus, "%s: not yet implemented\n", __func__); return (NULL); #else bus_space_tag_t tag; struct siba_pcib_softc *sc = device_get_softc(bus); struct rman *rmanp; struct resource *rv; tag = 0; rv = NULL; switch (type) { case SYS_RES_IRQ: rmanp = &sc->sc_irq_rman; 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_MEMORY) { #if 0 rman_set_bustag(rv, tag); rman_set_bushandle(rv, rman_get_bushandle(sc->sc_mem) + (rman_get_start(rv) - IXP425_PCI_MEM_HWBASE)); #endif } } return (rv); #endif }
static struct resource * gpiobus_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 gpiobus_softc *sc; struct resource *rv; struct resource_list *rl; struct resource_list_entry *rle; int isdefault; if (type != SYS_RES_IRQ) return (NULL); isdefault = (start == 0UL && end == ~0UL && count == 1); rle = NULL; if (isdefault) { rl = BUS_GET_RESOURCE_LIST(bus, child); if (rl == NULL) return (NULL); rle = resource_list_find(rl, type, *rid); if (rle == NULL) return (NULL); if (rle->res != NULL) panic("%s: resource entry is busy", __func__); start = rle->start; count = rle->count; end = rle->end; } sc = device_get_softc(bus); rv = rman_reserve_resource(&sc->sc_intr_rman, start, end, count, flags, child); if (rv == NULL) return (NULL); rman_set_rid(rv, *rid); if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, *rid, rv) != 0) { rman_release_resource(rv); return (NULL); } return (rv); }
static struct resource * nexus_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 resource *rv; struct rman *rm; size_t i; switch (type) { case SYS_RES_MEMORY: rm = &mem_rman; break; case SYS_RES_IRQ: rm = &irq_rman; break; default: return (NULL); } for (i = 0; i < rtems_bsd_nexus_device_count; ++i) { const rtems_bsd_device *nd = &rtems_bsd_nexus_devices[i]; if (strcmp(device_get_name(child), nd->name) == 0 && device_get_unit(child) == nd->unit) { if (!nexus_get_start(nd, type, &start)) { return (NULL); }; } else { return (NULL); } } rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv != NULL) { rman_set_rid(rv, *rid); rman_set_bushandle(rv, rman_get_start(rv)); } return (rv); }
static struct resource * lbc_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 lbc_softc *sc; struct lbc_devinfo *di; struct resource_list_entry *rle; struct resource *res; struct rman *rm; int needactivate; /* We only support default allocations. */ if (start != 0ul || end != ~0ul) return (NULL); sc = device_get_softc(bus); if (type == SYS_RES_IRQ) return (bus_alloc_resource(bus, type, rid, start, end, count, flags)); /* * Request for the default allocation with a given rid: use resource * list stored in the local device info. */ if ((di = device_get_ivars(child)) == NULL) return (NULL); if (type == SYS_RES_IOPORT) type = SYS_RES_MEMORY; rid = &di->di_bank; rle = resource_list_find(&di->di_res, type, *rid); if (rle == NULL) { device_printf(bus, "no default resources for " "rid = %d, type = %d\n", *rid, type); return (NULL); } start = rle->start; count = rle->count; end = start + count - 1; sc = device_get_softc(bus); needactivate = flags & RF_ACTIVE; flags &= ~RF_ACTIVE; rm = &sc->sc_rman; res = rman_reserve_resource(rm, start, end, count, flags, child); if (res == NULL) { device_printf(bus, "failed to reserve resource %#lx - %#lx " "(%#lx)\n", start, end, count); return (NULL); } rman_set_rid(res, *rid); rman_set_bustag(res, &bs_be_tag); rman_set_bushandle(res, rman_get_start(res)); if (needactivate) if (bus_activate_resource(child, type, *rid, res)) { device_printf(child, "resource activation failed\n"); rman_release_resource(res); return (NULL); } return (res); }
static struct resource * apb_alloc_resource(device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { struct apb_softc *sc = device_get_softc(bus); struct apb_ivar *ivar = device_get_ivars(child); struct resource *rv; struct resource_list_entry *rle; struct rman *rm; int isdefault, needactivate, passthrough; isdefault = (RMAN_IS_DEFAULT_RANGE(start, end)); needactivate = flags & RF_ACTIVE; /* * Pass memory requests to nexus device */ passthrough = (device_get_parent(child) != bus); rle = NULL; dprintf("%s: entry (%p, %p, %d, %d, %p, %p, %jd, %d)\n", __func__, bus, child, type, *rid, (void *)(intptr_t)start, (void *)(intptr_t)end, count, flags); if (passthrough) return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, start, end, count, flags)); /* * If this is an allocation of the "default" range for a given RID, * and we know what the resources for this device are (ie. they aren't * maintained by a child bus), then work out the start/end values. */ if (isdefault) { rle = resource_list_find(&ivar->resources, type, *rid); if (rle == NULL) { return (NULL); } if (rle->res != NULL) { panic("%s: resource entry is busy", __func__); } start = rle->start; end = rle->end; count = rle->count; dprintf("%s: default resource (%p, %p, %ld)\n", __func__, (void *)(intptr_t)start, (void *)(intptr_t)end, count); } switch (type) { case SYS_RES_IRQ: rm = &sc->apb_irq_rman; break; case SYS_RES_MEMORY: rm = &sc->apb_mem_rman; break; default: printf("%s: unknown resource type %d\n", __func__, type); return (0); } rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == 0) { printf("%s: could not reserve resource\n", __func__); return (0); } rman_set_rid(rv, *rid); if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { printf("%s: could not activate resource\n", __func__); rman_release_resource(rv); return (0); } } return (rv); }
struct resource * thunder_pcie_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 thunder_pcie_softc *sc = device_get_softc(dev); struct rman *rm = NULL; struct resource *res; pci_addr_t map, testval; switch (type) { case SYS_RES_IOPORT: goto fail; break; case SYS_RES_MEMORY: rm = &sc->mem_rman; break; default: return (bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags)); }; if ((start == 0UL) && (end == ~0UL)) { /* Read BAR manually to get resource address and size */ pci_read_bar(child, *rid, &map, &testval, NULL); /* Mask the information bits */ if (PCI_BAR_MEM(map)) map &= PCIM_BAR_MEM_BASE; else map &= PCIM_BAR_IO_BASE; if (PCI_BAR_MEM(testval)) testval &= PCIM_BAR_MEM_BASE; else testval &= PCIM_BAR_IO_BASE; start = map; count = (~testval) + 1; /* * Internal ThunderX devices supports up to 3 64-bit BARs. * If we're allocating anything above, that means upper layer * wants us to allocate VF-BAR. In that case reserve bigger * slice to make a room for other VFs adjacent to this one. */ if (*rid > PCIR_BAR(5)) count = count * thunder_pcie_max_vfs; end = start + count - 1; } /* Convert input BUS address to required PHYS */ if (range_addr_is_pci(sc->ranges, start, count) == 0) goto fail; start = range_addr_pci_to_phys(sc->ranges, start); end = start + count - 1; if (bootverbose) { device_printf(dev, "rman_reserve_resource: start=%#lx, end=%#lx, count=%#lx\n", start, end, count); } res = rman_reserve_resource(rm, start, end, count, flags, child); if (res == NULL) goto fail; rman_set_rid(res, *rid); if ((flags & RF_ACTIVE) != 0) if (bus_activate_resource(child, type, *rid, res)) { rman_release_resource(res); goto fail; } return (res); fail: if (bootverbose) { device_printf(dev, "%s FAIL: type=%d, rid=%d, " "start=%016lx, end=%016lx, count=%016lx, flags=%x\n", __func__, type, *rid, start, end, count, flags); } return (NULL); }
static struct resource * pxa_smi_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 pxa_smi_softc *sc; struct smi_ivars *smid; struct resource *rv; struct resource_list *rl; struct resource_list_entry *rle; int needactivate; sc = (struct pxa_smi_softc *)device_get_softc(dev); smid = (struct smi_ivars *)device_get_ivars(child); rl = &smid->smid_resources; if (type == SYS_RES_IOPORT) type = SYS_RES_MEMORY; rle = resource_list_find(rl, type, *rid); if (rle == NULL) return (NULL); if (rle->res != NULL) panic("pxa_smi_alloc_resource: resource is busy"); needactivate = flags & RF_ACTIVE; flags &= ~RF_ACTIVE; switch (type) { case SYS_RES_MEMORY: rv = rman_reserve_resource(&sc->ps_mem, rle->start, rle->end, rle->count, flags, child); if (rv == NULL) return (NULL); rle->res = rv; rman_set_rid(rv, *rid); rman_set_bustag(rv, sc->ps_bst); rman_set_bushandle(rv, rle->start); if (needactivate) { if (bus_activate_resource(child, type, *rid, rv) != 0) { rman_release_resource(rv); return (NULL); } } break; case SYS_RES_IRQ: rv = bus_alloc_resource(dev, type, rid, rle->start, rle->end, rle->count, flags); if (rv == NULL) return (NULL); if (needactivate) { if (bus_activate_resource(child, type, *rid, rv) != 0) { bus_release_resource(dev, type, *rid, rv); return (NULL); } } break; default: return (NULL); } return (rv); }