int ndis_alloc_amem(void *arg) { struct ndis_softc *sc; int error, rid; if (arg == NULL) return(EINVAL); sc = arg; rid = NDIS_AM_RID; #if defined(__DragonFly__) sc->ndis_res_am = bus_alloc_resource(sc->ndis_dev, SYS_RES_MEMORY, &rid, 0UL, ~0UL, 0x1000, RF_ACTIVE); #else sc->ndis_res_am = bus_alloc_resource_anywhere(sc->ndis_dev, SYS_RES_MEMORY, &rid, 0x1000, RF_ACTIVE); #endif if (sc->ndis_res_am == NULL) { device_printf(sc->ndis_dev, "failed to allocate attribute memory\n"); return(ENXIO); } sc->ndis_rescnt++; #if defined(__DragonFly__) resource_list_add(&sc->ndis_rl, SYS_RES_MEMORY, rid, rman_get_start(sc->ndis_res_am), rman_get_end(sc->ndis_res_am), rman_get_size(sc->ndis_res_am), -1); #else resource_list_add(&sc->ndis_rl, SYS_RES_MEMORY, rid, rman_get_start(sc->ndis_res_am), rman_get_end(sc->ndis_res_am), rman_get_size(sc->ndis_res_am)); #endif error = CARD_SET_MEMORY_OFFSET(device_get_parent(sc->ndis_dev), sc->ndis_dev, rid, 0, NULL); if (error) { device_printf(sc->ndis_dev, "CARD_SET_MEMORY_OFFSET() returned 0x%x\n", error); return(error); } error = CARD_SET_RES_FLAGS(device_get_parent(sc->ndis_dev), sc->ndis_dev, SYS_RES_MEMORY, rid, PCCARD_A_MEM_ATTR); if (error) { device_printf(sc->ndis_dev, "CARD_SET_RES_FLAGS() returned 0x%x\n", error); return(error); } sc->ndis_am_rid = rid; return(0); }
static struct ebus_devinfo * ebus_setup_dinfo(device_t dev, struct ebus_softc *sc, phandle_t node) { struct ebus_devinfo *edi; struct isa_regs *reg; ofw_isa_intr_t *intrs; ofw_pci_intr_t rintr; u_int64_t start; int nreg, nintr, i; edi = malloc(sizeof(*edi), M_DEVBUF, M_ZERO | M_WAITOK); if (ofw_bus_gen_setup_devinfo(&edi->edi_obdinfo, node) != 0) { free(edi, M_DEVBUF); return (NULL); } resource_list_init(&edi->edi_rl); nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)®); if (nreg == -1) { device_printf(dev, "<%s>: incomplete\n", edi->edi_obdinfo.obd_name); goto fail; } for (i = 0; i < nreg; i++) { start = ISA_REG_PHYS(reg + i); resource_list_add(&edi->edi_rl, SYS_RES_MEMORY, i, start, start + reg[i].size - 1, reg[i].size); } free(reg, M_OFWPROP); nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intrs), (void **)&intrs); for (i = 0; i < nintr; i++) { rintr = ofw_isa_route_intr(dev, node, &sc->sc_iinfo, intrs[i]); if (rintr == PCI_INVALID_IRQ) { device_printf(dev, "<%s>: could not map EBus interrupt %d\n", edi->edi_obdinfo.obd_name, intrs[i]); free(intrs, M_OFWPROP); goto fail; } resource_list_add(&edi->edi_rl, SYS_RES_IRQ, i, rintr, rintr, 1); } free(intrs, M_OFWPROP); return (edi); fail: ebus_destroy_dinfo(edi); return (NULL); }
int pxa_attach(device_t dev) { struct obio_softc *sc; struct obio_device *od; int i; device_t child; sc = device_get_softc(dev); sc->obio_bst = obio_tag; sc->obio_mem.rm_type = RMAN_ARRAY; sc->obio_mem.rm_descr = "PXA2X0 OBIO Memory"; if (rman_init(&sc->obio_mem) != 0) panic("pxa_attach: failed to init obio mem rman"); if (rman_manage_region(&sc->obio_mem, 0, PXA250_PERIPH_END) != 0) panic("pxa_attach: failed to set up obio mem rman"); sc->obio_irq.rm_type = RMAN_ARRAY; sc->obio_irq.rm_descr = "PXA2X0 OBIO IRQ"; if (rman_init(&sc->obio_irq) != 0) panic("pxa_attach: failed to init obio irq rman"); if (rman_manage_region(&sc->obio_irq, 0, 31) != 0) panic("pxa_attach: failed to set up obio irq rman (main irqs)"); if (rman_manage_region(&sc->obio_irq, IRQ_GPIO0, IRQ_GPIO_MAX) != 0) panic("pxa_attach: failed to set up obio irq rman (gpio irqs)"); for (od = obio_devices; od->od_name != NULL; od++) { resource_list_init(&od->od_resources); resource_list_add(&od->od_resources, SYS_RES_MEMORY, 0, od->od_base, od->od_base + od->od_size, od->od_size); for (i = 0; od->od_irqs[i] != 0; i++) { resource_list_add(&od->od_resources, SYS_RES_IRQ, i, od->od_irqs[i], od->od_irqs[i], 1); } child = device_add_child(dev, od->od_name, -1); device_set_ivars(child, od); } bus_generic_probe(dev); bus_generic_attach(dev); return (0); }
static void gic_v3_add_children(ACPI_SUBTABLE_HEADER *entry, void *arg) { ACPI_MADT_GENERIC_TRANSLATOR *gict; struct gic_v3_acpi_devinfo *di; struct gic_v3_softc *sc; device_t child, dev; if (entry->Type == ACPI_MADT_TYPE_GENERIC_TRANSLATOR) { /* We have an ITS, add it as a child */ gict = (ACPI_MADT_GENERIC_TRANSLATOR *)entry; dev = arg; sc = device_get_softc(dev); child = device_add_child(dev, "its", -1); if (child == NULL) return; di = malloc(sizeof(*di), M_GIC_V3, M_WAITOK | M_ZERO); resource_list_init(&di->di_rl); resource_list_add(&di->di_rl, SYS_RES_MEMORY, 0, gict->BaseAddress, gict->BaseAddress + 128 * 1024 - 1, 128 * 1024); di->di_gic_dinfo.gic_domain = -1; sc->gic_nchildren++; device_set_ivars(child, di); } }
static void madt_gicv2m_handler(ACPI_SUBTABLE_HEADER *entry, void *arg) { struct arm_gic_softc *sc; ACPI_MADT_GENERIC_MSI_FRAME *msi; struct gic_acpi_devinfo *dinfo; device_t dev, cdev; if (entry->Type == ACPI_MADT_TYPE_GENERIC_MSI_FRAME) { sc = arg; dev = sc->gic_dev; msi = (ACPI_MADT_GENERIC_MSI_FRAME *)entry; device_printf(dev, "frame: %x %lx %x %u %u\n", msi->MsiFrameId, msi->BaseAddress, msi->Flags, msi->SpiCount, msi->SpiBase); cdev = device_add_child(dev, NULL, -1); if (cdev == NULL) return; dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO); resource_list_init(&dinfo->rl); resource_list_add(&dinfo->rl, SYS_RES_MEMORY, 0, msi->BaseAddress, msi->BaseAddress + PAGE_SIZE - 1, PAGE_SIZE); device_set_ivars(cdev, dinfo); } }
static int pccard_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) { struct pccard_devinfo *devi = PCCARD_DEVINFO(child); struct resource_list *rl = &devi->resources; if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY && type != SYS_RES_IRQ && type != SYS_RES_DRQ) return EINVAL; if (rid < 0) return EINVAL; if (type == SYS_RES_IOPORT && rid >= PCCARD_NPORT) return EINVAL; if (type == SYS_RES_MEMORY && rid >= PCCARD_NMEM) return EINVAL; if (type == SYS_RES_IRQ && rid >= PCCARD_NIRQ) return EINVAL; if (type == SYS_RES_DRQ && rid >= PCCARD_NDRQ) return EINVAL; resource_list_add(rl, type, rid, start, start + count - 1, count); return 0; }
static void iobus_add_reg(phandle_t devnode, struct iobus_devinfo *dinfo, vm_offset_t iobus_off) { u_int size; int i; size = OF_getprop(devnode, "reg", dinfo->id_reg,sizeof(dinfo->id_reg)); if (size != -1) { dinfo->id_nregs = size / (sizeof(dinfo->id_reg[0])); for (i = 0; i < dinfo->id_nregs; i+= 3) { /* * Scale the absolute addresses back to iobus * relative offsets. This is to better simulate * macio */ dinfo->id_reg[i+1] -= iobus_off; resource_list_add(&dinfo->id_resources, SYS_RES_MEMORY, 0, dinfo->id_reg[i+1], dinfo->id_reg[i+1] + dinfo->id_reg[i+2], dinfo->id_reg[i+2]); } } }
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) { struct isa_device* idev = DEVTOISA(child); struct resource_list *rl = &idev->id_resources; int isdefault, passthrough, rids; isdefault = (start == 0UL && end == ~0UL) ? 1 : 0; passthrough = (device_get_parent(child) != bus) ? 1 : 0; if (!passthrough && !isdefault && resource_list_find(rl, type, *rid) == NULL) { switch (type) { case SYS_RES_IOPORT: rids = ISA_PNP_NPORT; break; case SYS_RES_IRQ: rids = ISA_PNP_NIRQ; break; case SYS_RES_MEMORY: rids = ISA_PNP_NMEM; break; default: rids = 0; break; } if (*rid < 0 || *rid >= rids) return (NULL); resource_list_add(rl, type, *rid, start, end, count); } return (resource_list_alloc(rl, bus, child, type, rid, start, end, count, flags)); }
static int jz4780_pinctrl_attach(device_t dev) { struct jz4780_pinctrl_softc *sc; struct resource_list *rs; struct resource_list_entry *re; phandle_t dt_parent, dt_child; int i, ret; sc = device_get_softc(dev); sc->dev = dev; /* * Fetch our own resource list to dole memory between children */ rs = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); if (rs == NULL) return (ENXIO); re = resource_list_find(rs, SYS_RES_MEMORY, 0); if (re == NULL) return (ENXIO); simplebus_init(dev, 0); /* Iterate over this node children, looking for pin controllers */ dt_parent = ofw_bus_get_node(dev); i = 0; for (dt_child = OF_child(dt_parent); dt_child != 0; dt_child = OF_peer(dt_child)) { struct simplebus_devinfo *ndi; device_t child; bus_addr_t phys; bus_size_t size; /* Add gpio controller child */ if (!OF_hasprop(dt_child, "gpio-controller")) continue; child = simplebus_add_device(dev, dt_child, 0, NULL, -1, NULL); if (child == NULL) break; /* Setup child resources */ phys = CHIP_REG_OFFSET(re->start, i); size = CHIP_REG_STRIDE; if (phys + size - 1 <= re->end) { ndi = device_get_ivars(child); resource_list_add(&ndi->rl, SYS_RES_MEMORY, 0, phys, phys + size - 1, size); } i++; } ret = bus_generic_attach(dev); if (ret == 0) { fdt_pinctrl_register(dev, "ingenic,pins"); fdt_pinctrl_configure_tree(dev); } return (ret); }
static int central_attach(device_t dev) { struct central_devinfo *cdi; struct sbus_regs *reg; struct central_softc *sc; phandle_t child; phandle_t node; device_t cdev; int nreg; int i; sc = device_get_softc(dev); node = ofw_bus_get_node(dev); sc->sc_nrange = OF_getprop_alloc(node, "ranges", sizeof(*sc->sc_ranges), (void **)&sc->sc_ranges); if (sc->sc_nrange == -1) { device_printf(dev, "can't get ranges\n"); return (ENXIO); } for (child = OF_child(node); child != 0; child = OF_peer(child)) { cdi = malloc(sizeof(*cdi), M_DEVBUF, M_WAITOK | M_ZERO); if (ofw_bus_gen_setup_devinfo(&cdi->cdi_obdinfo, child) != 0) { free(cdi, M_DEVBUF); continue; } nreg = OF_getprop_alloc(child, "reg", sizeof(*reg), (void **)®); if (nreg == -1) { device_printf(dev, "<%s>: incomplete\n", cdi->cdi_obdinfo.obd_name); ofw_bus_gen_destroy_devinfo(&cdi->cdi_obdinfo); free(cdi, M_DEVBUF); continue; } resource_list_init(&cdi->cdi_rl); for (i = 0; i < nreg; i++) resource_list_add(&cdi->cdi_rl, SYS_RES_MEMORY, i, reg[i].sbr_offset, reg[i].sbr_offset + reg[i].sbr_size, reg[i].sbr_size); free(reg, M_OFWPROP); cdev = device_add_child(dev, NULL, -1); if (cdev == NULL) { device_printf(dev, "<%s>: device_add_child failed\n", cdi->cdi_obdinfo.obd_name); resource_list_free(&cdi->cdi_rl); ofw_bus_gen_destroy_devinfo(&cdi->cdi_obdinfo); free(cdi, M_DEVBUF); continue; } device_set_ivars(cdev, cdi); } return (bus_generic_attach(dev)); }
static int fdt_lbc_reg_decode(phandle_t node, struct lbc_softc *sc, struct lbc_devinfo *di) { rman_res_t start, end, count; pcell_t *reg, *regptr; pcell_t addr_cells, size_cells; int tuple_size, tuples; int i, j, rv, bank; if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells) != 0) return (ENXIO); tuple_size = sizeof(pcell_t) * (addr_cells + size_cells); tuples = OF_getencprop_alloc_multi(node, "reg", tuple_size, (void **)®); debugf("addr_cells = %d, size_cells = %d\n", addr_cells, size_cells); debugf("tuples = %d, tuple size = %d\n", tuples, tuple_size); if (tuples <= 0) /* No 'reg' property in this node. */ return (0); regptr = reg; for (i = 0; i < tuples; i++) { bank = fdt_data_get((void *)reg, 1); di->di_bank = bank; reg += 1; /* Get address/size. */ start = count = 0; for (j = 0; j < addr_cells; j++) { start <<= 32; start |= reg[j]; } for (j = 0; j < size_cells; j++) { count <<= 32; count |= reg[addr_cells + j - 1]; } reg += addr_cells - 1 + size_cells; /* Calculate address range relative to VA base. */ start = sc->sc_banks[bank].kva + start; end = start + count - 1; debugf("reg addr bank = %d, start = %jx, end = %jx, " "count = %jx\n", bank, start, end, count); /* Use bank (CS) cell as rid. */ resource_list_add(&di->di_res, SYS_RES_MEMORY, bank, start, end, count); } rv = 0; OF_prop_free(regptr); return (rv); }
static int nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; /* XXX this should return a success/failure indicator */ resource_list_add(rl, type, rid, start, start + count - 1, count); return(0); }
static void wiibus_init_device_resources(struct rman *rm, struct wiibus_devinfo *dinfo, unsigned int rid, uintptr_t addr, size_t len, unsigned int irq) { if (!dinfo->di_init) { resource_list_init(&dinfo->di_resources); dinfo->di_init++; } if (addr) { rman_manage_region(rm, addr, addr + len - 1); resource_list_add(&dinfo->di_resources, SYS_RES_MEMORY, rid, addr, addr + len, len); } if (irq) resource_list_add(&dinfo->di_resources, SYS_RES_IRQ, rid, irq, irq, 1); }
static int vdevice_attach(device_t dev) { phandle_t root, child; device_t cdev; int icells, i, nintr, *intr; phandle_t iparent; struct vdevice_devinfo *dinfo; root = ofw_bus_get_node(dev); for (child = OF_child(root); child != 0; child = OF_peer(child)) { dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO); if (ofw_bus_gen_setup_devinfo(&dinfo->mdi_obdinfo, child) != 0) { free(dinfo, M_DEVBUF); continue; } resource_list_init(&dinfo->mdi_resources); if (OF_searchprop(child, "#interrupt-cells", &icells, sizeof(icells)) <= 0) icells = 2; if (OF_getprop(child, "interrupt-parent", &iparent, sizeof(iparent)) <= 0) iparent = -1; nintr = OF_getprop_alloc(child, "interrupts", sizeof(*intr), (void **)&intr); if (nintr > 0) { for (i = 0; i < nintr; i += icells) { u_int irq = intr[i]; if (iparent != -1) irq = ofw_bus_map_intr(dev, iparent, icells, &intr[i]); resource_list_add(&dinfo->mdi_resources, SYS_RES_IRQ, i, irq, irq, i); } } cdev = device_add_child(dev, NULL, -1); if (cdev == NULL) { device_printf(dev, "<%s>: device_add_child failed\n", dinfo->mdi_obdinfo.obd_name); ofw_bus_gen_destroy_devinfo(&dinfo->mdi_obdinfo); free(dinfo, M_DEVBUF); continue; } device_set_ivars(cdev, dinfo); } return (bus_generic_attach(dev)); }
/* * Add interrupt/addr range to the dev's resource list if present */ static void iobus_add_intr(phandle_t devnode, struct iobus_devinfo *dinfo) { u_int intr = -1; if (OF_getprop(devnode, "interrupt", &intr, sizeof(intr)) != -1) { resource_list_add(&dinfo->id_resources, SYS_RES_IRQ, 0, intr, intr, 1); } dinfo->id_interrupt = intr; }
static void pxa_smi_add_device(device_t dev, const char *name, int unit) { device_t child; int start, count; struct smi_ivars *ivars; ivars = (struct smi_ivars *)malloc( sizeof(struct smi_ivars), M_PXASMI, M_WAITOK); if (ivars == NULL) return; child = device_add_child(dev, name, unit); if (child == NULL) { free(ivars, M_PXASMI); return; } device_set_ivars(child, ivars); resource_list_init(&ivars->smid_resources); start = 0; count = 0; resource_int_value(name, unit, "mem", &start); resource_int_value(name, unit, "size", &count); if (start > 0 || count > 0) { resource_list_add(&ivars->smid_resources, SYS_RES_MEMORY, 0, start, start + count, count); ivars->smid_mem = (bus_addr_t)start; } start = -1; count = 0; resource_int_value(name, unit, "irq", &start); if (start > -1) resource_list_add(&ivars->smid_resources, SYS_RES_IRQ, 0, start, start, 1); if (resource_disabled(name, unit)) device_disable(child); }
static int fdt_lbc_reg_decode(phandle_t node, struct lbc_softc *sc, struct lbc_devinfo *di) { u_long start, end, count; pcell_t *reg, *regptr; pcell_t addr_cells, size_cells; int tuple_size, tuples; int i, rv, bank; if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells) != 0) return (ENXIO); tuple_size = sizeof(pcell_t) * (addr_cells + size_cells); tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)®); debugf("addr_cells = %d, size_cells = %d\n", addr_cells, size_cells); debugf("tuples = %d, tuple size = %d\n", tuples, tuple_size); if (tuples <= 0) /* No 'reg' property in this node. */ return (0); regptr = reg; for (i = 0; i < tuples; i++) { bank = fdt_data_get((void *)reg, 1); di->di_bank = bank; reg += 1; /* Get address/size. */ rv = fdt_data_to_res(reg, addr_cells - 1, size_cells, &start, &count); if (rv != 0) { resource_list_free(&di->di_res); goto out; } reg += addr_cells - 1 + size_cells; /* Calculate address range relative to VA base. */ start = sc->sc_banks[bank].kva + start; end = start + count - 1; debugf("reg addr bank = %d, start = %lx, end = %lx, " "count = %lx\n", bank, start, end, count); /* Use bank (CS) cell as rid. */ resource_list_add(&di->di_res, SYS_RES_MEMORY, bank, start, end, count); } rv = 0; out: free(regptr, M_OFWPROP); return (rv); }
static int canbus_set_resource ( device_t dev, device_t child, int type, int rid, u_long start, u_long count) { struct canbus_device *cbdev = (struct canbus_device *)device_get_ivars(child); struct resource_list *rl = &cbdev->cbdev_resources; resource_list_add(rl, type, rid, start, (start + count - 1), count); return (0); }
int fdt_reg_to_rl(phandle_t node, struct resource_list *rl) { u_long end, count, start; pcell_t *reg, *regptr; pcell_t addr_cells, size_cells; int tuple_size, tuples; int i, rv; long busaddr, bussize; if (fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells) != 0) return (ENXIO); if (fdt_get_range(OF_parent(node), 0, &busaddr, &bussize)) { busaddr = 0; bussize = 0; } tuple_size = sizeof(pcell_t) * (addr_cells + size_cells); tuples = OF_getprop_alloc(node, "reg", tuple_size, (void **)®); debugf("addr_cells = %d, size_cells = %d\n", addr_cells, size_cells); debugf("tuples = %d, tuple size = %d\n", tuples, tuple_size); if (tuples <= 0) /* No 'reg' property in this node. */ return (0); regptr = reg; for (i = 0; i < tuples; i++) { rv = fdt_data_to_res(reg, addr_cells, size_cells, &start, &count); if (rv != 0) { resource_list_free(rl); goto out; } reg += addr_cells + size_cells; /* Calculate address range relative to base. */ start += busaddr; end = start + count - 1; debugf("reg addr start = %lx, end = %lx, count = %lx\n", start, end, count); resource_list_add(rl, SYS_RES_MEMORY, i, start, end, count); } rv = 0; out: free(regptr, M_OFWPROP); return (rv); }
/* * Add an interrupt to the dev's resource list if present */ static void unin_chip_add_intr(phandle_t devnode, struct unin_chip_devinfo *dinfo) { phandle_t iparent; int *intr; int i, nintr; int icells; if (dinfo->udi_ninterrupts >= 6) { printf("unin: device has more than 6 interrupts\n"); return; } nintr = OF_getprop_alloc(devnode, "interrupts", sizeof(*intr), (void **)&intr); if (nintr == -1) { nintr = OF_getprop_alloc(devnode, "AAPL,interrupts", sizeof(*intr), (void **)&intr); if (nintr == -1) return; } if (intr[0] == -1) return; if (OF_getprop(devnode, "interrupt-parent", &iparent, sizeof(iparent)) <= 0) panic("Interrupt but no interrupt parent!\n"); if (OF_searchprop(iparent, "#interrupt-cells", &icells, sizeof(icells)) <= 0) icells = 1; for (i = 0; i < nintr; i+=icells) { u_int irq = MAP_IRQ(iparent, intr[i]); resource_list_add(&dinfo->udi_resources, SYS_RES_IRQ, dinfo->udi_ninterrupts, irq, irq, 1); if (icells > 1) { powerpc_config_intr(irq, (intr[i+1] & 1) ? INTR_TRIGGER_LEVEL : INTR_TRIGGER_EDGE, INTR_POLARITY_LOW); } dinfo->udi_interrupts[dinfo->udi_ninterrupts] = irq; dinfo->udi_ninterrupts++; } }
/* * This implementation simply passes the request up to the parent * bus, which in our case is the special i386 nexus, substituting any * configured values if the caller defaulted. We can get away with * this because there is no special mapping for ISA resources on an Intel * platform. When porting this code to another architecture, it may be * necessary to interpose a mapping layer here. */ 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, int cpuid) { /* * 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; 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; cpuid = machintr_legacy_intr_cpuid(start); 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, cpuid); } } return resource_list_alloc(rl, bus, child, type, rid, start, end, count, flags, cpuid); }
static struct resource * pccard_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 for * irq, 0-3 for memory and 0-1 for ports */ int passthrough = (device_get_parent(child) != bus); int isdefault = (start == 0UL && end == ~0UL); struct pccard_devinfo *devi = device_get_ivars(child); struct resource_list *rl = &devi->resources; struct resource_list_entry *rle; struct resource *res; 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 >= PCCARD_NIRQ) return 0; break; case SYS_RES_DRQ: if (*rid >= PCCARD_NDRQ) return 0; break; case SYS_RES_MEMORY: if (*rid >= PCCARD_NMEM) return 0; break; case SYS_RES_IOPORT: if (*rid >= PCCARD_NPORT) return 0; break; default: return 0; } resource_list_add(rl, type, *rid, start, end, count); } } res = resource_list_alloc(rl, bus, child, type, rid, start, end, count, flags); return res; }
static int ofw_bus_reg_to_rl_helper(device_t dev, phandle_t node, pcell_t acells, pcell_t scells, struct resource_list *rl, const char *reg_source) { uint64_t phys, size; ssize_t i, j, rid, nreg, ret; uint32_t *reg; char *name; /* * This may be just redundant when having ofw_bus_devinfo * but makes this routine independent of it. */ ret = OF_getprop_alloc(node, "name", (void **)&name); if (ret == -1) name = NULL; ret = OF_getencprop_alloc_multi(node, reg_source, sizeof(*reg), (void **)®); nreg = (ret == -1) ? 0 : ret; if (nreg % (acells + scells) != 0) { if (bootverbose) device_printf(dev, "Malformed reg property on <%s>\n", (name == NULL) ? "unknown" : name); nreg = 0; } for (i = 0, rid = 0; i < nreg; i += acells + scells, rid++) { phys = size = 0; for (j = 0; j < acells; j++) { phys <<= 32; phys |= reg[i + j]; } for (j = 0; j < scells; j++) { size <<= 32; size |= reg[i + acells + j]; } /* Skip the dummy reg property of glue devices like ssm(4). */ if (size != 0) resource_list_add(rl, SYS_RES_MEMORY, rid, phys, phys + size - 1, size); } free(name, M_OFWPROP); free(reg, M_OFWPROP); return (0); }
static void macio_add_reg(phandle_t devnode, struct macio_devinfo *dinfo) { struct macio_reg *reg, *regp; phandle_t child; char buf[8]; int i, layout_id = 0, nreg, res; nreg = OF_getprop_alloc(devnode, "reg", sizeof(*reg), (void **)®); if (nreg == -1) return; /* * Some G5's have broken properties in the i2s-a area. If so we try * to fix it. Right now we know of two different cases, one for * sound layout-id 36 and the other one for sound layout-id 76. * What is missing is the base address for the memory addresses. * We take them from the parent node (i2s) and use the size * information from the child. */ if (reg[0].mr_base == 0) { child = OF_child(devnode); while (child != 0) { res = OF_getprop(child, "name", buf, sizeof(buf)); if (res > 0 && strcmp(buf, "sound") == 0) break; child = OF_peer(child); } res = OF_getprop(child, "layout-id", &layout_id, sizeof(layout_id)); if (res > 0 && (layout_id == 36 || layout_id == 76)) { res = OF_getprop_alloc(OF_parent(devnode), "reg", sizeof(*regp), (void **)®p); reg[0] = regp[0]; reg[1].mr_base = regp[1].mr_base; reg[2].mr_base = regp[1].mr_base + reg[1].mr_size; } } 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); } }
static void macio_add_reg(phandle_t devnode, struct macio_devinfo *dinfo) { struct macio_reg *reg; int i, nreg; nreg = OF_getprop_alloc(devnode, "reg", sizeof(*reg), (void **)®); if (nreg == -1) return; 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); } }
static device_t atkbdc_isa_add_child(device_t bus, u_int order, const char *name, int unit) { atkbdc_device_t *ivar; atkbdc_softc_t *sc; device_t child; int t; sc = *(atkbdc_softc_t **)device_get_softc(bus); ivar = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV, M_NOWAIT | M_ZERO); if (!ivar) return NULL; child = device_add_child_ordered(bus, order, name, unit); if (child == NULL) { free(ivar, M_ATKBDDEV); return child; } resource_list_init(&ivar->resources); ivar->rid = order; /* * If the device is not created by the PnP BIOS or ACPI, refer * to device hints for IRQ. We always populate the resource * list entry so we can use a standard bus_get_resource() * method. */ if (order == KBDC_RID_KBD) { if (sc->irq == NULL) { if (resource_int_value(name, unit, "irq", &t) != 0) t = -1; } else t = rman_get_start(sc->irq); if (t > 0) resource_list_add(&ivar->resources, SYS_RES_IRQ, ivar->rid, t, t, 1); } if (resource_disabled(name, unit)) device_disable(child); device_set_ivars(child, ivar); return child; }
static struct resource * pxa_alloc_gpio_irq(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { struct obio_softc *sc; struct obio_device *od; struct resource_list *rl; struct resource_list_entry *rle; struct resource *rv; struct rman *rm; int needactivate; sc = device_get_softc(dev); od = device_get_ivars(child); rl = &od->od_resources; rm = &sc->obio_irq; needactivate = flags & RF_ACTIVE; flags &= ~RF_ACTIVE; rv = rman_reserve_resource(rm, start, end, count, flags, child); if (rv == NULL) return (NULL); resource_list_add(rl, type, *rid, start, end, count); rle = resource_list_find(rl, type, *rid); if (rle == NULL) panic("pxa_alloc_gpio_irq: unexpectedly can't find resource"); rle->res = rv; rle->start = rman_get_start(rv); rle->end = rman_get_end(rv); rle->count = count; if (needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { rman_release_resource(rv); return (NULL); } } if (bootverbose) device_printf(dev, "lazy allocation of irq %ld for %s\n", start, device_get_nameunit(child)); return (rv); }
static int gpiobus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) { struct gpiobus_ivar *devi; struct resource_list_entry *rle; dprintf("%s: entry (%p, %p, %d, %d, %p, %ld)\n", __func__, dev, child, type, rid, (void *)(intptr_t)start, count); devi = GPIOBUS_IVAR(child); rle = resource_list_add(&devi->rl, type, rid, start, start + count - 1, count); if (rle == NULL) return (ENXIO); return (0); }
/* * This implementation simply passes the request up to the parent * bus, which in our case is the special i386 nexus, substituting any * configured values if the caller defaulted. We can get away with * this because there is no special mapping for ISA resources on an Intel * platform. When porting this code to another architecture, it may be * necessary to interpose a mapping layer here. */ 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. */ 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; 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); } } return resource_list_alloc(rl, bus, child, type, rid, start, end, count, flags); }
static int nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) { struct nexus_device *ndev = DEVTONX(child); struct resource_list *rl = &ndev->nx_resources; struct resource_list_entry *rle; dprintf("%s: entry (%p, %p, %d, %d, %p, %ld)\n", __func__, dev, child, type, rid, (void *)(intptr_t)start, count); rle = resource_list_add(rl, type, rid, start, start + count - 1, count); if (rle == NULL) return (ENXIO); return (0); }