Re: [PATCH] asm-generic: add a dma-mapping.h file

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 19 May 2009 18:22:47 +0200
Arnd Bergmann <arnd@xxxxxxxx> 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@xxxxxxxx>
> 
>  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. ;)

--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux