Date: Sun, 31 Aug 97 09:39 PDT From: Denis DeLaRoca <CSP1DWD@MVS.OAC.UCLA.EDU> To: multimedia@FREEBSD.ORG Subject: isa.c 2.2.2 for guspnp18 sound driver Message-ID: <199708311639.JAA09646@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
For running Amancio's latest sound driver, guspnp18, on FreeBSD 2.2.2
here's a set of patches for /sys/i386/isa/isa.c.
-- Denis
--------------------------------------------------------------------
*** /sys/i386/isa/isa.c Sun Aug 31 09:06:13 1997
--- /sys/i386/isa/isa.c.orig Wed Feb 12 23:20:42 1997
***************
*** 114,121 ****
static int haveseen __P((struct isa_device *dvp, struct isa_device *tmpdvp,
u_int checkbits));
static int isa_dmarangecheck __P((caddr_t va, u_int length, int chan));
- int isa_dmastatus __P((int chan));
- static int isa_dmastop __P((int chan));
static inthand2_t isa_strayintr;
static void register_imask __P((struct isa_device *dvp, u_int mask));
--- 114,119 ----
***************
*** 514,520 ****
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)
--- 512,517 ----
***************
*** 576,582 ****
return (EBUSY);
}
dma_inuse |= (1 << chan);
- dma_auto_mode &= ~(1 << chan);
return (0);
}
--- 573,578 ----
***************
*** 593,599 ****
if (chan & ~VALID_DMA_MASK)
panic("isa_dma_release: channel out of range");
! if ((dma_inuse & (1 << chan)) == 0)
printf("isa_dma_release: channel %d not in use\n", chan);
#endif
--- 589,595 ----
if (chan & ~VALID_DMA_MASK)
panic("isa_dma_release: channel out of range");
! if (dma_inuse & (1 << chan) == 0)
printf("isa_dma_release: channel %d not in use\n", chan);
#endif
***************
*** 608,614 ****
}
dma_inuse &= ~(1 << chan);
- dma_auto_mode &= ~(1 << chan);
}
/*
--- 604,609 ----
***************
*** 634,725 ****
}
/*
- * 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;
- u_long low1, high1, low2, high2;
-
- /* channel active? */
- if ((dma_inuse & (1 << chan)) == 0) {
- printf("isa_dmastatus: channel %d not in use\n", chan);
- return(-1);
- }
-
- /*
- * do not print an error message if the chan is not busy,
- * it might just be a race condition.
- */
- if ( !(dma_busy & (1 << chan)) && !(dma_auto_mode & (1<<chan)) ) {
- /* printf("chan %d not busy\n", chan); */
- return(-2);
- }
-
- 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;
- }
-
- disable_intr(); /* no interrupts Mr Jones! */
- outb(ffport, 0); /* clear register LSB flipflop */
- low1 = inb(waport);
- high1 = inb(waport);
- outb(ffport, 0); /* clear again (paranoia? */
- low2 = inb(waport);
- high2 = inb(waport);
- enable_intr();
-
- /*
- * Now decide if a wrap has tried to skew our results.
- * Note that after TC, the count will read 0xffff, while we want
- * to return zero, so we add and then mask to compensate.
- */
- if (low1 >= low2)
- cnt = (low1 + (high1 << 8) + 1) & 0xffff;
- else
- cnt = (low2 + (high2 << 8) + 1) & 0xffff;
-
- if (chan >=4) /* 16-bit chans transfer words */
- cnt *= 2 ;
- return(cnt);
- }
-
- /*
* isa_dmastart(): program 8237 DMA controller channel, avoid page alignment
* problems by using a bounce buffer.
*/
--- 629,634 ----
***************
*** 737,757 ****
|| (chan >= 4 && (nbytes > (1<<17) || (u_int)addr & 1)))
panic("isa_dmastart: impossible request");
! if ( (dma_inuse & (1 << chan)) == 0)
printf("isa_dmastart: channel %d not acquired\n", chan);
-
#endif
if (dma_busy & (1 << chan))
printf("isa_dmastart: channel %d busy\n", chan);
- #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))
- printf("isa_dmastart: channel %d busy\n", chan);
- #endif
dma_busy |= (1 << chan);
--- 646,657 ----
|| (chan >= 4 && (nbytes > (1<<17) || (u_int)addr & 1)))
panic("isa_dmastart: impossible request");
! if (dma_inuse & (1 << chan) == 0)
printf("isa_dmastart: channel %d not acquired\n", chan);
#endif
+
if (dma_busy & (1 << chan))
printf("isa_dmastart: channel %d busy\n", chan);
dma_busy |= (1 << chan);
***************
*** 771,781 ****
/* 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
--- 671,676 ----
***************
*** 846,887 ****
}
}
- /*
- * Stop a DMA transfer currently in progress.
- * this stops the dma channel and returns the residual count
- * derived calling isa_dmastatus
- */
- int isa_dmastop(int chan)
- {
- if ( !(dma_inuse & (1 << chan)) )
- printf("isa_dmastop: channel %d not acquired\n", chan);
-
- if ( ! (dma_busy & (1 << chan)) &&
- ! (dma_auto_mode & (1 << chan)) ) {
- printf("isa_dmastop: channel %d not busy\n", chan);
- return(-2);
- }
-
- if ( chan & 4 )
- outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
- else
- outb(DMA1_SMSK, (chan & 3) | 4 /* disable mask */);
- return isa_dmastatus(chan);
- }
-
void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
{
#ifdef DIAGNOSTIC
if (chan & ~VALID_DMA_MASK)
panic("isa_dmadone: channel out of range");
! if ( (dma_inuse & (1 << chan)) == 0)
printf("isa_dmadone: channel %d not acquired\n", chan);
#endif
! if ( ! (dma_busy & (1 << chan)) &&
! ! (dma_auto_mode & (1 << chan)) )
printf("isa_dmadone: channel %d not busy\n", chan);
if (dma_bounced & (1 << chan)) {
/* copy bounce buffer on read */
--- 741,765 ----
}
}
void isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
{
#ifdef DIAGNOSTIC
if (chan & ~VALID_DMA_MASK)
panic("isa_dmadone: channel out of range");
! if (dma_inuse & (1 << chan) == 0)
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)
printf("isa_dmadone: channel %d not busy\n", chan);
+ #endif
if (dma_bounced & (1 << chan)) {
/* copy bounce buffer on read */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199708311639.JAA09646>
