| Commit | Line | Data |
|---|---|---|
| 1f7ab7c9 MD |
1 | /*- |
| 2 | * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. | |
| 3 | * All rights reserved. | |
| 4 | * | |
| 5 | * This code is derived from software contributed to The NetBSD Foundation | |
| 6 | * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, | |
| 7 | * NASA Ames Research Center. | |
| 8 | * | |
| 9 | * Redistribution and use in source and binary forms, with or without | |
| 10 | * modification, are permitted provided that the following conditions | |
| 11 | * are met: | |
| 12 | * 1. Redistributions of source code must retain the above copyright | |
| 13 | * notice, this list of conditions and the following disclaimer. | |
| 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 15 | * notice, this list of conditions and the following disclaimer in the | |
| 16 | * documentation and/or other materials provided with the distribution. | |
| 17 | * 3. All advertising materials mentioning features or use of this software | |
| 18 | * must display the following acknowledgement: | |
| 19 | * This product includes software developed by the NetBSD | |
| 20 | * Foundation, Inc. and its contributors. | |
| 21 | * 4. Neither the name of The NetBSD Foundation nor the names of its | |
| 22 | * contributors may be used to endorse or promote products derived | |
| 23 | * from this software without specific prior written permission. | |
| 24 | * | |
| 25 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
| 26 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
| 27 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 28 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
| 29 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| 30 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| 31 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| 32 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| 33 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 35 | * POSSIBILITY OF SUCH DAMAGE. | |
| 36 | */ | |
| 37 | /* | |
| 38 | * Copyright (c) 1996 Charles M. Hannum. All rights reserved. | |
| 39 | * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. | |
| 40 | * | |
| 41 | * Redistribution and use in source and binary forms, with or without | |
| 42 | * modification, are permitted provided that the following conditions | |
| 43 | * are met: | |
| 44 | * 1. Redistributions of source code must retain the above copyright | |
| 45 | * notice, this list of conditions and the following disclaimer. | |
| 46 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 47 | * notice, this list of conditions and the following disclaimer in the | |
| 48 | * documentation and/or other materials provided with the distribution. | |
| 49 | * 3. All advertising materials mentioning features or use of this software | |
| 50 | * must display the following acknowledgement: | |
| 51 | * This product includes software developed by Christopher G. Demetriou | |
| 52 | * for the NetBSD Project. | |
| 53 | * 4. The name of the author may not be used to endorse or promote products | |
| 54 | * derived from this software without specific prior written permission | |
| 55 | * | |
| 56 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
| 57 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
| 58 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
| 59 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 60 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 61 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 62 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 63 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 64 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
| 65 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 66 | */ | |
| 67 | /* | |
| 68 | * $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ | |
| 69 | * $FreeBSD: src/sys/i386/include/bus_dma.h,v 1.15.2.2 2002/11/21 23:36:01 sam Exp $ | |
| 70 | * $DragonFly: src/sys/sys/bus_dma.h,v 1.1 2006/10/25 20:56:03 dillon Exp $ | |
| 71 | */ | |
| 72 | ||
| 73 | #ifndef _SYS_BUS_DMA_H_ | |
| 74 | #define _SYS_BUS_DMA_H_ | |
| 75 | ||
| 76 | /* | |
| 77 | * Include machine-specific bus stuff | |
| 78 | */ | |
| 79 | #ifndef _MACHINE_BUS_DMA_H_ | |
| 80 | #include <machine/bus_dma.h> /* bus_addr_t */ | |
| 81 | #endif | |
| 82 | ||
| 83 | /* | |
| 84 | * Flags used in various bus DMA methods. | |
| 85 | */ | |
| 90a9e482 SZ |
86 | #define BUS_DMA_WAITOK 0x0000 /* safe to sleep (pseudo-flag) */ |
| 87 | #define BUS_DMA_NOWAIT 0x0001 /* not safe to sleep */ | |
| 88 | #define BUS_DMA_ALLOCNOW 0x0002 /* perform resource allocation now */ | |
| 89 | #define BUS_DMA_COHERENT 0x0004 /* map memory to not require sync */ | |
| 90 | #define BUS_DMA_ZERO 0x0008 /* allocate zero'ed memory */ | |
| 91 | #define BUS_DMA_BUS1 0x0010 /* placeholders for bus functions... */ | |
| 92 | #define BUS_DMA_BUS2 0x0020 | |
| 93 | #define BUS_DMA_BUS3 0x0040 | |
| 94 | #define BUS_DMA_BUS4 0x0080 | |
| 95 | #define BUS_DMA_ONEBPAGE 0x0100 /* allocate one bpage per map at most */ | |
| 96 | #define BUS_DMA_ALIGNED 0x0200 /* no bpage should be allocated due to | |
| 97 | * alignment requirement; all to-be- | |
| 98 | * loaded memory is properly aligned */ | |
| 7dbe273f SZ |
99 | #define BUS_DMA_PRIVBZONE 0x0400 /* need private bounce zone */ |
| 100 | #define BUS_DMA_ALLOCALL 0x0800 /* allocate all needed resources */ | |
| c26842b6 SZ |
101 | #define BUS_DMA_PROTECTED 0x1000 /* all busdma functions are already |
| 102 | * protected */ | |
| 1f7ab7c9 MD |
103 | |
| 104 | /* Forwards needed by prototypes below. */ | |
| 105 | struct mbuf; | |
| 106 | struct uio; | |
| 107 | ||
| 108 | /* | |
| 109 | * bus_dmasync_op_t | |
| 110 | * | |
| 111 | * Operations performed by bus_dmamap_sync(). | |
| 112 | */ | |
| 113 | typedef enum { | |
| 114 | BUS_DMASYNC_PREREAD, | |
| 115 | BUS_DMASYNC_POSTREAD, | |
| 116 | BUS_DMASYNC_PREWRITE, | |
| 117 | BUS_DMASYNC_POSTWRITE | |
| 118 | } bus_dmasync_op_t; | |
| 119 | ||
| 120 | /* | |
| 121 | * bus_dma_tag_t | |
| 122 | * | |
| 123 | * A machine-dependent opaque type describing the characteristics | |
| 124 | * of how to perform DMA mappings. This structure encapsultes | |
| 125 | * information concerning address and alignment restrictions, number | |
| 126 | * of S/G segments, amount of data per S/G segment, etc. | |
| 127 | */ | |
| 128 | typedef struct bus_dma_tag *bus_dma_tag_t; | |
| 129 | ||
| 130 | /* | |
| 131 | * bus_dmamap_t | |
| 132 | * | |
| 133 | * DMA mapping instance information. | |
| 134 | */ | |
| 135 | typedef struct bus_dmamap *bus_dmamap_t; | |
| 136 | ||
| 137 | /* | |
| 138 | * bus_dma_segment_t | |
| 139 | * | |
| 140 | * Describes a single contiguous DMA transaction. Values | |
| 141 | * are suitable for programming into DMA registers. | |
| 142 | */ | |
| 143 | typedef struct bus_dma_segment { | |
| 144 | bus_addr_t ds_addr; /* DMA address */ | |
| 145 | bus_size_t ds_len; /* length of transfer */ | |
| 146 | } bus_dma_segment_t; | |
| 147 | ||
| 0336fbc8 SZ |
148 | typedef struct bus_dmamem { |
| 149 | bus_dma_tag_t dmem_tag; | |
| 150 | bus_dmamap_t dmem_map; | |
| 151 | void *dmem_addr; | |
| 152 | bus_addr_t dmem_busaddr; | |
| 153 | } bus_dmamem_t; | |
| 154 | ||
| 1f7ab7c9 MD |
155 | /* |
| 156 | * A function that returns 1 if the address cannot be accessed by | |
| 157 | * a device and 0 if it can be. | |
| 158 | */ | |
| 159 | typedef int bus_dma_filter_t(void *, bus_addr_t); | |
| 160 | ||
| 161 | /* | |
| 162 | * Allocate a device specific dma_tag encapsulating the constraints of | |
| 163 | * the parent tag in addition to other restrictions specified: | |
| 164 | * | |
| 165 | * alignment: alignment for segments. | |
| 166 | * boundary: Boundary that segments cannot cross. | |
| 167 | * lowaddr: Low restricted address that cannot appear in a mapping. | |
| 168 | * highaddr: High restricted address that cannot appear in a mapping. | |
| 169 | * filtfunc: An optional function to further test if an address | |
| 170 | * within the range of lowaddr and highaddr cannot appear | |
| 171 | * in a mapping. | |
| 172 | * filtfuncarg: An argument that will be passed to filtfunc in addition | |
| 173 | * to the address to test. | |
| 174 | * maxsize: Maximum mapping size supported by this tag. | |
| 175 | * nsegments: Number of discontinuities allowed in maps. | |
| 176 | * maxsegsz: Maximum size of a segment in the map. | |
| 177 | * flags: Bus DMA flags. | |
| 178 | * dmat: A pointer to set to a valid dma tag should the return | |
| 179 | * value of this function indicate success. | |
| 180 | */ | |
| 181 | /* XXX Should probably allow specification of alignment */ | |
| 182 | int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, | |
| 183 | bus_size_t boundary, bus_addr_t lowaddr, | |
| 184 | bus_addr_t highaddr, bus_dma_filter_t *filtfunc, | |
| 185 | void *filtfuncarg, bus_size_t maxsize, int nsegments, | |
| 186 | bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat); | |
| 187 | ||
| 188 | int bus_dma_tag_destroy(bus_dma_tag_t dmat); | |
| b97bcf45 | 189 | bus_size_t bus_dma_tag_getmaxsize(bus_dma_tag_t tag); |
| 1f7ab7c9 MD |
190 | |
| 191 | /* | |
| 192 | * Allocate a handle for mapping from kva/uva/physical | |
| 193 | * address space into bus device space. | |
| 194 | */ | |
| 195 | int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); | |
| 196 | ||
| 197 | /* | |
| 198 | * Destroy a handle for mapping from kva/uva/physical | |
| 199 | * address space into bus device space. | |
| 200 | */ | |
| 201 | int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map); | |
| 202 | ||
| 203 | /* | |
| 204 | * Allocate a piece of memory that can be efficiently mapped into | |
| 205 | * bus device space based on the constraints lited in the dma tag. | |
| 206 | * A dmamap to for use with dmamap_load is also allocated. | |
| 207 | */ | |
| 208 | int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, | |
| 209 | bus_dmamap_t *mapp); | |
| 210 | ||
| 211 | /* | |
| 212 | * Free a piece of memory and it's allociated dmamap, that was allocated | |
| 213 | * via bus_dmamem_alloc. | |
| 214 | */ | |
| 215 | void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map); | |
| 216 | ||
| 217 | /* | |
| 218 | * A function that processes a successfully loaded dma map or an error | |
| 219 | * from a delayed load map. | |
| 220 | */ | |
| 221 | typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); | |
| 222 | ||
| 223 | /* | |
| 224 | * Map the buffer buf into bus space using the dmamap map. | |
| 225 | */ | |
| 226 | int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, | |
| 227 | bus_size_t buflen, bus_dmamap_callback_t *callback, | |
| 228 | void *callback_arg, int flags); | |
| 229 | ||
| 230 | /* | |
| 231 | * Like bus_dmamap_callback but includes map size in bytes. This is | |
| 232 | * defined as a separate interface to maintain compatiiblity for users | |
| 233 | * of bus_dmamap_callback_t--at some point these interfaces should be merged. | |
| 234 | */ | |
| 235 | typedef void bus_dmamap_callback2_t(void *, bus_dma_segment_t *, int, bus_size_t, int); | |
| 236 | /* | |
| 237 | * Like bus_dmamap_load but for mbufs. Note the use of the | |
| 238 | * bus_dmamap_callback2_t interface. | |
| 239 | */ | |
| 240 | int bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, | |
| 241 | struct mbuf *mbuf, | |
| 242 | bus_dmamap_callback2_t *callback, void *callback_arg, | |
| 243 | int flags); | |
| 244 | /* | |
| 245 | * Like bus_dmamap_load but for uios. Note the use of the | |
| 246 | * bus_dmamap_callback2_t interface. | |
| 247 | */ | |
| 248 | int bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, | |
| 249 | struct uio *ui, | |
| 250 | bus_dmamap_callback2_t *callback, void *callback_arg, | |
| 251 | int flags); | |
| 252 | ||
| 253 | /* | |
| aa2d9ae8 SZ |
254 | * Like bus_dmamap_load_mbuf without callback. |
| 255 | * Segmentation information are saved in 'segs' and 'nsegs' if | |
| 256 | * the loading is successful. 'maxsegs' must be set by caller | |
| 257 | * and must be at least 1 but less than 'dmat' nsegment. It | |
| 258 | * indicates the number of elements in 'segs'. 'flags' must | |
| 259 | * have BUS_DMA_NOWAIT turned on. | |
| 260 | */ | |
| 261 | int | |
| 262 | bus_dmamap_load_mbuf_segment(bus_dma_tag_t dmat, bus_dmamap_t map, | |
| 263 | struct mbuf *mbuf, | |
| 264 | bus_dma_segment_t *segs, int maxsegs, | |
| 265 | int *nsegs, int flags); | |
| 266 | ||
| 267 | /* | |
| b83f28b9 SZ |
268 | * Like bus_dmamap_load_mbuf_segment, but it will call m_defrag() |
| 269 | * and try reloading if low level code indicates too many fragments | |
| 270 | * in the '*mbuf'; 'mbuf' will be updated under this situation. | |
| 271 | */ | |
| 272 | int | |
| 273 | bus_dmamap_load_mbuf_defrag(bus_dma_tag_t dmat, bus_dmamap_t map, | |
| 274 | struct mbuf **mbuf, | |
| 275 | bus_dma_segment_t *segs, int maxsegs, | |
| 276 | int *nsegs, int flags); | |
| 277 | ||
| 278 | /* | |
| 0336fbc8 SZ |
279 | * Convenient function to create coherent busdma memory |
| 280 | */ | |
| 281 | int | |
| 282 | bus_dmamem_coherent(bus_dma_tag_t parent, | |
| 283 | bus_size_t alignment, bus_size_t boundary, | |
| 284 | bus_addr_t lowaddr, bus_addr_t highaddr, | |
| 285 | bus_size_t maxsize, int flags, | |
| 286 | bus_dmamem_t *dmem); | |
| 287 | ||
| 288 | /* | |
| 8ecafcc7 SZ |
289 | * Simplified version of bus_dmamem_coherent() with: |
| 290 | * boundary == 0 | |
| 291 | * lowaddr == BUS_SPACE_MAXADDR | |
| 292 | * highaddr == BUS_SPACE_MAXADDR | |
| 293 | * | |
| 294 | * 'parent' usually should not be NULL, so we could inherit | |
| 295 | * boundary, lowaddr and highaddr from it. | |
| 296 | */ | |
| 297 | void * | |
| 298 | bus_dmamem_coherent_any(bus_dma_tag_t parent, bus_size_t alignment, | |
| 299 | bus_size_t maxsize, int flags, | |
| 300 | bus_dma_tag_t *dtag, bus_dmamap_t *dmap, | |
| 301 | bus_addr_t *busaddr); | |
| 302 | ||
| 303 | /* | |
| 1f7ab7c9 MD |
304 | * Perform a syncronization operation on the given map. |
| 305 | */ | |
| 306 | void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t); | |
| 307 | #define bus_dmamap_sync(dmat, dmamap, op) \ | |
| 308 | if ((dmamap) != NULL) \ | |
| 309 | _bus_dmamap_sync(dmat, dmamap, op) | |
| 310 | ||
| 311 | /* | |
| 312 | * Release the mapping held by map. | |
| 313 | */ | |
| 314 | void _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map); | |
| 315 | #define bus_dmamap_unload(dmat, dmamap) \ | |
| 316 | if ((dmamap) != NULL) \ | |
| 317 | _bus_dmamap_unload(dmat, dmamap) | |
| 318 | ||
| 319 | #endif /* _SYS_BUS_DMA_H_ */ |