Ejemplo n.º 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);
}
Ejemplo n.º 2
0
static __inline void
get_masks(struct resource *res, uint32_t *mask, uint32_t *mask2)
{
	int i;

	*mask = 0;
	for (i = rman_get_start(res); i < 32 && i <= rman_get_end(res); i++)
		*mask |= 1 << i;
	*mask2 = 0;
	for (; i <= rman_get_end(res); i++)
		*mask2 |= 1 << (i - 32);
}
Ejemplo n.º 3
0
static int
pci_iov_alloc_bar_ea(struct pci_devinfo *dinfo, int bar)
{
	struct pcicfg_iov *iov;
	rman_res_t start, end;
	struct resource *res;
	struct resource_list *rl;
	struct resource_list_entry *rle;

	rl = &dinfo->resources;
	iov = dinfo->cfg.iov;

	rle = resource_list_find(rl, SYS_RES_MEMORY,
	    iov->iov_pos + PCIR_SRIOV_BAR(bar));
	if (rle == NULL)
		rle = resource_list_find(rl, SYS_RES_IOPORT,
		    iov->iov_pos + PCIR_SRIOV_BAR(bar));
	if (rle == NULL)
		return (ENXIO);
	res = rle->res;

	iov->iov_bar[bar].res = res;
	iov->iov_bar[bar].bar_size = rman_get_size(res) / iov->iov_num_vfs;
	iov->iov_bar[bar].bar_shift = pci_mapsize(iov->iov_bar[bar].bar_size);

	start = rman_get_start(res);
	end = rman_get_end(res);

	return (rman_manage_region(&iov->rman, start, end));
}
Ejemplo n.º 4
0
static int
pci_iov_alloc_bar(struct pci_devinfo *dinfo, int bar, pci_addr_t bar_shift)
{
	struct resource *res;
	struct pcicfg_iov *iov;
	device_t dev, bus;
	rman_res_t start, end;
	pci_addr_t bar_size;
	int rid;

	iov = dinfo->cfg.iov;
	dev = dinfo->cfg.dev;
	bus = device_get_parent(dev);
	rid = iov->iov_pos + PCIR_SRIOV_BAR(bar);
	bar_size = 1 << bar_shift;

	res = pci_alloc_multi_resource(bus, dev, SYS_RES_MEMORY, &rid, 0,
	    ~0, 1, iov->iov_num_vfs, RF_ACTIVE);

	if (res == NULL)
		return (ENXIO);

	iov->iov_bar[bar].res = res;
	iov->iov_bar[bar].bar_size = bar_size;
	iov->iov_bar[bar].bar_shift = bar_shift;

	start = rman_get_start(res);
	end = rman_get_end(res);
	return (rman_manage_region(&iov->rman, start, end));
}
Ejemplo n.º 5
0
static int
nexus_activate_resource(device_t bus, device_t child, int type, int rid,
			struct resource *r)
{
	/*
	 * If this is a memory resource, map it into the kernel.
	 */
	if (rman_get_bustag(r) == I386_BUS_SPACE_MEM) {
		caddr_t vaddr = 0;

		if (rman_get_end(r) < 1024 * 1024) {
			/*
			 * The first 1Mb is mapped at KERNBASE.
			 */
			vaddr = (caddr_t)(uintptr_t)(KERNBASE + rman_get_start(r));
		} else {
			u_int64_t paddr;
			u_int64_t psize;
			u_int32_t poffs;

			paddr = rman_get_start(r);
			psize = rman_get_size(r);

			poffs = paddr - trunc_page(paddr);
			vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
		}
		rman_set_virtual(r, vaddr);
		/* IBM-PC: the type of bus_space_handle_t is u_int */
		rman_set_bushandle(r, (bus_space_handle_t) vaddr);
	}
	return (rman_activate_resource(r));
}
Ejemplo n.º 6
0
static struct resource *
ofwbus_alloc_resource(device_t bus, device_t child, int type, int *rid,
    rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
	struct ofwbus_softc *sc;
	struct rman *rm;
	struct resource *rv;
	struct resource_list_entry *rle;
	int isdefault, passthrough;

	isdefault = RMAN_IS_DEFAULT_RANGE(start, end);
	passthrough = (device_get_parent(child) != bus);
	sc = device_get_softc(bus);
	rle = NULL;
	if (!passthrough && isdefault) {
		rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child),
		    type, *rid);
		if (rle == NULL) {
			if (bootverbose)
				device_printf(bus, "no default resources for "
				    "rid = %d, type = %d\n", *rid, type);
			return (NULL);
		}
		start = rle->start;
		count = ulmax(count, rle->count);
		end = ulmax(rle->end, start + count - 1);
	}

	switch (type) {
	case SYS_RES_IRQ:
		rm = &sc->sc_intr_rman;
		break;
	case SYS_RES_MEMORY:
		rm = &sc->sc_mem_rman;
		break;
	default:
		return (NULL);
	}

	rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
	    child);
	if (rv == NULL)
		return (NULL);
	rman_set_rid(rv, *rid);

	if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
	    *rid, rv) != 0) {
		rman_release_resource(rv);
		return (NULL);
	}

	if (!passthrough && rle != NULL) {
		rle->res = rv;
		rle->start = rman_get_start(rv);
		rle->end = rman_get_end(rv);
		rle->count = rle->end - rle->start + 1;
	}

	return (rv);
}
Ejemplo n.º 7
0
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
                 driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
{
    int irq;

#ifdef MIPS_INTRNG
    for (irq = rman_get_start(res); irq <= rman_get_end(res); irq++) {
        intr_irq_add_handler(child, filt, intr, arg, irq, flags,
                             cookiep);
    }
#else
    register_t s;

    s = intr_disable();
    irq = rman_get_start(res);
    if (irq >= NUM_MIPS_IRQS) {
        intr_restore(s);
        return (0);
    }

    cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg,
                           irq, flags, cookiep);
    intr_restore(s);
#endif
    return (0);
}
Ejemplo n.º 8
0
static int
chipc_adjust_resource(device_t dev, device_t child, int type,
    struct resource *r, rman_res_t start, rman_res_t end)
{
	struct chipc_softc		*sc;
	struct chipc_region		*cr;
	struct rman			*rm;
	
	sc = device_get_softc(dev);

	/* Handled by parent bus? */
	rm = chipc_get_rman(sc, type);
	if (rm == NULL || !rman_is_region_manager(r, rm)) {
		return (bus_generic_adjust_resource(dev, child, type, r, start,
		    end));
	}

	/* The range is limited to the existing region mapping */
	cr = chipc_find_region(sc, rman_get_start(r), rman_get_end(r));
	if (cr == NULL)
		return (EINVAL);
	
	if (end <= start)
		return (EINVAL);

	if (start < cr->cr_addr || end > cr->cr_end)
		return (EINVAL);

	/* Range falls within the existing region */
	return (rman_adjust_resource(r, start, end));
}
Ejemplo n.º 9
0
int
puc_bus_get_resource(device_t dev, device_t child, int type, int rid,
    u_long *startp, u_long *countp)
{
	struct puc_port *port;
	struct resource *res;
	u_long start;

	/* Get our immediate child. */
	while (child != NULL && device_get_parent(child) != dev)
		child = device_get_parent(child);
	if (child == NULL)
		return (EINVAL);

	port = device_get_ivars(child);
	KASSERT(port != NULL, ("%s %d", __func__, __LINE__));

	if (type == port->p_bar->b_type)
		res = port->p_rres;
	else if (type == SYS_RES_IRQ)
		res = port->p_ires;
	else
		return (ENXIO);

	if (rid != 0 || res == NULL)
		return (ENXIO);

	start = rman_get_start(res);
	if (startp != NULL)
		*startp = start;
	if (countp != NULL)
		*countp = rman_get_end(res) - start + 1;
	return (0);
}
Ejemplo n.º 10
0
/**
 * Default bhndb(4) implementation of BUS_DEACTIVATE_RESOURCE().
 */
static int
chipc_deactivate_resource(device_t dev, device_t child, int type,
    int rid, struct resource *r)
{
	struct chipc_softc	*sc;
	struct chipc_region	*cr;
	struct rman		*rm;
	int			 error;

	sc = device_get_softc(dev);

	/* Handled by parent bus? */
	rm = chipc_get_rman(sc, type);
	if (rm == NULL || !rman_is_region_manager(r, rm)) {
		return (bus_generic_deactivate_resource(dev, child, type, rid,
		    r));
	}

	/* Find the corresponding chipc region */
	cr = chipc_find_region(sc, rman_get_start(r), rman_get_end(r));
	if (cr == NULL)
		return (EINVAL);

	/* Mark inactive */
	if ((error = rman_deactivate_resource(r)))
		return (error);

	/* Drop associated RF_ACTIVE reference */
	chipc_release_region(sc, cr, RF_ACTIVE);

	return (0);
}
Ejemplo n.º 11
0
static struct resource *
ofwbus_alloc_resource(device_t bus, device_t child, int type, int *rid,
    u_long start, u_long end, u_long count, u_int flags)
{
	struct ofwbus_softc *sc;
	struct rman *rm;
	struct resource *rv;
	struct resource_list_entry *rle;
	int isdefault, passthrough;

	isdefault = (start == 0UL && end == ~0UL);
	passthrough = (device_get_parent(child) != bus);
	sc = device_get_softc(bus);
	rle = NULL;

	if (!passthrough && isdefault) {
		rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child),
		    type, *rid);
		if (rle == NULL)
			return (NULL);
		if (rle->res != NULL)
			panic("%s: resource entry is busy", __func__);
		start = rle->start;
		count = ulmax(count, rle->count);
		end = ulmax(rle->end, start + count - 1);
	}

	switch (type) {
	case SYS_RES_IRQ:
		rm = &sc->sc_intr_rman;
		break;
	case SYS_RES_MEMORY:
		rm = &sc->sc_mem_rman;
		break;
	default:
		return (NULL);
	}

	rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
	    child);
	if (rv == NULL)
		return (NULL);
	rman_set_rid(rv, *rid);

	if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
	    *rid, rv) != 0) {
		rman_release_resource(rv);
		return (NULL);
	}

	if (!passthrough && rle != NULL) {
		rle->res = rv;
		rle->start = rman_get_start(rv);
		rle->end = rman_get_end(rv);
		rle->count = rle->end - rle->start + 1;
	}

	return (rv);
}
Ejemplo n.º 12
0
struct resource *
pcib_host_res_alloc(struct pcib_host_resources *hr, device_t dev, int type,
    int *rid, u_long start, u_long end, u_long count, u_int flags)
{
	struct resource_list_entry *rle;
	struct resource *r;
	u_long new_start, new_end;

	if (flags & RF_PREFETCHABLE)
		KASSERT(type == SYS_RES_MEMORY,
		    ("only memory is prefetchable"));

	rle = resource_list_find(&hr->hr_rl, type, 0);
	if (rle == NULL) {
		/*
		 * No decoding ranges for this resource type, just pass
		 * the request up to the parent.
		 */
		return (bus_generic_alloc_resource(hr->hr_pcib, dev, type, rid,
		    start, end, count, flags));
	}

restart:
	/* Try to allocate from each decoded range. */
	for (; rle != NULL; rle = STAILQ_NEXT(rle, link)) {
		if (rle->type != type)
			continue;
		if (((flags & RF_PREFETCHABLE) != 0) !=
		    ((rle->flags & RLE_PREFETCH) != 0))
			continue;
		new_start = ulmax(start, rle->start);
		new_end = ulmin(end, rle->end);
		if (new_start > new_end ||
		    new_start + count - 1 > new_end ||
		    new_start + count < new_start)
			continue;
		r = bus_generic_alloc_resource(hr->hr_pcib, dev, type, rid,
		    new_start, new_end, count, flags);
		if (r != NULL) {
			if (bootverbose)
				device_printf(hr->hr_pcib,
			    "allocated type %d (%#lx-%#lx) for rid %x of %s\n",
				    type, rman_get_start(r), rman_get_end(r),
				    *rid, pcib_child_name(dev));
			return (r);
		}
	}

	/*
	 * If we failed to find a prefetch range for a memory
	 * resource, try again without prefetch.
	 */
	if (flags & RF_PREFETCHABLE) {
		flags &= ~RF_PREFETCHABLE;
		rle = resource_list_find(&hr->hr_rl, type, 0);
		goto restart;
	}
	return (NULL);
}
Ejemplo n.º 13
0
struct puc_bar *
puc_get_bar(struct puc_softc *sc, int rid)
{
	struct puc_bar *bar;
	struct rman *rm;
	u_long end, start;
	int error, i;

	/* Find the BAR entry with the given RID. */
	i = 0;
	while (i < PUC_PCI_BARS && sc->sc_bar[i].b_rid != rid)
		i++;
	if (i < PUC_PCI_BARS)
		return (&sc->sc_bar[i]);

	/* Not found. If we're looking for an unused entry, return NULL. */
	if (rid == -1)
		return (NULL);

	/* Get an unused entry for us to fill.  */
	bar = puc_get_bar(sc, -1);
	if (bar == NULL)
		return (NULL);
	bar->b_rid = rid;
	bar->b_type = SYS_RES_IOPORT;
	bar->b_res = bus_alloc_resource_any(sc->sc_dev, bar->b_type,
	    &bar->b_rid, RF_ACTIVE);
	if (bar->b_res == NULL) {
		bar->b_rid = rid;
		bar->b_type = SYS_RES_MEMORY;
		bar->b_res = bus_alloc_resource_any(sc->sc_dev, bar->b_type,
		    &bar->b_rid, RF_ACTIVE);
		if (bar->b_res == NULL) {
			bar->b_rid = -1;
			return (NULL);
		}
	}

	/* Update our managed space. */
	rm = (bar->b_type == SYS_RES_IOPORT) ? &sc->sc_ioport : &sc->sc_iomem;
	start = rman_get_start(bar->b_res);
	end = rman_get_end(bar->b_res);
	error = rman_manage_region(rm, start, end);
	if (error) {
		bus_release_resource(sc->sc_dev, bar->b_type, bar->b_rid,
		    bar->b_res);
		bar->b_res = NULL;
		bar->b_rid = -1;
		bar = NULL;
	}

	return (bar);
}
Ejemplo n.º 14
0
/**
 *	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);
}
Ejemplo n.º 15
0
static int
generic_pcie_activate_resource(device_t dev, device_t child, int type,
    int rid, struct resource *r)
{
	struct generic_pcie_core_softc *sc;
	uint64_t phys_base;
	uint64_t pci_base;
	uint64_t size;
	int found;
	int res;
	int i;

	sc = device_get_softc(dev);

	if ((res = rman_activate_resource(r)) != 0)
		return (res);

	switch (type) {
	case SYS_RES_IOPORT:
		found = 0;
		for (i = 0; i < MAX_RANGES_TUPLES; i++) {
			pci_base = sc->ranges[i].pci_base;
			phys_base = sc->ranges[i].phys_base;
			size = sc->ranges[i].size;

			if ((rid > pci_base) && (rid < (pci_base + size))) {
				found = 1;
				break;
			}
		}
		if (found) {
			rman_set_start(r, rman_get_start(r) + phys_base);
			rman_set_end(r, rman_get_end(r) + phys_base);
			res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev),
			    child, type, rid, r);
		} else {
			device_printf(dev,
			    "Failed to activate IOPORT resource\n");
			res = 0;
		}
		break;
	case SYS_RES_MEMORY:
	case SYS_RES_IRQ:
		res = BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child,
		    type, rid, r);
		break;
	default:
		break;
	}

	return (res);
}
Ejemplo n.º 16
0
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);
}
Ejemplo n.º 17
0
/**
 *	omap_teardown_intr 
 *
 *	RETURNS:
 *	0 on success
 */
int
omap_teardown_intr(device_t dev, device_t child, struct resource *res,
					 void *cookie)
{
	unsigned int i;

	/* Mask (disable) all the interrupts in the range ... will probably be only one */
	for (i = rman_get_start(res); (i < NIRQ) && (i <= rman_get_end(res)); i++) {
		arm_mask_irq(i);
	}
	
	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
}
Ejemplo n.º 18
0
/**
 * Retain an RF_ACTIVE reference to the region mapping @p r, and
 * configure @p r with its subregion values.
 *
 * @param sc Driver instance state.
 * @param child Requesting child device.
 * @param type resource type of @p r.
 * @param rid resource id of @p r
 * @param r resource to be activated.
 * @param req_direct If true, failure to allocate a direct bhnd resource
 * will be treated as an error. If false, the resource will not be marked
 * as RF_ACTIVE if bhnd direct resource allocation fails.
 */
static int
chipc_try_activate_resource(struct chipc_softc *sc, device_t child, int type,
    int rid, struct resource *r, bool req_direct)
{
	struct rman		*rm;
	struct chipc_region	*cr;
	bhnd_size_t		 cr_offset;
	rman_res_t		 r_start, r_end, r_size;
	int			 error;

	rm = chipc_get_rman(sc, type);
	if (rm == NULL || !rman_is_region_manager(r, rm))
		return (EINVAL);

	r_start = rman_get_start(r);
	r_end = rman_get_end(r);
	r_size = rman_get_size(r);

	/* Find the corresponding chipc region */
	cr = chipc_find_region(sc, r_start, r_end);
	if (cr == NULL)
		return (EINVAL);
	
	/* Calculate subregion offset within the chipc region */
	cr_offset = r_start - cr->cr_addr;

	/* Retain (and activate, if necessary) the chipc region */
	if ((error = chipc_retain_region(sc, cr, RF_ACTIVE)))
		return (error);

	/* Configure child resource with its subregion values. */
	if (cr->cr_res->direct) {
		error = chipc_init_child_resource(r, cr->cr_res->res,
		    cr_offset, r_size);
		if (error)
			goto cleanup;

		/* Mark active */
		if ((error = rman_activate_resource(r)))
			goto cleanup;
	} else if (req_direct) {
		error = ENOMEM;
		goto cleanup;
	}

	return (0);

cleanup:
	chipc_release_region(sc, cr, RF_ACTIVE);
	return (error);
}
Ejemplo n.º 19
0
/*
 * Allocate a physical address range from our mmio region.
 */
static int
xenpci_alloc_space_int(struct xenpci_softc *scp, size_t sz,
    vm_paddr_t *pa)
{

	if (scp->phys_next + sz > rman_get_end(scp->res_memory)) {
		return (ENOMEM);
	}

	*pa = scp->phys_next;
	scp->phys_next += sz;

	return (0);
}
Ejemplo n.º 20
0
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);
}
Ejemplo n.º 21
0
static int
nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags,
    driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep)
{
	int irq;

	if ((rman_get_flags(res) & RF_SHAREABLE) == 0)
		flags |= INTR_EXCL;

	for (irq = rman_get_start(res); irq <= rman_get_end(res); irq++) {
		arm_setup_irqhandler(device_get_nameunit(child),
		    filt, intr, arg, irq, flags, cookiep);
		arm_unmask_irq(irq);
	}
	return (0);
}
Ejemplo n.º 22
0
/**
 *	omap_setup_intr - initialises and unmasks the IRQ.
 *
 *	RETURNS:
 *	0 on success
 */
int
omap_setup_intr(device_t dev, device_t child,
                struct resource *res, int flags, driver_filter_t *filt, 
                driver_intr_t *intr, void *arg, void **cookiep)    
{
	unsigned int i;

	BUS_SETUP_INTR(device_get_parent(dev), child, res, flags, filt, intr,
				   arg, cookiep);

	/* Enable all the interrupts in the range ... will probably be only one */
	for (i = rman_get_start(res); (i < NIRQ) && (i <= rman_get_end(res)); i++) {
		arm_unmask_irq(i);
	}
	
	return (0);
}
Ejemplo n.º 23
0
Archivo: nexus.c Proyecto: MarginC/kame
static int
nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
			  struct resource *r)
{
	/*
	 * If this is a memory resource, unmap it.
	 */
	if ((rman_get_bustag(r) == I386_BUS_SPACE_MEM) &&
	    (rman_get_end(r) >= 1024 * 1024)) {
		u_int32_t psize;

		psize = rman_get_size(r);
		pmap_unmapdev((vm_offset_t)rman_get_virtual(r), psize);
	}
		
	return (rman_deactivate_resource(r));
}
Ejemplo n.º 24
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);
}
Ejemplo n.º 25
0
static int
chipc_release_resource(device_t dev, device_t child, int type, int rid,
    struct resource *r)
{
	struct chipc_softc		*sc;
	struct chipc_region		*cr;
	struct rman			*rm;
	struct resource_list_entry	*rle;
	int			 	 error;

	sc = device_get_softc(dev);

	/* Handled by parent bus? */
	rm = chipc_get_rman(sc, type);
	if (rm == NULL || !rman_is_region_manager(r, rm)) {
		return (bus_generic_rl_release_resource(dev, child, type, rid,
		    r));
	}

	/* Locate the mapping region */
	cr = chipc_find_region(sc, rman_get_start(r), rman_get_end(r));
	if (cr == NULL)
		return (EINVAL);

	/* Deactivate resources */
	if (rman_get_flags(r) & RF_ACTIVE) {
		error = BUS_DEACTIVATE_RESOURCE(dev, child, type, rid, r);
		if (error)
			return (error);
	}

	if ((error = rman_release_resource(r)))
		return (error);

	/* Drop allocation reference */
	chipc_release_region(sc, cr, RF_ALLOCATED);

	/* Clear reference from the resource list entry if exists */
	rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child), type, rid);
	if (rle != NULL)
		rle->res = NULL;

	return (0);
}
Ejemplo n.º 26
0
static int
s3c24x0_setup_intr(device_t dev, device_t child,
        struct resource *ires,  int flags, driver_filter_t *filt,
	driver_intr_t *intr, void *arg, void **cookiep)
{
	int error, irq;

	error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt,
	    intr, arg, cookiep);
	if (error != 0)
		return (error);

	for (irq = rman_get_start(ires); irq <= rman_get_end(ires); irq++) {
		if (irq >= S3C24X0_EXTIRQ_MIN && irq <= S3C24X0_EXTIRQ_MAX) {
			/* Enable the external interrupt pin */
			s3c24x0_enable_ext_intr(irq - S3C24X0_EXTIRQ_MIN);
		}
	}
	return (0);
}
Ejemplo n.º 27
0
static int
ndis_alloc_amem(struct ndis_softc *sc)
{
	int error, rid = NDIS_AM_RID;

	sc->ndis_res_am = bus_alloc_resource(sc->ndis_dev, SYS_RES_MEMORY,
	    &rid, 0UL, ~0UL, 0x1000, RF_ACTIVE);
	if (sc->ndis_res_am == NULL) {
		device_printf(sc->ndis_dev,
		    "failed to allocate attribute memory\n");
		return (ENXIO);
	}
	sc->ndis_rescnt++;
	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));

	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);
}
Ejemplo n.º 28
0
static int
hme_sbus_attach(device_t dev)
{
	struct hme_sbus_softc *hsc;
	struct hme_softc *sc;
	u_long start, count;
	uint32_t burst;
	int i, error = 0;

	hsc = device_get_softc(dev);
	sc = &hsc->hsc_hme;
	mtx_init(&sc->sc_lock, device_get_nameunit(dev), MTX_NETWORK_LOCK,
	    MTX_DEF);
	/*
	 * Map five register banks:
	 *
	 *	bank 0: HME SEB registers
	 *	bank 1: HME ETX registers
	 *	bank 2: HME ERX registers
	 *	bank 3: HME MAC registers
	 *	bank 4: HME MIF registers
	 *
	 */
	i = 0;
	hsc->hsc_seb_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE);
	if (hsc->hsc_seb_res == NULL) {
		device_printf(dev, "cannot map SEB registers\n");
		error = ENXIO;
		goto fail_mtx_res;
	}
	sc->sc_sebt = rman_get_bustag(hsc->hsc_seb_res);
	sc->sc_sebh = rman_get_bushandle(hsc->hsc_seb_res);

	i = 1;
	hsc->hsc_etx_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE);
	if (hsc->hsc_etx_res == NULL) {
		device_printf(dev, "cannot map ETX registers\n");
		error = ENXIO;
		goto fail_seb_res;
	}
	sc->sc_etxt = rman_get_bustag(hsc->hsc_etx_res);
	sc->sc_etxh = rman_get_bushandle(hsc->hsc_etx_res);

	i = 2;
	hsc->hsc_erx_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE);
	if (hsc->hsc_erx_res == NULL) {
		device_printf(dev, "cannot map ERX registers\n");
		error = ENXIO;
		goto fail_etx_res;
	}
	sc->sc_erxt = rman_get_bustag(hsc->hsc_erx_res);
	sc->sc_erxh = rman_get_bushandle(hsc->hsc_erx_res);

	i = 3;
	hsc->hsc_mac_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE);
	if (hsc->hsc_mac_res == NULL) {
		device_printf(dev, "cannot map MAC registers\n");
		error = ENXIO;
		goto fail_erx_res;
	}
	sc->sc_mact = rman_get_bustag(hsc->hsc_mac_res);
	sc->sc_mach = rman_get_bushandle(hsc->hsc_mac_res);

	/*
	 * At least on some HMEs, the MIF registers seem to be inside the MAC
	 * range, so try to kludge around it.
	 */
	i = 4;
	hsc->hsc_mif_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &i, RF_ACTIVE);
	if (hsc->hsc_mif_res == NULL) {
		if (bus_get_resource(dev, SYS_RES_MEMORY, i,
		    &start, &count) != 0) {
			device_printf(dev, "cannot get MIF registers\n");
			error = ENXIO;
			goto fail_mac_res;
		}
		if (start < rman_get_start(hsc->hsc_mac_res) ||
		    start + count - 1 > rman_get_end(hsc->hsc_mac_res)) {
			device_printf(dev, "cannot move MIF registers to MAC "
			    "bank\n");
			error = ENXIO;
			goto fail_mac_res;
		}
		sc->sc_mift = sc->sc_mact;
		bus_space_subregion(sc->sc_mact, sc->sc_mach,
		    start - rman_get_start(hsc->hsc_mac_res), count,
		    &sc->sc_mifh);
	} else {
		sc->sc_mift = rman_get_bustag(hsc->hsc_mif_res);
		sc->sc_mifh = rman_get_bushandle(hsc->hsc_mif_res);
	}

	i = 0;
	hsc->hsc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &i, RF_SHAREABLE | RF_ACTIVE);
	if (hsc->hsc_ires == NULL) {
		device_printf(dev, "could not allocate interrupt\n");
		error = ENXIO;
		goto fail_mif_res;
	}

	OF_getetheraddr(dev, sc->sc_enaddr);

	burst = sbus_get_burstsz(dev);
	/* Translate into plain numerical format */
	if ((burst & SBUS_BURST_64))
		sc->sc_burst = 64;
	else if ((burst & SBUS_BURST_32))
		sc->sc_burst = 32;
	else if ((burst & SBUS_BURST_16))
		sc->sc_burst = 16;
	else
		 sc->sc_burst = 0;

	sc->sc_dev = dev;
	sc->sc_flags = 0;

	if ((error = hme_config(sc)) != 0) {
		device_printf(dev, "could not be configured\n");
		goto fail_ires;
	}

	if ((error = bus_setup_intr(dev, hsc->hsc_ires, INTR_TYPE_NET |
	    INTR_MPSAFE, NULL, hme_intr, sc, &hsc->hsc_ih)) != 0) {
		device_printf(dev, "couldn't establish interrupt\n");
		hme_detach(sc);
		goto fail_ires;
	}
	return (0);

fail_ires:
	bus_release_resource(dev, SYS_RES_IRQ,
	    rman_get_rid(hsc->hsc_ires), hsc->hsc_ires);
fail_mif_res:
	if (hsc->hsc_mif_res != NULL) {
		bus_release_resource(dev, SYS_RES_MEMORY,
		    rman_get_rid(hsc->hsc_mif_res), hsc->hsc_mif_res);
	}
fail_mac_res:
	bus_release_resource(dev, SYS_RES_MEMORY,
	    rman_get_rid(hsc->hsc_mac_res), hsc->hsc_mac_res);
fail_erx_res:
	bus_release_resource(dev, SYS_RES_MEMORY,
	    rman_get_rid(hsc->hsc_erx_res), hsc->hsc_erx_res);
fail_etx_res:
	bus_release_resource(dev, SYS_RES_MEMORY,
	    rman_get_rid(hsc->hsc_etx_res), hsc->hsc_etx_res);
fail_seb_res:
	bus_release_resource(dev, SYS_RES_MEMORY,
	    rman_get_rid(hsc->hsc_seb_res), hsc->hsc_seb_res);
fail_mtx_res:
	mtx_destroy(&sc->sc_lock);
	return (error);
}
Ejemplo n.º 29
0
static int
mvs_attach(device_t dev)
{
	struct mvs_controller *ctlr = device_get_softc(dev);
	device_t child;
	int	error, unit, i;
	uint32_t devid, revid;

	soc_id(&devid, &revid);
	ctlr->dev = dev;
	i = 0;
	while (mvs_ids[i].id != 0 &&
	    (mvs_ids[i].id != devid ||
	     mvs_ids[i].rev > revid))
		i++;
	ctlr->channels = mvs_ids[i].ports;
	ctlr->quirks = mvs_ids[i].quirks;
	resource_int_value(device_get_name(dev),
	    device_get_unit(dev), "ccc", &ctlr->ccc);
	ctlr->cccc = 8;
	resource_int_value(device_get_name(dev),
	    device_get_unit(dev), "cccc", &ctlr->cccc);
	if (ctlr->ccc == 0 || ctlr->cccc == 0) {
		ctlr->ccc = 0;
		ctlr->cccc = 0;
	}
	if (ctlr->ccc > 100000)
		ctlr->ccc = 100000;
	device_printf(dev,
	    "Gen-%s, %d %sGbps ports, Port Multiplier %s%s\n",
	    ((ctlr->quirks & MVS_Q_GENI) ? "I" :
	     ((ctlr->quirks & MVS_Q_GENII) ? "II" : "IIe")),
	    ctlr->channels,
	    ((ctlr->quirks & MVS_Q_GENI) ? "1.5" : "3"),
	    ((ctlr->quirks & MVS_Q_GENI) ?
	    "not supported" : "supported"),
	    ((ctlr->quirks & MVS_Q_GENIIE) ?
	    " with FBS" : ""));
	mtx_init(&ctlr->mtx, "MVS controller lock", NULL, MTX_DEF);
	/* We should have a memory BAR(0). */
	ctlr->r_rid = 0;
	if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &ctlr->r_rid, RF_ACTIVE)))
		return ENXIO;
	if (ATA_INL(ctlr->r_mem, PORT_BASE(0) + SATA_PHYCFG_OFS) != 0)
		ctlr->quirks |= MVS_Q_SOC65;
	/* Setup our own memory management for channels. */
	ctlr->sc_iomem.rm_start = rman_get_start(ctlr->r_mem);
	ctlr->sc_iomem.rm_end = rman_get_end(ctlr->r_mem);
	ctlr->sc_iomem.rm_type = RMAN_ARRAY;
	ctlr->sc_iomem.rm_descr = "I/O memory addresses";
	if ((error = rman_init(&ctlr->sc_iomem)) != 0) {
		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
		return (error);
	}
	if ((error = rman_manage_region(&ctlr->sc_iomem,
	    rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) {
		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
		rman_fini(&ctlr->sc_iomem);
		return (error);
	}
	mvs_ctlr_setup(dev);
	/* Setup interrupts. */
	if (mvs_setup_interrupt(dev)) {
		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
		rman_fini(&ctlr->sc_iomem);
		return ENXIO;
	}
	/* Attach all channels on this controller */
	for (unit = 0; unit < ctlr->channels; unit++) {
		child = device_add_child(dev, "mvsch", -1);
		if (child == NULL)
			device_printf(dev, "failed to add channel device\n");
		else
			device_set_ivars(child, (void *)(intptr_t)unit);
	}
	bus_generic_attach(dev);
	return 0;
}
Ejemplo n.º 30
0
static int
ebus_attach(device_t dev)
{
	struct ebus_softc *sc;
	struct ebus_devinfo *edi;
	struct ebus_rinfo *eri;
	struct resource *res;
	device_t cdev;
	phandle_t node;
	int i, rnum, rid;

	sc = device_get_softc(dev);

	node = ofw_bus_get_node(dev);
	sc->sc_nrange = OF_getprop_alloc(node, "ranges",
	    sizeof(*sc->sc_range), (void **)&sc->sc_range);
	if (sc->sc_nrange == -1) {
		printf("ebus_attach: could not get ranges property\n");
		return (ENXIO);
	}

	sc->sc_rinfo = malloc(sizeof(*sc->sc_rinfo) * sc->sc_nrange, M_DEVBUF,
	    M_WAITOK | M_ZERO);

	/* For every range, there must be a matching resource. */
	for (rnum = 0; rnum < sc->sc_nrange; rnum++) {
		eri = &sc->sc_rinfo[rnum];
		eri->eri_rtype = ofw_isa_range_restype(&sc->sc_range[rnum]);
		rid = PCIR_BAR(rnum);
		res = bus_alloc_resource_any(dev, eri->eri_rtype, &rid,
		    RF_ACTIVE);
		if (res == NULL) {
			printf("ebus_attach: failed to allocate range "
			    "resource!\n");
			goto fail;
		}
		eri->eri_res = res;
		eri->eri_rman.rm_type = RMAN_ARRAY;
		eri->eri_rman.rm_descr = "EBus range";
		if (rman_init(&eri->eri_rman) != 0) {
			printf("ebus_attach: failed to initialize rman!");
			goto fail;
		}
		if (rman_manage_region(&eri->eri_rman, rman_get_start(res),
		    rman_get_end(res)) != 0) {
			printf("ebus_attach: failed to register region!");
			rman_fini(&eri->eri_rman);
			goto fail;
		}
	}

	ofw_bus_setup_iinfo(node, &sc->sc_iinfo, sizeof(ofw_isa_intr_t));

	/*
	 * Now attach our children.
	 */
	for (node = OF_child(node); node > 0; node = OF_peer(node)) {
		if ((edi = ebus_setup_dinfo(dev, sc, node)) == NULL)
			continue;
		if ((cdev = device_add_child(dev, NULL, -1)) == NULL) {
			device_printf(dev, "<%s>: device_add_child failed\n",
			    edi->edi_obdinfo.obd_name);
			ebus_destroy_dinfo(edi);
			continue;
		}
		device_set_ivars(cdev, edi);
	}
	return (bus_generic_attach(dev));

fail:
	for (i = rnum; i >= 0; i--) {
		eri = &sc->sc_rinfo[i];
		if (i < rnum)
			rman_fini(&eri->eri_rman);
		if (eri->eri_res != 0) {
			bus_release_resource(dev, eri->eri_rtype,
			    PCIR_BAR(rnum), eri->eri_res);
		}
	}
	free(sc->sc_rinfo, M_DEVBUF);
	free(sc->sc_range, M_OFWPROP);
	return (ENXIO);
}