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:
mycroft 1997-05-28 20:02:39 +00:00
parent 7781a356bb
commit e9028468cd
1 changed files with 32 additions and 21 deletions

View File

@ -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;
} }
} }