FreeBSD/sys/dev/pci/pci_pci.c
/*
 * We have to trap resource allocation requests and ensure that the bridge
 * is set up to, or capable of handling them.
 */
We have to trap resource allocation requests and ensure that the bridge
is set up to, or capable of handling them.
We have to trap resource allocation requests and ensure that the bridge is set up to or capable of handling them .
struct resource *
pcib_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 pcib_softc	*sc = device_get_softc(dev);
	const char *name, *suffix;
	int ok;
	name = device_get_nameunit(child);
	if (name == NULL) {
		name = "";
		suffix = "";
	} else
		suffix = " ";
	switch (type) {
	case SYS_RES_IOPORT:
		ok = 0;
		if (!pcib_is_io_open(sc))
			break;
		ok = (start >= sc->iobase && end <= sc->iolimit);
		if (!ok && pci_is_vga_ioport_range(start, end))
			ok = (sc->bridgectl & PCIB_BCR_VGA_ENABLE) ? 1 : 0;
		if ((sc->flags & PCIB_SUBTRACTIVE) == 0) {
			if (!ok) {
				if (start < sc->iobase)
					start = sc->iobase;
				if (end > sc->iolimit)
					end = sc->iolimit;
				if (start < end)
					ok = 1;
			}
		} else {
			ok = 1;
#if 0
			if (start < sc->iolimit && end > sc->iobase)
				start = sc->iolimit + 1;
#endif
		}
		if (end < start) {
			device_printf(dev, "ioport: end (%jx) < start (%jx)\n",
			    end, start);
			start = 0;
			end = 0;
			ok = 0;
		}
		if (!ok) {
			device_printf(dev, "%s%srequested unsupported I/O "
			    "range 0x%jx-0x%jx (decoding 0x%x-0x%x)\n",
			    name, suffix, start, end, sc->iobase, sc->iolimit);
			return (NULL);
		}
		if (bootverbose)
			device_printf(dev,
			    "%s%srequested I/O range 0x%jx-0x%jx: in range\n",
			    name, suffix, start, end);
		break;
	case SYS_RES_MEMORY:
		ok = 0;
		if (pcib_is_nonprefetch_open(sc))
			ok = ok || (start >= sc->membase && end <= sc->memlimit);
		if (pcib_is_prefetch_open(sc))
			ok = ok || (start >= sc->pmembase && end <= sc->pmemlimit);
		if (!ok && pci_is_vga_memory_range(start, end))
			ok = (sc->bridgectl & PCIB_BCR_VGA_ENABLE) ? 1 : 0;
		if ((sc->flags & PCIB_SUBTRACTIVE) == 0) {
			if (!ok) {
				ok = 1;
				if (flags & RF_PREFETCHABLE) {
					if (pcib_is_prefetch_open(sc)) {
						if (start < sc->pmembase)
							start = sc->pmembase;
						if (end > sc->pmemlimit)
							end = sc->pmemlimit;
					} else {
						ok = 0;
					}
				} else {	
					if (pcib_is_nonprefetch_open(sc)) {
						if (start < sc->membase)
							start = sc->membase;
						if (end > sc->memlimit)
							end = sc->memlimit;
					} else {
						ok = 0;
					}
				}
			}
		} else if (!ok) {
			ok = 1;	
#if 0
			if (pcib_is_nonprefetch_open(sc)) {
				if (start < sc->memlimit && end > sc->membase)
					start = sc->memlimit + 1;
			}
			if (pcib_is_prefetch_open(sc)) {
				if (start < sc->pmemlimit && end > sc->pmembase)
					start = sc->pmemlimit + 1;
			}
#endif
		}
		if (end < start) {
			device_printf(dev, "memory: end (%jx) < start (%jx)\n",
			    end, start);
			start = 0;
			end = 0;
			ok = 0;
		}
		if (!ok && bootverbose)
			device_printf(dev,
			    "%s%srequested unsupported memory range %#jx-%#jx "
			    "(decoding %#jx-%#jx, %#jx-%#jx)\n",
			    name, suffix, start, end,
			    (uintmax_t)sc->membase, (uintmax_t)sc->memlimit,
			    (uintmax_t)sc->pmembase, (uintmax_t)sc->pmemlimit);
		if (!ok)
			return (NULL);
		if (bootverbose)
			device_printf(dev,"%s%srequested memory range "
			    "0x%jx-0x%jx: good\n",
			    name, suffix, start, end);
		break;
	default:
		break;
	}
	return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
	    count, flags));
}
struct resource * pcib_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 pcib_softc * sc = device_get_softc ( dev ) ; const char * name , * suffix ; int ok ; name = device_get_nameunit ( child ) ; if ( name == NULL ) { name = " " ; suffix = " " ; } else suffix = " " ; switch ( type ) { case SYS_RES_IOPORT : ok = 0 ; if ( ! pcib_is_io_open ( sc ) ) break ; ok = ( start >= sc -> iobase && end <= sc -> iolimit ) ; if ( ! ok && pci_is_vga_ioport_range ( start , end ) ) ok = ( sc -> bridgectl & PCIB_BCR_VGA_ENABLE ) ? 1 : 0 ; if ( ( sc -> flags & PCIB_SUBTRACTIVE ) == 0 ) { if ( ! ok ) { if ( start < sc -> iobase ) start = sc -> iobase ; if ( end > sc -> iolimit ) end = sc -> iolimit ; if ( start < end ) ok = 1 ; } } else { ok = 1 ; #if 0 if ( start < sc -> iolimit && end > sc -> iobase ) start = sc -> iolimit + 1 ; #endif } if ( end < start ) { device_printf ( dev , " \n " , end , start ) ; start = 0 ; end = 0 ; ok = 0 ; } if ( ! ok ) { device_printf ( dev , " " " \n " , name , suffix , start , end , sc -> iobase , sc -> iolimit ) ; return ( NULL ) ; } if ( bootverbose ) device_printf ( dev , " \n " , name , suffix , start , end ) ; break ; case SYS_RES_MEMORY : ok = 0 ; if ( pcib_is_nonprefetch_open ( sc ) ) ok = ok || ( start >= sc -> membase && end <= sc -> memlimit ) ; if ( pcib_is_prefetch_open ( sc ) ) ok = ok || ( start >= sc -> pmembase && end <= sc -> pmemlimit ) ; if ( ! ok && pci_is_vga_memory_range ( start , end ) ) ok = ( sc -> bridgectl & PCIB_BCR_VGA_ENABLE ) ? 1 : 0 ; if ( ( sc -> flags & PCIB_SUBTRACTIVE ) == 0 ) { if ( ! ok ) { ok = 1 ; if ( flags & RF_PREFETCHABLE ) { if ( pcib_is_prefetch_open ( sc ) ) { if ( start < sc -> pmembase ) start = sc -> pmembase ; if ( end > sc -> pmemlimit ) end = sc -> pmemlimit ; } else { ok = 0 ; } } else { if ( pcib_is_nonprefetch_open ( sc ) ) { if ( start < sc -> membase ) start = sc -> membase ; if ( end > sc -> memlimit ) end = sc -> memlimit ; } else { ok = 0 ; } } } } else if ( ! ok ) { ok = 1 ; #if 0 if ( pcib_is_nonprefetch_open ( sc ) ) { if ( start < sc -> memlimit && end > sc -> membase ) start = sc -> memlimit + 1 ; } if ( pcib_is_prefetch_open ( sc ) ) { if ( start < sc -> pmemlimit && end > sc -> pmembase ) start = sc -> pmemlimit + 1 ; } #endif } if ( end < start ) { device_printf ( dev , " \n " , end , start ) ; start = 0 ; end = 0 ; ok = 0 ; } if ( ! ok && bootverbose ) device_printf ( dev , " " " \n " , name , suffix , start , end , ( uintmax_t ) sc -> membase , ( uintmax_t ) sc -> memlimit , ( uintmax_t ) sc -> pmembase , ( uintmax_t ) sc -> pmemlimit ) ; if ( ! ok ) return ( NULL ) ; if ( bootverbose ) device_printf ( dev , " " " \n " , name , suffix , start , end ) ; break ; default : break ; } return ( bus_generic_alloc_resource ( dev , child , type , rid , start , end , count , flags ) ) ; }
We have to trap resource allocation requests and ensure that the bridge
 is set up to, or capable of handling them.
We have to trap resource allocation requests and ensure that the bridge is set up to or capable of handling them .
/*
	 * Fail the allocation for this range if it's not supported.
	 */ /*
		 * Make sure we allow access to VGA I/O addresses when the
		 * bridge has the "VGA Enable" bit set.
		 */ /*
			 * If we overlap with the subtractive range, then
			 * pick the upper range to use.
			 */ /*
		 * Make sure we allow access to VGA memory addresses when the
		 * bridge has the "VGA Enable" bit set.
		 */ /* non-prefetchable */ /* subtractive bridge: always ok */ /*
	 * Bridge is OK decoding this resource, so pass it up.
	 */