FreeBSD/sys/dev/pci/pci_pci.c
/* Try to expand an existing window to the requested base and limit. */
Try to expand an existing window to the requested base and limit.
Try to expand an existing window to the requested base and limit .
static int
pcib_expand_window(struct pcib_softc *sc, struct pcib_window *w, int type,
    rman_res_t base, rman_res_t limit)
{
	struct resource *res;
	int error, i, force_64k_base;
	KASSERT(base <= w->base && limit >= w->limit,
	    ("attempting to shrink window"));
	KASSERT(limit == w->limit || base == w->base,
	    ("attempting to grow both ends of a window"));
	if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE &&
	    (limit <= 65535 || (base <= 65535 && base != w->base))) {
		KASSERT(limit == w->limit || limit <= 65535,
		    ("attempting to grow both ends across 64k ISA alias"));
		if (base != w->base)
			error = pcib_alloc_nonisa_ranges(sc, base, w->base - 1);
		else
			error = pcib_alloc_nonisa_ranges(sc, w->limit + 1,
			    limit);
		if (error == 0) {
			w->base = base;
			w->limit = limit;
		}
		return (error);
	}
	for (i = 0; i < w->count; i++) {
		if (rman_get_end(w->res[i]) == w->limit)
			break;
	}
	KASSERT(i != w->count, ("did not find existing resource"));
	res = w->res[i];
	if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE &&
	    w->base <= 65535) {
		KASSERT(rman_get_start(res) == 65536,
		    ("existing resource mismatch"));
		force_64k_base = 1;
	} else {
		KASSERT(w->base == rman_get_start(res),
		    ("existing resource mismatch"));
		force_64k_base = 0;
	}
	error = bus_adjust_resource(sc->dev, type, res, force_64k_base ?
	    rman_get_start(res) : base, limit);
	if (error)
		return (error);
	if (w->base != base) {
		error = rman_manage_region(&w->rman, base, w->base - 1);
		w->base = base;
	} else {
		error = rman_manage_region(&w->rman, w->limit + 1, limit);
		w->limit = limit;
	}
	if (error) {
		if (bootverbose)
			device_printf(sc->dev,
			    "failed to expand %s resource manager\n", w->name);
		(void)bus_adjust_resource(sc->dev, type, res, force_64k_base ?
		    rman_get_start(res) : w->base, w->limit);
	}
	return (error);
}
static int pcib_expand_window ( struct pcib_softc * sc , struct pcib_window * w , int type , rman_res_t base , rman_res_t limit ) { struct resource * res ; int error , i , force_64k_base ; KASSERT ( base <= w -> base && limit >= w -> limit , ( " " ) ) ; KASSERT ( limit == w -> limit || base == w -> base , ( " " ) ) ; if ( type == SYS_RES_IOPORT && sc -> bridgectl & PCIB_BCR_ISA_ENABLE && ( limit <= 65535 || ( base <= 65535 && base != w -> base ) ) ) { KASSERT ( limit == w -> limit || limit <= 65535 , ( " " ) ) ; if ( base != w -> base ) error = pcib_alloc_nonisa_ranges ( sc , base , w -> base - 1 ) ; else error = pcib_alloc_nonisa_ranges ( sc , w -> limit + 1 , limit ) ; if ( error == 0 ) { w -> base = base ; w -> limit = limit ; } return ( error ) ; } for ( i = 0 ; i < w -> count ; i ++ ) { if ( rman_get_end ( w -> res [ i ] ) == w -> limit ) break ; } KASSERT ( i != w -> count , ( " " ) ) ; res = w -> res [ i ] ; if ( type == SYS_RES_IOPORT && sc -> bridgectl & PCIB_BCR_ISA_ENABLE && w -> base <= 65535 ) { KASSERT ( rman_get_start ( res ) == 65536 , ( " " ) ) ; force_64k_base = 1 ; } else { KASSERT ( w -> base == rman_get_start ( res ) , ( " " ) ) ; force_64k_base = 0 ; } error = bus_adjust_resource ( sc -> dev , type , res , force_64k_base ? rman_get_start ( res ) : base , limit ) ; if ( error ) return ( error ) ; if ( w -> base != base ) { error = rman_manage_region ( & w -> rman , base , w -> base - 1 ) ; w -> base = base ; } else { error = rman_manage_region ( & w -> rman , w -> limit + 1 , limit ) ; w -> limit = limit ; } if ( error ) { if ( bootverbose ) device_printf ( sc -> dev , " \n " , w -> name ) ; ( void ) bus_adjust_resource ( sc -> dev , type , res , force_64k_base ? rman_get_start ( res ) : w -> base , w -> limit ) ; } return ( error ) ; }
Try to expand an existing window to the requested base and limit.
Try to expand an existing window to the requested base and limit .
/*
	 * XXX: pcib_grow_window() doesn't try to do this anyway and
	 * the error handling for all the edge cases would be tedious.
	 */ /*
	 * Yet more special handling for requests to expand an I/O
	 * window behind an ISA-enabled bridge.  Since I/O windows
	 * have to grow in 0x1000 increments and the end of the 0xffff
	 * range is an alias, growing a window below 64k will always
	 * result in allocating new resources and never adjusting an
	 * existing resource.
	 */ /*
	 * Find the existing resource to adjust.  Usually there is only one,
	 * but for an ISA-enabled bridge we might be growing the I/O window
	 * above 64k and need to find the existing resource that maps all
	 * of the area above 64k.
	 */ /*
	 * Usually the resource we found should match the window's
	 * existing range.  The one exception is the ISA-enabled case
	 * mentioned above in which case the resource should start at
	 * 64k.
	 */ /* Add the newly allocated region to the resource manager. */