Add isa_dmastatus() for reading the current ISA DMA counter for a
given channel. Submitted by: luigi@labinfo.iet.unipi.it (Luigi Rizzo)
This commit is contained in:
parent
526dc5f515
commit
a27c19ecbf
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: isa.c,v 1.94 1997/07/09 17:58:16 ache Exp $
|
||||
* $Id: isa.c,v 1.95 1997/07/20 14:10:03 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -869,6 +869,86 @@ isa_dmarangecheck(caddr_t va, u_int length, int chan) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the progress of a transfer on a DMA channel.
|
||||
*
|
||||
* To avoid having to interrupt a transfer in progress, we sample
|
||||
* each of the high and low databytes twice, and apply the following
|
||||
* logic to determine the correct count.
|
||||
*
|
||||
* Reads are performed with interrupts disabled, thus it is to be
|
||||
* expected that the time between reads is very small. At most
|
||||
* one rollover in the low count byte can be expected within the
|
||||
* four reads that are performed.
|
||||
*
|
||||
* There are three gaps in which a rollover can occur :
|
||||
*
|
||||
* - read low1
|
||||
* gap1
|
||||
* - read high1
|
||||
* gap2
|
||||
* - read low2
|
||||
* gap3
|
||||
* - read high2
|
||||
*
|
||||
* If a rollover occurs in gap1 or gap2, the low2 value will be
|
||||
* greater than the low1 value. In this case, low2 and high2 are a
|
||||
* corresponding pair.
|
||||
*
|
||||
* In any other case, low1 and high1 can be considered to be correct.
|
||||
*
|
||||
* The function returns the number of bytes remaining in the transfer,
|
||||
* or -1 if the channel requested is not active.
|
||||
*
|
||||
*/
|
||||
int
|
||||
isa_dmastatus(int chan)
|
||||
{
|
||||
u_long cnt = 0;
|
||||
int ffport, waport, s;
|
||||
u_long low, high, low2, high2;
|
||||
|
||||
/* channel active? */
|
||||
if (dma_inuse & (1 << chan) == 0) {
|
||||
printf("isa_dmastatus: channel %d not active\n", chan);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* still busy? */
|
||||
if (dma_busy & (1 << chan) == 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (chan < 4) { /* low DMA controller */
|
||||
ffport = DMA1_FFC;
|
||||
waport = DMA1_CHN(chan) + 1;
|
||||
} else { /* high DMA controller */
|
||||
ffport = DMA2_FFC;
|
||||
waport = DMA2_CHN(chan - 4) + 2;
|
||||
}
|
||||
|
||||
s = splhigh(); /* no interrupts Mr Jones! */
|
||||
outb(ffport, 0); /* clear register LSB flipflop */
|
||||
low = inb(waport);
|
||||
high = inb(waport);
|
||||
outb(ffport, 0); /* clear again (paranoia?) */
|
||||
low2 = inb(waport);
|
||||
high2 = inb(waport);
|
||||
splx(s);
|
||||
|
||||
/* now decide if a wrap has tried to skew our results */
|
||||
if (low >= low2) {
|
||||
cnt = low + (high << 8) + 1;
|
||||
} else {
|
||||
cnt = low2 + (high2 << 8) + 1;
|
||||
}
|
||||
cnt = (cnt + 1) & 0xffff;
|
||||
|
||||
if (chan >= 4) /* high channels move words */
|
||||
cnt *= 2;
|
||||
return(cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the highest priority enabled display device. Since we can't
|
||||
* distinguish display devices from ttys, depend on display devices
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: isa.c,v 1.94 1997/07/09 17:58:16 ache Exp $
|
||||
* $Id: isa.c,v 1.95 1997/07/20 14:10:03 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -869,6 +869,86 @@ isa_dmarangecheck(caddr_t va, u_int length, int chan) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the progress of a transfer on a DMA channel.
|
||||
*
|
||||
* To avoid having to interrupt a transfer in progress, we sample
|
||||
* each of the high and low databytes twice, and apply the following
|
||||
* logic to determine the correct count.
|
||||
*
|
||||
* Reads are performed with interrupts disabled, thus it is to be
|
||||
* expected that the time between reads is very small. At most
|
||||
* one rollover in the low count byte can be expected within the
|
||||
* four reads that are performed.
|
||||
*
|
||||
* There are three gaps in which a rollover can occur :
|
||||
*
|
||||
* - read low1
|
||||
* gap1
|
||||
* - read high1
|
||||
* gap2
|
||||
* - read low2
|
||||
* gap3
|
||||
* - read high2
|
||||
*
|
||||
* If a rollover occurs in gap1 or gap2, the low2 value will be
|
||||
* greater than the low1 value. In this case, low2 and high2 are a
|
||||
* corresponding pair.
|
||||
*
|
||||
* In any other case, low1 and high1 can be considered to be correct.
|
||||
*
|
||||
* The function returns the number of bytes remaining in the transfer,
|
||||
* or -1 if the channel requested is not active.
|
||||
*
|
||||
*/
|
||||
int
|
||||
isa_dmastatus(int chan)
|
||||
{
|
||||
u_long cnt = 0;
|
||||
int ffport, waport, s;
|
||||
u_long low, high, low2, high2;
|
||||
|
||||
/* channel active? */
|
||||
if (dma_inuse & (1 << chan) == 0) {
|
||||
printf("isa_dmastatus: channel %d not active\n", chan);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* still busy? */
|
||||
if (dma_busy & (1 << chan) == 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (chan < 4) { /* low DMA controller */
|
||||
ffport = DMA1_FFC;
|
||||
waport = DMA1_CHN(chan) + 1;
|
||||
} else { /* high DMA controller */
|
||||
ffport = DMA2_FFC;
|
||||
waport = DMA2_CHN(chan - 4) + 2;
|
||||
}
|
||||
|
||||
s = splhigh(); /* no interrupts Mr Jones! */
|
||||
outb(ffport, 0); /* clear register LSB flipflop */
|
||||
low = inb(waport);
|
||||
high = inb(waport);
|
||||
outb(ffport, 0); /* clear again (paranoia?) */
|
||||
low2 = inb(waport);
|
||||
high2 = inb(waport);
|
||||
splx(s);
|
||||
|
||||
/* now decide if a wrap has tried to skew our results */
|
||||
if (low >= low2) {
|
||||
cnt = low + (high << 8) + 1;
|
||||
} else {
|
||||
cnt = low2 + (high2 << 8) + 1;
|
||||
}
|
||||
cnt = (cnt + 1) & 0xffff;
|
||||
|
||||
if (chan >= 4) /* high channels move words */
|
||||
cnt *= 2;
|
||||
return(cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the highest priority enabled display device. Since we can't
|
||||
* distinguish display devices from ttys, depend on display devices
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91
|
||||
* $Id: isa_device.h,v 1.42 1997/06/02 08:19:05 dfr Exp $
|
||||
* $Id: isa_device.h,v 1.43 1997/07/20 12:34:15 bde Exp $
|
||||
*/
|
||||
|
||||
#ifndef _I386_ISA_ISA_DEVICE_H_
|
||||
@ -117,6 +117,7 @@ void isa_dmainit __P((int chan, u_int bouncebufsize));
|
||||
void isa_dmastart __P((int flags, caddr_t addr, u_int nbytes, int chan));
|
||||
int isa_dma_acquire __P((int chan));
|
||||
void isa_dma_release __P((int chan));
|
||||
void isa_dmastatus __P((int chan));
|
||||
void reconfig_isadev __P((struct isa_device *isdp, u_int *mp));
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
Loading…
x
Reference in New Issue
Block a user