1/*- 2 * Copyright (c) 2017 Jason A. Harmening. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29#ifndef _X86_BUS_DMA_H_ 30#define _X86_BUS_DMA_H_ 31 32#define WANT_INLINE_DMAMAP 33#include <sys/bus_dma.h> 34#include <sys/_null.h> 35 36#include <x86/busdma_impl.h> 37 38/* 39 * Is DMA address 1:1 mapping of physical address 40 */ 41static inline bool 42bus_dma_id_mapped(bus_dma_tag_t dmat, vm_paddr_t buf, bus_size_t buflen) 43{ 44 struct bus_dma_tag_common *tc; 45 46 tc = (struct bus_dma_tag_common *)dmat; 47 return (tc->impl->id_mapped(dmat, buf, buflen)); 48} 49 50/* 51 * Allocate a handle for mapping from kva/uva/physical 52 * address space into bus device space. 53 */ 54static inline int 55bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) 56{ 57 struct bus_dma_tag_common *tc; 58 59 tc = (struct bus_dma_tag_common *)dmat; 60 return (tc->impl->map_create(dmat, flags, mapp)); 61} 62 63/* 64 * Destroy a handle for mapping from kva/uva/physical 65 * address space into bus device space. 66 */ 67static inline int 68bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) 69{ 70 struct bus_dma_tag_common *tc; 71 72 tc = (struct bus_dma_tag_common *)dmat; 73 return (tc->impl->map_destroy(dmat, map)); 74} 75 76/* 77 * Allocate a piece of memory that can be efficiently mapped into 78 * bus device space based on the constraints lited in the dma tag. 79 * A dmamap to for use with dmamap_load is also allocated. 80 */ 81static inline int 82bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, 83 bus_dmamap_t *mapp) 84{ 85 struct bus_dma_tag_common *tc; 86 87 tc = (struct bus_dma_tag_common *)dmat; 88 return (tc->impl->mem_alloc(dmat, vaddr, flags, mapp)); 89} 90 91/* 92 * Free a piece of memory and it's allociated dmamap, that was allocated 93 * via bus_dmamem_alloc. Make the same choice for free/contigfree. 94 */ 95static inline void 96bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) 97{ 98 struct bus_dma_tag_common *tc; 99 100 tc = (struct bus_dma_tag_common *)dmat; 101 tc->impl->mem_free(dmat, vaddr, map); 102} 103 104/* 105 * Release the mapping held by map. 106 */ 107static inline void 108bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) 109{ 110 struct bus_dma_tag_common *tc; 111 112 if (map != NULL) { 113 tc = (struct bus_dma_tag_common *)dmat; 114 tc->impl->map_unload(dmat, map); 115 } 116} 117 118static inline void 119bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) 120{ 121 struct bus_dma_tag_common *tc; 122 123 if (map != NULL) { 124 tc = (struct bus_dma_tag_common *)dmat; 125 tc->impl->map_sync(dmat, map, op); 126 } 127} 128 129/* 130 * Utility function to load a physical buffer. segp contains 131 * the starting segment on entrace, and the ending segment on exit. 132 */ 133static inline int 134_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf, 135 bus_size_t buflen, int flags, bus_dma_segment_t *segs, int *segp) 136{ 137 struct bus_dma_tag_common *tc; 138 139 tc = (struct bus_dma_tag_common *)dmat; 140 return (tc->impl->load_phys(dmat, map, buf, buflen, flags, segs, 141 segp)); 142} 143 144static inline int 145_bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map, struct vm_page **ma, 146 bus_size_t tlen, int ma_offs, int flags, bus_dma_segment_t *segs, 147 int *segp) 148{ 149 struct bus_dma_tag_common *tc; 150 151 tc = (struct bus_dma_tag_common *)dmat; 152 return (tc->impl->load_ma(dmat, map, ma, tlen, ma_offs, flags, 153 segs, segp)); 154} 155 156/* 157 * Utility function to load a linear buffer. segp contains 158 * the starting segment on entrace, and the ending segment on exit. 159 */ 160static inline int 161_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 162 bus_size_t buflen, struct pmap *pmap, int flags, bus_dma_segment_t *segs, 163 int *segp) 164{ 165 struct bus_dma_tag_common *tc; 166 167 tc = (struct bus_dma_tag_common *)dmat; 168 return (tc->impl->load_buffer(dmat, map, buf, buflen, pmap, flags, segs, 169 segp)); 170} 171 172static inline void 173_bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map, 174 struct memdesc *mem, bus_dmamap_callback_t *callback, void *callback_arg) 175{ 176 struct bus_dma_tag_common *tc; 177 178 if (map != NULL) { 179 tc = (struct bus_dma_tag_common *)dmat; 180 tc->impl->map_waitok(dmat, map, mem, callback, callback_arg); 181 } 182} 183 184static inline bus_dma_segment_t * 185_bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map, 186 bus_dma_segment_t *segs, int nsegs, int error) 187{ 188 struct bus_dma_tag_common *tc; 189 190 tc = (struct bus_dma_tag_common *)dmat; 191 return (tc->impl->map_complete(dmat, map, segs, nsegs, error)); 192} 193 194#ifdef _KERNEL 195bool bus_dma_dmar_set_buswide(device_t dev); 196int bus_dma_dmar_load_ident(bus_dma_tag_t dmat, bus_dmamap_t map, 197 vm_paddr_t start, vm_size_t length, int flags); 198#endif 199 200#endif /* !_X86_BUS_DMA_H_ */ 201 202