lkml.org 
[lkml]   [2009]   [May]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    SubjectRe: [PATCH] asm-generic: add a dma-mapping.h file
    From
    On Tue, 19 May 2009 18:22:47 +0200
    Arnd Bergmann <arnd@arndb.de> wrote:

    > On Tuesday 19 May 2009, FUJITA Tomonori wrote:
    > > > Would you agree to a patch that works with the same
    > > > code on e.g. arm, microblaze, mn10300 and sh and
    > > > uses only a few #ifdefs?
    > >
    > > Having such helper for a linear mapping might be helpful but your
    > > approach is wrong.
    >
    > Do you like this approach better? I've merged a few architectures
    > that were relatively simple. This file should be usable by all
    > architectures that have a linear mapping and are either fully coherent
    > (like cris) or just require flushing the dcache when passing a
    > buffer to the device.
    >
    > It's become pretty obvious where some of my bugs were in the previous
    > code, I hopefully did better this time and maybe you find the rest.
    > I've also added the dma debugging stuff in here and fixed a number
    > of bugs in all the different architectures on the way, but I can
    > send separate patches for those before doing the merge.
    >
    > I've also tried merging frv and m68k, but they have some peculiarities
    > that made it slightly harder.
    >
    > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
    >
    > include/asm-generic/dma-mapping-linear.h | 391 +++++++++++++++++++++++++++++
    > arch/avr32/include/asm/dma-mapping.h | 408 ++++---------------------------
    > arch/blackfin/include/asm/dma-mapping.h | 118 +-------
    > arch/cris/include/asm/dma-mapping.h | 194 +-------------
    > arch/mn10300/include/asm/dma-mapping.h | 266 ++------------------
    > arch/sh/include/asm/dma-mapping.h | 258 ++-----------------
    > arch/xtensa/include/asm/dma-mapping.h | 220 +++-------------
    > 7 files changed, 606 insertions(+), 1249 deletions(-)
    >
    > diff --git a/include/asm-generic/dma-mapping-linear.h b/include/asm-generic/dma-mapping-linear.h
    > new file mode 100644
    > index 0000000..13f37db
    > --- /dev/null
    > +++ b/include/asm-generic/dma-mapping-linear.h
    > @@ -0,0 +1,391 @@
    > +#ifndef __ASM_GENERIC_DMA_MAPPING_H
    > +#define __ASM_GENERIC_DMA_MAPPING_H
    > +
    > +#include <linux/mm.h>
    > +#include <linux/device.h>
    > +#include <linux/dma-debug.h>
    > +#include <linux/scatterlist.h>
    > +#include <asm/cacheflush.h>
    > +#include <asm/io.h>
    > +
    > +#ifdef CONFIG_DMA_COHERENT
    > +/*
    > + * An architecture should override these if it needs to
    > + * perform cache flushes before passing bus addresses
    > + * to a device.
    > + * It can either do a full flush in dma_coherent_dev
    > + * and return 1 from there, or implement more specific
    > + * synchronization in dma_cache_sync, which will be
    > + * applied separately to each sg element.
    > + */
    > +static inline int
    > +dma_coherent_dev(struct device *dev)
    > +{
    > + return 1;
    > +}
    > +
    > +static inline void
    > +dma_cache_sync(struct device *dev, void *cpu_addr, size_t size,
    > + enum dma_data_direction direction)
    > +{
    > +}
    > +
    > +/**
    > + * dma_alloc_coherent - allocate consistent memory for DMA
    > + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
    > + * @size: required memory size
    > + * @handle: bus-specific DMA address
    > + *
    > + * Allocate some uncached, unbuffered memory for a device for
    > + * performing DMA. This function allocates pages, and will
    > + * return the CPU-viewed address, and sets @handle to be the
    > + * device-viewed address.
    > + */
    > +void *dma_alloc_coherent(struct device *dev, size_t size,
    > + dma_addr_t *dma_handle, gfp_t flag)
    > +{
    > + void *ret;
    > + struct page *page;
    > + int node = dev_to_node(dev);
    > +
    > + /* ignore region specifiers */
    > + flag &= ~(__GFP_HIGHMEM);
    > +
    > + page = alloc_pages_node(node, flag, get_order(size));
    > + if (page == NULL)
    > + return NULL;
    > + ret = page_address(page);
    > + memset(ret, 0, size);
    > + *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev);
    > +
    > + return ret;
    > +}

    I don't think that this works for all architectures because a returned
    buffer of alloc_pages_node might not be DMA-capable. Needs to use the
    coherent_dma_mask here. See x86's dma_alloc_coherent and Alpha's
    pci-noop.c (there might be other examples).

    I think that having a generic header for simple mapping functions
    (dma_map_single, dma_map_page, dma_map_sg, etc) would be useful but
    I'm not sure if we can't have a generic version of
    dma_alloc_coherent. There are lots of architectures that do
    architecture-specific things. For example, you replaced avr32
    dma-mapping.h except for dma_alloc_coherent, which seems to be can't
    be generic.

    BTW, it looks odd to add dma_debug to dma_map_single, etc but not
    dma_alloc_coherent. ;)



    \
     
     \ /
      Last update: 2009-05-22 14:19    [from the cache]
    ©2003-2011 Jasper Spaans. Advertise on this site