summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/mac68k/dev/esp.c13
-rw-r--r--sys/arch/mac68k/dev/espvar.h3
-rw-r--r--sys/arch/mac68k/dev/if_ae_nubus.c11
-rw-r--r--sys/arch/mac68k/dev/mac68k5380.c15
-rw-r--r--sys/arch/mac68k/dev/sbc_obio.c15
-rw-r--r--sys/arch/mac68k/dev/sbcvar.h3
-rw-r--r--sys/arch/mac68k/include/viareg.h15
-rw-r--r--sys/arch/mac68k/mac68k/via.c151
8 files changed, 139 insertions, 87 deletions
diff --git a/sys/arch/mac68k/dev/esp.c b/sys/arch/mac68k/dev/esp.c
index 927f0a20d38..4b9bd537693 100644
--- a/sys/arch/mac68k/dev/esp.c
+++ b/sys/arch/mac68k/dev/esp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: esp.c,v 1.18 2004/11/26 21:21:24 miod Exp $ */
+/* $OpenBSD: esp.c,v 1.19 2004/12/08 06:59:43 miod Exp $ */
/* $NetBSD: esp.c,v 1.59 1996/10/13 02:59:48 christos Exp $ */
/*
@@ -179,6 +179,9 @@ espattach(parent, self, aux)
*/
sc->sc_glue = &esp_glue;
+ esc->sc_ih.vh_fn = ncr53c9x_intr;
+ esc->sc_ih.vh_arg = esc;
+
/*
* Save the regs
*/
@@ -186,8 +189,8 @@ espattach(parent, self, aux)
unsigned long reg_offset;
esc->sc_reg = (volatile u_char *) SCSIBase;
- via2_register_irq(VIA2_SCSIIRQ, ncr53c9x_intr, esc,
- self->dv_xname);
+ esc->sc_ih.vh_ipl = VIA2_SCSIIRQ;
+ via2_register_irq(&esc->sc_ih, self->dv_xname);
esc->irq_mask = V2IF_SCSIIRQ;
reg_offset = SCSIBase - IOBase;
if (reg_offset == 0x10000) {
@@ -197,8 +200,8 @@ espattach(parent, self, aux)
}
} else {
esc->sc_reg = (volatile u_char *) SCSIBase + 0x402;
- via2_register_irq(VIA2_SCSIDRQ, ncr53c9x_intr, esc,
- self->dv_xname);
+ esc->sc_ih.vh_ipl = VIA2_SCSIDRQ;
+ via2_register_irq(&esc->sc_ih, self->dv_xname);
esc->irq_mask = V2IF_SCSIDRQ; /* V2IF_T1? */
sc->sc_freq = 25000000;
}
diff --git a/sys/arch/mac68k/dev/espvar.h b/sys/arch/mac68k/dev/espvar.h
index 95921cd2aba..38370af83ef 100644
--- a/sys/arch/mac68k/dev/espvar.h
+++ b/sys/arch/mac68k/dev/espvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: espvar.h,v 1.4 2001/07/04 08:52:45 niklas Exp $ */
+/* $OpenBSD: espvar.h,v 1.5 2004/12/08 06:59:43 miod Exp $ */
/* $NetBSD: espvar.h,v 1.16 1996/10/13 02:59:50 christos Exp $ */
/*
@@ -33,6 +33,7 @@
struct esp_softc {
struct ncr53c9x_softc sc_ncr53c9x; /* glue to MI code */
+ struct via2hand sc_ih;
volatile u_char *sc_reg; /* the registers */
diff --git a/sys/arch/mac68k/dev/if_ae_nubus.c b/sys/arch/mac68k/dev/if_ae_nubus.c
index 9ede3d5cf43..631f7f9532a 100644
--- a/sys/arch/mac68k/dev/if_ae_nubus.c
+++ b/sys/arch/mac68k/dev/if_ae_nubus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ae_nubus.c,v 1.11 2004/12/01 21:19:11 miod Exp $ */
+/* $OpenBSD: if_ae_nubus.c,v 1.12 2004/12/08 06:59:43 miod Exp $ */
/* $NetBSD: if_ae_nubus.c,v 1.17 1997/05/01 18:17:16 briggs Exp $ */
/*
@@ -426,15 +426,18 @@ ae_nb_watchdog(ifp)
struct ifnet *ifp;
{
struct ae_softc *sc = ifp->if_softc;
- extern struct intrhand via2intrs[7];
+ extern via2hand_t via2intrs[7];
/*
* This is a kludge! The via code seems to miss slot interrupts
* sometimes. This kludges around that by calling the handler
* by hand if the watchdog is activated. -- XXX (akb)
+ * XXX note that this assumes the nubus handler is first in the chain.
*/
- if (via2intrs[1].ih_fn != NULL)
- (void)(*via2intrs[1].ih_fn)(via2intrs[1].ih_arg);
+ if (!SLIST_EMPTY(&via2intrs[1])) {
+ struct via2hand *vh = SLIST_FIRST(&via2intrs[1]);
+ (void)(*vh->vh_fn)(vh->vh_arg);
+ }
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
++sc->sc_arpcom.ac_if.if_oerrors;
diff --git a/sys/arch/mac68k/dev/mac68k5380.c b/sys/arch/mac68k/dev/mac68k5380.c
index 5a409ef50d7..097a580521c 100644
--- a/sys/arch/mac68k/dev/mac68k5380.c
+++ b/sys/arch/mac68k/dev/mac68k5380.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mac68k5380.c,v 1.19 2004/11/26 21:21:24 miod Exp $ */
+/* $OpenBSD: mac68k5380.c,v 1.20 2004/12/08 06:59:43 miod Exp $ */
/* $NetBSD: mac68k5380.c,v 1.29 1997/02/28 15:50:50 scottr Exp $ */
/*
@@ -155,6 +155,7 @@ scsi_mach_init(sc)
struct ncr_softc *sc;
{
static int initted = 0;
+ static struct via2hand ih_irq, ih_drq;
if (initted++)
panic("scsi_mach_init called again.");
@@ -174,10 +175,14 @@ scsi_mach_init(sc)
scsi_flag = Via1Base + VIA2 * 0x2000 + rIFR;
}
- via2_register_irq(VIA2_SCSIIRQ, ncr5380_irq_intr, sc,
- sc->sc_dev.dv_xname);
- via2_register_irq(VIA2_SCSIDRQ, ncr5380_drq_intr, sc,
- sc->sc_dev.dv_xname);
+ ih_irq.vh_fn = ncr5380_irq_intr;
+ ih_irq.vh_arg = sc;
+ ih_irq.vh_ipl = VIA2_SCSIIRQ;
+ via2_register_irq(&ih_irq, sc->sc_dev.dv_xname);
+ ih_drq.vh_fn = ncr5380_drq_intr;
+ ih_drq.vh_arg = sc;
+ ih_drq.vh_ipl = VIA2_SCSIDRQ;
+ via2_register_irq(&ih_drq, sc->sc_dev.dv_xname);
}
static int
diff --git a/sys/arch/mac68k/dev/sbc_obio.c b/sys/arch/mac68k/dev/sbc_obio.c
index bff4f430845..6051a2c2076 100644
--- a/sys/arch/mac68k/dev/sbc_obio.c
+++ b/sys/arch/mac68k/dev/sbc_obio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sbc_obio.c,v 1.10 2004/12/02 06:43:25 miod Exp $ */
+/* $OpenBSD: sbc_obio.c,v 1.11 2004/12/08 06:59:43 miod Exp $ */
/* $NetBSD: sbc_obio.c,v 1.1 1997/03/01 20:18:59 scottr Exp $ */
/*
@@ -211,12 +211,17 @@ sbc_obio_attach(parent, self, args)
ncr_sc->sc_dma_start = sbc_dma_start;
ncr_sc->sc_dma_eop = sbc_dma_eop;
ncr_sc->sc_dma_stop = sbc_dma_stop;
- via2_register_irq(VIA2_SCSIDRQ, sbc_drq_intr, ncr_sc,
- ncr_sc->sc_dev.dv_xname);
+
+ sc->sc_ih_drq.vh_fn = sbc_drq_intr;
+ sc->sc_ih_drq.vh_arg = ncr_sc;
+ sc->sc_ih_drq.vh_ipl = VIA2_SCSIDRQ;
+ via2_register_irq(&sc->sc_ih_drq, ncr_sc->sc_dev.dv_xname);
}
- via2_register_irq(VIA2_SCSIIRQ, sbc_irq_intr, ncr_sc,
- ncr_sc->sc_dev.dv_xname);
+ sc->sc_ih_irq.vh_fn = sbc_irq_intr;
+ sc->sc_ih_irq.vh_arg = ncr_sc;
+ sc->sc_ih_irq.vh_ipl = VIA2_SCSIIRQ;
+ via2_register_irq(&sc->sc_ih_irq, ncr_sc->sc_dev.dv_xname);
sc->sc_clrintr = sbc_obio_clrintr;
if (sc->sc_options)
diff --git a/sys/arch/mac68k/dev/sbcvar.h b/sys/arch/mac68k/dev/sbcvar.h
index 4bec0604efd..96551d234dc 100644
--- a/sys/arch/mac68k/dev/sbcvar.h
+++ b/sys/arch/mac68k/dev/sbcvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sbcvar.h,v 1.4 2004/12/02 06:43:25 miod Exp $ */
+/* $OpenBSD: sbcvar.h,v 1.5 2004/12/08 06:59:43 miod Exp $ */
/* $NetBSD: sbcvar.h,v 1.1 1997/03/01 20:19:00 scottr Exp $ */
/*
@@ -75,6 +75,7 @@ struct sbc_pdma_handle {
*/
struct sbc_softc {
struct ncr5380_softc ncr_sc;
+ struct via2hand sc_ih_drq, sc_ih_irq;
volatile struct sbc_regs *sc_regs;
volatile vm_offset_t sc_drq_addr;
volatile vm_offset_t sc_nodrq_addr;
diff --git a/sys/arch/mac68k/include/viareg.h b/sys/arch/mac68k/include/viareg.h
index 355b12ed100..d09123dd0f3 100644
--- a/sys/arch/mac68k/include/viareg.h
+++ b/sys/arch/mac68k/include/viareg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: viareg.h,v 1.12 2004/12/01 21:19:12 miod Exp $ */
+/* $OpenBSD: viareg.h,v 1.13 2004/12/08 06:59:45 miod Exp $ */
/* $NetBSD: viareg.h,v 1.6 1997/02/28 07:41:41 scottr Exp $ */
/*-
@@ -190,6 +190,17 @@ extern int VIA2;
#define vDirA_ADBState 0x30
#ifdef _KERNEL
+/* VIA2 interrupts may be shared */
+struct via2hand {
+ SLIST_ENTRY(via2hand) v2h_link;
+ struct intrhand v2h_ih;
+#define vh_fn v2h_ih.ih_fn
+#define vh_arg v2h_ih.ih_arg
+#define vh_ipl v2h_ih.ih_ipl
+#define vh_count v2h_ih.ih_count
+};
+typedef SLIST_HEAD(, via2hand) via2hand_t;
+
void via_init(void);
int rbv_vidstatus(void);
void via_shutdown(void);
@@ -197,7 +208,7 @@ void via_set_modem(int);
void add_nubus_intr(int, int (*)(void *), void *, const char *);
void enable_nubus_intr(void);
void via1_register_irq(int, int (*)(void *), void *, const char *);
-void via2_register_irq(int, int (*)(void *), void *, const char *);
+int via2_register_irq(struct via2hand *, const char *);
#endif /* _KERNEL */
#endif /* _MAC68K_VIAREG_H_ */
diff --git a/sys/arch/mac68k/mac68k/via.c b/sys/arch/mac68k/mac68k/via.c
index 911027722e5..46ef5cd2e50 100644
--- a/sys/arch/mac68k/mac68k/via.c
+++ b/sys/arch/mac68k/mac68k/via.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: via.c,v 1.19 2004/11/26 21:21:28 miod Exp $ */
+/* $OpenBSD: via.c,v 1.20 2004/12/08 06:59:45 miod Exp $ */
/* $NetBSD: via.c,v 1.62 1997/09/10 04:38:48 scottr Exp $ */
/*-
@@ -62,7 +62,7 @@ int via2_nubus_intr(void *);
int VIA2 = 1; /* default for II, IIx, IIcx, SE/30. */
struct intrhand via1intrs[7];
-struct intrhand via2intrs[7];
+via2hand_t via2intrs[7];
void oss_intr(struct frame *);
void rbv_intr(struct frame *);
@@ -78,9 +78,13 @@ void (*real_via2_intr)(struct frame *);
*/
struct intrhand slotintrs[7];
+static struct via2hand nubus_intr;
+
void
via_init()
{
+ unsigned int i;
+
/* Initialize VIA1 */
/* set all timers to 0 */
via_reg(VIA1, vT1L) = 0;
@@ -98,6 +102,9 @@ via_init()
via1_register_irq(4, mrg_pmintr, NULL, "pm");
via1_register_irq(VIA1_T1, rtclock_intr, NULL, "clock");
+ for (i = 0; i < 7; i++)
+ SLIST_INIT(&via2intrs[i]);
+
if (VIA2 == VIA2OFF) {
/* Initialize VIA2 */
via2_reg(vT1L) = 0;
@@ -111,7 +118,9 @@ via_init()
via2_reg(vACR) &= 0x3f;
/* register default VIA2 interrupts */
- via2_register_irq(1, via2_nubus_intr, NULL, NULL);
+ nubus_intr.vh_ipl = 1;
+ nubus_intr.vh_fn = via2_nubus_intr;
+ via2_register_irq(&nubus_intr, NULL);
/* 4 snd_intr, 5 via2t2_intr */
/*
@@ -154,7 +163,10 @@ via_init()
via2_reg(rBufB) |= DB2O_CEnable;
}
real_via2_intr = rbv_intr;
- via2_register_irq(1, rbv_nubus_intr, NULL, NULL);
+
+ nubus_intr.vh_ipl = 1;
+ nubus_intr.vh_fn = rbv_nubus_intr;
+ via2_register_irq(&nubus_intr, NULL);
/* XXX necessary? */
add_nubus_intr(0, rbv_slot_ignore, NULL, "dummy");
}
@@ -211,9 +223,11 @@ via1_intr(struct frame *fp)
void
via2_intr(struct frame *fp)
{
- struct intrhand *ih;
+ struct via2hand *v2h;
+ via2hand_t *anchor;
u_int8_t intbits, bitnum;
u_int mask;
+ int handled, rc;
intbits = via2_reg(vIFR) & via2_reg(vIER);
@@ -224,45 +238,22 @@ via2_intr(struct frame *fp)
intbits &= 0x7f;
mask = 1;
- for (bitnum = 0, ih = via2intrs; ; bitnum++, ih++) {
- if ((intbits & mask) != 0 && ih->ih_fn != NULL) {
- if ((*ih->ih_fn)(ih->ih_arg) != 0)
- ih->ih_count.ec_count++;
- } else {
-#if 0
- printf("spurious VIA2 interrupt, source %d\n", bitnum);
-#endif
- }
- mask <<= 1;
- if (intbits < mask)
- break;
- }
-}
-
-void
-oss_intr(struct frame *fp)
-{
- struct intrhand *ih;
- u_int8_t intbits, bitnum;
- u_int mask;
-
- intbits = via2_reg(vIFR + rIFR);
-
- if (intbits == 0)
- return;
-
- intbits &= 0x7f;
- mask =1 ;
- for (bitnum = 0, ih = slotintrs; ; bitnum++, ih++) {
- if (intbits & mask) {
- if (ih->ih_fn != NULL) {
- if ((*ih->ih_fn)(ih->ih_arg) != 0)
+ for (bitnum = 0, anchor = via2intrs; ; bitnum++, anchor++) {
+ if ((intbits & mask) != 0) {
+ handled = 0;
+ SLIST_FOREACH(v2h, anchor, v2h_link) {
+ struct intrhand *ih = &v2h->v2h_ih;
+ rc = (*ih->ih_fn)(ih->ih_arg);
+ if (rc != 0) {
ih->ih_count.ec_count++;
- } else {
- printf("spurious nubus interrupt, slot %d\n",
- bitnum);
+ handled |= rc;
+ }
}
- via2_reg(rIFR) = mask;
+#if 0
+ if (handled == 0)
+ printf("spurious VIA2 interrupt, source %d\n",
+ bitnum);
+#endif
}
mask <<= 1;
if (intbits < mask)
@@ -273,9 +264,11 @@ oss_intr(struct frame *fp)
void
rbv_intr(struct frame *fp)
{
- struct intrhand *ih;
+ struct via2hand *v2h;
+ via2hand_t *anchor;
u_int8_t intbits, bitnum;
u_int mask;
+ int handled, rc;
intbits = (via2_reg(vIFR + rIFR) & via2_reg(vIER + rIER));
@@ -286,13 +279,21 @@ rbv_intr(struct frame *fp)
intbits &= 0x7f;
mask = 1;
- for (bitnum = 0, ih = via2intrs; ; bitnum++, ih++) {
- if ((intbits & mask) != 0 && ih->ih_fn != NULL) {
- if ((*ih->ih_fn)(ih->ih_arg) != 0)
- ih->ih_count.ec_count++;
- } else {
+ for (bitnum = 0, anchor = via2intrs; ; bitnum++, anchor++) {
+ if ((intbits & mask) != 0) {
+ handled = 0;
+ SLIST_FOREACH(v2h, anchor, v2h_link) {
+ struct intrhand *ih = &v2h->v2h_ih;
+ rc = (*ih->ih_fn)(ih->ih_arg);
+ if (rc != 0) {
+ ih->ih_count.ec_count++;
+ handled |= rc;
+ }
+ }
#if 0
- printf("spurious VIA2 interrupt, source %d\n", bitnum);
+ if (handled == 0)
+ printf("spurious VIA2 interrupt, source %d\n",
+ bitnum);
#endif
}
mask <<= 1;
@@ -353,6 +354,37 @@ enable_nubus_intr()
via2_reg(rIER) = 0x80 | V2IF_SLOTINT;
}
+void
+oss_intr(struct frame *fp)
+{
+ struct intrhand *ih;
+ u_int8_t intbits, bitnum;
+ u_int mask;
+
+ intbits = via2_reg(vIFR + rIFR);
+
+ if (intbits == 0)
+ return;
+
+ intbits &= 0x7f;
+ mask =1 ;
+ for (bitnum = 0, ih = slotintrs; ; bitnum++, ih++) {
+ if (intbits & mask) {
+ if (ih->ih_fn != NULL) {
+ if ((*ih->ih_fn)(ih->ih_arg) != 0)
+ ih->ih_count.ec_count++;
+ } else {
+ printf("spurious nubus interrupt, slot %d\n",
+ bitnum);
+ }
+ via2_reg(rIFR) = mask;
+ }
+ mask <<= 1;
+ if (intbits < mask)
+ break;
+ }
+}
+
/*ARGSUSED*/
int
via2_nubus_intr(void *bitarg)
@@ -488,28 +520,19 @@ via1_register_irq(int irq, int (*irq_func)(void *), void *client_data,
&evcount_intr);
}
-void
-via2_register_irq(int irq, int (*irq_func)(void *), void *client_data,
- const char *name)
+int
+via2_register_irq(struct via2hand *vh, const char *name)
{
- struct intrhand *ih;
+ int irq = vh->vh_ipl;
#ifdef DIAGNOSTIC
if (irq < 0 || irq > 7)
panic("via2_register_irq: bad irq %d", irq);
#endif
- ih = &via2intrs[irq];
-
-#ifdef DIAGNOSTIC
- if (ih->ih_fn != NULL)
- panic("via2_register_irq: attempt to share irq %d", irq);
-#endif
-
- ih->ih_fn = irq_func;
- ih->ih_arg = client_data;
- ih->ih_ipl = irq;
if (name != NULL)
- evcount_attach(&ih->ih_count, name, (void *)&ih->ih_ipl,
+ evcount_attach(&vh->vh_count, name, (void *)&vh->vh_ipl,
&evcount_intr);
+ SLIST_INSERT_HEAD(&via2intrs[irq], vh, v2h_link);
+ return (0);
}