Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

FUJITA Tomonori and committed by
Linus Torvalds
0acedc12 f41b1771

+80 -15
+58
Documentation/DMA-API.txt
··· 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
+16
include/linux/dma-mapping.h
··· 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
+6 -15
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