Don't use the TC bit to check for wraparound in isa_dmacount(); remember the
transfer length and use that.
This commit is contained in:
parent
7781a356bb
commit
e9028468cd
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: isadma.c,v 1.23 1997/03/21 02:17:11 mycroft Exp $ */
|
/* $NetBSD: isadma.c,v 1.24 1997/05/28 20:02:39 mycroft Exp $ */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -20,9 +20,10 @@
|
||||||
/* region of physical memory known to be contiguous */
|
/* region of physical memory known to be contiguous */
|
||||||
vm_offset_t isaphysmem;
|
vm_offset_t isaphysmem;
|
||||||
static caddr_t dma_bounce[8]; /* XXX */
|
static caddr_t dma_bounce[8]; /* XXX */
|
||||||
static char bounced[8]; /* XXX */
|
static char dma_bounced[8]; /* XXX */
|
||||||
#define MAXDMASZ 512 /* XXX */
|
#define MAXDMASZ 512 /* XXX */
|
||||||
static u_int8_t dma_finished;
|
static u_int8_t dma_finished;
|
||||||
|
static vm_size_t dma_length[8];
|
||||||
|
|
||||||
/* high byte of address is stored in this port for i-th dma channel */
|
/* high byte of address is stored in this port for i-th dma channel */
|
||||||
static int dmapageport[2][4] = {
|
static int dmapageport[2][4] = {
|
||||||
|
@ -132,7 +133,7 @@ isa_dmastart(flags, addr, nbytes, chan)
|
||||||
dma_bounce[chan] =
|
dma_bounce[chan] =
|
||||||
/*(caddr_t)malloc(MAXDMASZ, M_TEMP, M_WAITOK);*/
|
/*(caddr_t)malloc(MAXDMASZ, M_TEMP, M_WAITOK);*/
|
||||||
(caddr_t) isaphysmem + NBPG*chan;
|
(caddr_t) isaphysmem + NBPG*chan;
|
||||||
bounced[chan] = 1;
|
dma_bounced[chan] = 1;
|
||||||
newaddr = dma_bounce[chan];
|
newaddr = dma_bounce[chan];
|
||||||
*(int *) newaddr = 0; /* XXX */
|
*(int *) newaddr = 0; /* XXX */
|
||||||
/* copy bounce buffer on write */
|
/* copy bounce buffer on write */
|
||||||
|
@ -141,6 +142,8 @@ isa_dmastart(flags, addr, nbytes, chan)
|
||||||
addr = newaddr;
|
addr = newaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dma_length[chan] = nbytes;
|
||||||
|
|
||||||
/* translate to physical */
|
/* translate to physical */
|
||||||
phys = pmap_extract(pmap_kernel(), (vm_offset_t)addr);
|
phys = pmap_extract(pmap_kernel(), (vm_offset_t)addr);
|
||||||
|
|
||||||
|
@ -192,7 +195,7 @@ isa_dmaabort(chan)
|
||||||
|
|
||||||
isa_dmamask(chan);
|
isa_dmamask(chan);
|
||||||
|
|
||||||
bounced[chan] = 0;
|
dma_bounced[chan] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_size_t
|
vm_size_t
|
||||||
|
@ -205,25 +208,33 @@ isa_dmacount(chan)
|
||||||
|
|
||||||
#ifdef ISADMA_DEBUG
|
#ifdef ISADMA_DEBUG
|
||||||
if (chan < 0 || chan > 7)
|
if (chan < 0 || chan > 7)
|
||||||
panic("isa_dmafinished: impossible request");
|
panic("isa_dmacount: impossible request");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
isa_dmamask(chan);
|
isa_dmamask(chan);
|
||||||
|
|
||||||
/* check that the terminal count was reached */
|
/*
|
||||||
if (!isa_dmafinished(chan)) {
|
* We have to shift the byte count by 1. If we're in auto-initialize
|
||||||
/* read count */
|
* mode, the count may have wrapped around to the initial value. We
|
||||||
if ((chan & 4) == 0) {
|
* can't use the TC bit to check for this case, so instead we compare
|
||||||
waport = DMA1_CHN(ochan);
|
* against the original byte count.
|
||||||
nbytes = inb(waport + 1) + 1;
|
* If we're not in auto-initialize mode, then the count will wrap to
|
||||||
nbytes += inb(waport + 1) << 8;
|
* -1, so we also handle that case.
|
||||||
} else {
|
*/
|
||||||
waport = DMA2_CHN(ochan);
|
if ((chan & 4) == 0) {
|
||||||
nbytes = inb(waport + 2) + 1;
|
waport = DMA1_CHN(ochan);
|
||||||
nbytes += inb(waport + 2) << 8;
|
nbytes = inb(waport + 1) + 1;
|
||||||
nbytes <<= 1;
|
nbytes += inb(waport + 1) << 8;
|
||||||
}
|
nbytes &= 0xffff;
|
||||||
} else
|
} else {
|
||||||
|
waport = DMA2_CHN(ochan);
|
||||||
|
nbytes = inb(waport + 2) + 1;
|
||||||
|
nbytes += inb(waport + 2) << 8;
|
||||||
|
nbytes <<= 1;
|
||||||
|
nbytes &= 0x1ffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbytes == dma_length[chan])
|
||||||
nbytes = 0;
|
nbytes = 0;
|
||||||
|
|
||||||
isa_dmaunmask(chan);
|
isa_dmaunmask(chan);
|
||||||
|
@ -268,9 +279,9 @@ isa_dmadone(flags, addr, nbytes, chan)
|
||||||
printf("isa_dmadone: channel %d not finished\n", chan);
|
printf("isa_dmadone: channel %d not finished\n", chan);
|
||||||
|
|
||||||
/* copy bounce buffer on read */
|
/* copy bounce buffer on read */
|
||||||
if (bounced[chan]) {
|
if (dma_bounced[chan]) {
|
||||||
bcopy(dma_bounce[chan], addr, nbytes);
|
bcopy(dma_bounce[chan], addr, nbytes);
|
||||||
bounced[chan] = 0;
|
dma_bounced[chan] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue