dma-mapping.h: add the dma_unmap state API
Adds the following macros: DECLARE_DMA_UNMAP_ADDR(ADDR_NAME) DECLARE_DMA_UNMAP_LEN(LEN_NAME) dma_unmap_addr(PTR, ADDR_NAME) dma_unmap_addr_set(PTR, ADDR_NAME, VAL) dma_unmap_len(PTR, LEN_NAME) dma_unmap_len_set(PTR, LEN_NAME, VAL) The API corresponds to the pci_unmap state API. We'll move to this new generic API from the PCI specific API in the long term. As include/asm-generic/pci-dma-compat.h does, the pci_unmap API simply calls the new generic API for some time. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: James Bottomley <James.Bottomley@suse.de> Cc: David S. Miller <davem@davemloft.net> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
f41b177157
commit
0acedc124a
|
@ -472,6 +472,64 @@ void whizco_dma_map_sg_attrs(struct device *dev, dma_addr_t dma_addr,
|
||||||
....
|
....
|
||||||
|
|
||||||
|
|
||||||
|
Part Ie - Optimizing Unmap State Space Consumption
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
On some platforms, dma_unmap_{single,page}() is simply a nop.
|
||||||
|
Therefore, keeping track of the mapping address and length is a waste
|
||||||
|
of space. Instead of filling your drivers up with ifdefs and the like
|
||||||
|
to "work around" this (which would defeat the whole purpose of a
|
||||||
|
portable API) the following facilities are provided.
|
||||||
|
|
||||||
|
Actually, instead of describing the macros one by one, we'll
|
||||||
|
transform some example code.
|
||||||
|
|
||||||
|
1) Use DEFINE_DMA_UNMAP_{ADDR,LEN} in state saving structures.
|
||||||
|
Example, before:
|
||||||
|
|
||||||
|
struct ring_state {
|
||||||
|
struct sk_buff *skb;
|
||||||
|
dma_addr_t mapping;
|
||||||
|
__u32 len;
|
||||||
|
};
|
||||||
|
|
||||||
|
after:
|
||||||
|
|
||||||
|
struct ring_state {
|
||||||
|
struct sk_buff *skb;
|
||||||
|
DEFINE_DMA_UNMAP_ADDR(mapping);
|
||||||
|
DEFINE_DMA_UNMAP_LEN(len);
|
||||||
|
};
|
||||||
|
|
||||||
|
2) Use dma_unmap_{addr,len}_set to set these values.
|
||||||
|
Example, before:
|
||||||
|
|
||||||
|
ringp->mapping = FOO;
|
||||||
|
ringp->len = BAR;
|
||||||
|
|
||||||
|
after:
|
||||||
|
|
||||||
|
dma_unmap_addr_set(ringp, mapping, FOO);
|
||||||
|
dma_unmap_len_set(ringp, len, BAR);
|
||||||
|
|
||||||
|
3) Use dma_unmap_{addr,len} to access these values.
|
||||||
|
Example, before:
|
||||||
|
|
||||||
|
dma_unmap_single(dev, ringp->mapping, ringp->len,
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
|
|
||||||
|
after:
|
||||||
|
|
||||||
|
dma_unmap_single(dev,
|
||||||
|
dma_unmap_addr(ringp, mapping),
|
||||||
|
dma_unmap_len(ringp, len),
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
|
|
||||||
|
It really should be self-explanatory. We treat the ADDR and LEN
|
||||||
|
separately, because it is possible for an implementation to only
|
||||||
|
need the address in order to perform the unmap operation.
|
||||||
|
|
||||||
|
|
||||||
Part II - Advanced dma_ usage
|
Part II - Advanced dma_ usage
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
|
|
@ -232,4 +232,20 @@ struct dma_attrs;
|
||||||
|
|
||||||
#endif /* CONFIG_HAVE_DMA_ATTRS */
|
#endif /* CONFIG_HAVE_DMA_ATTRS */
|
||||||
|
|
||||||
|
#ifdef CONFIG_NEED_DMA_MAP_STATE
|
||||||
|
#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME
|
||||||
|
#define DEFINE_DMA_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME
|
||||||
|
#define dma_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
|
||||||
|
#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
|
||||||
|
#define dma_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
|
||||||
|
#define dma_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
|
||||||
|
#else
|
||||||
|
#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME)
|
||||||
|
#define DEFINE_DMA_UNMAP_LEN(LEN_NAME)
|
||||||
|
#define dma_unmap_addr(PTR, ADDR_NAME) (0)
|
||||||
|
#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
|
||||||
|
#define dma_unmap_len(PTR, LEN_NAME) (0)
|
||||||
|
#define dma_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,20 +1,11 @@
|
||||||
#ifndef _LINUX_PCI_DMA_H
|
#ifndef _LINUX_PCI_DMA_H
|
||||||
#define _LINUX_PCI_DMA_H
|
#define _LINUX_PCI_DMA_H
|
||||||
|
|
||||||
#ifdef CONFIG_NEED_DMA_MAP_STATE
|
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) DEFINE_DMA_UNMAP_ADDR(ADDR_NAME);
|
||||||
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME;
|
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) DEFINE_DMA_UNMAP_LEN(LEN_NAME);
|
||||||
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME;
|
#define pci_unmap_addr dma_unmap_addr
|
||||||
#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
|
#define pci_unmap_addr_set dma_unmap_addr_set
|
||||||
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
|
#define pci_unmap_len dma_unmap_len
|
||||||
#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
|
#define pci_unmap_len_set dma_unmap_len_set
|
||||||
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
|
|
||||||
#else
|
|
||||||
#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
|
|
||||||
#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
|
|
||||||
#define pci_unmap_addr(PTR, ADDR_NAME) (0)
|
|
||||||
#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
|
|
||||||
#define pci_unmap_len(PTR, LEN_NAME) (0)
|
|
||||||
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue