Use evcnts properly for interrupt counting.

The architecture here follows that of the vax port -- each device has its
evcnt in its softc, but defers actually incrementing it to the IRQ
dispatcher.  This way, devices can attach sub-counts (e.g. Rx and Tx counts
for Ethernet interfaces), but don't all have to have code to increment the
counters.

Drivers deliberately call evcnt_attach_dynamic() before establishing their
interrupt handler so that the establish routine can attach a parent event if
that's appropriate.  At present, it isn't.
This commit is contained in:
bjh21 2001-01-23 22:07:59 +00:00
parent 8c87715ce0
commit f32fc0fc90
11 changed files with 89 additions and 50 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ioc.c,v 1.7 2001/01/07 15:56:02 bjh21 Exp $ */
/* $NetBSD: ioc.c,v 1.8 2001/01/23 22:07:59 bjh21 Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 Ben Harris
@ -33,7 +33,7 @@
#include <sys/param.h>
__RCSID("$NetBSD: ioc.c,v 1.7 2001/01/07 15:56:02 bjh21 Exp $");
__RCSID("$NetBSD: ioc.c,v 1.8 2001/01/23 22:07:59 bjh21 Exp $");
#include <sys/device.h>
#include <sys/kernel.h>
@ -64,7 +64,9 @@ struct ioc_softc {
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
struct irq_handler *sc_clkirq;
struct evcnt sc_clkev;
struct irq_handler *sc_sclkirq;
struct evcnt sc_sclkev;
u_int8_t sc_ctl;
};
@ -361,16 +363,20 @@ cpu_initclocks(void)
(t0_count = IOC_TIMER_RATE / hz) > 65535)
panic("ioc_initclocks: Impossible clock rate: %d Hz", hz);
ioc_counter_start(self, 0, t0_count);
evcnt_attach_dynamic(&sc->sc_clkev, EVCNT_TYPE_INTR, NULL,
sc->sc_dev.dv_xname, "clock");
sc->sc_clkirq = irq_establish(IOC_IRQ_TM0, IPL_CLOCK, ioc_irq_clock,
NULL, "hardclock");
NULL, &sc->sc_clkev);
if (bootverbose)
printf("%s: %d Hz clock interrupting at %s\n",
self->dv_xname, hz, irq_string(sc->sc_clkirq));
if (stathz) {
setstatclockrate(stathz);
evcnt_attach_dynamic(&sc->sc_sclkev, EVCNT_TYPE_INTR, NULL,
sc->sc_dev.dv_xname, "statclock");
sc->sc_sclkirq = irq_establish(IOC_IRQ_TM1, IPL_STATCLOCK,
ioc_irq_statclock, NULL, "statclock");
ioc_irq_statclock, NULL, &sc->sc_sclkev);
if (bootverbose)
printf("%s: %d Hz statclock interrupting at %s\n",
self->dv_xname, stathz, irq_string(sc->sc_sclkirq));

View File

@ -1,4 +1,4 @@
/* $NetBSD: upc_iobus.c,v 1.3 2001/01/11 14:56:07 bjh21 Exp $ */
/* $NetBSD: upc_iobus.c,v 1.4 2001/01/23 22:07:59 bjh21 Exp $ */
/*-
* Copyright (c) 2000 Ben Harris
* All rights reserved.
@ -32,7 +32,7 @@
#include <sys/param.h>
__RCSID("$NetBSD: upc_iobus.c,v 1.3 2001/01/11 14:56:07 bjh21 Exp $");
__RCSID("$NetBSD: upc_iobus.c,v 1.4 2001/01/23 22:07:59 bjh21 Exp $");
#include <sys/device.h>
@ -51,6 +51,10 @@ static void upc_iobus_attach(struct device *, struct device *, void *);
struct upc_iobus_softc {
struct upc_softc sc_upc;
struct evcnt sc_intrcnt4;
struct evcnt sc_intrcntw;
struct evcnt sc_intrcntf;
struct evcnt sc_intrcntp;
};
struct cfattach upc_iobus_ca = {
@ -91,13 +95,33 @@ upc_iobus_attach(struct device *parent, struct device *self, void *aux)
&upc->sc_ioh);
upc_attach(upc);
irq_establish(IOC_IRQ_IL2, upc->sc_irq4.uih_level,
upc->sc_irq4.uih_func, upc->sc_irq4.uih_arg, "upc(irq4)");
irq_establish(IOC_IRQ_IL3, upc->sc_wintr.uih_level,
upc->sc_wintr.uih_func, upc->sc_wintr.uih_arg, "upc(wintr)");
irq_establish(IOC_IRQ_IL4, upc->sc_fintr.uih_level,
upc->sc_fintr.uih_func, upc->sc_fintr.uih_arg, "upc(fintr)");
irq_establish(IOC_IRQ_IL6, upc->sc_pintr.uih_level,
upc->sc_pintr.uih_func, upc->sc_pintr.uih_arg, "upc(pintr)");
if (upc->sc_irq4.uih_func != NULL) {
evcnt_attach_dynamic(&sc->sc_intrcnt4, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "irq4");
irq_establish(IOC_IRQ_IL2, upc->sc_irq4.uih_level,
upc->sc_irq4.uih_func, upc->sc_irq4.uih_arg,
&sc->sc_intrcnt4);
}
if (upc->sc_wintr.uih_func != NULL) {
evcnt_attach_dynamic(&sc->sc_intrcntw, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "wdc intr");
irq_establish(IOC_IRQ_IL3, upc->sc_wintr.uih_level,
upc->sc_wintr.uih_func, upc->sc_wintr.uih_arg,
&sc->sc_intrcntw);
}
if (upc->sc_fintr.uih_func != NULL) {
evcnt_attach_dynamic(&sc->sc_intrcntf, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "fdc intr");
irq_establish(IOC_IRQ_IL4, upc->sc_fintr.uih_level,
upc->sc_fintr.uih_func, upc->sc_fintr.uih_arg,
&sc->sc_intrcntf);
}
if (upc->sc_pintr.uih_func != NULL) {
evcnt_attach_dynamic(&sc->sc_intrcntp, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "lpt intr");
irq_establish(IOC_IRQ_IL6, upc->sc_pintr.uih_level,
upc->sc_pintr.uih_func, upc->sc_pintr.uih_arg,
&sc->sc_intrcntp);
}
/* IRQ3 on the 82C71x is not connected */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: arckbd.c,v 1.9 2001/01/22 23:08:27 bjh21 Exp $ */
/* $NetBSD: arckbd.c,v 1.10 2001/01/23 22:07:59 bjh21 Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 Ben Harris
* All rights reserved.
@ -43,7 +43,7 @@
#include <sys/param.h>
__RCSID("$NetBSD: arckbd.c,v 1.9 2001/01/22 23:08:27 bjh21 Exp $");
__RCSID("$NetBSD: arckbd.c,v 1.10 2001/01/23 22:07:59 bjh21 Exp $");
#include <sys/device.h>
#include <sys/errno.h>
@ -206,18 +206,18 @@ arckbd_attach(struct device *parent, struct device *self, void *aux)
bst = sc->sc_bst = ioc->ioc_fast_t;
bsh = sc->sc_bsh = ioc->ioc_fast_h;
sc->sc_rirq = irq_establish(IOC_IRQ_SRX, IPL_TTY, arckbd_rint, self,
NULL);
evcnt_attach_dynamic(&sc->sc_rev, EVCNT_TYPE_INTR, NULL,
sc->sc_dev.dv_xname, "rx intr");
sc->sc_rirq = irq_establish(IOC_IRQ_SRX, IPL_TTY, arckbd_rint, self,
&sc->sc_rev);
if (bootverbose)
printf("\n%s: interrupting at %s (rx)", self->dv_xname,
irq_string(sc->sc_rirq));
sc->sc_xirq = irq_establish(IOC_IRQ_STX, IPL_TTY, arckbd_xint, self,
NULL);
evcnt_attach_dynamic(&sc->sc_xev, EVCNT_TYPE_INTR, NULL,
sc->sc_dev.dv_xname, "tx intr");
sc->sc_xirq = irq_establish(IOC_IRQ_STX, IPL_TTY, arckbd_xint, self,
&sc->sc_xev);
irq_disable(sc->sc_xirq);
if (bootverbose)
printf(" and %s (tx)", irq_string(sc->sc_xirq));
@ -422,8 +422,6 @@ arckbd_xint(void *cookie)
{
struct arckbd_softc *sc = cookie;
if (!(sc->sc_flags & AKF_POLLING))
sc->sc_xev.ev_count++;
irq_disable(sc->sc_xirq);
/* First, process queued commands (acks from the last receive) */
if (sc->sc_cmdqueued) {
@ -453,8 +451,6 @@ arckbd_rint(void *cookie)
bus_space_handle_t bsh = sc->sc_bsh;
int data;
if (!(sc->sc_flags & AKF_POLLING))
sc->sc_rev.ev_count++;
bus_space_barrier(bst, bsh, 0, 1, BUS_BARRIER_READ);
data = bus_space_read_1(bst, bsh, 0);
bus_space_barrier(bst, bsh, 0, 1, BUS_BARRIER_READ);

View File

@ -1,4 +1,4 @@
/* $NetBSD: asc.c,v 1.2 2001/01/07 15:56:02 bjh21 Exp $ */
/* $NetBSD: asc.c,v 1.3 2001/01/23 22:07:59 bjh21 Exp $ */
/*
* Copyright (c) 1996 Mark Brinicombe
@ -187,9 +187,11 @@ ascattach(pdp, dp, auxp)
sbicinit(sbic);
if (!asc_poll) {
evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
dp->dv_xname, "intr");
sc->sc_ih =
podulebus_irq_establish(sc->sc_softc.sc_dev.dv_parent,
pa->pa_slotnum, IPL_BIO, asc_intr, sc, dp->dv_xname);
pa->pa_slotnum, IPL_BIO, asc_intr, sc, &sc->sc_intrcnt);
irq_enable(sc->sc_ih);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ascvar.h,v 1.1 2000/05/09 21:56:03 bjh21 Exp $ */
/* $NetBSD: ascvar.h,v 1.2 2001/01/23 22:07:59 bjh21 Exp $ */
/*
* Copyright (c) 1996 Mark Brinicombe
@ -43,6 +43,7 @@ struct asc_softc {
int sc_podule_number;
struct irq_handler *sc_ih;
struct evcnt sc_intrcnt;
vu_int sc_pagereg;
vu_int sc_intstat;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ea.c,v 1.22 2001/01/07 15:56:02 bjh21 Exp $ */
/* $NetBSD: if_ea.c,v 1.23 2001/01/23 22:07:59 bjh21 Exp $ */
/*
* Copyright (c) 2000 Ben Harris
@ -38,7 +38,7 @@
#include <sys/param.h>
__RCSID("$NetBSD: if_ea.c,v 1.22 2001/01/07 15:56:02 bjh21 Exp $");
__RCSID("$NetBSD: if_ea.c,v 1.23 2001/01/23 22:07:59 bjh21 Exp $");
#include <sys/device.h>
#include <sys/socket.h>
@ -64,6 +64,7 @@ __RCSID("$NetBSD: if_ea.c,v 1.22 2001/01/07 15:56:02 bjh21 Exp $");
struct ea_softc {
struct seeq8005_softc sc_8005;
struct irq_handler *sc_ih;
struct evcnt sc_intrcnt;
};
/*
@ -147,8 +148,10 @@ eaattach(struct device *parent, struct device *self, void *aux)
/* Claim a podule interrupt */
evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "intr");
sc->sc_ih = podulebus_irq_establish(sc->sc_8005.sc_dev.dv_parent,
pa->pa_slotnum, IPL_NET, seeq8005intr, sc, self->dv_xname);
pa->pa_slotnum, IPL_NET, seeq8005intr, sc, &sc->sc_intrcnt);
}
/* End of if_ea.c */

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_eh.c,v 1.10 2001/01/07 15:56:02 bjh21 Exp $ */
/* $NetBSD: if_eh.c,v 1.11 2001/01/23 22:07:59 bjh21 Exp $ */
/*-
* Copyright (c) 2000 Ben Harris
@ -53,7 +53,7 @@
#include <sys/param.h>
__KERNEL_RCSID(0, "$NetBSD: if_eh.c,v 1.10 2001/01/07 15:56:02 bjh21 Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_eh.c,v 1.11 2001/01/23 22:07:59 bjh21 Exp $");
#include <sys/systm.h>
#include <sys/device.h>
@ -105,6 +105,7 @@ struct eh_softc {
bus_space_tag_t sc_ctl2t;
bus_space_handle_t sc_ctl2h;
struct irq_handler *sc_ih;
struct evcnt sc_intrcnt;
int sc_flags;
#define EHF_16BIT 0x01
#define EHF_MAU 0x02
@ -314,8 +315,10 @@ eh_attach(struct device *parent, struct device *self, void *aux)
dp8390_config(dsc, media, nmedia, media[0]);
dp8390_stop(dsc);
evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "intr");
sc->sc_ih = podulebus_irq_establish(self->dv_parent, pa->pa_slotnum,
IPL_NET, dp8390_intr, self, self->dv_xname);
IPL_NET, dp8390_intr, self, &sc->sc_intrcnt);
if (bootverbose)
printf("%s: interrupting at %s\n",
self->dv_xname, irq_string(sc->sc_ih));

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_ei.c,v 1.5 2001/01/22 22:28:43 bjh21 Exp $ */
/* $NetBSD: if_ei.c,v 1.6 2001/01/23 22:08:00 bjh21 Exp $ */
/*-
* Copyright (c) 2000 Ben Harris
@ -38,7 +38,7 @@
#include <sys/param.h>
__RCSID("$NetBSD: if_ei.c,v 1.5 2001/01/22 22:28:43 bjh21 Exp $");
__RCSID("$NetBSD: if_ei.c,v 1.6 2001/01/23 22:08:00 bjh21 Exp $");
#include <sys/device.h>
#include <sys/malloc.h>
@ -83,6 +83,7 @@ struct ei_softc {
bus_space_handle_t sc_rom_h;
u_int8_t sc_idrom[EI_ROMSIZE];
struct irq_handler *sc_ih;
struct evcnt sc_intrcnt;
};
struct cfattach ei_ca = {
@ -193,8 +194,10 @@ ei_attach(struct device *parent, struct device *self, void *aux)
i82586_attach(&sc->sc_ie, descr, sc->sc_idrom + EI_ROM_EADDR,
NULL, 0, 0);
evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
self->dv_xname, "intr");
sc->sc_ih = podulebus_irq_establish(self->dv_parent, pa->pa_slotnum,
IPL_NET, i82586_intr, self, self->dv_xname);
IPL_NET, i82586_intr, self, &sc->sc_intrcnt);
if (bootverbose)
printf("%s: interrupting at %s\n", self->dv_xname,
irq_string(sc->sc_ih));

View File

@ -1,4 +1,4 @@
/* $NetBSD: podulebus.c,v 1.6 2001/01/07 15:56:03 bjh21 Exp $ */
/* $NetBSD: podulebus.c,v 1.7 2001/01/23 22:08:00 bjh21 Exp $ */
/*-
* Copyright (c) 2000 Ben Harris
@ -30,7 +30,7 @@
#include <sys/param.h>
__RCSID("$NetBSD: podulebus.c,v 1.6 2001/01/07 15:56:03 bjh21 Exp $");
__RCSID("$NetBSD: podulebus.c,v 1.7 2001/01/23 22:08:00 bjh21 Exp $");
#include <sys/device.h>
#include <sys/malloc.h>
@ -336,14 +336,14 @@ podulebus_submatch(struct device *parent, struct cfdata *cf, void *aux)
struct irq_handler *
podulebus_irq_establish(struct device *self, int slot, int ipl,
int (*func)(void *), void *arg, char const *name)
int (*func)(void *), void *arg, struct evcnt *ev)
{
/* XXX: support for checking IRQ bit on podule? */
#if NUNIXBP > 0
if (unixbp_cd.cd_ndevs > 0 && unixbp_cd.cd_devs[0] != NULL)
return irq_establish(IRQ_UNIXBP_BASE + slot, ipl, func, arg,
name);
ev);
#endif
return irq_establish(IRQ_PIRQ, ipl, func, arg, name);
return irq_establish(IRQ_PIRQ, ipl, func, arg, ev);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: podulebus.h,v 1.3 2001/01/07 15:56:03 bjh21 Exp $ */
/* $NetBSD: podulebus.h,v 1.4 2001/01/23 22:08:00 bjh21 Exp $ */
/*
* Copyright (c) 1995 Mark Brinicombe.
@ -78,8 +78,10 @@ struct podulebus_attach_args {
#ifdef _KERNEL
struct evcnt;
extern struct irq_handler *podulebus_irq_establish(struct device *, int, int,
int (*)(void *), void *, char const *name);
int (*)(void *), void *, struct evcnt *);
extern int podulebus_initloader(struct podulebus_attach_args *);
extern int podloader_readbyte(struct podulebus_attach_args *, u_int);
extern void podloader_writebyte(struct podulebus_attach_args *, u_int, int);

View File

@ -1,4 +1,4 @@
/* $NetBSD: arcvideo.c,v 1.10 2001/01/22 23:29:34 bjh21 Exp $ */
/* $NetBSD: arcvideo.c,v 1.11 2001/01/23 22:08:00 bjh21 Exp $ */
/*-
* Copyright (c) 1998, 2000 Ben Harris
* All rights reserved.
@ -39,7 +39,7 @@
#include <sys/param.h>
__RCSID("$NetBSD: arcvideo.c,v 1.10 2001/01/22 23:29:34 bjh21 Exp $");
__RCSID("$NetBSD: arcvideo.c,v 1.11 2001/01/23 22:08:00 bjh21 Exp $");
#include <sys/device.h>
#include <sys/errno.h>
@ -158,13 +158,13 @@ arcvideo_attach(struct device *parent, struct device *self, void *aux)
if (ioc_cd.cd_ndevs > 0 && ioc_cd.cd_devs[0] != NULL) {
/* ioc0 exists */
sc->sc_ioc = ioc_cd.cd_devs[0];
evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
sc->sc_dev.dv_xname, "vsync intr");
sc->sc_irq = irq_establish(IOC_IRQ_IR, IPL_TTY, arcvideo_intr,
self, NULL);
self, &sc->sc_intrcnt);
if (bootverbose)
printf(": VSYNC interrupts at %s",
irq_string(sc->sc_irq));
evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
sc->sc_dev.dv_xname, "vsync intr");
irq_disable(sc->sc_irq);
} else
#endif /* NIOC > 0 */
@ -300,9 +300,8 @@ arcvideo_await_vsync(struct device *self)
static int
arcvideo_intr(void *cookie)
{
struct arcvideo_softc *sc = cookie;
/* struct arcvideo_softc *sc = cookie; */
sc->sc_intrcnt.ev_count++;
return IRQ_HANDLED;
}