Mon Jan 4 18:23:10 2021 UTC ()
malloc(9) -> kmem(9)


(thorpej)
diff -r1.12 -r1.13 src/sys/arch/atari/isa/isa_dma.c

cvs diff -r1.12 -r1.13 src/sys/arch/atari/isa/isa_dma.c (expand / switch to unified diff)

--- src/sys/arch/atari/isa/isa_dma.c 2016/02/26 18:16:51 1.12
+++ src/sys/arch/atari/isa/isa_dma.c 2021/01/04 18:23:10 1.13
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: isa_dma.c,v 1.12 2016/02/26 18:16:51 christos Exp $ */ 1/* $NetBSD: isa_dma.c,v 1.13 2021/01/04 18:23:10 thorpej Exp $ */
2 2
3#define ISA_DMA_STATS 3#define ISA_DMA_STATS
4 4
5/*- 5/*-
6 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 6 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * This code is derived from software contributed to The NetBSD Foundation 9 * This code is derived from software contributed to The NetBSD Foundation
10 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 10 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
11 * Simulation Facility, NASA Ames Research Center. 11 * Simulation Facility, NASA Ames Research Center.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions 14 * modification, are permitted provided that the following conditions
@@ -23,34 +23,34 @@ @@ -23,34 +23,34 @@
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE. 32 * POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: isa_dma.c,v 1.12 2016/02/26 18:16:51 christos Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: isa_dma.c,v 1.13 2021/01/04 18:23:10 thorpej Exp $");
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/systm.h> 39#include <sys/systm.h>
40#include <sys/kernel.h> 40#include <sys/kernel.h>
41#include <sys/syslog.h> 41#include <sys/syslog.h>
42#include <sys/device.h> 42#include <sys/device.h>
43#include <sys/malloc.h> 43#include <sys/kmem.h>
44#include <sys/proc.h> 44#include <sys/proc.h>
45#include <sys/mbuf.h> 45#include <sys/mbuf.h>
46 46
47#define _ATARI_BUS_DMA_PRIVATE 47#define _ATARI_BUS_DMA_PRIVATE
48#include <sys/bus.h> 48#include <sys/bus.h>
49 49
50#include <dev/isa/isareg.h> 50#include <dev/isa/isareg.h>
51#include <dev/isa/isavar.h> 51#include <dev/isa/isavar.h>
52 52
53#include <uvm/uvm_extern.h> 53#include <uvm/uvm_extern.h>
54 54
55extern paddr_t avail_end; 55extern paddr_t avail_end;
56 56
@@ -140,48 +140,31 @@ struct atari_bus_dma_tag isa_bus_dma_tag @@ -140,48 +140,31 @@ struct atari_bus_dma_tag isa_bus_dma_tag
140 if ((v) == 0) \ 140 if ((v) == 0) \
141 printf("%s:%d -- Already 0!\n", __FILE__, __LINE__); \ 141 printf("%s:%d -- Already 0!\n", __FILE__, __LINE__); \
142 else \ 142 else \
143 (v)--; \ 143 (v)--; \
144 } while (0) 144 } while (0)
145u_long isa_dma_stats_loads; 145u_long isa_dma_stats_loads;
146u_long isa_dma_stats_bounces; 146u_long isa_dma_stats_bounces;
147u_long isa_dma_stats_nbouncebufs; 147u_long isa_dma_stats_nbouncebufs;
148#else 148#else
149#define STAT_INCR(v) 149#define STAT_INCR(v)
150#define STAT_DECR(v) 150#define STAT_DECR(v)
151#endif 151#endif
152 152
153/* 153static int
154 * Create an ISA DMA map. 154isadma_bounce_cookieflags(bus_dma_tag_t const t, bus_dmamap_t const map,
155 */ 155 int const flags)
156int 
157_isa_bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp) 
158{ 156{
159 struct atari_isa_dma_cookie *cookie; 157 int cookieflags = 0;
160 bus_dmamap_t map; 
161 int error, cookieflags; 
162 void *cookiestore; 
163 size_t cookiesize; 
164 
165 /* Call common function to create the basic map. */ 
166 error = _bus_dmamap_create(t, size, nsegments, maxsegsz, boundary, 
167 flags, dmamp); 
168 if (error) 
169 return (error); 
170 
171 map = *dmamp; 
172 map->_dm_cookie = NULL; 
173 
174 cookiesize = sizeof(struct atari_isa_dma_cookie); 
175 158
176 /* 159 /*
177 * ISA only has 24-bits of address space. This means 160 * ISA only has 24-bits of address space. This means
178 * we can't DMA to pages over 16M. In order to DMA to 161 * we can't DMA to pages over 16M. In order to DMA to
179 * arbitrary buffers, we use "bounce buffers" - pages 162 * arbitrary buffers, we use "bounce buffers" - pages
180 * in memory below the 16M boundary. On DMA reads, 163 * in memory below the 16M boundary. On DMA reads,
181 * DMA happens to the bounce buffers, and is copied into 164 * DMA happens to the bounce buffers, and is copied into
182 * the caller's buffer. On writes, data is copied into 165 * the caller's buffer. On writes, data is copied into
183 * but bounce buffer, and the DMA happens from those 166 * but bounce buffer, and the DMA happens from those
184 * pages. To software using the DMA mapping interface, 167 * pages. To software using the DMA mapping interface,
185 * this looks simply like a data cache. 168 * this looks simply like a data cache.
186 * 169 *
187 * If we have more than 16M of RAM in the system, we may 170 * If we have more than 16M of RAM in the system, we may
@@ -190,81 +173,134 @@ _isa_bus_dmamap_create(bus_dma_tag_t t,  @@ -190,81 +173,134 @@ _isa_bus_dmamap_create(bus_dma_tag_t t,
190 * There are exceptions, however. VLB devices can do 173 * There are exceptions, however. VLB devices can do
191 * 32-bit DMA, and indicate that here. 174 * 32-bit DMA, and indicate that here.
192 * 175 *
193 * ...or, there is an opposite case. The most segments 176 * ...or, there is an opposite case. The most segments
194 * a transfer will require is (maxxfer / PAGE_SIZE) + 1. If 177 * a transfer will require is (maxxfer / PAGE_SIZE) + 1. If
195 * the caller can't handle that many segments (e.g. the 178 * the caller can't handle that many segments (e.g. the
196 * ISA DMA controller), we may have to bounce it as well. 179 * ISA DMA controller), we may have to bounce it as well.
197 */ 180 */
198 if (avail_end <= t->_bounce_thresh || 181 if (avail_end <= t->_bounce_thresh ||
199 (flags & ISABUS_DMA_32BIT) != 0) { 182 (flags & ISABUS_DMA_32BIT) != 0) {
200 /* Bouncing not necessary due to memory size. */  183 /* Bouncing not necessary due to memory size. */
201 map->_dm_bounce_thresh = 0; 184 map->_dm_bounce_thresh = 0;
202 } 185 }
203 cookieflags = 0; 
204 if (map->_dm_bounce_thresh != 0 || 186 if (map->_dm_bounce_thresh != 0 ||
205 ((map->_dm_size / PAGE_SIZE) + 1) > map->_dm_segcnt) { 187 ((map->_dm_size / PAGE_SIZE) + 1) > map->_dm_segcnt) {
206 cookieflags |= ID_MIGHT_NEED_BOUNCE; 188 cookieflags |= ID_MIGHT_NEED_BOUNCE;
 189 }
 190 return cookieflags;
 191}
 192
 193static size_t
 194isadma_bounce_cookiesize(bus_dmamap_t const map, int cookieflags)
 195{
 196 size_t cookiesize = sizeof(struct atari_isa_dma_cookie);
 197
 198 if (cookieflags & ID_MIGHT_NEED_BOUNCE) {
207 cookiesize += (sizeof(bus_dma_segment_t) * map->_dm_segcnt); 199 cookiesize += (sizeof(bus_dma_segment_t) * map->_dm_segcnt);
208 } 200 }
 201 return cookiesize;
 202}
 203
 204static int
 205isadma_bounce_cookie_alloc(bus_dma_tag_t const t, bus_dmamap_t const map,
 206 int const flags)
 207{
 208 struct atari_isa_dma_cookie *cookie;
 209 int cookieflags = isadma_bounce_cookieflags(t, map, flags);
 210
 211 if ((cookie = kmem_zalloc(isadma_bounce_cookiesize(map, cookieflags),
 212 (flags & BUS_DMA_NOWAIT) ? KM_NOSLEEP : KM_SLEEP)) == NULL) {
 213 return ENOMEM;
 214 }
 215
 216 cookie->id_flags = cookieflags;
 217 map->_dm_cookie = cookie;
 218
 219 return 0;
 220}
 221
 222static void
 223isadma_bounce_cookie_free(bus_dmamap_t const map)
 224{
 225 struct atari_isa_dma_cookie *cookie = map->_dm_cookie;
 226
 227 if (cookie != NULL) {
 228 kmem_free(map->_dm_cookie,
 229 isadma_bounce_cookiesize(map, cookie->id_flags));
 230 map->_dm_cookie = NULL;
 231 }
 232}
 233
 234/*
 235 * Create an ISA DMA map.
 236 */
 237int
 238_isa_bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp)
 239{
 240 struct atari_isa_dma_cookie *cookie;
 241 bus_dmamap_t map;
 242 int error;
 243
 244 /* Call common function to create the basic map. */
 245 error = _bus_dmamap_create(t, size, nsegments, maxsegsz, boundary,
 246 flags, dmamp);
 247 if (error)
 248 return (error);
 249
 250 map = *dmamp;
 251 map->_dm_cookie = NULL;
209 252
210 /* 253 /*
211 * Allocate our cookie. 254 * Allocate our cookie.
212 */ 255 */
213 if ((cookiestore = malloc(cookiesize, M_DMAMAP, 256 if ((error = isadma_bounce_cookie_alloc(t, map, flags)) != 0) {
214 (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) { 
215 error = ENOMEM; 
216 goto out; 257 goto out;
217 } 258 }
218 memset(cookiestore, 0, cookiesize); 259 cookie = map->_dm_cookie;
219 cookie = (struct atari_isa_dma_cookie *)cookiestore; 
220 cookie->id_flags = cookieflags; 
221 map->_dm_cookie = cookie; 
222 260
223 if (cookieflags & ID_MIGHT_NEED_BOUNCE) { 261 if (cookie->id_flags & ID_MIGHT_NEED_BOUNCE) {
224 /* 262 /*
225 * Allocate the bounce pages now if the caller 263 * Allocate the bounce pages now if the caller
226 * wishes us to do so. 264 * wishes us to do so.
227 */ 265 */
228 if ((flags & BUS_DMA_ALLOCNOW) == 0) 266 if (flags & BUS_DMA_ALLOCNOW) {
229 goto out; 267 error = _isa_dma_alloc_bouncebuf(t, map, size, flags);
230 268 }
231 error = _isa_dma_alloc_bouncebuf(t, map, size, flags); 
232 } 269 }
233 270
234 out: 271 out:
235 if (error) { 272 if (error) {
236 if (map->_dm_cookie != NULL) 273 isadma_bounce_cookie_free(map);
237 free(map->_dm_cookie, M_DMAMAP); 
238 _bus_dmamap_destroy(t, map); 274 _bus_dmamap_destroy(t, map);
239 } 275 }
240 return (error); 276 return (error);
241} 277}
242 278
243/* 279/*
244 * Destroy an ISA DMA map. 280 * Destroy an ISA DMA map.
245 */ 281 */
246void 282void
247_isa_bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map) 283_isa_bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map)
248{ 284{
249 struct atari_isa_dma_cookie *cookie = map->_dm_cookie; 285 struct atari_isa_dma_cookie *cookie = map->_dm_cookie;
250 286
251 /* 287 /*
252 * Free any bounce pages this map might hold. 288 * Free any bounce pages this map might hold.
253 */ 289 */
254 if (cookie->id_flags & ID_HAS_BOUNCE) 290 if (cookie->id_flags & ID_HAS_BOUNCE)
255 _isa_dma_free_bouncebuf(t, map); 291 _isa_dma_free_bouncebuf(t, map);
256 292
257 free(cookie, M_DMAMAP); 293 isadma_bounce_cookie_free(map);
258 _bus_dmamap_destroy(t, map); 294 _bus_dmamap_destroy(t, map);
259} 295}
260 296
261/* 297/*
262 * Load an ISA DMA map with a linear buffer. 298 * Load an ISA DMA map with a linear buffer.
263 */ 299 */
264int 300int
265_isa_bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, 301_isa_bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf,
266 bus_size_t buflen, struct proc *p, int flags) 302 bus_size_t buflen, struct proc *p, int flags)
267{ 303{
268 struct atari_isa_dma_cookie *cookie = map->_dm_cookie; 304 struct atari_isa_dma_cookie *cookie = map->_dm_cookie;
269 int error; 305 int error;
270 306