Dan Williams | 34c0fd5 | 2016-01-15 16:56:14 -0800 | [diff] [blame] | 1 | #ifndef _LINUX_PFN_T_H_ |
| 2 | #define _LINUX_PFN_T_H_ |
| 3 | #include <linux/mm.h> |
| 4 | |
| 5 | /* |
| 6 | * PFN_FLAGS_MASK - mask of all the possible valid pfn_t flags |
| 7 | * PFN_SG_CHAIN - pfn is a pointer to the next scatterlist entry |
| 8 | * PFN_SG_LAST - pfn references a page and is the last scatterlist entry |
| 9 | * PFN_DEV - pfn is not covered by system memmap by default |
| 10 | * PFN_MAP - pfn has a dynamic page mapping established by a device driver |
| 11 | */ |
| 12 | #define PFN_FLAGS_MASK (((unsigned long) ~PAGE_MASK) \ |
| 13 | << (BITS_PER_LONG - PAGE_SHIFT)) |
| 14 | #define PFN_SG_CHAIN (1UL << (BITS_PER_LONG - 1)) |
| 15 | #define PFN_SG_LAST (1UL << (BITS_PER_LONG - 2)) |
| 16 | #define PFN_DEV (1UL << (BITS_PER_LONG - 3)) |
| 17 | #define PFN_MAP (1UL << (BITS_PER_LONG - 4)) |
| 18 | |
| 19 | static inline pfn_t __pfn_to_pfn_t(unsigned long pfn, unsigned long flags) |
| 20 | { |
| 21 | pfn_t pfn_t = { .val = pfn | (flags & PFN_FLAGS_MASK), }; |
| 22 | |
| 23 | return pfn_t; |
| 24 | } |
| 25 | |
| 26 | /* a default pfn to pfn_t conversion assumes that @pfn is pfn_valid() */ |
| 27 | static inline pfn_t pfn_to_pfn_t(unsigned long pfn) |
| 28 | { |
| 29 | return __pfn_to_pfn_t(pfn, 0); |
| 30 | } |
| 31 | |
| 32 | extern pfn_t phys_to_pfn_t(dma_addr_t addr, unsigned long flags); |
| 33 | |
| 34 | static inline bool pfn_t_has_page(pfn_t pfn) |
| 35 | { |
| 36 | return (pfn.val & PFN_MAP) == PFN_MAP || (pfn.val & PFN_DEV) == 0; |
| 37 | } |
| 38 | |
| 39 | static inline unsigned long pfn_t_to_pfn(pfn_t pfn) |
| 40 | { |
| 41 | return pfn.val & ~PFN_FLAGS_MASK; |
| 42 | } |
| 43 | |
| 44 | static inline struct page *pfn_t_to_page(pfn_t pfn) |
| 45 | { |
| 46 | if (pfn_t_has_page(pfn)) |
| 47 | return pfn_to_page(pfn_t_to_pfn(pfn)); |
| 48 | return NULL; |
| 49 | } |
| 50 | |
| 51 | static inline dma_addr_t pfn_t_to_phys(pfn_t pfn) |
| 52 | { |
| 53 | return PFN_PHYS(pfn_t_to_pfn(pfn)); |
| 54 | } |
| 55 | |
| 56 | static inline void *pfn_t_to_virt(pfn_t pfn) |
| 57 | { |
| 58 | if (pfn_t_has_page(pfn)) |
| 59 | return __va(pfn_t_to_phys(pfn)); |
| 60 | return NULL; |
| 61 | } |
| 62 | |
| 63 | static inline pfn_t page_to_pfn_t(struct page *page) |
| 64 | { |
| 65 | return pfn_to_pfn_t(page_to_pfn(page)); |
| 66 | } |
| 67 | #endif /* _LINUX_PFN_T_H_ */ |