Beispiel #1
0
int
i386_memio_subregion(bus_space_tag_t t, bus_space_handle_t pbsh,
                     bus_size_t offset, bus_size_t size,
                     bus_space_handle_t *tbshp)
{
    int i, error = 0;
    bus_space_handle_t bsh;
    bus_addr_t pbase;

    pbase = pbsh->bsh_base + offset;
    switch (t->bs_tag) {
    case BUS_SPACE_TAG_IO:
        if (pbsh->bsh_iatsz > 0) {
            if (offset >= pbsh->bsh_iatsz ||
                    offset + size > pbsh->bsh_iatsz)
                return EINVAL;
            pbase = pbsh->bsh_base;
        }
        break;

    case BUS_SPACE_TAG_MEM:
        if (pbsh->bsh_iatsz > 0)
            return EINVAL;
        if (offset > pbsh->bsh_sz || offset + size > pbsh->bsh_sz)
            return EINVAL;
        break;

    default:
        panic("i386_memio_subregion: bad bus space tag");
        break;
    }

    error = i386_bus_space_handle_alloc(t, pbase, size, &bsh);
    if (error != 0)
        return error;

    switch (t->bs_tag) {
    case BUS_SPACE_TAG_IO:
        if (pbsh->bsh_iatsz > 0) {
            for (i = 0; i < size; i ++)
                bsh->bsh_iat[i] = pbsh->bsh_iat[i + offset];
            bsh->bsh_iatsz = size;
        } else if (pbsh->bsh_base > bsh->bsh_base ||
                   pbsh->bsh_base + pbsh->bsh_sz <
                   bsh->bsh_base + bsh->bsh_sz) {
            i386_bus_space_handle_free(t, bsh, size);
            return EINVAL;
        }
        break;

    case BUS_SPACE_TAG_MEM:
        break;
    }

    if (pbsh->bsh_iatsz > 0)
        bsh->bsh_bam = t->bs_ra;	/* relocate access */
    *tbshp = bsh;
    return error;
}
Beispiel #2
0
static int
nexus_release_resource(device_t bus, device_t child, int type, int rid,
		       struct resource *r)
{
	if (rman_get_flags(r) & RF_ACTIVE) {
		int error = bus_deactivate_resource(child, type, rid, r);
		if (error)
			return error;
	}
#ifdef PC98
	if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
		i386_bus_space_handle_free(r->r_bustag, r->r_bushandle,
					   r->r_bushandle->bsh_sz);
	}
#endif
	return (rman_release_resource(r));
}
Beispiel #3
0
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 (type == SYS_RES_MEMORY) {
		pmap_unmapdev((vm_offset_t)rman_get_virtual(r),
		    rman_get_size(r));
	}
#ifdef PC98
	if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
		bus_space_handle_t bh;

		bh = rman_get_bushandle(r);
		i386_bus_space_handle_free(rman_get_bustag(r), bh, bh->bsh_sz);
	}
#endif
	return (rman_deactivate_resource(r));
}
Beispiel #4
0
/*
 * Allocate a resource on behalf of child.  NB: child is usually going to be a
 * child of one of our descendants, not a direct child of nexus0.
 * (Exceptions include npx.)
 */
static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
		     u_long start, u_long end, u_long count, u_int flags)
{
	struct nexus_device *ndev = DEVTONX(child);
	struct	resource *rv;
	struct resource_list_entry *rle;
	struct	rman *rm;
	int needactivate = flags & RF_ACTIVE;

	/*
	 * If this is an allocation of the "default" range for a given RID, and
	 * we know what the resources for this device are (ie. they aren't maintained
	 * by a child bus), then work out the start/end values.
	 */
	if ((start == 0UL) && (end == ~0UL) && (count == 1)) {
		if (ndev == NULL)
			return(NULL);
		rle = resource_list_find(&ndev->nx_resources, type, *rid);
		if (rle == NULL)
			return(NULL);
		start = rle->start;
		end = rle->end;
		count = rle->count;
	}

	flags &= ~RF_ACTIVE;

	switch (type) {
	case SYS_RES_IRQ:
		rm = &irq_rman;
		break;

	case SYS_RES_DRQ:
		rm = &drq_rman;
		break;

	case SYS_RES_IOPORT:
		rm = &port_rman;
		break;

	case SYS_RES_MEMORY:
		rm = &mem_rman;
		break;

	default:
		return 0;
	}

	rv = rman_reserve_resource(rm, start, end, count, flags, child);
	if (rv == 0)
		return 0;

	if (type == SYS_RES_MEMORY) {
		rman_set_bustag(rv, I386_BUS_SPACE_MEM);
	} else if (type == SYS_RES_IOPORT) {
		rman_set_bustag(rv, I386_BUS_SPACE_IO);
#ifndef PC98
		rman_set_bushandle(rv, rv->r_start);
#endif
	}

#ifdef PC98
	if ((type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) &&
	    i386_bus_space_handle_alloc(rv->r_bustag, rv->r_start, count,
					&rv->r_bushandle) != 0) {
		rman_release_resource(rv);
		return 0;
	}
#endif

	if (needactivate) {
		if (bus_activate_resource(child, type, *rid, rv)) {
#ifdef PC98
			if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
				i386_bus_space_handle_free(rv->r_bustag,
				    rv->r_bushandle, rv->r_bushandle->bsh_sz);
			}
#endif
			rman_release_resource(rv);
			return 0;
		}
	}
	
	return rv;
}
Beispiel #5
0
void
i386_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
{

    i386_bus_space_handle_free(t, bsh, bsh->bsh_sz);
}