dma-mapping.h revision 270710
1226031Sstas/*- 2226031Sstas * Copyright (c) 2010 Isilon Systems, Inc. 3226128Sstas * Copyright (c) 2010 iX Systems, Inc. 4226128Sstas * Copyright (c) 2010 Panasas, Inc. 5226031Sstas * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. 6226031Sstas * All rights reserved. 7226128Sstas * 8226031Sstas * Redistribution and use in source and binary forms, with or without 9226031Sstas * modification, are permitted provided that the following conditions 10226031Sstas * are met: 11226031Sstas * 1. Redistributions of source code must retain the above copyright 12226128Sstas * notice unmodified, this list of conditions, and the following 13226031Sstas * disclaimer. 14226031Sstas * 2. Redistributions in binary form must reproduce the above copyright 15226031Sstas * notice, this list of conditions and the following disclaimer in the 16226031Sstas * documentation and/or other materials provided with the distribution. 17226031Sstas * 18226031Sstas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19226031Sstas * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20226031Sstas * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21226031Sstas * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22226031Sstas * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23226031Sstas * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24226031Sstas * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25226031Sstas * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26226031Sstas * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27226031Sstas * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28226031Sstas */ 29226031Sstas#ifndef _LINUX_DMA_MAPPING_H_ 30226031Sstas#define _LINUX_DMA_MAPPING_H_ 31226031Sstas 32226031Sstas#include <linux/types.h> 33226031Sstas#include <linux/device.h> 34226031Sstas#include <linux/err.h> 35226031Sstas#include <linux/dma-attrs.h> 36226031Sstas#include <linux/scatterlist.h> 37226031Sstas#include <linux/mm.h> 38226031Sstas#include <linux/page.h> 39226031Sstas 40226031Sstas#include <sys/systm.h> 41226031Sstas#include <sys/malloc.h> 42226031Sstas 43226031Sstas#include <vm/vm.h> 44226031Sstas#include <vm/vm_page.h> 45226031Sstas#include <vm/pmap.h> 46226031Sstas 47226031Sstas#include <machine/bus.h> 48226031Sstas#include <machine/pmap.h> 49226031Sstas 50226031Sstasenum dma_data_direction { 51226031Sstas DMA_BIDIRECTIONAL = 0, 52226031Sstas DMA_TO_DEVICE = 1, 53226031Sstas DMA_FROM_DEVICE = 2, 54226031Sstas DMA_NONE = 3, 55226031Sstas}; 56226031Sstas 57226031Sstasstruct dma_map_ops { 58226031Sstas void* (*alloc_coherent)(struct device *dev, size_t size, 59226031Sstas dma_addr_t *dma_handle, gfp_t gfp); 60226031Sstas void (*free_coherent)(struct device *dev, size_t size, 61226031Sstas void *vaddr, dma_addr_t dma_handle); 62226031Sstas dma_addr_t (*map_page)(struct device *dev, struct page *page, 63226031Sstas unsigned long offset, size_t size, enum dma_data_direction dir, 64226031Sstas struct dma_attrs *attrs); 65226031Sstas void (*unmap_page)(struct device *dev, dma_addr_t dma_handle, 66226031Sstas size_t size, enum dma_data_direction dir, struct dma_attrs *attrs); 67226031Sstas int (*map_sg)(struct device *dev, struct scatterlist *sg, 68226031Sstas int nents, enum dma_data_direction dir, struct dma_attrs *attrs); 69226031Sstas void (*unmap_sg)(struct device *dev, struct scatterlist *sg, int nents, 70226031Sstas enum dma_data_direction dir, struct dma_attrs *attrs); 71226031Sstas void (*sync_single_for_cpu)(struct device *dev, dma_addr_t dma_handle, 72226031Sstas size_t size, enum dma_data_direction dir); 73226031Sstas void (*sync_single_for_device)(struct device *dev, 74226031Sstas dma_addr_t dma_handle, size_t size, enum dma_data_direction dir); 75226031Sstas void (*sync_single_range_for_cpu)(struct device *dev, 76226031Sstas dma_addr_t dma_handle, unsigned long offset, size_t size, 77226031Sstas enum dma_data_direction dir); 78226031Sstas void (*sync_single_range_for_device)(struct device *dev, 79226031Sstas dma_addr_t dma_handle, unsigned long offset, size_t size, 80226031Sstas enum dma_data_direction dir); 81226031Sstas void (*sync_sg_for_cpu)(struct device *dev, struct scatterlist *sg, 82226031Sstas int nents, enum dma_data_direction dir); 83226031Sstas void (*sync_sg_for_device)(struct device *dev, struct scatterlist *sg, 84226031Sstas int nents, enum dma_data_direction dir); 85226031Sstas int (*mapping_error)(struct device *dev, dma_addr_t dma_addr); 86226031Sstas int (*dma_supported)(struct device *dev, u64 mask); 87226031Sstas int is_phys; 88226031Sstas}; 89226031Sstas 90226031Sstas#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL << (n)) - 1)) 91226031Sstas 92226031Sstasstatic inline int 93226031Sstasdma_supported(struct device *dev, u64 mask) 94226128Sstas{ 95226031Sstas 96226031Sstas /* XXX busdma takes care of this elsewhere. */ 97226031Sstas return (1); 98226031Sstas} 99226031Sstas 100226031Sstasstatic inline int 101226031Sstasdma_set_mask(struct device *dev, u64 dma_mask) 102226031Sstas{ 103226031Sstas 104226031Sstas if (!dev->dma_mask || !dma_supported(dev, dma_mask)) 105226031Sstas return -EIO; 106226031Sstas 107226031Sstas *dev->dma_mask = dma_mask; 108226031Sstas return (0); 109226031Sstas} 110226031Sstas 111226031Sstasstatic inline int 112226031Sstasdma_set_coherent_mask(struct device *dev, u64 mask) 113226031Sstas{ 114226031Sstas 115226031Sstas if (!dma_supported(dev, mask)) 116226031Sstas return -EIO; 117226031Sstas /* XXX Currently we don't support a seperate coherent mask. */ 118226031Sstas return 0; 119226031Sstas} 120226031Sstas 121226031Sstasstatic inline void * 122226031Sstasdma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, 123226031Sstas gfp_t flag) 124226031Sstas{ 125226031Sstas vm_paddr_t high; 126226031Sstas size_t align; 127226031Sstas void *mem; 128226031Sstas 129226031Sstas if (dev->dma_mask) 130226031Sstas high = *dev->dma_mask; 131226031Sstas else 132226031Sstas high = BUS_SPACE_MAXADDR_32BIT; 133226031Sstas align = PAGE_SIZE << get_order(size); 134226031Sstas mem = (void *)kmem_alloc_contig(kmem_arena, size, flag, 0, high, align, 135226031Sstas 0, VM_MEMATTR_DEFAULT); 136226031Sstas if (mem) 137226031Sstas *dma_handle = vtophys(mem); 138226031Sstas else 139226031Sstas *dma_handle = 0; 140226031Sstas return (mem); 141226031Sstas} 142226128Sstas 143226128Sstasstatic inline void 144226128Sstasdma_free_coherent(struct device *dev, size_t size, void *cpu_addr, 145226031Sstas dma_addr_t dma_handle) 146226031Sstas{ 147226031Sstas 148226031Sstas kmem_free(kmem_arena, (vm_offset_t)cpu_addr, size); 149226031Sstas} 150226031Sstas 151226031Sstas/* XXX This only works with no iommu. */ 152226031Sstasstatic inline dma_addr_t 153226031Sstasdma_map_single_attrs(struct device *dev, void *ptr, size_t size, 154226031Sstas enum dma_data_direction dir, struct dma_attrs *attrs) 155226031Sstas{ 156226031Sstas 157226031Sstas return vtophys(ptr); 158226031Sstas} 159226031Sstas 160226031Sstasstatic inline void 161226031Sstasdma_unmap_single_attrs(struct device *dev, dma_addr_t addr, size_t size, 162226031Sstas enum dma_data_direction dir, struct dma_attrs *attrs) 163226031Sstas{ 164226031Sstas} 165226031Sstas 166226031Sstasstatic inline int 167226031Sstasdma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, int nents, 168226031Sstas enum dma_data_direction dir, struct dma_attrs *attrs) 169226031Sstas{ 170226031Sstas struct scatterlist *sg; 171226031Sstas int i; 172226031Sstas 173226031Sstas for_each_sg(sgl, sg, nents, i) 174226031Sstas sg_dma_address(sg) = sg_phys(sg); 175226031Sstas 176226031Sstas return (nents); 177226031Sstas} 178226031Sstas 179226031Sstasstatic inline void 180226031Sstasdma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, 181226031Sstas enum dma_data_direction dir, struct dma_attrs *attrs) 182226031Sstas{ 183226031Sstas} 184226031Sstas 185226031Sstasstatic inline dma_addr_t 186226031Sstasdma_map_page(struct device *dev, struct page *page, 187226031Sstas unsigned long offset, size_t size, enum dma_data_direction direction) 188226031Sstas{ 189226031Sstas 190226031Sstas return VM_PAGE_TO_PHYS(page) + offset; 191226031Sstas} 192226031Sstas 193226031Sstasstatic inline void 194226128Sstasdma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, 195226128Sstas enum dma_data_direction direction) 196226128Sstas{ 197226128Sstas} 198226128Sstas 199226128Sstasstatic inline void 200226128Sstasdma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, 201226128Sstas enum dma_data_direction direction) 202226031Sstas{ 203226128Sstas} 204226031Sstas 205226031Sstasstatic inline void 206226031Sstasdma_sync_single(struct device *dev, dma_addr_t addr, size_t size, 207226031Sstas enum dma_data_direction dir) 208226031Sstas{ 209226031Sstas dma_sync_single_for_cpu(dev, addr, size, dir); 210226031Sstas} 211226031Sstas 212226031Sstasstatic inline void 213226031Sstasdma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, 214226031Sstas size_t size, enum dma_data_direction direction) 215226031Sstas{ 216226031Sstas} 217226031Sstas 218226128Sstasstatic inline void 219226128Sstasdma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, 220226031Sstas enum dma_data_direction direction) 221226128Sstas{ 222226128Sstas} 223226128Sstas 224226128Sstasstatic inline void 225226128Sstasdma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, 226226128Sstas enum dma_data_direction direction) 227226128Sstas{ 228226031Sstas} 229226128Sstas 230226128Sstasstatic inline void 231226031Sstasdma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle, 232226128Sstas unsigned long offset, size_t size, int direction) 233226031Sstas{ 234226031Sstas} 235226031Sstas 236226031Sstasstatic inline void 237226031Sstasdma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, 238226031Sstas unsigned long offset, size_t size, int direction) 239226031Sstas{ 240226031Sstas} 241226031Sstas 242226031Sstasstatic inline int 243226031Sstasdma_mapping_error(struct device *dev, dma_addr_t dma_addr) 244226031Sstas{ 245226031Sstas 246226031Sstas return (0); 247226031Sstas} 248226031Sstas 249226031Sstasstatic inline unsigned int dma_set_max_seg_size(struct device *dev, 250226031Sstas unsigned int size) 251226031Sstas{ 252226031Sstas return (0); 253226031Sstas} 254226031Sstas 255226031Sstas 256226031Sstas#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL) 257226031Sstas#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL) 258226031Sstas#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL) 259226031Sstas#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL) 260226031Sstas 261226031Sstas#define DEFINE_DMA_UNMAP_ADDR(name) dma_addr_t name 262226031Sstas#define DEFINE_DMA_UNMAP_LEN(name) __u32 name 263226031Sstas#define dma_unmap_addr(p, name) ((p)->name) 264226031Sstas#define dma_unmap_addr_set(p, name, v) (((p)->name) = (v)) 265226031Sstas#define dma_unmap_len(p, name) ((p)->name) 266226031Sstas#define dma_unmap_len_set(p, name, v) (((p)->name) = (v)) 267226031Sstas 268226031Sstasextern int uma_align_cache; 269226031Sstas#define dma_get_cache_alignment() uma_align_cache 270226031Sstas 271226031Sstas#endif /* _LINUX_DMA_MAPPING_H_ */ 272226031Sstas