Defer hooking up the DMA controller interrupt. Add a new funciton,

dmacomputeipl(), which is called by drivers which use DMA once they've
hooked up their interrupts.  This new function computes the appropriate
ipl to use for the DMA controller and (re-)establishes it's interrupt.
This commit is contained in:
thorpej 1996-12-09 03:09:51 +00:00
parent 75a37ecc60
commit 0d6571ba4d
2 changed files with 33 additions and 8 deletions

View File

@ -1,7 +1,7 @@
/* $NetBSD: dma.c,v 1.9 1996/10/13 03:14:09 christos Exp $ */ /* $NetBSD: dma.c,v 1.10 1996/12/09 03:09:51 thorpej Exp $ */
/* /*
* Copyright (c) 1995 Jason R. Thorpe. * Copyright (c) 1995, 1996 Jason R. Thorpe. All rights reserved.
* Copyright (c) 1982, 1990, 1993 * Copyright (c) 1982, 1990, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -54,7 +54,6 @@
#include <hp300/hp300/isr.h> #include <hp300/hp300/isr.h>
extern void isrlink();
extern void _insque(); extern void _insque();
extern void _remque(); extern void _remque();
extern u_int kvtop(); extern u_int kvtop();
@ -89,6 +88,8 @@ struct dma_softc {
struct dmareg *sc_dmareg; /* pointer to our hardware */ struct dmareg *sc_dmareg; /* pointer to our hardware */
struct dma_channel sc_chan[NDMACHAN]; /* 2 channels */ struct dma_channel sc_chan[NDMACHAN]; /* 2 channels */
char sc_type; /* A, B, or C */ char sc_type; /* A, B, or C */
int sc_ipl; /* our interrupt level */
void *sc_ih; /* interrupt cookie */
} Dma_softc; } Dma_softc;
/* types */ /* types */
@ -140,7 +141,7 @@ dmainit()
* *
* XXX Don't know how to easily differentiate the A and B cards, * XXX Don't know how to easily differentiate the A and B cards,
* so we just hope nobody has an A card (A cards will work if * so we just hope nobody has an A card (A cards will work if
* DMAINTLVL is set to 3). * splbio works out to ipl 3).
*/ */
if (badbaddr((char *)&dma->dma_id[2])) { if (badbaddr((char *)&dma->dma_id[2])) {
rev = 'B'; rev = 'B';
@ -181,8 +182,31 @@ dmainit()
printf("%s: 98620%c, 2 channels, %d bit\n", sc->sc_xname, printf("%s: 98620%c, 2 channels, %d bit\n", sc->sc_xname,
rev, (rev == 'B') ? 16 : 32); rev, (rev == 'B') ? 16 : 32);
/* Establish the interrupt handler */ /*
isrlink(dmaintr, sc, DMAINTLVL, ISRPRI_BIO); * Defer hooking up our interrupt until the first
* DMA-using controller has hooked up theirs.
*/
sc->sc_ih = NULL;
}
/*
* Compute the ipl and (re)establish the interrupt handler
* for the DMA controller.
*/
void
dmacomputeipl()
{
struct dma_softc *sc = &Dma_softc;
if (sc->sc_ih != NULL)
isrunlink(sc->sc_ih);
/*
* Our interrupt level must be as high as the highest
* device using DMA (i.e. splbio).
*/
sc->sc_ipl = PSLTOIPL(hp300_bioipl);
sc->sc_ih = isrlink(dmaintr, sc, sc->sc_ipl, ISRPRI_BIO);
} }
int int
@ -342,7 +366,7 @@ dmago(unit, addr, count, flags)
/* /*
* Set up the command word based on flags * Set up the command word based on flags
*/ */
dc->dm_cmd = DMA_ENAB | DMA_IPL(DMAINTLVL) | DMA_START; dc->dm_cmd = DMA_ENAB | DMA_IPL(sc->sc_ipl) | DMA_START;
if ((flags & DMAGO_READ) == 0) if ((flags & DMAGO_READ) == 0)
dc->dm_cmd |= DMA_WRT; dc->dm_cmd |= DMA_WRT;
if (flags & DMAGO_LWORD) if (flags & DMAGO_LWORD)

View File

@ -1,4 +1,4 @@
/* $NetBSD: dmavar.h,v 1.5 1995/03/28 18:16:03 jtc Exp $ */ /* $NetBSD: dmavar.h,v 1.6 1996/12/09 03:09:51 thorpej Exp $ */
/* /*
* Copyright (c) 1982, 1990, 1993 * Copyright (c) 1982, 1990, 1993
@ -50,4 +50,5 @@
#ifdef _KERNEL #ifdef _KERNEL
extern void dmago(), dmafree(); extern void dmago(), dmafree();
extern int dmareq(); extern int dmareq();
extern void dmacomputeipl __P((void));
#endif #endif