1 /* $NetBSD: isadma.c,v 1.61 2009/05/12 09:10:15 cegger Exp $ */
4 * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
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.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
34 * Device driver for the ISA on-board DMA controller.
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: isadma.c,v 1.61 2009/05/12 09:10:15 cegger Exp $");
40 #include <sys/param.h>
41 #include <sys/systm.h>
43 #include <sys/device.h>
44 #include <sys/malloc.h>
48 #include <uvm/uvm_extern.h>
50 #include <dev/isa/isareg.h>
51 #include <dev/isa/isavar.h>
52 #include <dev/isa/isadmavar.h>
53 #include <dev/isa/isadmareg.h>
55 struct isa_mem
*isa_mem_head
;
58 * High byte of DMA address is stored in this DMAPG register for
59 * the Nth DMA channel.
61 static int dmapageport
[2][4] = {
66 static u_int8_t dmamode
[] = {
67 /* write to device/read from device */
68 DMA37MD_READ
| DMA37MD_SINGLE
,
69 DMA37MD_WRITE
| DMA37MD_SINGLE
,
71 /* write to device/read from device */
72 DMA37MD_READ
| DMA37MD_DEMAND
,
73 DMA37MD_WRITE
| DMA37MD_DEMAND
,
75 /* write to device/read from device - DMAMODE_LOOP */
76 DMA37MD_READ
| DMA37MD_SINGLE
| DMA37MD_LOOP
,
77 DMA37MD_WRITE
| DMA37MD_SINGLE
| DMA37MD_LOOP
,
79 /* write to device/read from device - DMAMODE_LOOPDEMAND */
80 DMA37MD_READ
| DMA37MD_DEMAND
| DMA37MD_LOOP
,
81 DMA37MD_WRITE
| DMA37MD_DEMAND
| DMA37MD_LOOP
,
84 static inline void _isa_dmaunmask(struct isa_dma_state
*, int);
85 static inline void _isa_dmamask(struct isa_dma_state
*, int);
88 _isa_dmaunmask(struct isa_dma_state
*ids
, int chan
)
92 ISA_DMA_MASK_CLR(ids
, chan
);
95 * If DMA is frozen, don't unmask it now. It will be
96 * unmasked when DMA is thawed again.
101 /* set dma channel mode, and set dma channel mode */
103 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
,
104 DMA1_SMSK
, ochan
| DMA37SM_CLEAR
);
106 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
,
107 DMA2_SMSK
, ochan
| DMA37SM_CLEAR
);
111 _isa_dmamask(struct isa_dma_state
*ids
, int chan
)
113 int ochan
= chan
& 3;
115 ISA_DMA_MASK_SET(ids
, chan
);
118 * XXX Should we avoid masking the channel if DMA is
119 * XXX frozen? It seems like what we're doing should
120 * XXX be safe, and we do need to reset FFC...
123 /* set dma channel mode, and set dma channel mode */
124 if ((chan
& 4) == 0) {
125 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
,
126 DMA1_SMSK
, ochan
| DMA37SM_SET
);
127 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
,
130 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
,
131 DMA2_SMSK
, ochan
| DMA37SM_SET
);
132 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
,
138 * _isa_dmainit(): Initialize the isa_dma_state for this chipset.
141 _isa_dmainit(struct isa_dma_state
*ids
, bus_space_tag_t bst
, bus_dma_tag_t dmat
, device_t dev
)
147 if (ids
->ids_initialized
) {
149 * Some systems may have e.g. `ofisa' (OpenFirmware
150 * configuration of ISA bus) and a regular `isa'.
151 * We allow both to call the initialization function,
152 * and take the device name from the last caller
153 * (assuming it will be the indirect ISA bus). Since
154 * `ofisa' and `isa' are the same bus with different
155 * configuration mechanisms, the space and dma tags
158 if (ids
->ids_bst
!= bst
|| ids
->ids_dmat
!= dmat
)
159 panic("_isa_dmainit: inconsistent ISA tags");
162 ids
->ids_dmat
= dmat
;
165 * Map the registers used by the ISA DMA controller.
167 if (bus_space_map(ids
->ids_bst
, IO_DMA1
, DMA1_IOSIZE
, 0,
169 panic("_isa_dmainit: unable to map DMA controller #1");
170 if (bus_space_map(ids
->ids_bst
, IO_DMA2
, DMA2_IOSIZE
, 0,
172 panic("_isa_dmainit: unable to map DMA controller #2");
173 if (bus_space_map(ids
->ids_bst
, IO_DMAPG
, 0xf, 0,
175 panic("_isa_dmainit: unable to map DMA page registers");
178 * All 8 DMA channels start out "masked".
180 ids
->ids_masked
= 0xff;
183 * Initialize the max transfer size for each channel, if
184 * it is not initialized already (i.e. by a bus-dependent
187 for (chan
= 0; chan
< 8; chan
++) {
188 if (ids
->ids_maxsize
[chan
] == 0)
189 ids
->ids_maxsize
[chan
] =
190 ISA_DMA_MAXSIZE_DEFAULT(chan
);
193 ids
->ids_initialized
= 1;
196 * DRQ 4 is used to chain the two 8237s together; make
197 * sure it's always cascaded, and that it will be unmasked
198 * when DMA is thawed.
200 _isa_dmacascade(ids
, 4);
205 _isa_dmadestroy(struct isa_dma_state
*ids
)
207 if (!ids
->ids_initialized
)
210 _isa_dmacascade_stop(ids
, 4);
213 * Unmap the registers used by the ISA DMA controller.
215 bus_space_unmap(ids
->ids_bst
, ids
->ids_dmapgh
, 0xf);
216 bus_space_unmap(ids
->ids_bst
, ids
->ids_dma2h
, DMA2_IOSIZE
);
217 bus_space_unmap(ids
->ids_bst
, ids
->ids_dma1h
, DMA1_IOSIZE
);
219 ids
->ids_initialized
= 0;
223 * _isa_dmacascade(): program 8237 DMA controller channel to accept
224 * external dma control by a board.
227 _isa_dmacascade(struct isa_dma_state
*ids
, int chan
)
229 int ochan
= chan
& 3;
231 if (chan
< 0 || chan
> 7) {
232 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
236 if (!ISA_DMA_DRQ_ISFREE(ids
, chan
)) {
237 printf("%s: DRQ %d is not free\n", device_xname(ids
->ids_dev
),
242 ISA_DMA_DRQ_ALLOC(ids
, chan
);
244 /* set dma channel mode, and set dma channel mode */
246 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
,
247 DMA1_MODE
, ochan
| DMA37MD_CASCADE
);
249 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
,
250 DMA2_MODE
, ochan
| DMA37MD_CASCADE
);
252 _isa_dmaunmask(ids
, chan
);
257 * _isa_dmacascade_stop(): turn off cascading on the 8237 DMA controller channel
258 * external dma control by a board.
261 _isa_dmacascade_stop(struct isa_dma_state
*ids
, int chan
)
263 if (chan
< 0 || chan
> 7) {
264 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
268 if (ISA_DMA_DRQ_ISFREE(ids
, chan
))
271 _isa_dmamask(ids
, chan
);
273 ISA_DMA_DRQ_FREE(ids
, chan
);
279 _isa_drq_alloc(struct isa_dma_state
*ids
, int chan
)
281 if (!ISA_DMA_DRQ_ISFREE(ids
, chan
))
283 ISA_DMA_DRQ_ALLOC(ids
, chan
);
288 _isa_drq_free(struct isa_dma_state
*ids
, int chan
)
290 if (ISA_DMA_DRQ_ISFREE(ids
, chan
))
292 ISA_DMA_DRQ_FREE(ids
, chan
);
297 _isa_dmamaxsize(struct isa_dma_state
*ids
, int chan
)
300 if (chan
< 0 || chan
> 7) {
301 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
305 return (ids
->ids_maxsize
[chan
]);
309 _isa_dmamap_create(struct isa_dma_state
*ids
, int chan
, bus_size_t size
, int flags
)
313 if (chan
< 0 || chan
> 7) {
314 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
318 if (size
> ids
->ids_maxsize
[chan
])
321 error
= bus_dmamap_create(ids
->ids_dmat
, size
, 1, size
,
322 ids
->ids_maxsize
[chan
], flags
, &ids
->ids_dmamaps
[chan
]);
328 _isa_dmamap_destroy(struct isa_dma_state
*ids
, int chan
)
331 if (chan
< 0 || chan
> 7) {
332 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
336 bus_dmamap_destroy(ids
->ids_dmat
, ids
->ids_dmamaps
[chan
]);
340 panic("_isa_dmamap_destroy");
344 * _isa_dmastart(): program 8237 DMA controller channel and set it
348 _isa_dmastart(struct isa_dma_state
*ids
, int chan
, void *addr
, bus_size_t nbytes
, struct proc
*p
, int flags
, int busdmaflags
)
353 int ochan
= chan
& 3;
356 if (chan
< 0 || chan
> 7) {
357 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
362 printf("_isa_dmastart: drq %d, addr %p, nbytes 0x%lx, p %p, "
363 "flags 0x%x, dmaflags 0x%x\n",
364 chan
, addr
, (u_long
)nbytes
, p
, flags
, busdmaflags
);
367 if (ISA_DMA_DRQ_ISFREE(ids
, chan
)) {
368 printf("%s: dma start on free channel %d\n",
369 device_xname(ids
->ids_dev
), chan
);
374 if (nbytes
> (1 << 17) || nbytes
& 1 || (u_long
)addr
& 1) {
375 printf("%s: drq %d, nbytes 0x%lx, addr %p\n",
376 device_xname(ids
->ids_dev
), chan
,
377 (unsigned long) nbytes
, addr
);
381 if (nbytes
> (1 << 16)) {
382 printf("%s: drq %d, nbytes 0x%lx\n",
383 device_xname(ids
->ids_dev
), chan
,
384 (unsigned long) nbytes
);
389 dmam
= ids
->ids_dmamaps
[chan
];
391 panic("_isa_dmastart: no DMA map for chan %d", chan
);
393 error
= bus_dmamap_load(ids
->ids_dmat
, dmam
, addr
, nbytes
,
395 ((flags
& DMAMODE_READ
) ? BUS_DMA_READ
: BUS_DMA_WRITE
));
400 __asm(".globl isa_dmastart_afterload ; isa_dmastart_afterload:");
403 if (flags
& DMAMODE_READ
) {
404 bus_dmamap_sync(ids
->ids_dmat
, dmam
, 0, dmam
->dm_mapsize
,
405 BUS_DMASYNC_PREREAD
);
406 ids
->ids_dmareads
|= (1 << chan
);
408 bus_dmamap_sync(ids
->ids_dmat
, dmam
, 0, dmam
->dm_mapsize
,
409 BUS_DMASYNC_PREWRITE
);
410 ids
->ids_dmareads
&= ~(1 << chan
);
413 dmaaddr
= dmam
->dm_segs
[0].ds_addr
;
416 printf(" dmaaddr 0x%lx\n", dmaaddr
);
418 __asm(".globl isa_dmastart_aftersync ; isa_dmastart_aftersync:");
421 ids
->ids_dmalength
[chan
] = nbytes
;
423 _isa_dmamask(ids
, chan
);
424 ids
->ids_dmafinished
&= ~(1 << chan
);
426 if ((chan
& 4) == 0) {
427 /* set dma channel mode */
428 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
, DMA1_MODE
,
429 ochan
| dmamode
[flags
]);
431 /* send start address */
432 waport
= DMA1_CHN(ochan
);
433 bus_space_write_1(ids
->ids_bst
, ids
->ids_dmapgh
,
434 dmapageport
[0][ochan
], (dmaaddr
>> 16) & 0xff);
435 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
, waport
,
437 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
, waport
,
438 (dmaaddr
>> 8) & 0xff);
441 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
, waport
+ 1,
443 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
, waport
+ 1,
444 (nbytes
>> 8) & 0xff);
446 /* set dma channel mode */
447 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
, DMA2_MODE
,
448 ochan
| dmamode
[flags
]);
450 /* send start address */
451 waport
= DMA2_CHN(ochan
);
452 bus_space_write_1(ids
->ids_bst
, ids
->ids_dmapgh
,
453 dmapageport
[1][ochan
], (dmaaddr
>> 16) & 0xff);
455 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
, waport
,
457 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
, waport
,
458 (dmaaddr
>> 8) & 0xff);
462 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
, waport
+ 2,
464 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
, waport
+ 2,
465 (nbytes
>> 8) & 0xff);
468 _isa_dmaunmask(ids
, chan
);
472 panic("_isa_dmastart");
476 _isa_dmaabort(struct isa_dma_state
*ids
, int chan
)
479 if (chan
< 0 || chan
> 7) {
480 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
481 panic("_isa_dmaabort");
484 _isa_dmamask(ids
, chan
);
485 bus_dmamap_unload(ids
->ids_dmat
, ids
->ids_dmamaps
[chan
]);
486 ids
->ids_dmareads
&= ~(1 << chan
);
490 _isa_dmacount(struct isa_dma_state
*ids
, int chan
)
494 int ochan
= chan
& 3;
496 if (chan
< 0 || chan
> 7) {
497 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
498 panic("isa_dmacount");
501 _isa_dmamask(ids
, chan
);
504 * We have to shift the byte count by 1. If we're in auto-initialize
505 * mode, the count may have wrapped around to the initial value. We
506 * can't use the TC bit to check for this case, so instead we compare
507 * against the original byte count.
508 * If we're not in auto-initialize mode, then the count will wrap to
509 * -1, so we also handle that case.
511 if ((chan
& 4) == 0) {
512 waport
= DMA1_CHN(ochan
);
513 nbytes
= bus_space_read_1(ids
->ids_bst
, ids
->ids_dma1h
,
515 nbytes
+= bus_space_read_1(ids
->ids_bst
, ids
->ids_dma1h
,
519 waport
= DMA2_CHN(ochan
);
520 nbytes
= bus_space_read_1(ids
->ids_bst
, ids
->ids_dma2h
,
522 nbytes
+= bus_space_read_1(ids
->ids_bst
, ids
->ids_dma2h
,
528 if (nbytes
== ids
->ids_dmalength
[chan
])
531 _isa_dmaunmask(ids
, chan
);
536 _isa_dmafinished(struct isa_dma_state
*ids
, int chan
)
539 if (chan
< 0 || chan
> 7) {
540 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
541 panic("_isa_dmafinished");
544 /* check that the terminal count was reached */
546 ids
->ids_dmafinished
|= bus_space_read_1(ids
->ids_bst
,
547 ids
->ids_dma1h
, DMA1_SR
) & 0x0f;
549 ids
->ids_dmafinished
|= (bus_space_read_1(ids
->ids_bst
,
550 ids
->ids_dma2h
, DMA2_SR
) & 0x0f) << 4;
552 return ((ids
->ids_dmafinished
& (1 << chan
)) != 0);
556 _isa_dmadone(struct isa_dma_state
*ids
, int chan
)
560 if (chan
< 0 || chan
> 7) {
561 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
562 panic("_isa_dmadone");
565 dmam
= ids
->ids_dmamaps
[chan
];
567 _isa_dmamask(ids
, chan
);
569 if (_isa_dmafinished(ids
, chan
) == 0)
570 printf("%s: _isa_dmadone: channel %d not finished\n",
571 device_xname(ids
->ids_dev
), chan
);
573 bus_dmamap_sync(ids
->ids_dmat
, dmam
, 0, dmam
->dm_mapsize
,
574 (ids
->ids_dmareads
& (1 << chan
)) ? BUS_DMASYNC_POSTREAD
:
575 BUS_DMASYNC_POSTWRITE
);
577 bus_dmamap_unload(ids
->ids_dmat
, dmam
);
578 ids
->ids_dmareads
&= ~(1 << chan
);
582 _isa_dmafreeze(struct isa_dma_state
*ids
)
588 if (ids
->ids_frozen
== 0) {
589 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
,
591 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
,
596 if (ids
->ids_frozen
< 1)
597 panic("_isa_dmafreeze: overflow");
603 _isa_dmathaw(struct isa_dma_state
*ids
)
610 if (ids
->ids_frozen
< 0)
611 panic("_isa_dmathaw: underflow");
613 if (ids
->ids_frozen
== 0) {
614 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma1h
,
615 DMA1_MASK
, ids
->ids_masked
& 0x0f);
616 bus_space_write_1(ids
->ids_bst
, ids
->ids_dma2h
,
617 DMA2_MASK
, (ids
->ids_masked
>> 4) & 0x0f);
624 _isa_dmamem_alloc(struct isa_dma_state
*ids
, int chan
, bus_size_t size
, bus_addr_t
*addrp
, int flags
)
626 bus_dma_segment_t seg
;
627 int error
, boundary
, rsegs
;
629 if (chan
< 0 || chan
> 7) {
630 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
631 panic("_isa_dmamem_alloc");
634 boundary
= (chan
& 4) ? (1 << 17) : (1 << 16);
636 size
= round_page(size
);
638 error
= bus_dmamem_alloc(ids
->ids_dmat
, size
, PAGE_SIZE
, boundary
,
639 &seg
, 1, &rsegs
, flags
);
643 *addrp
= seg
.ds_addr
;
648 _isa_dmamem_free(struct isa_dma_state
*ids
, int chan
, bus_addr_t addr
, bus_size_t size
)
650 bus_dma_segment_t seg
;
652 if (chan
< 0 || chan
> 7) {
653 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
654 panic("_isa_dmamem_free");
660 bus_dmamem_free(ids
->ids_dmat
, &seg
, 1);
664 _isa_dmamem_map(struct isa_dma_state
*ids
, int chan
, bus_addr_t addr
, bus_size_t size
, void **kvap
, int flags
)
666 bus_dma_segment_t seg
;
668 if (chan
< 0 || chan
> 7) {
669 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
670 panic("_isa_dmamem_map");
676 return (bus_dmamem_map(ids
->ids_dmat
, &seg
, 1, size
, kvap
, flags
));
680 _isa_dmamem_unmap(struct isa_dma_state
*ids
, int chan
, void *kva
, size_t size
)
683 if (chan
< 0 || chan
> 7) {
684 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
685 panic("_isa_dmamem_unmap");
688 bus_dmamem_unmap(ids
->ids_dmat
, kva
, size
);
692 _isa_dmamem_mmap(struct isa_dma_state
*ids
, int chan
, bus_addr_t addr
, bus_size_t size
, off_t off
, int prot
, int flags
)
694 bus_dma_segment_t seg
;
696 if (chan
< 0 || chan
> 7) {
697 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
698 panic("_isa_dmamem_mmap");
707 return (bus_dmamem_mmap(ids
->ids_dmat
, &seg
, 1, off
, prot
, flags
));
711 _isa_drq_isfree(struct isa_dma_state
*ids
, int chan
)
714 if (chan
< 0 || chan
> 7) {
715 printf("%s: bogus drq %d\n", device_xname(ids
->ids_dev
), chan
);
716 panic("_isa_drq_isfree");
719 return ISA_DMA_DRQ_ISFREE(ids
, chan
);
723 _isa_malloc(struct isa_dma_state
*ids
, int chan
, size_t size
, struct malloc_type
*pool
, int flags
)
730 bflags
= flags
& M_WAITOK
? BUS_DMA_WAITOK
: BUS_DMA_NOWAIT
;
732 if (_isa_dmamem_alloc(ids
, chan
, size
, &addr
, bflags
))
734 if (_isa_dmamem_map(ids
, chan
, addr
, size
, &kva
, bflags
)) {
735 _isa_dmamem_free(ids
, chan
, addr
, size
);
738 m
= malloc(sizeof(*m
), pool
, flags
);
740 _isa_dmamem_unmap(ids
, chan
, kva
, size
);
741 _isa_dmamem_free(ids
, chan
, addr
, size
);
749 m
->next
= isa_mem_head
;
755 _isa_free(void *addr
, struct malloc_type
*pool
)
757 struct isa_mem
**mp
, *m
;
758 void *kva
= (void *)addr
;
760 for(mp
= &isa_mem_head
; *mp
&& (*mp
)->kva
!= kva
;
765 printf("_isa_free: freeing unallocted memory\n");
769 _isa_dmamem_unmap(m
->ids
, m
->chan
, kva
, m
->size
);
770 _isa_dmamem_free(m
->ids
, m
->chan
, m
->addr
, m
->size
);
775 _isa_mappage(void *mem
, off_t off
, int prot
)
779 for(m
= isa_mem_head
; m
&& m
->kva
!= (void *)mem
; m
= m
->next
)
782 printf("_isa_mappage: mapping unallocted memory\n");
785 return _isa_dmamem_mmap(m
->ids
, m
->chan
, m
->addr
,
786 m
->size
, off
, prot
, BUS_DMA_WAITOK
);