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