1 /* $NetBSD: tc_dma_3000_500.c,v 1.19 2013/11/04 16:56:17 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 34 35 __KERNEL_RCSID(0, "$NetBSD: tc_dma_3000_500.c,v 1.19 2013/11/04 16:56:17 christos Exp $"); 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/device.h> 40 #include <sys/kernel.h> 41 #include <sys/malloc.h> 42 43 #define _ALPHA_BUS_DMA_PRIVATE 44 #include <sys/bus.h> 45 46 #include <dev/tc/tcvar.h> 47 #include <alpha/tc/tc_sgmap.h> 48 #include <alpha/tc/tc_dma_3000_500.h> 49 50 struct alpha_bus_dma_tag tc_dmat_sgmap = { 51 NULL, /* _cookie */ 52 0, /* _wbase */ 53 0, /* _wsize */ 54 NULL, /* _next_window */ 55 0, /* _boundary */ 56 NULL, /* _sgmap */ 57 0, /* _pfthresh */ 58 NULL, /* _get_tag */ 59 tc_bus_dmamap_create_sgmap, 60 tc_bus_dmamap_destroy_sgmap, 61 tc_bus_dmamap_load_sgmap, 62 tc_bus_dmamap_load_mbuf_sgmap, 63 tc_bus_dmamap_load_uio_sgmap, 64 tc_bus_dmamap_load_raw_sgmap, 65 tc_bus_dmamap_unload_sgmap, 66 _bus_dmamap_sync, 67 _bus_dmamem_alloc, 68 _bus_dmamem_free, 69 _bus_dmamem_map, 70 _bus_dmamem_unmap, 71 _bus_dmamem_mmap, 72 }; 73 74 struct tc_dma_slot_info { 75 struct alpha_sgmap tdsi_sgmap; /* sgmap for slot */ 76 struct alpha_bus_dma_tag tdsi_dmat; /* dma tag for slot */ 77 }; 78 struct tc_dma_slot_info *tc_dma_slot_info; 79 80 void 81 tc_dma_init_3000_500(int nslots) 82 { 83 extern struct alpha_bus_dma_tag tc_dmat_direct; 84 size_t sisize; 85 int i; 86 87 /* Allocate per-slot DMA info. */ 88 sisize = nslots * sizeof(struct tc_dma_slot_info); 89 tc_dma_slot_info = malloc(sisize, M_DEVBUF, M_NOWAIT); 90 if (tc_dma_slot_info == NULL) 91 panic("tc_dma_init: can't allocate per-slot DMA info"); 92 memset(tc_dma_slot_info, 0, sisize); 93 94 /* Default all slots to direct-mapped. */ 95 for (i = 0; i < nslots; i++) 96 memcpy(&tc_dma_slot_info[i].tdsi_dmat, &tc_dmat_direct, 97 sizeof(tc_dma_slot_info[i].tdsi_dmat)); 98 } 99 100 /* 101 * Return the DMA tag for the given slot. 102 */ 103 bus_dma_tag_t 104 tc_dma_get_tag_3000_500(int slot) 105 { 106 107 return (&tc_dma_slot_info[slot].tdsi_dmat); 108 } 109 110 /* 111 * Create a TurboChannel SGMAP-mapped DMA map. 112 */ 113 int 114 tc_bus_dmamap_create_sgmap( 115 bus_dma_tag_t t, 116 bus_size_t size, 117 int nsegments, 118 bus_size_t maxsegsz, 119 bus_size_t boundary, 120 int flags, 121 bus_dmamap_t *dmamp) 122 { 123 int error; 124 125 error = _bus_dmamap_create(t, size, nsegments, maxsegsz, 126 boundary, flags, dmamp); 127 if (error) 128 return (error); 129 130 (void)*dmamp; 131 132 /* XXX BUS_DMA_ALLOCNOW */ 133 134 return (error); 135 } 136 137 /* 138 * Destroy a TurboChannel SGMAP-mapped DMA map. 139 */ 140 void 141 tc_bus_dmamap_destroy_sgmap(bus_dma_tag_t t, bus_dmamap_t map) 142 { 143 144 KASSERT(map->dm_mapsize == 0); 145 146 _bus_dmamap_destroy(t, map); 147 } 148 149 /* 150 * Load a TurboChannel SGMAP-mapped DMA map with a linear buffer. 151 */ 152 int 153 tc_bus_dmamap_load_sgmap(bus_dma_tag_t t, bus_dmamap_t map, void *buf, bus_size_t buflen, struct proc *p, int flags) 154 { 155 struct tc_dma_slot_info *tdsi = t->_cookie; 156 157 return (tc_sgmap_load(t, map, buf, buflen, p, flags, 158 &tdsi->tdsi_sgmap)); 159 } 160 161 /* 162 * Load a TurboChannel SGMAP-mapped DMA map with an mbuf chain. 163 */ 164 int 165 tc_bus_dmamap_load_mbuf_sgmap(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m, int flags) 166 { 167 struct tc_dma_slot_info *tdsi = t->_cookie; 168 169 return (tc_sgmap_load_mbuf(t, map, m, flags, &tdsi->tdsi_sgmap)); 170 } 171 172 /* 173 * Load a TurboChannel SGMAP-mapped DMA map with a uio. 174 */ 175 int 176 tc_bus_dmamap_load_uio_sgmap(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio, int flags) 177 { 178 struct tc_dma_slot_info *tdsi = t->_cookie; 179 180 return (tc_sgmap_load_uio(t, map, uio, flags, &tdsi->tdsi_sgmap)); 181 } 182 183 /* 184 * Load a TurboChannel SGMAP-mapped DMA map with raw memory. 185 */ 186 int 187 tc_bus_dmamap_load_raw_sgmap(bus_dma_tag_t t, bus_dmamap_t map, bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags) 188 { 189 struct tc_dma_slot_info *tdsi = t->_cookie; 190 191 return (tc_sgmap_load_raw(t, map, segs, nsegs, size, flags, 192 &tdsi->tdsi_sgmap)); 193 } 194 195 /* 196 * Unload a TurboChannel SGMAP-mapped DMA map. 197 */ 198 void 199 tc_bus_dmamap_unload_sgmap(bus_dma_tag_t t, bus_dmamap_t map) 200 { 201 struct tc_dma_slot_info *tdsi = t->_cookie; 202 203 /* 204 * Invalidate any SGMAP page table entries used by this 205 * mapping. 206 */ 207 tc_sgmap_unload(t, map, &tdsi->tdsi_sgmap); 208 209 /* 210 * Do the generic bits of the unload. 211 */ 212 _bus_dmamap_unload(t, map); 213 } 214