Example #1
0
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);
}
Example #2
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 **)&reg);
	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);
}
Example #3
0
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);
}
Example #4
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);
	}
}
Example #5
0
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);
	}
}
Example #6
0
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;
}
Example #7
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]);
		}
	}
}
Example #8
0
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));
}
Example #9
0
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);
}
Example #10
0
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 **)&reg);
		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));
}
Example #11
0
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 **)&reg);
	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);
}
Example #12
0
File: nexus.c Project: MarginC/kame
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);
}
Example #13
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);
}
Example #14
0
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));
}
Example #15
0
/*
 * 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;
}
Example #16
0
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);
}
Example #17
0
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 **)&reg);
	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);
}
Example #18
0
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);
}
Example #19
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 **)&reg);
	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);
}
Example #20
0
/*
 * 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++;
	}
}
Example #21
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, 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);
}
Example #22
0
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;
}
Example #23
0
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 **)&reg);
	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);
}
Example #24
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 **)&reg);
	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 **)&regp);
                        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);
	}
}
Example #25
0
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 **)&reg);
	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);
	}
}
Example #26
0
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;
}
Example #27
0
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);
}
Example #28
0
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);
}
Example #29
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);
}
Example #30
0
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);
}