Here is a patch to alleviate the current problem with the dma interface
and the sound driver which uses auto dma. The dma interface functionality remains however it now checks to see if a dma is operating in auto dma mode and if so it bypasses the busy flag check . I have modified the sound driver 3.5 to adjust for this new behavior and tested it under FreeBSD 3.0 -current This patch also includes the new function isa_dmastop. Submitted by: Amancio Hasty <hasty@rah.star-gate.com>
This commit is contained in:
parent
6eb0e3b9f9
commit
67fb1e6a0c
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
|
||||
* $Id: isa.c,v 1.101 1997/08/21 05:08:07 fsmp Exp $
|
||||
* $Id: isa.c,v 1.102 1997/08/25 22:52:59 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -573,6 +573,7 @@ static u_int dma_bouncebufsize[8];
|
||||
static u_int8_t dma_bounced = 0;
|
||||
static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */
|
||||
static u_int8_t dma_inuse = 0; /* User for acquire/release */
|
||||
static u_int8_t dma_auto_mode = 0;
|
||||
|
||||
#define VALID_DMA_MASK (7)
|
||||
|
||||
@ -634,6 +635,7 @@ isa_dma_acquire(chan)
|
||||
return (EBUSY);
|
||||
}
|
||||
dma_inuse |= (1 << chan);
|
||||
dma_auto_mode &= ~(1 << chan);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -665,6 +667,7 @@ isa_dma_release(chan)
|
||||
}
|
||||
|
||||
dma_inuse &= ~(1 << chan);
|
||||
dma_auto_mode &= ~(1 << chan);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -739,6 +742,12 @@ void isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
|
||||
/* translate to physical */
|
||||
phys = pmap_extract(pmap_kernel(), (vm_offset_t)addr);
|
||||
|
||||
if (flags & B_RAW) {
|
||||
dma_auto_mode |= (1 << chan);
|
||||
} else {
|
||||
dma_auto_mode &= ~(1 << chan);
|
||||
}
|
||||
|
||||
if ((chan & 4) == 0) {
|
||||
/*
|
||||
* Program one of DMA channels 0..3. These are
|
||||
@ -819,15 +828,10 @@ void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
|
||||
printf("isa_dmadone: channel %d not acquired\n", chan);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* XXX This should be checked, but drivers like ad1848 only call
|
||||
* isa_dmastart() once because they use Auto DMA mode. If we
|
||||
* leave this in, drivers that do this will print this continuously.
|
||||
*/
|
||||
if ((dma_busy & (1 << chan)) == 0)
|
||||
if (((dma_busy & (1 << chan)) == 0) &&
|
||||
(dma_auto_mode & (1 << chan)) == 0 )
|
||||
printf("isa_dmadone: channel %d not busy\n", chan);
|
||||
#endif
|
||||
|
||||
|
||||
if (dma_bounced & (1 << chan)) {
|
||||
/* copy bounce buffer on read */
|
||||
@ -916,12 +920,13 @@ isa_dmastatus(int chan)
|
||||
printf("isa_dmastatus: channel %d not active\n", chan);
|
||||
return(-1);
|
||||
}
|
||||
/* channel busy? */
|
||||
|
||||
/* still busy? */
|
||||
if ((dma_busy & (1 << chan)) == 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (((dma_busy & (1 << chan)) == 0) &&
|
||||
(dma_auto_mode & (1 << chan)) == 0 ) {
|
||||
printf("chan %d not busy\n", chan);
|
||||
return -2 ;
|
||||
}
|
||||
if (chan < 4) { /* low DMA controller */
|
||||
ffport = DMA1_FFC;
|
||||
waport = DMA1_CHN(chan) + 1;
|
||||
@ -955,6 +960,29 @@ isa_dmastatus(int chan)
|
||||
return(cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop a DMA transfer currently in progress.
|
||||
*/
|
||||
int
|
||||
isa_dmastop(int chan)
|
||||
{
|
||||
if ((dma_inuse & (1 << chan)) == 0)
|
||||
printf("isa_dmastop: channel %d not acquired\n", chan);
|
||||
|
||||
if (((dma_busy & (1 << chan)) == 0) &&
|
||||
((dma_auto_mode & (1 << chan)) == 0)) {
|
||||
printf("chan %d not busy\n", chan);
|
||||
return -2 ;
|
||||
}
|
||||
|
||||
if ((chan & 4) == 0) {
|
||||
outb(DMA1_SMSK, (chan & 3) | 4 /* disable mask */);
|
||||
} else {
|
||||
outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
|
||||
}
|
||||
return(isa_dmastatus(chan));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.101 1997/08/21 05:08:07 fsmp Exp $
|
||||
* $Id: isa.c,v 1.102 1997/08/25 22:52:59 bde Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -573,6 +573,7 @@ static u_int dma_bouncebufsize[8];
|
||||
static u_int8_t dma_bounced = 0;
|
||||
static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */
|
||||
static u_int8_t dma_inuse = 0; /* User for acquire/release */
|
||||
static u_int8_t dma_auto_mode = 0;
|
||||
|
||||
#define VALID_DMA_MASK (7)
|
||||
|
||||
@ -634,6 +635,7 @@ isa_dma_acquire(chan)
|
||||
return (EBUSY);
|
||||
}
|
||||
dma_inuse |= (1 << chan);
|
||||
dma_auto_mode &= ~(1 << chan);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -665,6 +667,7 @@ isa_dma_release(chan)
|
||||
}
|
||||
|
||||
dma_inuse &= ~(1 << chan);
|
||||
dma_auto_mode &= ~(1 << chan);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -739,6 +742,12 @@ void isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
|
||||
/* translate to physical */
|
||||
phys = pmap_extract(pmap_kernel(), (vm_offset_t)addr);
|
||||
|
||||
if (flags & B_RAW) {
|
||||
dma_auto_mode |= (1 << chan);
|
||||
} else {
|
||||
dma_auto_mode &= ~(1 << chan);
|
||||
}
|
||||
|
||||
if ((chan & 4) == 0) {
|
||||
/*
|
||||
* Program one of DMA channels 0..3. These are
|
||||
@ -819,15 +828,10 @@ void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
|
||||
printf("isa_dmadone: channel %d not acquired\n", chan);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* XXX This should be checked, but drivers like ad1848 only call
|
||||
* isa_dmastart() once because they use Auto DMA mode. If we
|
||||
* leave this in, drivers that do this will print this continuously.
|
||||
*/
|
||||
if ((dma_busy & (1 << chan)) == 0)
|
||||
if (((dma_busy & (1 << chan)) == 0) &&
|
||||
(dma_auto_mode & (1 << chan)) == 0 )
|
||||
printf("isa_dmadone: channel %d not busy\n", chan);
|
||||
#endif
|
||||
|
||||
|
||||
if (dma_bounced & (1 << chan)) {
|
||||
/* copy bounce buffer on read */
|
||||
@ -916,12 +920,13 @@ isa_dmastatus(int chan)
|
||||
printf("isa_dmastatus: channel %d not active\n", chan);
|
||||
return(-1);
|
||||
}
|
||||
/* channel busy? */
|
||||
|
||||
/* still busy? */
|
||||
if ((dma_busy & (1 << chan)) == 0) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (((dma_busy & (1 << chan)) == 0) &&
|
||||
(dma_auto_mode & (1 << chan)) == 0 ) {
|
||||
printf("chan %d not busy\n", chan);
|
||||
return -2 ;
|
||||
}
|
||||
if (chan < 4) { /* low DMA controller */
|
||||
ffport = DMA1_FFC;
|
||||
waport = DMA1_CHN(chan) + 1;
|
||||
@ -955,6 +960,29 @@ isa_dmastatus(int chan)
|
||||
return(cnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop a DMA transfer currently in progress.
|
||||
*/
|
||||
int
|
||||
isa_dmastop(int chan)
|
||||
{
|
||||
if ((dma_inuse & (1 << chan)) == 0)
|
||||
printf("isa_dmastop: channel %d not acquired\n", chan);
|
||||
|
||||
if (((dma_busy & (1 << chan)) == 0) &&
|
||||
((dma_auto_mode & (1 << chan)) == 0)) {
|
||||
printf("chan %d not busy\n", chan);
|
||||
return -2 ;
|
||||
}
|
||||
|
||||
if ((chan & 4) == 0) {
|
||||
outb(DMA1_SMSK, (chan & 3) | 4 /* disable mask */);
|
||||
} else {
|
||||
outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
|
||||
}
|
||||
return(isa_dmastatus(chan));
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the highest priority enabled display device. Since we can't
|
||||
* distinguish display devices from ttys, depend on display devices
|
||||
|
Loading…
Reference in New Issue
Block a user