diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2010-03-10 18:23:31 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-12 18:52:42 -0500 |
commit | 0acedc124aca35f5cce9d4ee288dc372bf517e09 (patch) | |
tree | 699113a95be38de29457d0cc71139d9c82efba3e | |
parent | f41b177157718abe9a93868bb76e47d4a6f3681d (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.txt | 58 | ||||
-rw-r--r-- | include/linux/dma-mapping.h | 16 | ||||
-rw-r--r-- | include/linux/pci-dma.h | 21 |
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 | ||
475 | Part Ie - Optimizing Unmap State Space Consumption | ||
476 | -------------------------------- | ||
477 | |||
478 | On some platforms, dma_unmap_{single,page}() is simply a nop. | ||
479 | Therefore, keeping track of the mapping address and length is a waste | ||
480 | of space. Instead of filling your drivers up with ifdefs and the like | ||
481 | to "work around" this (which would defeat the whole purpose of a | ||
482 | portable API) the following facilities are provided. | ||
483 | |||
484 | Actually, instead of describing the macros one by one, we'll | ||
485 | transform some example code. | ||
486 | |||
487 | 1) 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 | |||
504 | 2) 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 | |||
515 | 3) 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 | |||
528 | It really should be self-explanatory. We treat the ADDR and LEN | ||
529 | separately, because it is possible for an implementation to only | ||
530 | need the address in order to perform the unmap operation. | ||
531 | |||
532 | |||
475 | Part II - Advanced dma_ usage | 533 | Part 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 |