summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/isa.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1997-08-28 03:36:40 +0000
committermsmith <msmith@FreeBSD.org>1997-08-28 03:36:40 +0000
commit4561d606a5e886201d11344c7d54e415b043b3cd (patch)
treeb9924875864f2241940625b55979653b809ff5ec /sys/i386/isa/isa.c
parent66c70016d708f2896b9c124444c612dc0264861e (diff)
downloadFreeBSD-src-4561d606a5e886201d11344c7d54e415b043b3cd.zip
FreeBSD-src-4561d606a5e886201d11344c7d54e415b043b3cd.tar.gz
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>
Diffstat (limited to 'sys/i386/isa/isa.c')
-rw-r--r--sys/i386/isa/isa.c56
1 files changed, 42 insertions, 14 deletions
diff --git a/sys/i386/isa/isa.c b/sys/i386/isa/isa.c
index 0b6fe36..abdcfa3 100644
--- a/sys/i386/isa/isa.c
+++ b/sys/i386/isa/isa.c
@@ -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;
@@ -956,6 +961,29 @@ isa_dmastatus(int chan)
}
/*
+ * 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
* being sensitive and before sensitive non-display devices (if any)
OpenPOWER on IntegriCloud