FreeBSD/sys/dev/pci/pci_pci.c
/* Allocate a fresh resource range for an unconfigured window. */
Allocate a fresh resource range for an unconfigured window.
Allocate a fresh resource range for an unconfigured window .
static int
pcib_alloc_new_window(struct pcib_softc *sc, struct pcib_window *w, int type,
    rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
	struct resource *res;
	rman_res_t base, limit, wmask;
	int rid;
	if (type == SYS_RES_IOPORT && sc->bridgectl & PCIB_BCR_ISA_ENABLE &&
	    start < 65536) {
		for (base = 0xf000; (long)base >= 0; base -= 0x1000) {
			limit = base + 0xfff;
			if (start + count > limit - 0x400)
				continue;
			if (base == 0) {
				if (end - count + 1 < 0x400)
					continue;
			} else {
				if (end - count + 1 < base)
					continue;
			}
			if (pcib_alloc_nonisa_ranges(sc, base, limit) == 0) {
				w->base = base;
				w->limit = limit;
				return (0);
			}
		}
		return (ENOSPC);
	}
	wmask = ((rman_res_t)1 << w->step) - 1;
	if (RF_ALIGNMENT(flags) < w->step) {
		flags &= ~RF_ALIGNMENT_MASK;
		flags |= RF_ALIGNMENT_LOG2(w->step);
	}
	start &= ~wmask;
	end |= wmask;
	count = roundup2(count, (rman_res_t)1 << w->step);
	rid = w->reg;
	res = bus_alloc_resource(sc->dev, type, &rid, start, end, count,
	    flags & ~RF_ACTIVE);
	if (res == NULL)
		return (ENOSPC);
	pcib_add_window_resources(w, &res, 1);
	pcib_activate_window(sc, type);
	w->base = rman_get_start(res);
	w->limit = rman_get_end(res);
	return (0);
}
static int pcib_alloc_new_window ( struct pcib_softc * sc , struct pcib_window * w , int type , rman_res_t start , rman_res_t end , rman_res_t count , u_int flags ) { struct resource * res ; rman_res_t base , limit , wmask ; int rid ; if ( type == SYS_RES_IOPORT && sc -> bridgectl & PCIB_BCR_ISA_ENABLE && start < 65536 ) { for ( base = 0xf000 ; ( long ) base >= 0 ; base -= 0x1000 ) { limit = base + 0xfff ; if ( start + count > limit - 0x400 ) continue ; if ( base == 0 ) { if ( end - count + 1 < 0x400 ) continue ; } else { if ( end - count + 1 < base ) continue ; } if ( pcib_alloc_nonisa_ranges ( sc , base , limit ) == 0 ) { w -> base = base ; w -> limit = limit ; return ( 0 ) ; } } return ( ENOSPC ) ; } wmask = ( ( rman_res_t ) 1 << w -> step ) - 1 ; if ( RF_ALIGNMENT ( flags ) < w -> step ) { flags &= ~ RF_ALIGNMENT_MASK ; flags |= RF_ALIGNMENT_LOG2 ( w -> step ) ; } start &= ~ wmask ; end |= wmask ; count = roundup2 ( count , ( rman_res_t ) 1 << w -> step ) ; rid = w -> reg ; res = bus_alloc_resource ( sc -> dev , type , & rid , start , end , count , flags & ~ RF_ACTIVE ) ; if ( res == NULL ) return ( ENOSPC ) ; pcib_add_window_resources ( w , & res , 1 ) ; pcib_activate_window ( sc , type ) ; w -> base = rman_get_start ( res ) ; w -> limit = rman_get_end ( res ) ; return ( 0 ) ; }
Allocate a fresh resource range for an unconfigured window.
Allocate a fresh resource range for an unconfigured window .
/*
	 * If this is an I/O window on a bridge with ISA enable set
	 * and the start address is below 64k, then try to allocate an
	 * initial window of 0x1000 bytes long starting at address
	 * 0xf000 and walking down.  Note that if the original request
	 * was larger than the non-aliased range size of 0x100 our
	 * caller would have raised the start address up to 64k
	 * already.
	 */ /*
			 * Skip ranges that wouldn't work for the
			 * original request.  Note that the actual
			 * window that overlaps are the non-alias
			 * ranges within [base, limit], so this isn't
			 * quite a simple comparison.
			 */ /*
				 * The first open region for the window at
				 * 0 is 0x400-0x4ff.
				 */