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

Configure Feed

Select the types of activity you want to include in your feed.

at ee9dce44362b2d8132c32964656ab6dff7dfbc6a 215 lines 6.4 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * PCI Peer 2 Peer DMA support. 4 * 5 * Copyright (c) 2016-2018, Logan Gunthorpe 6 * Copyright (c) 2016-2017, Microsemi Corporation 7 * Copyright (c) 2017, Christoph Hellwig 8 * Copyright (c) 2018, Eideticom Inc. 9 */ 10 11#ifndef _LINUX_PCI_P2PDMA_H 12#define _LINUX_PCI_P2PDMA_H 13 14#include <linux/pci.h> 15 16struct block_device; 17struct scatterlist; 18 19/** 20 * struct p2pdma_provider 21 * 22 * A p2pdma provider is a range of MMIO address space available to the CPU. 23 * @owner: Device to which this provider belongs. 24 * @bus_offset: Bus offset for p2p communication. 25 */ 26struct p2pdma_provider { 27 struct device *owner; 28 u64 bus_offset; 29}; 30 31enum pci_p2pdma_map_type { 32 /* 33 * PCI_P2PDMA_MAP_UNKNOWN: Used internally as an initial state before 34 * the mapping type has been calculated. Exported routines for the API 35 * will never return this value. 36 */ 37 PCI_P2PDMA_MAP_UNKNOWN = 0, 38 39 /* 40 * Not a PCI P2PDMA transfer. 41 */ 42 PCI_P2PDMA_MAP_NONE, 43 44 /* 45 * PCI_P2PDMA_MAP_NOT_SUPPORTED: Indicates the transaction will 46 * traverse the host bridge and the host bridge is not in the 47 * allowlist. DMA Mapping routines should return an error when 48 * this is returned. 49 */ 50 PCI_P2PDMA_MAP_NOT_SUPPORTED, 51 52 /* 53 * PCI_P2PDMA_MAP_BUS_ADDR: Indicates that two devices can talk to 54 * each other directly through a PCI switch and the transaction will 55 * not traverse the host bridge. Such a mapping should program 56 * the DMA engine with PCI bus addresses. 57 */ 58 PCI_P2PDMA_MAP_BUS_ADDR, 59 60 /* 61 * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE: Indicates two devices can talk 62 * to each other, but the transaction traverses a host bridge on the 63 * allowlist. In this case, a normal mapping either with CPU physical 64 * addresses (in the case of dma-direct) or IOVA addresses (in the 65 * case of IOMMUs) should be used to program the DMA engine. 66 */ 67 PCI_P2PDMA_MAP_THRU_HOST_BRIDGE, 68}; 69 70#ifdef CONFIG_PCI_P2PDMA 71int pcim_p2pdma_init(struct pci_dev *pdev); 72struct p2pdma_provider *pcim_p2pdma_provider(struct pci_dev *pdev, int bar); 73int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size, 74 u64 offset); 75int pci_p2pdma_distance_many(struct pci_dev *provider, struct device **clients, 76 int num_clients, bool verbose); 77struct pci_dev *pci_p2pmem_find_many(struct device **clients, int num_clients); 78void *pci_alloc_p2pmem(struct pci_dev *pdev, size_t size); 79void pci_free_p2pmem(struct pci_dev *pdev, void *addr, size_t size); 80pci_bus_addr_t pci_p2pmem_virt_to_bus(struct pci_dev *pdev, void *addr); 81struct scatterlist *pci_p2pmem_alloc_sgl(struct pci_dev *pdev, 82 unsigned int *nents, u32 length); 83void pci_p2pmem_free_sgl(struct pci_dev *pdev, struct scatterlist *sgl); 84void pci_p2pmem_publish(struct pci_dev *pdev, bool publish); 85int pci_p2pdma_enable_store(const char *page, struct pci_dev **p2p_dev, 86 bool *use_p2pdma); 87ssize_t pci_p2pdma_enable_show(char *page, struct pci_dev *p2p_dev, 88 bool use_p2pdma); 89enum pci_p2pdma_map_type pci_p2pdma_map_type(struct p2pdma_provider *provider, 90 struct device *dev); 91#else /* CONFIG_PCI_P2PDMA */ 92static inline int pcim_p2pdma_init(struct pci_dev *pdev) 93{ 94 return -EOPNOTSUPP; 95} 96static inline struct p2pdma_provider *pcim_p2pdma_provider(struct pci_dev *pdev, 97 int bar) 98{ 99 return NULL; 100} 101static inline int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, 102 size_t size, u64 offset) 103{ 104 return -EOPNOTSUPP; 105} 106static inline int pci_p2pdma_distance_many(struct pci_dev *provider, 107 struct device **clients, int num_clients, bool verbose) 108{ 109 return -1; 110} 111static inline struct pci_dev *pci_p2pmem_find_many(struct device **clients, 112 int num_clients) 113{ 114 return NULL; 115} 116static inline void *pci_alloc_p2pmem(struct pci_dev *pdev, size_t size) 117{ 118 return NULL; 119} 120static inline void pci_free_p2pmem(struct pci_dev *pdev, void *addr, 121 size_t size) 122{ 123} 124static inline pci_bus_addr_t pci_p2pmem_virt_to_bus(struct pci_dev *pdev, 125 void *addr) 126{ 127 return 0; 128} 129static inline struct scatterlist *pci_p2pmem_alloc_sgl(struct pci_dev *pdev, 130 unsigned int *nents, u32 length) 131{ 132 return NULL; 133} 134static inline void pci_p2pmem_free_sgl(struct pci_dev *pdev, 135 struct scatterlist *sgl) 136{ 137} 138static inline void pci_p2pmem_publish(struct pci_dev *pdev, bool publish) 139{ 140} 141static inline int pci_p2pdma_enable_store(const char *page, 142 struct pci_dev **p2p_dev, bool *use_p2pdma) 143{ 144 *use_p2pdma = false; 145 return 0; 146} 147static inline ssize_t pci_p2pdma_enable_show(char *page, 148 struct pci_dev *p2p_dev, bool use_p2pdma) 149{ 150 return sprintf(page, "none\n"); 151} 152static inline enum pci_p2pdma_map_type 153pci_p2pdma_map_type(struct p2pdma_provider *provider, struct device *dev) 154{ 155 return PCI_P2PDMA_MAP_NOT_SUPPORTED; 156} 157#endif /* CONFIG_PCI_P2PDMA */ 158 159 160static inline int pci_p2pdma_distance(struct pci_dev *provider, 161 struct device *client, bool verbose) 162{ 163 return pci_p2pdma_distance_many(provider, &client, 1, verbose); 164} 165 166static inline struct pci_dev *pci_p2pmem_find(struct device *client) 167{ 168 return pci_p2pmem_find_many(&client, 1); 169} 170 171struct pci_p2pdma_map_state { 172 struct p2pdma_provider *mem; 173 enum pci_p2pdma_map_type map; 174}; 175 176 177/* helper for pci_p2pdma_state(), do not use directly */ 178void __pci_p2pdma_update_state(struct pci_p2pdma_map_state *state, 179 struct device *dev, struct page *page); 180 181/** 182 * pci_p2pdma_state - check the P2P transfer state of a page 183 * @state: P2P state structure 184 * @dev: device to transfer to/from 185 * @page: page to map 186 * 187 * Check if @page is a PCI P2PDMA page, and if yes of what kind. Returns the 188 * map type, and updates @state with all information needed for a P2P transfer. 189 */ 190static inline enum pci_p2pdma_map_type 191pci_p2pdma_state(struct pci_p2pdma_map_state *state, struct device *dev, 192 struct page *page) 193{ 194 if (IS_ENABLED(CONFIG_PCI_P2PDMA) && is_pci_p2pdma_page(page)) { 195 __pci_p2pdma_update_state(state, dev, page); 196 return state->map; 197 } 198 return PCI_P2PDMA_MAP_NONE; 199} 200 201/** 202 * pci_p2pdma_bus_addr_map - Translate a physical address to a bus address 203 * for a PCI_P2PDMA_MAP_BUS_ADDR transfer. 204 * @provider: P2P provider structure 205 * @paddr: physical address to map 206 * 207 * Map a physically contiguous PCI_P2PDMA_MAP_BUS_ADDR transfer. 208 */ 209static inline dma_addr_t 210pci_p2pdma_bus_addr_map(struct p2pdma_provider *provider, phys_addr_t paddr) 211{ 212 return paddr + provider->bus_offset; 213} 214 215#endif /* _LINUX_PCI_P2P_H */