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>