linux/arch/sparc/kernel/ioport.c
/*
 * Allocate a chunk of memory suitable for DMA.
 * Typically devices use them for control blocks.
 * CPU may access them without any explicit flushing.
 */
Allocate a chunk of memory suitable for DMA.
Typically devices use them for control blocks.
CPU may access them without any explicit flushing.
Allocate a chunk of memory suitable for DMA . Typically devices use them for control blocks . CPU may access them without any explicit flushing .
static void *sbus_alloc_coherent(struct device *dev, size_t len,
				 dma_addr_t *dma_addrp, gfp_t gfp,
				 unsigned long attrs)
{
	struct platform_device *op = to_platform_device(dev);
	unsigned long len_total = PAGE_ALIGN(len);
	unsigned long va;
	struct resource *res;
	int order;
	if (len <= 0) {
		return NULL;
	}
	if (len > 256*1024) {			
		return NULL;
	}
	order = get_order(len_total);
	va = __get_free_pages(gfp, order);
	if (va == 0)
		goto err_nopages;
	if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL)
		goto err_nomem;
	if (allocate_resource(&_sparc_dvma, res, len_total,
	    _sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) {
		printk("sbus_alloc_consistent: cannot occupy 0x%lx", len_total);
		goto err_nova;
	}
	if (sbus_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0)
		goto err_noiommu;
	res->name = op->dev.of_node->name;
	return (void *)(unsigned long)res->start;
err_noiommu:
	release_resource(res);
err_nova:
	kfree(res);
err_nomem:
	free_pages(va, order);
err_nopages:
	return NULL;
}
static void * sbus_alloc_coherent ( struct device * dev , size_t len , dma_addr_t * dma_addrp , gfp_t gfp , unsigned long attrs ) { struct platform_device * op = to_platform_device ( dev ) ; unsigned long len_total = PAGE_ALIGN ( len ) ; unsigned long va ; struct resource * res ; int order ; if ( len <= 0 ) { return NULL ; } if ( len > 256 * 1024 ) { return NULL ; } order = get_order ( len_total ) ; va = __get_free_pages ( gfp , order ) ; if ( va == 0 ) goto err_nopages ; if ( ( res = kzalloc ( sizeof ( struct resource ) , GFP_KERNEL ) ) == NULL ) goto err_nomem ; if ( allocate_resource ( & _sparc_dvma , res , len_total , _sparc_dvma . start , _sparc_dvma . end , PAGE_SIZE , NULL , NULL ) != 0 ) { printk ( " " , len_total ) ; goto err_nova ; } if ( sbus_map_dma_area ( dev , dma_addrp , va , res -> start , len_total ) != 0 ) goto err_noiommu ; res -> name = op -> dev . of_node -> name ; return ( void * ) ( unsigned long ) res -> start ; err_noiommu : release_resource ( res ) ; err_nova : kfree ( res ) ; err_nomem : free_pages ( va , order ) ; err_nopages : return NULL ; }
Allocate a chunk of memory suitable for DMA.
Allocate a chunk of memory suitable for DMA .
/* XXX why are some lengths signed, others unsigned? */ /* XXX So what is maxphys for us and how do drivers know it? */ /* __get_free_pages() limit */ // XXX The sbus_map_dma_area does this for us below, see comments. // srmmu_mapiorange(0, virt_to_phys(va), res->start, len_total); /*
	 * XXX That's where sdev would be used. Currently we load
	 * all iommu tables with the same translations.
	 */