aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2010-03-10 18:23:31 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-12 18:52:42 -0500
commit0acedc124aca35f5cce9d4ee288dc372bf517e09 (patch)
tree699113a95be38de29457d0cc71139d9c82efba3e
parentf41b177157718abe9a93868bb76e47d4a6f3681d (diff)
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>
-rw-r--r--Documentation/DMA-API.txt58
-rw-r--r--include/linux/dma-mapping.h16
-rw-r--r--include/linux/pci-dma.h21
3 files changed, 80 insertions, 15 deletions
diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index 364a6cb444a5..29a48fbae779 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -472,6 +472,64 @@ void whizco_dma_map_sg_attrs(struct device *dev, dma_addr_t dma_addr,
472 .... 472 ....
473 473
474 474
475Part Ie - Optimizing Unmap State Space Consumption
476--------------------------------
477
478On some platforms, dma_unmap_{single,page}() is simply a nop.
479Therefore, keeping track of the mapping address and length is a waste
480of space. Instead of filling your drivers up with ifdefs and the like
481to "work around" this (which would defeat the whole purpose of a
482portable API) the following facilities are provided.
483
484Actually, instead of describing the macros one by one, we'll
485transform some example code.
486
4871) Use DEFINE_DMA_UNMAP_{ADDR,LEN} in state saving structures.
488 Example, before:
489
490 struct ring_state {
491 struct sk_buff *skb;
492 dma_addr_t mapping;
493 __u32 len;
494 };
495
496 after:
497
498 struct ring_state {
499 struct sk_buff *skb;
500 DEFINE_DMA_UNMAP_ADDR(mapping);
501 DEFINE_DMA_UNMAP_LEN(len);
502 };
503
5042) Use dma_unmap_{addr,len}_set to set these values.
505 Example, before:
506
507 ringp->mapping = FOO;
508 ringp->len = BAR;
509
510 after:
511
512 dma_unmap_addr_set(ringp, mapping, FOO);
513 dma_unmap_len_set(ringp, len, BAR);
514
5153) Use dma_unmap_{addr,len} to access these values.
516 Example, before:
517
518 dma_unmap_single(dev, ringp->mapping, ringp->len,
519 DMA_FROM_DEVICE);
520
521 after:
522
523 dma_unmap_single(dev,
524 dma_unmap_addr(ringp, mapping),
525 dma_unmap_len(ringp, len),
526 DMA_FROM_DEVICE);
527
528It really should be self-explanatory. We treat the ADDR and LEN
529separately, because it is possible for an implementation to only
530need the address in order to perform the unmap operation.
531
532
475Part II - Advanced dma_ usage 533Part II - Advanced dma_ usage
476----------------------------- 534-----------------------------
477 535
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 91b761846061..c5ac9d49cc06 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -232,4 +232,20 @@ struct dma_attrs;
232 232
233#endif /* CONFIG_HAVE_DMA_ATTRS */ 233#endif /* CONFIG_HAVE_DMA_ATTRS */
234 234
235#ifdef CONFIG_NEED_DMA_MAP_STATE
236#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME
237#define DEFINE_DMA_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME
238#define dma_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
239#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
240#define dma_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
241#define dma_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
242#else
243#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME)
244#define DEFINE_DMA_UNMAP_LEN(LEN_NAME)
245#define dma_unmap_addr(PTR, ADDR_NAME) (0)
246#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
247#define dma_unmap_len(PTR, LEN_NAME) (0)
248#define dma_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
249#endif
250
235#endif 251#endif
diff --git a/include/linux/pci-dma.h b/include/linux/pci-dma.h
index cfd63ab09abc..549a041f9c08 100644
--- a/include/linux/pci-dma.h
+++ b/include/linux/pci-dma.h
@@ -1,20 +1,11 @@
1#ifndef _LINUX_PCI_DMA_H 1#ifndef _LINUX_PCI_DMA_H
2#define _LINUX_PCI_DMA_H 2#define _LINUX_PCI_DMA_H
3 3
4#ifdef CONFIG_NEED_DMA_MAP_STATE 4#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) DEFINE_DMA_UNMAP_ADDR(ADDR_NAME);
5#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; 5#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) DEFINE_DMA_UNMAP_LEN(LEN_NAME);
6#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME; 6#define pci_unmap_addr dma_unmap_addr
7#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) 7#define pci_unmap_addr_set dma_unmap_addr_set
8#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) 8#define pci_unmap_len dma_unmap_len
9#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) 9#define pci_unmap_len_set dma_unmap_len_set
10#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
11#else
12#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
13#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
14#define pci_unmap_addr(PTR, ADDR_NAME) (0)
15#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
16#define pci_unmap_len(PTR, LEN_NAME) (0)
17#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
18#endif
19 10
20#endif 11#endif