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;
	struct resource *r;
	sc = device_get_softc(dev);
	if ((type == SYS_RES_IOPORT && pci_is_vga_ioport_range(start, end)) ||
	    (type == SYS_RES_MEMORY && pci_is_vga_memory_range(start, end))) {
		if (sc->bridgectl & PCIB_BCR_VGA_ENABLE)
			return (bus_generic_alloc_resource(dev, child, type,
			    rid, start, end, count, flags));
		else
			return (NULL);
	}
	switch (type) {
#ifdef PCI_RES_BUS
	case PCI_RES_BUS:
		return (pcib_alloc_subbus(&sc->bus, child, rid, start, end,
		    count, flags));
#endif
	case SYS_RES_IOPORT:
		if (pcib_is_isa_range(sc, start, end, count))
			return (NULL);
		r = pcib_suballoc_resource(sc, &sc->io, child, type, rid, start,
		    end, count, flags);
		if (r != NULL || (sc->flags & PCIB_SUBTRACTIVE) != 0)
			break;
		if (pcib_grow_window(sc, &sc->io, type, start, end, count,
		    flags) == 0)
			r = pcib_suballoc_resource(sc, &sc->io, child, type,
			    rid, start, end, count, flags);
		break;
	case SYS_RES_MEMORY:
		if (flags & RF_PREFETCHABLE) {
			r = pcib_suballoc_resource(sc, &sc->pmem, child, type,
			    rid, start, end, count, flags);
			if (r != NULL)
				break;
		}
		r = pcib_suballoc_resource(sc, &sc->mem, child, type, rid,
		    start, end, count, flags);
		if (r != NULL || (sc->flags & PCIB_SUBTRACTIVE) != 0)
			break;
		if (flags & RF_PREFETCHABLE) {
			if (pcib_grow_window(sc, &sc->pmem, type, start, end,
			    count, flags) == 0) {
				r = pcib_suballoc_resource(sc, &sc->pmem, child,
				    type, rid, start, end, count, flags);
				if (r != NULL)
					break;
			}
		}
		if (pcib_grow_window(sc, &sc->mem, type, start, end, count,
		    flags & ~RF_PREFETCHABLE) == 0)
			r = pcib_suballoc_resource(sc, &sc->mem, child, type,
			    rid, start, end, count, flags);
		break;
	default:
		return (bus_generic_alloc_resource(dev, child, type, rid,
		    start, end, count, flags));
	}
	if (sc->flags & PCIB_SUBTRACTIVE && r == NULL)
		return (bus_generic_alloc_resource(dev, child, type, rid,
		    start, end, count, flags));
	return (r);
}
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 ; struct resource * r ; sc = device_get_softc ( dev ) ; if ( ( type == SYS_RES_IOPORT && pci_is_vga_ioport_range ( start , end ) ) || ( type == SYS_RES_MEMORY && pci_is_vga_memory_range ( start , end ) ) ) { if ( sc -> bridgectl & PCIB_BCR_VGA_ENABLE ) return ( bus_generic_alloc_resource ( dev , child , type , rid , start , end , count , flags ) ) ; else return ( NULL ) ; } switch ( type ) { #ifdef PCI_RES_BUS case PCI_RES_BUS : return ( pcib_alloc_subbus ( & sc -> bus , child , rid , start , end , count , flags ) ) ; #endif case SYS_RES_IOPORT : if ( pcib_is_isa_range ( sc , start , end , count ) ) return ( NULL ) ; r = pcib_suballoc_resource ( sc , & sc -> io , child , type , rid , start , end , count , flags ) ; if ( r != NULL || ( sc -> flags & PCIB_SUBTRACTIVE ) != 0 ) break ; if ( pcib_grow_window ( sc , & sc -> io , type , start , end , count , flags ) == 0 ) r = pcib_suballoc_resource ( sc , & sc -> io , child , type , rid , start , end , count , flags ) ; break ; case SYS_RES_MEMORY : if ( flags & RF_PREFETCHABLE ) { r = pcib_suballoc_resource ( sc , & sc -> pmem , child , type , rid , start , end , count , flags ) ; if ( r != NULL ) break ; } r = pcib_suballoc_resource ( sc , & sc -> mem , child , type , rid , start , end , count , flags ) ; if ( r != NULL || ( sc -> flags & PCIB_SUBTRACTIVE ) != 0 ) break ; if ( flags & RF_PREFETCHABLE ) { if ( pcib_grow_window ( sc , & sc -> pmem , type , start , end , count , flags ) == 0 ) { r = pcib_suballoc_resource ( sc , & sc -> pmem , child , type , rid , start , end , count , flags ) ; if ( r != NULL ) break ; } } if ( pcib_grow_window ( sc , & sc -> mem , type , start , end , count , flags & ~ RF_PREFETCHABLE ) == 0 ) r = pcib_suballoc_resource ( sc , & sc -> mem , child , type , rid , start , end , count , flags ) ; break ; default : return ( bus_generic_alloc_resource ( dev , child , type , rid , start , end , count , flags ) ) ; } if ( sc -> flags & PCIB_SUBTRACTIVE && r == NULL ) return ( bus_generic_alloc_resource ( dev , child , type , rid , start , end , count , flags ) ) ; return ( r ) ; }
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 .
/*
	 * VGA resources are decoded iff the VGA enable bit is set in
	 * the bridge control register.  VGA resources do not fall into
	 * the resource windows and are passed up to the parent.
	 */ /*
		 * For prefetchable resources, prefer the prefetchable
		 * memory window, but fall back to the regular memory
		 * window if that fails.  Try both windows before
		 * attempting to grow a window in case the firmware
		 * has used a range in the regular memory window to
		 * map a prefetchable BAR.
		 */ /*
	 * If attempts to suballocate from the window fail but this is a
	 * subtractive bridge, pass the request up the tree.
	 */