Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64/sparc64 Allow multiple drivers to share one...
details: https://anonhg.NetBSD.org/src/rev/5f42a70043f6
branches: trunk
changeset: 487516:5f42a70043f6
user: eeh <eeh%NetBSD.org@localhost>
date: Thu Jun 08 23:01:22 2000 +0000
description:
Allow multiple drivers to share one interrupt vector.
diffstat:
sys/arch/sparc64/sparc64/intr.c | 61 +++++++++++++++++++++++++++++++++++++---
1 files changed, 56 insertions(+), 5 deletions(-)
diffs (90 lines):
diff -r 82f9d9b7d0c6 -r 5f42a70043f6 sys/arch/sparc64/sparc64/intr.c
--- a/sys/arch/sparc64/sparc64/intr.c Thu Jun 08 22:58:42 2000 +0000
+++ b/sys/arch/sparc64/sparc64/intr.c Thu Jun 08 23:01:22 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.24 2000/06/02 15:36:53 eeh Exp $ */
+/* $NetBSD: intr.c,v 1.25 2000/06/08 23:01:22 eeh Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -111,6 +111,7 @@
int softintr __P((void *));
int softnet __P((void *));
int send_softclock __P((void *));
+int intr_list_handler __P((void *));
/*
* Stray interrupt handler. Clear it if possible.
@@ -243,6 +244,35 @@
int fastvec = 0;
/*
+ * PCI devices can share interrupts so we need to have
+ * a handler to hand out interrupts.
+ */
+int
+intr_list_handler(arg)
+ void * arg;
+{
+ int claimed = 0;
+ struct intrhand *ih = (struct intrhand *)arg;
+
+ if (!arg) panic("intr_list_handler: no handlers!");
+ while (ih && !claimed) {
+ claimed = (*ih->ih_fun)(ih->ih_arg);
+#ifdef DEBUG
+ {
+ extern int intrdebug;
+ if (intrdebug)
+ printf("intr %p %x arg %p %s\n",
+ ih, ih->ih_number, ih->ih_arg,
+ claimed ? "claimed" : "");
+ }
+#endif
+ ih = ih->ih_next;
+ }
+ return (claimed);
+}
+
+
+/*
* Attach an interrupt handler to the vector chain for the given level.
* This is not possible if it has been taken away as a fast vector.
*/
@@ -275,11 +305,32 @@
}
#endif
if (ih->ih_number < MAXINTNUM && ih->ih_number >= 0) {
- if (intrlev[ih->ih_number])
- panic("intr_establish: intr reused %d", ih->ih_number);
- intrlev[ih->ih_number] = ih;
+ if ((q = intrlev[ih->ih_number])) {
+ struct intrhand *nih;
+ /*
+ * Interrupt is already there. We need to create a
+ * new interrupt handler and interpose it.
+ */
+ printf("intr_establish: intr reused %d\n", ih->ih_number);
+
+ if (q->ih_fun != intr_list_handler) {
+ nih = (struct intrhand *)
+ malloc(sizeof(struct intrhand),
+ M_DEVBUF, M_NOWAIT);
+ /* Point the old IH at the new handler */
+ *nih = *q;
+ q->ih_fun = intr_list_handler;
+ q->ih_arg = (void *)nih;
+ nih->ih_next = NULL;
+ }
+ /* Add the ih to the head of the list */
+ ih->ih_next = (struct intrhand *)q->ih_arg;
+ q->ih_arg = (void *)ih;
+ }
+ else
+ intrlev[ih->ih_number] = ih;
#ifdef NOT_DEBUG
- printf("\nintr_establish: vector %x pli %x mapintr %p clrintr %p fun %p arg %p\n",
+ printf("\nintr_establish: vector %x pil %x mapintr %p clrintr %p fun %p arg %p\n",
ih->ih_number, ih->ih_pil, (long)ih->ih_map, (long)ih->ih_clr, ih->ih_fun, ih->ih_arg);
/*Debugger();*/
#endif
Home |
Main Index |
Thread Index |
Old Index