diff options
| author | leo <leo@NetBSD.org> | 1995-03-26 07:12:03 +0000 |
|---|---|---|
| committer | leo <leo@NetBSD.org> | 1995-03-26 07:12:03 +0000 |
| commit | 8b0113cfceadf3ee3bc427c4680b6b46bb57ceea (patch) | |
| tree | 2a5b7db0400149a733175c4b1a56774b2d4c1eb7 /sys/arch/atari/dev/dma.c | |
| parent | 282052c7a8346370f47965457329f3b0b3fa01b7 (diff) | |
NetBSD/Atari, port by Leo Weppelman.
Diffstat (limited to 'sys/arch/atari/dev/dma.c')
| -rw-r--r-- | sys/arch/atari/dev/dma.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/sys/arch/atari/dev/dma.c b/sys/arch/atari/dev/dma.c new file mode 100644 index 00000000000..bca7297ac12 --- /dev/null +++ b/sys/arch/atari/dev/dma.c @@ -0,0 +1,202 @@ +/* $NetBSD: dma.c,v 1.1.1.1 1995/03/26 07:12:13 leo Exp $ */ + +/* + * Copyright (c) 1995 Leo Weppelman. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Leo Weppelman. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file contains special code dealing with the DMA interface + * on the Atari ST. + * + * The DMA circuitry requires some special treatment for the peripheral + * devices which make use of the ST's DMA feature (the hard disk and the + * floppy drive). + * All devices using DMA need mutually exclusive access and can follow some + * standard pattern which will be provided in this file. + * + * The file contains the following entry points: + * + * dmagrab: ensure exclusive access to the DMA circuitry + * dmafree: free exclusive access to the DMA circuitry + * dmaint: DMA interrupt routine, switches to the current driver + * dmaaddr: specify 24 bit RAM address + * dmardat: set dma_mode and read word from dma_data + * dmawdat: set dma_mode and write word to dma_data + * dmacomm: like dmawdat, but first toggle WRBIT + * + * FIXME: The delay-loops should be done otherwise! + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <machine/cpu.h> +#include <machine/iomap.h> +#include <machine/dma.h> + +#define NDMA_DEV 10 /* Max 2 floppy's, 8 hard-disks */ +typedef struct { + int (*call_func)(); + int (*int_func)(); + void *softc; +} DMA_DISP; + +static DMA_DISP dispatch[NDMA_DEV]; /* dispatch table */ +static int dma_free = 0; /* next free entry in dispatch table */ +static int dma_curr = 0; /* current entry in dispatch table */ +static int dmalock = 0; /* if != 0, dma is not free */ +static int (*xxxint)(); /* current interrupt function */ +static void *dma_softc; /* Device currently owning DMA-intr */ +static int sched_soft = 0; /* Software interrupt scheduled */ + +static void cdmasoft __P((void)); + +dmagrab(int_func, call_func, softc) +int (*int_func)(); +int (*call_func)(); +void *softc; +{ + int sps; + DMA_DISP *disp; + + sps = splbio(); + + if(dmalock) { + disp = &dispatch[dma_free++]; + if(dma_free >= NDMA_DEV) + dma_free = 0; + if(disp->call_func != NULL) + panic("dma dispatch table overflow"); + disp->call_func = call_func; + disp->int_func = int_func; + disp->softc = softc; + splx(sps); + return; + } + dmalock++; + xxxint = int_func; /* Grab DMA interrupts */ + dma_softc = softc; /* Identify device which got DMA */ + (*call_func)(softc); /* Call followup function */ + splx(sps); + +} + +dmafree() +{ + int sps; + DMA_DISP *disp; + + sps = splbio(); + disp = &dispatch[dma_curr]; + if(disp->call_func != NULL) { + xxxint = disp->int_func; + dma_softc = disp->softc; + (*disp->call_func)(dma_softc); + disp->call_func = NULL; + if(++dma_curr >= NDMA_DEV) + dma_curr = 0; + splx(sps); + return; + } + dmalock = 0; + xxxint = NULL; /* no more DMA interrupts */ + splx(sps); +} + +cdmaint(sr) +long sr; /* sr at time of interrupt */ +{ + if(xxxint != NULL) { + if(!BASEPRI(sr)) { + if(!sched_soft++) + add_sicallback(cdmasoft, 0, 0); + } + else { + spl1(); + cdmasoft(); + } + } + else printf("DMA interrupt discarded\r\n"); +} + +static void cdmasoft() +{ + sched_soft = 0; + (*xxxint)(dma_softc); +} + +dmaaddr(address) +caddr_t address; +{ + register u_long ad = (u_long)address; + + DMA->dma_addr[AD_LOW ] = (ad ) & 0xff; + DMA->dma_addr[AD_MID ] = (ad >> 8) & 0xff; + DMA->dma_addr[AD_HIGH] = (ad >>16) & 0xff; +} + +int +dmardat(mode, delay) +int mode, delay; +{ + while(--delay >= 0); + DMA->dma_mode = mode; + while(--delay >= 0); + return(DMA->dma_data); +} + +dmawdat(mode, data, delay) +int mode, data, delay; +{ + DMA->dma_mode = mode; + while(--delay >= 0); + DMA->dma_data = data; + while(--delay >= 0); +} + +dmacomm(mode, data, delay) +int mode, data, delay; +{ + DMA->dma_mode = mode; + DMA->dma_mode = mode ^ WRBIT; + DMA->dma_mode = mode; + while(--delay >= 0); + DMA->dma_data = data; + while(--delay >= 0); +} + +int +dmastat(mode, delay) +int mode, delay; +{ + while(--delay >= 0); + DMA->dma_mode = mode; + while(--delay >= 0); + return(DMA->dma_stat); +} |
