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