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 * Allocate a handle for mapping from kva/uva/physical 40 * address space into bus device space. 41 */ 42 static inline int 43 bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) 44 { 45 struct bus_dma_tag_common *tc; 46 47 tc = (struct bus_dma_tag_common *)dmat; 48 return (tc->impl->map_create(dmat, flags, mapp)); 49 } 50 51 /* 52 * Destroy a handle for mapping from kva/uva/physical 53 * address space into bus device space. 54 */ 55 static inline int 56 bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) 57 { 58 struct bus_dma_tag_common *tc; 59 60 tc = (struct bus_dma_tag_common *)dmat; 61 return (tc->impl->map_destroy(dmat, map)); 62 } 63 64 /* 65 * Allocate a piece of memory that can be efficiently mapped into 66 * bus device space based on the constraints lited in the dma tag. 67 * A dmamap to for use with dmamap_load is also allocated. 68 */ 69 static inline int 70 bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, 71 bus_dmamap_t *mapp) 72 { 73 struct bus_dma_tag_common *tc; 74 75 tc = (struct bus_dma_tag_common *)dmat; 76 return (tc->impl->mem_alloc(dmat, vaddr, flags, mapp)); 77 } 78 79 /* 80 * Free a piece of memory and it's allociated dmamap, that was allocated 81 * via bus_dmamem_alloc. Make the same choice for free/contigfree. 82 */ 83 static inline void 84 bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) 85 { 86 struct bus_dma_tag_common *tc; 87 88 tc = (struct bus_dma_tag_common *)dmat; 89 tc->impl->mem_free(dmat, vaddr, map); 90 } 91 92 /* 93 * Release the mapping held by map. 94 */ 95 static inline void 96 bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) 97 { 98 struct bus_dma_tag_common *tc; 99 100 if (map != NULL) { 101 tc = (struct bus_dma_tag_common *)dmat; 102 tc->impl->map_unload(dmat, map); 103 } 104 } 105 106 static inline void 107 bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) 108 { 109 struct bus_dma_tag_common *tc; 110 111 if (map != NULL) { 112 tc = (struct bus_dma_tag_common *)dmat; 113 tc->impl->map_sync(dmat, map, op); 114 } 115 } 116 117 /* 118 * Utility function to load a physical buffer. segp contains 119 * the starting segment on entrace, and the ending segment on exit. 120 */ 121 static inline int 122 _bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf, 123 bus_size_t buflen, int flags, bus_dma_segment_t *segs, int *segp) 124 { 125 struct bus_dma_tag_common *tc; 126 127 tc = (struct bus_dma_tag_common *)dmat; 128 return (tc->impl->load_phys(dmat, map, buf, buflen, flags, segs, 129 segp)); 130 } 131 132 static inline int 133 _bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map, struct vm_page **ma, 134 bus_size_t tlen, int ma_offs, int flags, bus_dma_segment_t *segs, 135 int *segp) 136 { 137 struct bus_dma_tag_common *tc; 138 139 tc = (struct bus_dma_tag_common *)dmat; 140 return (tc->impl->load_ma(dmat, map, ma, tlen, ma_offs, flags, 141 segs, segp)); 142 } 143 144 /* 145 * Utility function to load a linear buffer. segp contains 146 * the starting segment on entrace, and the ending segment on exit. 147 */ 148 static inline int 149 _bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, 150 bus_size_t buflen, struct pmap *pmap, int flags, bus_dma_segment_t *segs, 151 int *segp) 152 { 153 struct bus_dma_tag_common *tc; 154 155 tc = (struct bus_dma_tag_common *)dmat; 156 return (tc->impl->load_buffer(dmat, map, buf, buflen, pmap, flags, segs, 157 segp)); 158 } 159 160 static inline void 161 _bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map, 162 struct memdesc *mem, bus_dmamap_callback_t *callback, void *callback_arg) 163 { 164 struct bus_dma_tag_common *tc; 165 166 if (map != NULL) { 167 tc = (struct bus_dma_tag_common *)dmat; 168 tc->impl->map_waitok(dmat, map, mem, callback, callback_arg); 169 } 170 } 171 172 static inline bus_dma_segment_t * 173 _bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map, 174 bus_dma_segment_t *segs, int nsegs, int error) 175 { 176 struct bus_dma_tag_common *tc; 177 178 tc = (struct bus_dma_tag_common *)dmat; 179 return (tc->impl->map_complete(dmat, map, segs, nsegs, error)); 180 } 181 182 #endif /* !_X86_BUS_DMA_H_ */ 183 184