Commit 0acedc124aca35f5cce9d4ee288dc372bf517e09

Authored by FUJITA Tomonori
Committed by Linus Torvalds
1 parent f41b177157

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>

Showing 3 changed files with 80 additions and 15 deletions Side-by-side Diff

Documentation/DMA-API.txt
... ... @@ -472,6 +472,64 @@
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 533 Part II - Advanced dma_ usage
476 534 -----------------------------
477 535  
include/linux/dma-mapping.h
... ... @@ -232,5 +232,21 @@
232 232  
233 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 251 #endif
include/linux/pci-dma.h
1 1 #ifndef _LINUX_PCI_DMA_H
2 2 #define _LINUX_PCI_DMA_H
3 3  
4   -#ifdef CONFIG_NEED_DMA_MAP_STATE
5   -#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME;
6   -#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME;
7   -#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
8   -#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
9   -#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
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
  4 +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) DEFINE_DMA_UNMAP_ADDR(ADDR_NAME);
  5 +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) DEFINE_DMA_UNMAP_LEN(LEN_NAME);
  6 +#define pci_unmap_addr dma_unmap_addr
  7 +#define pci_unmap_addr_set dma_unmap_addr_set
  8 +#define pci_unmap_len dma_unmap_len
  9 +#define pci_unmap_len_set dma_unmap_len_set
19 10  
20 11 #endif