diff options
| author | leo <leo@NetBSD.org> | 1995-05-14 15:46:17 +0000 |
|---|---|---|
| committer | leo <leo@NetBSD.org> | 1995-05-14 15:46:17 +0000 |
| commit | 84c03e605886bc0d9d8c34646d40d34846bfe786 (patch) | |
| tree | 3ff303cb2567030ebf86c78c75b352e1c5cd7550 /sys/arch/atari/dev | |
| parent | 571c7445e078bed73763c37b2cbfc2b1f04df096 (diff) | |
- Remove race condition from DMA interrupt handler
- Add function to get current DMA address for Falcon SCSI.
Diffstat (limited to 'sys/arch/atari/dev')
| -rw-r--r-- | sys/arch/atari/dev/dma.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/sys/arch/atari/dev/dma.c b/sys/arch/atari/dev/dma.c index b94063f080d..4be5f26b62a 100644 --- a/sys/arch/atari/dev/dma.c +++ b/sys/arch/atari/dev/dma.c @@ -1,4 +1,4 @@ -/* $NetBSD: dma.c,v 1.3 1995/04/30 12:04:48 leo Exp $ */ +/* $NetBSD: dma.c,v 1.4 1995/05/14 15:46:17 leo Exp $ */ /* * Copyright (c) 1995 Leo Weppelman. @@ -46,7 +46,8 @@ * st_dmafree: free exclusive access to the DMA circuitry * st_dmawanted: somebody is queued waiting for DMA-access * dmaint: DMA interrupt routine, switches to the current driver - * st_dmaaddr: specify 24 bit RAM address + * st_dmaaddr_set: specify 24 bit RAM address + * st_dmaaddr_get: get address of last DMA-op * st_dmacomm: program DMA, flush FIFO first */ @@ -210,8 +211,25 @@ long sr; /* sr at time of interrupt */ static void cdmasoft() { + int s; + void (*int_func)(); + void *softc; + + /* + * Prevent a race condition here. DMA might be freed while + * the callback was pending! + */ + s = splhigh(); sched_soft = 0; - (*dma_active.tqh_first->int_func)(dma_active.tqh_first->softc); + if(dma_active.tqh_first != NULL) { + int_func = dma_active.tqh_first->int_func; + softc = dma_active.tqh_first->softc; + } + else int_func = NULL; + splx(s); + + if(int_func != NULL) + (*int_func)(softc); } /* @@ -219,7 +237,7 @@ static void cdmasoft() * Note: The order _is_ important! */ void -st_dmaaddr(address) +st_dmaaddr_set(address) caddr_t address; { register u_long ad = (u_long)address; @@ -230,15 +248,30 @@ caddr_t address; } /* + * Get address from DMA unit. + */ +u_long +st_dmaaddr_get() +{ + register u_long ad = 0; + + ad = (DMA->dma_addr[AD_LOW ] & 0xff); + ad |= (DMA->dma_addr[AD_MID ] & 0xff) << 8; + ad |= (DMA->dma_addr[AD_HIGH] & 0xff) <<16; + return(ad); +} + +/* * Program the DMA-controller to transfer 'nblk' blocks of 512 bytes. * The DMA_WRBIT trick flushes the FIFO before doing DMA. */ void -st_dmacomm(mode, data) -int mode, data; +st_dmacomm(mode, nblk) +int mode, nblk; { DMA->dma_mode = mode; DMA->dma_mode = mode ^ DMA_WRBIT; DMA->dma_mode = mode; - DMA->dma_data = data; + DMA->dma_data = nblk; + DMA->dma_mode = DMA_SCREG | (mode & DMA_WRBIT); } |
