X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fxtensa%2Fkernel%2Fpci-dma.c;h=ca76f071666e895aea125f3927d07bcb385fdcd7;hb=refs%2Fremotes%2Fvserver;hp=1ff82268e8eacf354e5f16eae1a9ea182d3ca191;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index 1ff82268e..ca76f0716 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -29,28 +29,48 @@ */ void * -dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) +dma_alloc_coherent(struct device *dev,size_t size,dma_addr_t *handle,gfp_t flag) { - void *ret; + unsigned long ret; + unsigned long uncached = 0; /* ignore region speicifiers */ - gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); - if (dev == NULL || (*dev->dma_mask < 0xffffffff)) - gfp |= GFP_DMA; - ret = (void *)__get_free_pages(gfp, get_order(size)); + flag &= ~(__GFP_DMA | __GFP_HIGHMEM); - if (ret != NULL) { - memset(ret, 0, size); - *handle = virt_to_bus(ret); + if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) + flag |= GFP_DMA; + ret = (unsigned long)__get_free_pages(flag, get_order(size)); + + if (ret == 0) + return NULL; + + /* We currently don't support coherent memory outside KSEG */ + + if (ret < XCHAL_KSEG_CACHED_VADDR + || ret >= XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE) + BUG(); + + + if (ret != 0) { + memset((void*) ret, 0, size); + uncached = ret+XCHAL_KSEG_BYPASS_VADDR-XCHAL_KSEG_CACHED_VADDR; + *handle = virt_to_bus((void*)ret); + __flush_invalidate_dcache_range(ret, size); } - return (void*) BYPASS_ADDR((unsigned long)ret); + + return (void*)uncached; } void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { - free_pages(CACHED_ADDR((unsigned long)vaddr), get_order(size)); + long addr=(long)vaddr+XCHAL_KSEG_CACHED_VADDR-XCHAL_KSEG_BYPASS_VADDR; + + if (addr < 0 || addr >= XCHAL_KSEG_SIZE) + BUG(); + + free_pages(addr, get_order(size)); }