diff -ruaN linux-oss.orig/arch/mips/mm/Makefile linux-oss/arch/mips/mm/Makefile --- linux-oss.orig/arch/mips/mm/Makefile 2002-09-09 21:30:12.000000000 +0200 +++ linux-oss/arch/mips/mm/Makefile 2002-09-13 12:53:17.000000000 +0200 @@ -10,8 +10,8 @@ O_TARGET := mm.o -export-objs += ioremap.o loadmmu.o umap.o -obj-y += extable.o init.o ioremap.o fault.o loadmmu.o +export-objs += ioremap.o loadmmu.o umap.o consistent.o +obj-y += extable.o init.o ioremap.o fault.o loadmmu.o consistent.o obj-$(CONFIG_CPU_R3000) += pg-r3k.o c-r3k.o c-tx39.o tlb-r3k.o \ tlbex-r3k.o diff -ruaN linux-oss.orig/arch/mips/mm/consistent.c linux-oss/arch/mips/mm/consistent.c --- linux-oss.orig/arch/mips/mm/consistent.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-oss/arch/mips/mm/consistent.c 2002-05-24 18:55:30.000000000 +0200 @@ -0,0 +1,108 @@ +/* + * linux/arch/mips/mm/consistent.c + * + * Copyright (C) 2002 Denis Oliver Kropp + * + * + * Based on linux/arch/arm/mm/consistent.c + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Dynamic DMA mapping support. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * This allocates one page of cache-coherent memory space and returns + * both the virtual and a "dma" address to that space. It is not clear + * whether this could be called from an interrupt context or not. For + * now, we expressly forbid it, especially as some of the stuff we do + * here is not interrupt context safe. + * + * Note that this does *not* zero the allocated area! + */ +void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) +{ + struct page *page, *free, *end; + unsigned long order; + void *virt; + + if (in_interrupt()) + BUG(); + + size = PAGE_ALIGN(size); + order = get_order(size); + + page = alloc_pages(gfp, order); + if (!page) + return NULL; + + virt = page_address(page); + *dma_handle = virt_to_bus(virt); + + /* + * free wasted pages. We skip the first page since we know + * that it will have count = 1 and won't require freeing. + * We also mark the pages in use as reserved so that + * remap_page_range works. + */ + page = virt_to_page(virt); + free = page + (size >> PAGE_SHIFT); + end = page + (1 << order); + + for (; page < end; page++) { + set_page_count(page, 1); + if (page >= free) + __free_page(page); + else + SetPageReserved(page); + } + + return (void*) KSEG1ADDR(virt); +} + +/* + * free a page as defined by the above mapping. We expressly forbid + * calling this from interrupt context. + */ +void consistent_free(void *vaddr, size_t size, dma_addr_t handle) +{ + struct page *page, *end; + void *virt; + + if (in_interrupt()) + BUG(); + + virt = bus_to_virt(handle); + + /* + * More messing around with the MM internals. This is + * sick, but then so is remap_page_range(). + */ + size = PAGE_ALIGN(size); + page = virt_to_page(virt); + end = page + (size >> PAGE_SHIFT); + + for (; page < end; page++) + ClearPageReserved(page); +} + +EXPORT_SYMBOL(consistent_alloc); +EXPORT_SYMBOL(consistent_free); + diff -ruaN linux-oss.orig/include/asm-mips/io.h linux-oss/include/asm-mips/io.h --- linux-oss.orig/include/asm-mips/io.h 2002-08-16 20:36:17.000000000 +0200 +++ linux-oss/include/asm-mips/io.h 2002-09-13 12:53:18.000000000 +0200 @@ -222,6 +222,15 @@ extern void iounmap(void *addr); /* + * DMA-consistent mapping functions. These allocate/free a region of + * uncached, unwrite-buffered mapped memory space for use with DMA + * devices. This is the "generic" version. The PCI specific version + * is in pci.h + */ +extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle); +extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle); + +/* * XXX We need system specific versions of these to handle EISA address bits * 24-31 on SNI. * XXX more SNI hacks.