FreeBSD/sys/sparc64/sparc64/iommu.c
/*
 * Try to find or allocate a slab of DVMA space; see above.
 */
Try to find or allocate a slab of DVMA space; see above.
Try to find or allocate a slab of DVMA space ; see above .
static int
iommu_dvma_vallocseg(bus_dma_tag_t dt, struct iommu_state *is, bus_dmamap_t map,
    vm_offset_t voffs, bus_size_t size, bus_addr_t amask, bus_addr_t *addr)
{
	bus_dmamap_t tm, last;
	bus_addr_t dvmaddr, freed;
	int error, complete = 0;
	dvmaddr = iommu_dvma_vfindseg(map, voffs, size, amask);
	if (dvmaddr == 0) {
		while ((error = iommu_dvma_valloc(dt, is, map,
			voffs + size)) == ENOMEM && !complete) {
			IS_LOCK(is);
			freed = 0;
			last = TAILQ_LAST(&is->is_maplruq, iommu_maplruq_head);
			do {
				tm = TAILQ_FIRST(&is->is_maplruq);
				complete = tm == last;
				if (tm == NULL)
					break;
				freed += iommu_dvma_vprune(is, tm);
				iommu_map_insq(is, tm);
			} while (freed < size && !complete);
			IS_UNLOCK(is);
		}
		if (error != 0)
			return (error);
		dvmaddr = iommu_dvma_vfindseg(map, voffs, size, amask);
		KASSERT(dvmaddr != 0, ("%s: allocation failed unexpectedly!",
		    __func__));
	}
	*addr = dvmaddr;
	return (0);
}
static int iommu_dvma_vallocseg ( bus_dma_tag_t dt , struct iommu_state * is , bus_dmamap_t map , vm_offset_t voffs , bus_size_t size , bus_addr_t amask , bus_addr_t * addr ) { bus_dmamap_t tm , last ; bus_addr_t dvmaddr , freed ; int error , complete = 0 ; dvmaddr = iommu_dvma_vfindseg ( map , voffs , size , amask ) ; if ( dvmaddr == 0 ) { while ( ( error = iommu_dvma_valloc ( dt , is , map , voffs + size ) ) == ENOMEM && ! complete ) { IS_LOCK ( is ) ; freed = 0 ; last = TAILQ_LAST ( & is -> is_maplruq , iommu_maplruq_head ) ; do { tm = TAILQ_FIRST ( & is -> is_maplruq ) ; complete = tm == last ; if ( tm == NULL ) break ; freed += iommu_dvma_vprune ( is , tm ) ; iommu_map_insq ( is , tm ) ; } while ( freed < size && ! complete ) ; IS_UNLOCK ( is ) ; } if ( error != 0 ) return ( error ) ; dvmaddr = iommu_dvma_vfindseg ( map , voffs , size , amask ) ; KASSERT ( dvmaddr != 0 , ( " " , __func__ ) ) ; } * addr = dvmaddr ; return ( 0 ) ; }
Try to find or allocate a slab of DVMA space; see above.
Try to find or allocate a slab of DVMA space ; see above .
/* Need to allocate. */ /*
			 * Free the allocated DVMA of a few maps until
			 * the required size is reached. This is an
			 * approximation to not have to call the allocation
			 * function too often; most likely one free run
			 * will not suffice if not one map was large enough
			 * itself due to fragmentation.
			 */ /* Move to the end. */