summaryrefslogtreecommitdiff
path: root/sys/dev/isa/isadma.c
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1996-04-18 23:48:25 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1996-04-18 23:48:25 +0000
commit76067dc38b59d22fa68139e9e0f6387455213fef (patch)
treea07a31d71b761635bad242646844c4ead9cdbed8 /sys/dev/isa/isadma.c
parent740ab8eb879aa7a6c29f0a9c83c747b8ae4988c9 (diff)
NetBSD 960317 merge
Diffstat (limited to 'sys/dev/isa/isadma.c')
-rw-r--r--sys/dev/isa/isadma.c76
1 files changed, 53 insertions, 23 deletions
diff --git a/sys/dev/isa/isadma.c b/sys/dev/isa/isadma.c
index cb353a57049..37a0795745a 100644
--- a/sys/dev/isa/isadma.c
+++ b/sys/dev/isa/isadma.c
@@ -1,4 +1,5 @@
-/* $NetBSD: isadma.c,v 1.12 1995/04/17 12:09:11 cgd Exp $ */
+/* $OpenBSD: isadma.c,v 1.3 1996/04/18 23:47:41 niklas Exp $ */
+/* $NetBSD: isadma.c,v 1.17 1996/03/01 04:35:27 mycroft Exp $ */
#include <sys/param.h>
#include <sys/systm.h>
@@ -24,10 +25,19 @@ struct dma_info {
};
static struct dma_info dma_info[8];
+static u_int8_t dma_finished;
/* high byte of address is stored in this port for i-th dma channel */
-static int dmapageport[8] =
- { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
+static int dmapageport[8] = {
+ 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a
+};
+
+static u_int8_t dmamode[4] = {
+ DMA37MD_READ | DMA37MD_SINGLE,
+ DMA37MD_WRITE | DMA37MD_SINGLE,
+ DMA37MD_READ | DMA37MD_LOOP,
+ DMA37MD_WRITE | DMA37MD_LOOP
+};
/*
* isadma_cascade(): program 8237 DMA controller channel to accept
@@ -38,18 +48,20 @@ isadma_cascade(chan)
int chan;
{
-#ifdef DIAGNOSTIC
+#ifdef ISADMA_DEBUG
if (chan < 0 || chan > 7)
panic("isadma_cascade: impossible request");
#endif
/* set dma channel mode, and set dma channel mode */
if ((chan & 4) == 0) {
- outb(DMA1_MODE, DMA37MD_CASCADE | chan);
+ outb(DMA1_MODE, chan | DMA37MD_CASCADE);
outb(DMA1_SMSK, chan);
} else {
- outb(DMA2_MODE, DMA37MD_CASCADE | (chan & 3));
- outb(DMA2_SMSK, chan & 3);
+ chan &= 3;
+
+ outb(DMA2_MODE, chan | DMA37MD_CASCADE);
+ outb(DMA2_SMSK, chan);
}
}
@@ -69,9 +81,10 @@ isadma_start(addr, nbytes, chan, flags)
int mflags;
vm_size_t size;
-#ifdef DIAGNOSTIC
+#ifdef ISADMA_DEBUG
if (chan < 0 || chan > 7 ||
- ((flags & ISADMA_START_READ) == 0) == ((flags & ISADMA_START_WRITE) == 0) ||
+ (((flags & DMAMODE_READ) != 0) + ((flags & DMAMODE_WRITE) != 0) +
+ ((flags & DMAMODE_LOOP) != 0) != 1) ||
((chan & 4) ? (nbytes >= (1<<17) || nbytes & 1 || (u_int)addr & 1) :
(nbytes >= (1<<16))))
panic("isadma_start: impossible request");
@@ -93,26 +106,26 @@ isadma_start(addr, nbytes, chan, flags)
if (isadma_map(addr, nbytes, di->phys, mflags) != 1)
panic("isadma_start: cannot map");
- if ((flags & ISADMA_START_READ) == 0)
+ /* XXX Will this do what we want with DMAMODE_LOOP? */
+ if ((flags & DMAMODE_READ) == 0)
isadma_copytobuf(addr, nbytes, 1, di->phys);
+ dma_finished &= ~(1 << chan);
+
if ((chan & 4) == 0) {
/*
* Program one of DMA channels 0..3. These are
* byte mode channels.
*/
/* set dma channel mode, and reset address ff */
- if (flags & ISADMA_START_READ)
- outb(DMA1_MODE, chan | DMA37MD_SINGLE | DMA37MD_WRITE);
- else
- outb(DMA1_MODE, chan | DMA37MD_SINGLE | DMA37MD_READ);
+ outb(DMA1_MODE, chan | dmamode[flags]);
outb(DMA1_FFC, 0);
/* send start address */
- waport = DMA1_CHN(chan);
+ waport = DMA1_CHN(chan);
+ outb(dmapageport[chan], di->phys[0].addr>>16);
outb(waport, di->phys[0].addr);
outb(waport, di->phys[0].addr>>8);
- outb(dmapageport[chan], di->phys[0].addr>>16);
/* send count */
outb(waport + 1, --nbytes);
@@ -126,17 +139,14 @@ isadma_start(addr, nbytes, chan, flags)
* word mode channels.
*/
/* set dma channel mode, and reset address ff */
- if (flags & ISADMA_START_READ)
- outb(DMA2_MODE, (chan & 3) | DMA37MD_SINGLE | DMA37MD_WRITE);
- else
- outb(DMA2_MODE, (chan & 3) | DMA37MD_SINGLE | DMA37MD_READ);
+ outb(DMA2_MODE, (chan & 3) | dmamode[flags]);
outb(DMA2_FFC, 0);
/* send start address */
waport = DMA2_CHN(chan & 3);
+ outb(dmapageport[chan], di->phys[0].addr>>16);
outb(waport, di->phys[0].addr>>1);
outb(waport, di->phys[0].addr>>9);
- outb(dmapageport[chan], di->phys[0].addr>>16);
/* send count */
nbytes >>= 1;
@@ -154,7 +164,7 @@ isadma_abort(chan)
{
struct dma_info *di;
-#ifdef DIAGNOSTIC
+#ifdef ISADMA_DEBUG
if (chan < 0 || chan > 7)
panic("isadma_abort: impossible request");
#endif
@@ -175,6 +185,25 @@ isadma_abort(chan)
di->flags = 0;
}
+int
+isadma_finished(chan)
+ int chan;
+{
+
+#ifdef ISADMA_DEBUG
+ if (chan < 0 || chan > 7)
+ panic("isadma_finished: impossible request");
+#endif
+
+ /* check that the terminal count was reached */
+ if ((chan & 4) == 0)
+ dma_finished |= inb(DMA1_SR) & 0x0f;
+ else
+ dma_finished |= (inb(DMA2_SR) & 0x0f) << 4;
+
+ return ((dma_finished & (1 << chan)) != 0);
+}
+
void
isadma_done(chan)
int chan;
@@ -208,7 +237,8 @@ isadma_done(chan)
else
outb(DMA2_SMSK, DMA37SM_SET | (chan & 3));
- if (di->flags & ISADMA_START_READ)
+ /* XXX Will this do what we want with DMAMODE_LOOP? */
+ if (di->flags & DMAMODE_READ)
isadma_copyfrombuf(di->addr, di->nbytes, 1, di->phys);
isadma_unmap(di->addr, di->nbytes, 1, di->phys);