struct resource * ata_pci_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 ata_pci_controller *controller = device_get_softc(dev); struct resource *res = NULL; if (device_get_devclass(child) == ata_devclass) { int unit = ((struct ata_channel *)device_get_softc(child))->unit; int myrid; if (type == SYS_RES_IOPORT) { switch (*rid) { case ATA_IOADDR_RID: if (controller->legacy) { start = (unit ? ATA_SECONDARY : ATA_PRIMARY); count = ATA_IOSIZE; end = start + count - 1; } myrid = PCIR_BAR(0) + (unit << 3); res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, SYS_RES_IOPORT, &myrid, start, end, count, flags); break; case ATA_CTLADDR_RID: if (controller->legacy) { start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_CTLOFFSET; count = ATA_CTLIOSIZE; end = start + count - 1; } myrid = PCIR_BAR(1) + (unit << 3); res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, SYS_RES_IOPORT, &myrid, start, end, count, flags); break; } } if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) { if (controller->legacy) { int irq = (unit == 0 ? 14 : 15); res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, SYS_RES_IRQ, rid, irq, irq, 1, flags); } else res = controller->r_irq; } } else { if (type == SYS_RES_IRQ) { if (*rid != ATA_IRQ_RID) return (NULL); res = controller->r_irq; } else { res = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid, start, end, count, flags); } } return (res); }
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); } }
static struct resource * canbus_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); }
static struct resource * isab_pci_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 isab_pci_softc *sc; int bar; if (device_get_parent(child) != dev) return bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags); switch (type) { case SYS_RES_MEMORY: case SYS_RES_IOPORT: /* * For BARs, we cache the resource so that we only allocate it * from the PCI bus once. */ bar = PCI_RID2BAR(*rid); if (bar < 0 || bar > PCIR_MAX_BAR_0) return (NULL); sc = device_get_softc(dev); if (sc->isab_pci_res[bar].ip_res == NULL) sc->isab_pci_res[bar].ip_res = bus_alloc_resource(dev, type, rid, start, end, count, flags); if (sc->isab_pci_res[bar].ip_res != NULL) sc->isab_pci_res[bar].ip_refs++; return (sc->isab_pci_res[bar].ip_res); } return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); }
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 * gt_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) { return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); }
/* proxying to the parent */ static struct resource * siba_bwn_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags, int cpuid) { return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid, start, end, count, flags, cpuid)); }
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); }
/** * 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 * xlp_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 resource *r; struct xlp_devinfo *xlp_devinfo; int busno; /* * Do custom allocation for MEMORY resource for SoC device if * MEM_RES_EMUL flag is set */ busno = pci_get_bus(child); if ((type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) && busno == 0) { xlp_devinfo = (struct xlp_devinfo *)device_get_ivars(child); if ((xlp_devinfo->flags & MEM_RES_EMUL) != 0) { /* no emulation for IO ports */ if (type == SYS_RES_IOPORT) return (NULL); start = xlp_devinfo->mem_res_start; count = XLP_PCIE_CFG_SIZE - XLP_IO_PCI_HDRSZ; /* MMC needs to 2 slots with rids 16 and 20 and a * fixup for size */ if (pci_get_device(child) == PCI_DEVICE_ID_NLM_MMC) { count = 0x100; if (*rid == 16) ; /* first slot already setup */ else if (*rid == 20) start += 0x100; /* second slot */ else return (NULL); } end = start + count - 1; r = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, start, end, count, flags); if (r == NULL) return (NULL); if ((xlp_devinfo->flags & DEV_MMIO32) != 0) rman_set_bustag(r, rmi_uart_bus_space); return (r); } } /* Not custom alloc, use PCI code */ return (pci_alloc_resource(bus, child, type, rid, start, end, count, flags)); }
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); }
/* * These can disappear when I update the pci code to use the new * device framework. */ struct intrec * intr_create(void *dev_instance, int irq, inthand2_t handler, void *arg, intrmask_t *maskptr, int flags) { struct resource *res; device_t pcib = chipset.intrdev; int zero = 0; void *cookie; res = BUS_ALLOC_RESOURCE(pcib, NULL, SYS_RES_IRQ, &zero, irq, irq, 1, RF_SHAREABLE | RF_ACTIVE); if (BUS_SETUP_INTR(pcib, pcib, res, (driver_intr_t *)handler, arg, &cookie)) return 0; return (struct intrec *)cookie; }
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 obio_softc *sc = device_get_softc(bus); struct obio_ivar *ivar = device_get_ivars(child); struct resource *rv; struct resource_list_entry *rle; struct rman *rm; int isdefault, needactivate, passthrough; isdefault = (start == 0UL && end == ~0UL); needactivate = flags & RF_ACTIVE; passthrough = (device_get_parent(child) != bus); rle = NULL; 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; } switch (type) { case SYS_RES_IRQ: rm = &sc->oba_irq_rman; break; case SYS_RES_MEMORY: rm = &sc->oba_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); }
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; switch (type) { case SYS_RES_IOPORT: rm = &sc->io_rman; break; case SYS_RES_MEMORY: rm = &sc->mem_rman; break; default: /* 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 ((start == 0UL) && (end == ~0UL)) { device_printf(dev, "Cannot allocate resource with unspecified range\n"); goto fail; } /* Translate PCI address to host 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) 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); }
/** * Helper function for implementing BHND_BUS_ALLOC_RESOURCE(). * * This simple implementation of BHND_BUS_ALLOC_RESOURCE() determines * any default values via BUS_GET_RESOURCE_LIST(), and calls * BHND_BUS_ALLOC_RESOURCE() method of the parent of @p dev. * * If no parent device is available, the request is instead delegated to * BUS_ALLOC_RESOURCE(). */ struct bhnd_resource * bhnd_generic_alloc_bhnd_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 bhnd_resource *r; struct resource_list *rl; struct resource_list_entry *rle; bool isdefault; bool passthrough; passthrough = (device_get_parent(child) != dev); isdefault = RMAN_IS_DEFAULT_RANGE(start, end); /* the default RID must always be the first device port/region. */ if (!passthrough && *rid == 0) { int rid0 = bhnd_get_port_rid(child, BHND_PORT_DEVICE, 0, 0); KASSERT(*rid == rid0, ("rid 0 does not map to the first device port (%d)", rid0)); } /* Determine locally-known defaults before delegating the request. */ if (!passthrough && isdefault) { /* fetch resource list from child's bus */ rl = BUS_GET_RESOURCE_LIST(dev, child); if (rl == NULL) return (NULL); /* no resource list */ /* look for matching type/rid pair */ rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child), type, *rid); if (rle == NULL) return (NULL); /* set default values */ start = rle->start; end = rle->end; count = ulmax(count, rle->count); } /* Try to delegate to our parent. */ if (device_get_parent(dev) != NULL) { return (BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); } /* If this is the bus root, use a real bus-allocated resource */ r = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT); if (r == NULL) return NULL; /* Allocate the bus resource, marking it as 'direct' (not requiring * any bus window remapping to perform I/O) */ r->direct = true; r->res = BUS_ALLOC_RESOURCE(dev, child, type, rid, start, end, count, flags); if (r->res == NULL) { free(r, M_BHND); return NULL; } return (r); }
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); }
static void pcib_mbus_identify(driver_t *driver, device_t parent) { const struct obio_pci *info = mv_pci_info; struct pcib_mbus_softc *sc; uint32_t control; while (info->op_base) { sc = malloc(driver->size, M_DEVBUF, M_NOWAIT | M_ZERO); if (sc == NULL) { device_printf(parent, "Could not allocate pcib " "memory\n"); break; } sc->sc_info = info++; /* * PCI bridge objects are instantiated immediately. PCI-Express * bridges require more complicated handling depending on * platform configuration. */ if (sc->sc_info->op_type == MV_TYPE_PCI) { pcib_mbus_add_child(driver, parent, sc); continue; } /* * Read link configuration */ sc->sc_rid = 0; sc->sc_res = BUS_ALLOC_RESOURCE(parent, parent, SYS_RES_MEMORY, &sc->sc_rid, sc->sc_info->op_base, sc->sc_info->op_base + sc->sc_info->op_size - 1, sc->sc_info->op_size, RF_ACTIVE); if (sc->sc_res == NULL) { device_printf(parent, "Could not map pcib memory\n"); break; } sc->sc_bst = rman_get_bustag(sc->sc_res); sc->sc_bsh = rman_get_bushandle(sc->sc_res); control = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_CONTROL); BUS_RELEASE_RESOURCE(parent, parent, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res); /* * If this PCI-E port (controller) is configured (by the * underlying firmware) with lane width other than 1x, there * are auxiliary resources defined for aggregating more width * on our lane. Skip all such entries as they are not * standalone ports and must not have a device object * instantiated. */ if ((control & PCIE_CTRL_LINK1X) == 0) while (info->op_base && info->op_type == MV_TYPE_PCIE_AGGR_LANE) info++; pcib_mbus_add_child(driver, parent, sc); } }
static struct resource * eisa_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { int isdefault; struct eisa_device *e_dev = device_get_ivars(child); struct resource *rv, **rvp = 0; isdefault = (device_get_parent(child) == dev && start == 0UL && end == ~0UL && count == 1); switch (type) { case SYS_RES_IRQ: if (isdefault) { struct irq_node * irq = eisa_find_irq(e_dev, *rid); if (irq == NULL) return (NULL); start = end = irq->irq_no; count = 1; if (irq->irq_trigger == EISA_TRIGGER_LEVEL) flags |= RF_SHAREABLE; else flags &= ~RF_SHAREABLE; } break; case SYS_RES_MEMORY: if (isdefault) { struct resvaddr *resv; resv = eisa_find_maddr(e_dev, *rid); if (resv == NULL) return (NULL); start = resv->addr; end = resv->addr + (resv->size - 1); count = resv->size; rvp = &resv->res; } break; case SYS_RES_IOPORT: if (isdefault) { struct resvaddr *resv; resv = eisa_find_ioaddr(e_dev, *rid); if (resv == NULL) return (NULL); start = resv->addr; end = resv->addr + (resv->size - 1); count = resv->size; rvp = &resv->res; } break; default: return 0; } rv = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags); if (rvp) *rvp = rv; return (rv); }
static int alloc_resource(sc_p scp) { int i, base, lid, flags; device_t dev; flags = 0; if (isa_get_vendorid(scp->dev)) lid = isa_get_logicalid(scp->dev); else { lid = LOGICALID_NOPNP; flags = device_get_flags(scp->dev); } switch(lid) { case LOGICALID_PCM: case LOGICALID_NOPNP: /* XXX Non-PnP */ if (lid == LOGICALID_NOPNP) base = isa_get_port(scp->dev); else base = 0; for (i = 0 ; i < sizeof(scp->io) / sizeof(*scp->io) ; i++) { if (scp->io[i] == NULL) { scp->io_rid[i] = i; if (base == 0) scp->io[i] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[i], 0, ~0, io_range[i], RF_ACTIVE); else scp->io[i] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[i], base + io_offset[i], base + io_offset[i] + io_range[i] - 1 , io_range[i], RF_ACTIVE); if (scp->io[i] == NULL) return (1); scp->io_alloced[i] = 0; } } if (scp->irq == NULL) { scp->irq_rid = 0; scp->irq = bus_alloc_resource_any(scp->dev, SYS_RES_IRQ, &scp->irq_rid, RF_ACTIVE|RF_SHAREABLE); if (scp->irq == NULL) return (1); scp->irq_alloced = 0; } for (i = 0 ; i < sizeof(scp->drq) / sizeof(*scp->drq) ; i++) { if (scp->drq[i] == NULL) { scp->drq_rid[i] = i; if (base == 0 || i == 0) scp->drq[i] = bus_alloc_resource_any( scp->dev, SYS_RES_DRQ, &scp->drq_rid[i], RF_ACTIVE); else if ((flags & DV_F_DUAL_DMA) != 0) /* XXX The secondary drq is specified in the flag. */ scp->drq[i] = bus_alloc_resource(scp->dev, SYS_RES_DRQ, &scp->drq_rid[i], flags & DV_F_DRQ_MASK, flags & DV_F_DRQ_MASK, 1, RF_ACTIVE); if (scp->drq[i] == NULL) return (1); scp->drq_alloced[i] = 0; } } break; case LOGICALID_OPL: if (scp->io[0] == NULL) { scp->io_rid[0] = 0; scp->io[0] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[0], 0, ~0, io_range[0], RF_ACTIVE); if (scp->io[0] == NULL) return (1); scp->io_alloced[0] = 0; } break; case LOGICALID_MIDI: if (scp->io[0] == NULL) { scp->io_rid[0] = 0; scp->io[0] = bus_alloc_resource(scp->dev, SYS_RES_IOPORT, &scp->io_rid[0], 0, ~0, io_range[0], RF_ACTIVE); if (scp->io[0] == NULL) return (1); scp->io_alloced[0] = 0; } if (scp->irq == NULL) { /* The irq is shared with pcm audio. */ dev = find_masterdev(scp); if (dev == NULL) return (1); scp->irq_rid = 0; scp->irq = BUS_ALLOC_RESOURCE(dev, NULL, SYS_RES_IRQ, &scp->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); if (scp->irq == NULL) return (1); scp->irq_alloced = 0; } break; } return (0); }
struct resource * ata_iobus_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 resource *res = NULL; int myrid; u_int *ofw_regs; ofw_regs = iobus_get_regs(dev); /* * The reg array for the PSIM ata device has 6 start/size entries: * 0 - unused * 1/2/3 - unused * 4/5/6 - primary command * 7/8/9 - secondary command * 10/11/12 - primary control * 13/14/15 - secondary control * 16/17/18 - primary/secondary dma registers, unimplemented * * The resource values are calculated from these registers */ if (type == SYS_RES_IOPORT) { switch (*rid) { case ATA_IOADDR_RID: myrid = 0; start = ofw_regs[4]; end = start + ATA_IOSIZE - 1; count = ATA_IOSIZE; res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, SYS_RES_MEMORY, &myrid, start, end, count, flags); break; case ATA_CTLADDR_RID: myrid = 0; start = ofw_regs[10]; end = start + ATA_CTLIOSIZE - 1; count = ATA_CTLIOSIZE; res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, SYS_RES_MEMORY, &myrid, start, end, count, flags); break; case ATA_BMADDR_RID: /* DMA not properly supported by psim */ break; } return (res); } else if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) { /* * Pass this on to the parent */ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, SYS_RES_IRQ, rid, 0, ~0, 1, flags)); } else { return (NULL); } }
static struct resource * unin_chip_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 unin_chip_softc *sc; int needactivate; struct resource *rv; struct rman *rm; u_long adjstart, adjend, adjcount; struct unin_chip_devinfo *dinfo; struct resource_list_entry *rle; sc = device_get_softc(bus); dinfo = device_get_ivars(child); needactivate = flags & RF_ACTIVE; flags &= ~RF_ACTIVE; switch (type) { case SYS_RES_MEMORY: case SYS_RES_IOPORT: rle = resource_list_find(&dinfo->udi_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); } rle->end = rle->end - 1; /* Hack? */ 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; break; case SYS_RES_IRQ: /* Check for passthrough from subattachments. */ if (device_get_parent(child) != bus) return BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, start, end, count, flags); rle = resource_list_find(&dinfo->udi_resources, SYS_RES_IRQ, *rid); if (rle == NULL) { if (dinfo->udi_ninterrupts >= 6) { device_printf(bus, "%s has more than 6 interrupts\n", device_get_nameunit(child)); return (NULL); } resource_list_add(&dinfo->udi_resources, SYS_RES_IRQ, dinfo->udi_ninterrupts, start, start, 1); dinfo->udi_interrupts[dinfo->udi_ninterrupts] = start; dinfo->udi_ninterrupts++; } return (resource_list_alloc(&dinfo->udi_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); } rv = rman_reserve_resource(rm, adjstart, adjend, adjcount, flags, child); if (rv == NULL) { device_printf(bus, "failed to reserve resource %#lx - %#lx (%#lx)" " for %s\n", adjstart, adjend, adjcount, 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); }
struct resource * isa_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { /* * Consider adding a resource definition. We allow rid 0-1 for * irq and drq, 0-3 for memory and 0-7 for ports which is * sufficient for isapnp. */ int passthrough = (device_get_parent(child) != bus); int isdefault = (start == 0UL && end == ~0UL); struct isa_device* idev = DEVTOISA(child); struct resource_list *rl = &idev->id_resources; struct resource_list_entry *rle; u_long base, limit; if (!passthrough && !isdefault) { rle = resource_list_find(rl, type, *rid); if (!rle) { if (*rid < 0) return 0; switch (type) { case SYS_RES_IRQ: if (*rid >= ISA_NIRQ) return 0; break; case SYS_RES_DRQ: if (*rid >= ISA_NDRQ) return 0; break; case SYS_RES_MEMORY: if (*rid >= ISA_NMEM) return 0; break; case SYS_RES_IOPORT: if (*rid >= ISA_NPORT) return 0; break; default: return 0; } resource_list_add(rl, type, *rid, start, end, count); } } /* * Add the base, change default allocations to be between base and * limit, and reject allocations if a resource type is not enabled. */ base = limit = 0; switch(type) { case SYS_RES_MEMORY: if (isa_mem_bt == NULL) return (NULL); base = isa_mem_base; limit = base + isa_mem_limit; break; case SYS_RES_IOPORT: if (isa_io_bt == NULL) return (NULL); base = isa_io_base; limit = base + isa_io_limit; break; case SYS_RES_IRQ: if (isdefault && passthrough) panic("isa_alloc_resource: cannot pass through default " "irq allocation"); if (!isdefault) { start = end = isa_route_intr_res(bus, start, end); if (start == 255) return (NULL); } break; default: panic("isa_alloc_resource: unsupported resource type %d", type); } if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { start = ulmin(start + base, limit); end = ulmin(end + base, limit); } /* * This inlines a modified resource_list_alloc(); this is needed * because the resources need to have offsets added to them, which * cannot be done beforehand without patching the resource list entries * (which is ugly). */ if (passthrough) { return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, start, end, count, flags)); } rle = resource_list_find(rl, type, *rid); if (rle == NULL) return (NULL); /* no resource of that type/rid */ if (rle->res != NULL) panic("isa_alloc_resource: resource entry is busy"); if (isdefault) { start = rle->start; count = ulmax(count, rle->count); end = ulmax(rle->end, start + count - 1); switch (type) { case SYS_RES_MEMORY: case SYS_RES_IOPORT: start += base; end += base; if (!INRANGE(start, base, limit) || !INRANGE(end, base, limit)) return (NULL); break; case SYS_RES_IRQ: start = end = isa_route_intr_res(bus, start, end); if (start == 255) return (NULL); break; } } rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid, start, end, count, flags); /* * Record the new range. */ if (rle->res != NULL) { rle->start = rman_get_start(rle->res) - base; rle->end = rman_get_end(rle->res) - base; rle->count = count; } return (rle->res); }