FreeBSD/sys/powerpc/powerpc/busdma_machdep.c
/*
 * Utility function to load a linear buffer.  segp contains
 * the starting segment on entrance, and the ending segment on exit.
 */
Utility function to load a linear buffer.  segp contains
the starting segment on entrance, and the ending segment on exit.
Utility function to load a linear buffer . segp contains the starting segment on entrance and the ending segment on exit .
int
_bus_dmamap_load_buffer(bus_dma_tag_t dmat,
    			bus_dmamap_t map,
			void *buf, bus_size_t buflen,
			pmap_t pmap,
			int flags,
			bus_dma_segment_t *segs,
			int *segp)
{
	bus_size_t sgsize;
	bus_addr_t curaddr;
	vm_offset_t vaddr;
	int error;
	if (segs == NULL)
		segs = map->segments;
	if ((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) {
		_bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, flags);
		if (map->pagesneeded != 0) {
			error = _bus_dmamap_reserve_pages(dmat, map, flags);
			if (error)
				return (error);
		}
	}
	vaddr = (vm_offset_t)buf;
	while (buflen > 0) {
		bus_size_t max_sgsize;
		if (pmap == kernel_pmap)
			curaddr = pmap_kextract(vaddr);
		else
			curaddr = pmap_extract(pmap, vaddr);
		max_sgsize = MIN(buflen, dmat->maxsegsz);
		sgsize = PAGE_SIZE - ((vm_offset_t)curaddr & PAGE_MASK);
		if (map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
			sgsize = roundup2(sgsize, dmat->alignment);
			sgsize = MIN(sgsize, max_sgsize);
			curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
			    sgsize);
		} else {
			sgsize = MIN(sgsize, max_sgsize);
		}
		sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
		    segp);
		if (sgsize == 0)
			break;
		vaddr += sgsize;
		buflen -= sgsize;
	}
	return (buflen != 0 ? EFBIG : 0); 
}
int _bus_dmamap_load_buffer ( bus_dma_tag_t dmat , bus_dmamap_t map , void * buf , bus_size_t buflen , pmap_t pmap , int flags , bus_dma_segment_t * segs , int * segp ) { bus_size_t sgsize ; bus_addr_t curaddr ; vm_offset_t vaddr ; int error ; if ( segs == NULL ) segs = map -> segments ; if ( ( dmat -> flags & BUS_DMA_COULD_BOUNCE ) != 0 ) { _bus_dmamap_count_pages ( dmat , map , pmap , buf , buflen , flags ) ; if ( map -> pagesneeded != 0 ) { error = _bus_dmamap_reserve_pages ( dmat , map , flags ) ; if ( error ) return ( error ) ; } } vaddr = ( vm_offset_t ) buf ; while ( buflen > 0 ) { bus_size_t max_sgsize ; if ( pmap == kernel_pmap ) curaddr = pmap_kextract ( vaddr ) ; else curaddr = pmap_extract ( pmap , vaddr ) ; max_sgsize = MIN ( buflen , dmat -> maxsegsz ) ; sgsize = PAGE_SIZE - ( ( vm_offset_t ) curaddr & PAGE_MASK ) ; if ( map -> pagesneeded != 0 && run_filter ( dmat , curaddr ) ) { sgsize = roundup2 ( sgsize , dmat -> alignment ) ; sgsize = MIN ( sgsize , max_sgsize ) ; curaddr = add_bounce_page ( dmat , map , vaddr , curaddr , sgsize ) ; } else { sgsize = MIN ( sgsize , max_sgsize ) ; } sgsize = _bus_dmamap_addseg ( dmat , map , curaddr , sgsize , segs , segp ) ; if ( sgsize == 0 ) break ; vaddr += sgsize ; buflen -= sgsize ; } return ( buflen != 0 ? EFBIG : 0 ) ; }
Utility function to load a linear buffer.
Utility function to load a linear buffer .
/*
		 * Get the physical address for this segment.
		 */ /*
		 * Compute the segment size, and adjust counts.
		 */ /*
	 * Did we fit?
	 */ /* XXX better return value here? */