* Tidy up interrupt handlers by implementing an intr_establish()

handler to hook up device interrupts and softc callbacks.

   Suggested by:  Jason Thorpe and Toru Nishimura

*  Fixup the indenting in a few places to conform to NetBSD style
This commit is contained in:
wdk 2000-08-15 04:56:45 +00:00
parent 94c7405838
commit 33016f23e0
13 changed files with 192 additions and 142 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.h,v 1.1 2000/08/12 22:58:06 wdk Exp $ */
/* $NetBSD: autoconf.h,v 1.2 2000/08/15 04:56:45 wdk Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -35,17 +35,12 @@
struct confargs;
/* Handle device interrupt for given unit of a driver */
typedef void* intr_arg_t; /* pointer to some softc */
typedef int (*intr_handler_t) __P((intr_arg_t));
struct confargs {
const char *ca_name; /* Device name. */
int ca_addr; /* Device address. */
int ca_intr; /* Device interrupt level */
bus_space_tag_t ca_bustag; /* parent bus tag */
bus_dma_tag_t ca_dmatag; /* parent bus dma */
bus_addr_t ca_paddr; /* physical address */
};
/* Locator aliases */

View File

@ -1,4 +1,4 @@
/* $NetBSD: bus.h,v 1.1 2000/08/12 22:58:09 wdk Exp $ */
/* $NetBSD: bus.h,v 1.2 2000/08/15 04:56:45 wdk Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
@ -163,6 +163,15 @@ struct mipsco_bus_space {
void (*bs_free) __P((bus_space_tag_t, bus_space_handle_t,
bus_size_t));
/* interrupt attach */
void (*bs_intr_establish) __P((
bus_space_tag_t,
int, /*bus-specific intr*/
int, /*priority/class*/
int, /*flags*/
int (*) __P((void *)), /*handler*/
void *)); /*handler arg*/
void *bs_aux;
};
@ -311,6 +320,17 @@ int mipsco_bus_space_alloc __P((bus_space_tag_t, bus_addr_t, bus_addr_t,
#define bus_space_free(t, h, s) \
(*(t)->bs_free)((t), (h), (s))
/*
* void bus_intr_establish __P((bus_space_tag_t bst,
* int level, int pri, int flags, int (*func) __P((void *))
* void *arg));
*
* Attach interrupt handler and softc argument
*/
#define bus_intr_establish(t, i, c, f, ihf, iha) \
(*(t)->bs_intr_establish)((t), (i), (c), (f), (ihf), (iha))
/*
* u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
* bus_space_handle_t bsh, bus_size_t offset));

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.1 2000/08/12 22:58:22 wdk Exp $ */
/* $NetBSD: intr.h,v 1.2 2000/08/15 04:56:45 wdk Exp $ */
/*
* Copyright (c) 1998 Jonathan Stone. All rights reserved.
@ -111,11 +111,27 @@ extern void _clrsoftintr __P((int));
#define splsoftnet() _splraise(MIPS_INT_MASK_SPL_SOFT1)
#define spllowersoftclock() _spllower(MIPS_INT_MASK_SPL_SOFT0)
/* handle i/o device interrupts */
extern void mipsco_intr __P((u_int, u_int, u_int, u_int));
struct intrhandler {
int (*func) __P((void *));
void *arg;
};
extern struct intrhandler intrtab[];
extern void (*enable_intr) __P((void));
extern void (*disable_intr) __P((void));
#define SYS_INTR_LEVEL0 0
#define SYS_INTR_LEVEL1 1
#define SYS_INTR_LEVEL2 2
#define SYS_INTR_LEVEL3 3
#define SYS_INTR_LEVEL4 4
#define SYS_INTR_LEVEL5 5
#define SYS_INTR_SCSI 6
#define SYS_INTR_TIMER 7
#define SYS_INTR_ETHER 8
#define SYS_INTR_SCC0 9
#define SYS_INTR_FDC 10
#define MAX_INTR_COOKIES 16
#define CALL_INTR(lev) ((*intrtab[lev].func)(intrtab[lev].arg))
#endif /* !_LOCORE */
#endif /* _KERNEL */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sysconf.h,v 1.1 2000/08/12 22:58:43 wdk Exp $ */
/* $NetBSD: sysconf.h,v 1.2 2000/08/15 04:56:46 wdk Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -59,6 +59,7 @@ struct platform {
unsigned (*clkread) __P((void));
void (*read_todr) __P((struct clock_ymdhms *));
void (*write_todr) __P((struct clock_ymdhms *));
void (*intr_establish) __P((int, int (*)__P((void *)), void *));
};
extern struct platform platform;

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.1 2000/08/12 22:58:50 wdk Exp $ */
/* $NetBSD: autoconf.c,v 1.2 2000/08/15 04:56:46 wdk Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -77,6 +77,8 @@ extern int initcpu __P((void)); /*XXX*/
void findroot __P((struct device **, int *));
struct intrhandler intrtab[MAX_INTR_COOKIES];
/*
* Determine mass storage and memory configuration for a machine.
* Print cpu type, and then iterate over an array of devices

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.1 2000/08/12 22:58:53 wdk Exp $ */
/* $NetBSD: machdep.c,v 1.2 2000/08/15 04:56:46 wdk Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -43,7 +43,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.1 2000/08/12 22:58:53 wdk Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.2 2000/08/15 04:56:46 wdk Exp $");
/* from: Utah Hdr: machdep.c 1.63 91/04/24 */
@ -154,6 +154,7 @@ static void unimpl_iointr __P((unsigned, unsigned, unsigned, unsigned));
static int unimpl_memsize __P((caddr_t));
static unsigned unimpl_clkread __P((void));
static void unimpl_todr __P((struct clock_ymdhms *));
static void unimpl_intr_establish __P((int, int (*)__P((void *)), void *));
struct platform platform = {
"iobus not set",
@ -163,6 +164,7 @@ struct platform platform = {
unimpl_clkread,
unimpl_todr,
unimpl_todr,
unimpl_intr_establish,
};
struct consdev *cn_tab = NULL;
@ -631,6 +633,15 @@ unimpl_todr(dt)
panic("sysconf.init didn't init TOD");
}
void
unimpl_intr_establish(level, func, arg)
int level;
int (*func) __P((void *));
void *arg;
{
panic("sysconf.init didn't init intr_establish\n");
}
void
delay(n)
int n;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mips_3x30.c,v 1.1 2000/08/12 22:58:54 wdk Exp $ */
/* $NetBSD: mips_3x30.c,v 1.2 2000/08/15 04:56:46 wdk Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -49,16 +49,12 @@
#include <machine/mainboard.h>
#include <machine/sysconf.h>
#include "le.h"
extern void asc_intr __P(());
extern void kbm_rint __P((int));
extern void MachFPInterrupt __P((u_int, u_int, u_int, struct frame *));
/* Local functions */
void pizazz_intr __P((u_int, u_int, u_int, u_int));
void pizazz_level0_intr __P((void));
int pizazz_level0_intr __P((void *));
void pizazz_intr_establish __P((int, int (*)(void *), void *));
void
pizazz_init()
@ -66,11 +62,21 @@ pizazz_init()
platform.iobus = "obio";
platform.cons_init = NULL;
platform.iointr = pizazz_intr;
platform.intr_establish = pizazz_intr_establish;
pizazz_intr_establish(SYS_INTR_LEVEL0, pizazz_level0_intr, NULL);
strcpy(cpu_model, "Mips 3230 Magnum (Pizazz)");
cpuspeed = 25;
}
#define HANDLE_INTR(intr, mask) \
do { \
if (ipending & (mask)) { \
CALL_INTR(intr); \
} \
} while (0)
void
pizazz_intr(status, cause, pc, ipending)
u_int status; /* status register at time of the exception */
@ -95,25 +101,19 @@ pizazz_intr(status, cause, pc, ipending)
/* If clock interrupts were enabled, re-enable them ASAP. */
_splset(MIPS_SR_INT_IE | (status & MIPS_INT_MASK_2));
HANDLE_INTR(SYS_INTR_FDC, MIPS_INT_MASK_4);
HANDLE_INTR(SYS_INTR_SCSI, MIPS_INT_MASK_1);
HANDLE_INTR(SYS_INTR_LEVEL0, MIPS_INT_MASK_0);
if (ipending & MIPS_INT_MASK_5) { /* level 5 interrupt */
printf("level 5 interrupt: PC %x CR %x SR %x\n",
pc, cause, status);
/* cause &= ~MIPS_INT_MASK_5; */
/* panic("level 5 interrupt"); */
}
if (ipending & MIPS_INT_MASK_4) { /* level 4 interrupt */
void fdintr __P((int));
fdintr(0);
/* cause &= ~MIPS_INT_MASK_4; */
}
if (ipending & MIPS_INT_MASK_1) { /* level 1 interrupt */
asc_intr();
cause &= ~MIPS_INT_MASK_1;
}
if (ipending & MIPS_INT_MASK_0) { /* level 0 interrupt */
pizazz_level0_intr();
cause &= ~MIPS_INT_MASK_0;
}
/* XXX: Keep FDC interrupt masked off */
cause &= ~(MIPS_INT_MASK_0 | MIPS_INT_MASK_1 | MIPS_INT_MASK_5);
_splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
@ -127,30 +127,44 @@ pizazz_intr(status, cause, pc, ipending)
}
}
/*
* Level 0 interrupt handler
*
* Pizazz shares Lance, SCC, Expansion slot and Keyboard on level 0
* A secondary interrupt status register shows the real interrupt source
*/
void
pizazz_level0_intr()
int
pizazz_level0_intr(arg)
void *arg;
{
register int stat;
/* stat register is active low */
stat = ~*(volatile u_char *)INTREG_0;
if (stat & INT_Lance) {
extern int leintr __P((int));
int s = splimp();
if (stat & INT_Lance)
CALL_INTR(SYS_INTR_ETHER);
leintr(0);
splx(s);
}
if (stat & INT_SCC) {
extern void zs_intr __P((void));
if (stat & INT_SCC)
CALL_INTR(SYS_INTR_SCC0);
zs_intr();
}
return 0;
}
void
pizazz_intr_establish(level, func, arg)
int level;
int (*func) __P((void *));
void *arg;
{
if (level < 0 || level >= MAX_INTR_COOKIES)
panic("invalid interrupt level");
if (intrtab[level].func != NULL)
panic("cannot share interrupt %d", level);
intrtab[level].func = func;
intrtab[level].arg = arg;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: asc.c,v 1.2 2000/08/14 21:04:44 wdk Exp $ */
/* $NetBSD: asc.c,v 1.3 2000/08/15 04:56:46 wdk Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
@ -83,8 +83,6 @@ struct asc_softc {
static int ascmatch __P((struct device *, struct cfdata *, void *));
static void ascattach __P((struct device *, struct device *, void *));
static struct asc_softc *asc0;
struct cfattach asc_ca = {
sizeof(struct asc_softc), ascmatch, ascattach
};
@ -116,6 +114,8 @@ static struct ncr53c9x_glue asc_glue = {
NULL, /* gl_clear_latched_intr */
};
static int asc_intr __P((void *));
#define MAX_SCSI_XFER (64*1024)
#define MAX_DMA_SZ MAX_SCSI_XFER
#define DMA_SEGS (MAX_DMA_SZ/NBPG)
@ -200,10 +200,10 @@ ascattach(parent, self, aux)
}
#endif
ncr53c9x_dmaselect = 0;
ncr53c9x_attach(sc, NULL, NULL);
ncr53c9x_dmaselect = 0;
asc0 = esc;
bus_intr_establish(esc->sc_bst, SYS_INTR_SCSI, 0, 0, asc_intr, esc);
}
/*
@ -522,22 +522,24 @@ rambo_dma_chain(esc)
bus_space_write_2(esc->sc_bst, esc->dm_bsh, RAMBO_BLKCNT, blocks);
}
void
asc_intr()
int
asc_intr(arg)
void *arg;
{
register u_int32_t dma_stat;
struct asc_softc *esc = asc0;
struct ncr53c9x_softc *sc = (void *)asc0;
register u_int32_t dma_stat;
struct asc_softc *esc = arg;
struct ncr53c9x_softc *sc = arg;
esc->sc_intrcnt.ev_count++;
esc->sc_intrcnt.ev_count++;
/* Check for NCR 53c94 interrupt */
if (NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT) {
ncr53c9x_intr((struct ncr53c9x_softc *) asc0);
}
/* Check for RAMBO DMA Interrupt */
dma_stat = bus_space_read_4(esc->sc_bst, esc->dm_bsh, RAMBO_MODE);
if (dma_stat & RB_INTR_PEND) {
rambo_dma_chain(esc);
}
/* Check for NCR 53c94 interrupt */
if (NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT) {
ncr53c9x_intr(sc);
}
/* Check for RAMBO DMA Interrupt */
dma_stat = bus_space_read_4(esc->sc_bst, esc->dm_bsh, RAMBO_MODE);
if (dma_stat & RB_INTR_PEND) {
rambo_dma_chain(esc);
}
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: i82072.c,v 1.1 2000/08/12 22:58:56 wdk Exp $ */
/* $NetBSD: i82072.c,v 1.2 2000/08/15 04:56:46 wdk Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
@ -67,6 +67,8 @@ struct cfattach fd_ca = {
sizeof(struct fd_softc), fd_match, fd_attach
};
static int fd_intr __P((void *));
int
fd_match(parent, cf, aux)
struct device *parent;
@ -95,6 +97,8 @@ fd_attach(parent, self, aux)
evcnt_attach_dynamic(&sc->fd_intrcnt, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "intr");
bus_intr_establish(sc->fd_bst, SYS_INTR_FDC, 0, 0, fd_intr, sc);
fd_reset(sc);
printf(": not fully implemented\n");
}
@ -134,17 +138,13 @@ void
fdsize()
{}
void
fdintr(unit)
int unit;
static int
fd_intr(arg)
void *arg;
{
struct fd_softc *sc;
extern struct cfdriver fd_cd;
struct fd_softc *sc = arg;
if (unit < fd_cd.cd_ndevs) {
sc = fd_cd.cd_devs[unit];
printf("stray floppy interrupt\n");
sc->fd_intrcnt.ev_count++;
fd_reset(sc);
}
sc->fd_intrcnt.ev_count++;
fd_reset(sc);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_le.c,v 1.1 2000/08/12 22:58:57 wdk Exp $ */
/* $NetBSD: if_le.c,v 1.2 2000/08/15 04:56:46 wdk Exp $ */
/*-
* Copyright (c) 1996, 2000 The NetBSD Foundation, Inc.
@ -104,6 +104,8 @@ struct cfattach le_ca = {
#define hide static
#endif
int le_intr __P((void *));
hide void lewrcsr __P((struct lance_softc *, u_int16_t, u_int16_t));
hide u_int16_t lerdcsr __P((struct lance_softc *, u_int16_t));
@ -244,6 +246,8 @@ le_attach(parent, self, aux)
evcnt_attach_dynamic(&lesc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "intr");
bus_intr_establish(lesc->sc_bustag, SYS_INTR_ETHER, 0, 0,
le_intr, lesc);
am7990_config(&lesc->sc_am7990);
return;
@ -254,16 +258,11 @@ bad:
}
int
leintr(unit)
int unit;
le_intr(arg)
void *arg;
{
struct am7990_softc *sc;
extern struct cfdriver le_cd;
struct le_softc *lesc = arg;
if (unit >= le_cd.cd_ndevs)
return 0;
sc = le_cd.cd_devs[unit];
((struct le_softc *)sc)->sc_intrcnt.ev_count++;
return am7990_intr(sc);
lesc->sc_intrcnt.ev_count++;
return am7990_intr(&lesc->sc_am7990);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: obio.c,v 1.1 2000/08/12 22:58:57 wdk Exp $ */
/* $NetBSD: obio.c,v 1.2 2000/08/15 04:56:46 wdk Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -43,11 +43,14 @@
#include <machine/autoconf.h>
#include <machine/mainboard.h>
#include <machine/bus.h>
#include <machine/sysconf.h>
static int obio_match __P((struct device *, struct cfdata *, void *));
static void obio_attach __P((struct device *, struct device *, void *));
static int obio_search __P((struct device *, struct cfdata *, void *));
static int obio_print __P((void *, const char *));
static void obio_intr_establish __P((bus_space_tag_t, int, int, int,
int (*)(void *), void *));
struct cfattach obio_ca = {
sizeof(struct device), obio_match, obio_attach
@ -86,12 +89,13 @@ obio_attach(parent, self, aux)
0xb8000000, 0x08000000);
_bus_dma_tag_init(&obio_dmatag);
obio_bustag.bs_intr_establish = obio_intr_establish; /* XXX */
ca->ca_bustag = &obio_bustag;
ca->ca_dmatag = &obio_dmatag;
printf("\n");
config_search(obio_search, self, ca);
}
static int
@ -131,3 +135,14 @@ obio_print(args, name)
return(UNCONF);
}
void
obio_intr_establish(bst, level, pri, flags, func, arg)
bus_space_tag_t bst;
int level;
int pri;
int flags;
int (*func) __P((void *));
void *arg;
{
(*platform.intr_establish)(level, func, arg);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: rambo.c,v 1.1 2000/08/12 22:58:58 wdk Exp $ */
/* $NetBSD: rambo.c,v 1.2 2000/08/15 04:56:47 wdk Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -56,6 +56,7 @@
static int rambo_match __P((struct device *, struct cfdata *, void *));
static void rambo_attach __P((struct device *, struct device *, void *));
static unsigned rambo_clkread __P((void));
void rambo_clkintr __P((struct clockframe *));
struct rambo_softc {
struct device dev;
@ -117,23 +118,23 @@ rambo_attach(parent, self, aux)
void
rambo_clkintr(cf)
struct clockframe *cf;
struct clockframe *cf;
{
register u_int32_t tbreak, tclast;
register int cycles = 0;
register u_int32_t tbreak, tclast;
register int cycles = 0;
rambo->sc_intrcnt.ev_count++;
tbreak = bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, RB_TBREAK);
/* This will also clear the interrupt */
while ((tclast=bus_space_read_4(rambo->sc_bst, rambo->sc_bsh,
RB_TCOUNT)) >= tbreak) {
hardclock(cf);
tbreak += rambo->sc_hzticks;
cycles++;
}
rambo->sc_intrcnt.ev_count++;
tbreak = bus_space_read_4(rambo->sc_bst, rambo->sc_bsh, RB_TBREAK);
/* This will also clear the interrupt */
while ((tclast=bus_space_read_4(rambo->sc_bst, rambo->sc_bsh,
RB_TCOUNT)) >= tbreak) {
hardclock(cf);
tbreak += rambo->sc_hzticks;
cycles++;
}
bus_space_write_4(rambo->sc_bst, rambo->sc_bsh, RB_TBREAK, tbreak);
rambo->sc_tclast = tclast;
bus_space_write_4(rambo->sc_bst, rambo->sc_bsh, RB_TBREAK, tbreak);
rambo->sc_tclast = tclast;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs.c,v 1.1 2000/08/12 22:58:59 wdk Exp $ */
/* $NetBSD: zs.c,v 1.2 2000/08/15 04:56:47 wdk Exp $ */
/*-
* Copyright (c) 1996, 2000 The NetBSD Foundation, Inc.
@ -171,7 +171,7 @@ struct cfattach zsc_ca = {
extern struct cfdriver zsc_cd;
static void zshard __P((void *));
static int zshard __P((void *));
static void zssoft __P((void *));
static int zs_get_speed __P((struct zs_chanstate *));
@ -218,7 +218,6 @@ zs_attach(parent, self, aux)
struct zschan *zc;
struct zs_chanstate *cs;
int s, zs_unit, channel;
static int didintr;
zsc->zsc_bustag = ca->ca_bustag;
if (bus_space_map(ca->ca_bustag, ca->ca_addr,
@ -290,18 +289,8 @@ zs_attach(parent, self, aux)
}
}
/*
* Now safe to install interrupt handlers. Note the arguments
* to the interrupt handlers aren't used. Note, we only do this
* once since both SCCs interrupt at the same level and vector.
*/
if (!didintr) {
didintr = 1;
#if 0
isr_add_autovect(zssoft, NULL, ZSSOFT_PRI);
isr_add_autovect(zshard, NULL, ca->ca_intpri);
#endif
}
/* bus_intr_establish(zssoft, NULL, ZSSOFT_PRI); */
bus_intr_establish(zsc->zsc_bustag, SYS_INTR_SCC0, 0, 0, zshard, NULL);
evcnt_attach_dynamic(&zsc->zs_intrcnt, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "intr");
@ -341,7 +330,7 @@ static volatile int zssoftpending;
* Our ZS chips all share a common, autovectored interrupt,
* so we have to look at all of them on each interrupt.
*/
static void
static int
zshard(arg)
void *arg;
{
@ -364,7 +353,7 @@ zshard(arg)
zssoftpending = 1;
zssoft(arg); /*isr_soft_request(ZSSOFT_PRI);*/
}
return;
return 0;
}
/*
@ -683,18 +672,3 @@ zscnpollc(dev, on)
int on;
{
}
/*
* ZS vector interrupt service routine.
*/
void
zs_intr()
{
int vec;
/*
* TODO: We can read the interrupt vector from the SCC
* registers.
*/
zshard((void *)vec); /* XXX vec is not used */
}