PERFORCE change 98908 for review
Paolo Pisati
piso at FreeBSD.org
Sat Jun 10 16:35:37 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=98908
Change 98908 by piso at piso_newluxor on 2006/06/10 11:53:48
Fix support for multiple fast handlers: not tested though.
While here, refactor&cleanup a bit the code (rename
struct ppc_intr_handler variables to ppc_ih, and
struct intr_handler vars to ih, etcetc).
Reviewed by: Awaiting for Peter Grehan review
Affected files ...
.. //depot/projects/soc2006/intr_filter/powerpc/include/intr_machdep.h#2 edit
.. //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#2 edit
Differences ...
==== //depot/projects/soc2006/intr_filter/powerpc/include/intr_machdep.h#2 (text+ko) ====
@@ -33,11 +33,8 @@
struct intr_event;
struct ppc_intr_handler {
- ih_func_t *ih_func;
- void *ih_arg;
struct intr_event *ih_event;
u_int ih_irq;
- u_int ih_flags;
u_int ih_index;
u_long *ih_count;
u_long *ih_straycount;
==== //depot/projects/soc2006/intr_filter/powerpc/powerpc/intr_machdep.c#2 (text+ko) ====
@@ -66,6 +66,7 @@
#include <sys/queue.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
+#include <sys/ktr.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
@@ -82,10 +83,8 @@
MALLOC_DEFINE(M_INTR, "intr", "interrupt handler data");
-static int intr_initialized = 0;
-
static u_int intr_nirq;
-static struct ppc_intr_handler *intr_handlers;
+static struct ppc_intr_handler *intr_handlers = NULL;
static struct mtx intr_table_lock;
@@ -94,7 +93,6 @@
static int intrcnt_index;
static ih_func_t intr_stray_handler;
-static ih_func_t sched_ithd;
static void (*irq_enable)(uintptr_t);
static void (*irq_disable)(uintptr_t);
@@ -110,26 +108,26 @@
}
static void
-intrcnt_updatename(struct ppc_intr_handler *ih)
+intrcnt_updatename(struct ppc_intr_handler *ppc_ih)
{
- intrcnt_setname(ih->ih_event->ie_fullname, ih->ih_index);
+ intrcnt_setname(ppc_ih->ih_event->ie_fullname, ppc_ih->ih_index);
}
static void
-intrcnt_register(struct ppc_intr_handler *ih)
+intrcnt_register(struct ppc_intr_handler *ppc_ih)
{
char straystr[MAXCOMLEN + 1];
- KASSERT(ih->ih_event != NULL,
+ KASSERT(ppc_ih->ih_event != NULL,
("%s: ppc_intr_handler with no event", __func__));
- ih->ih_index = intrcnt_index;
+ ppc_ih->ih_index = intrcnt_index;
intrcnt_index += 2;
- snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", ih->ih_irq);
- intrcnt_updatename(ih);
- ih->ih_count = &intrcnt[ih->ih_index];
- intrcnt_setname(straystr, ih->ih_index + 1);
- ih->ih_straycount = &intrcnt[ih->ih_index + 1];
+ snprintf(straystr, MAXCOMLEN + 1, "stray irq%d", ppc_ih->ih_irq);
+ intrcnt_updatename(ppc_ih);
+ ppc_ih->ih_count = &intrcnt[ppc_ih->ih_index];
+ intrcnt_setname(straystr, ppc_ih->ih_index + 1);
+ ppc_ih->ih_straycount = &intrcnt[ppc_ih->ih_index + 1];
}
void
@@ -139,10 +137,9 @@
int i;
u_int32_t msr;
- if (intr_initialized != 0)
+ if (intr_handlers != NULL)
panic("intr_init: interrupts intialized twice\n");
- intr_initialized++;
intr_nirq = nirq;
intr_handlers = malloc(nirq * sizeof(struct ppc_intr_handler), M_INTR,
@@ -150,14 +147,9 @@
if (intr_handlers == NULL)
panic("intr_init: unable to allocate interrupt handler array");
- for (i = 0; i < nirq; i++) {
- intr_handlers[i].ih_func = intr_stray_handler;
- intr_handlers[i].ih_arg = &intr_handlers[i];
- intr_handlers[i].ih_irq = i;
- intr_handlers[i].ih_flags = 0;
- /* mux all initial stray irqs onto same count... */
+ /* mux all initial stray irqs onto same count... */
+ for (i = 0; i < nirq; i++)
intr_handlers[i].ih_straycount = &intrcnt[0];
- }
intrcnt_setname("???", 0);
intrcnt_index = 1;
@@ -175,38 +167,21 @@
mtx_init(&intr_table_lock, "intr table", NULL, MTX_SPIN);
}
-void
-intr_setup(u_int irq, ih_func_t *ihf, void *iha, u_int flags)
-{
- u_int32_t msr;
-
- msr = mfmsr();
- mtmsr(msr & ~PSL_EE);
-
- intr_handlers[irq].ih_func = ihf;
- intr_handlers[irq].ih_arg = iha;
- intr_handlers[irq].ih_irq = irq;
- intr_handlers[irq].ih_flags = flags;
-
- mtmsr(msr);
-}
-
int
inthand_add(const char *name, u_int irq, void (*handler)(void *), void *arg,
int flags, void **cookiep)
{
- struct ppc_intr_handler *ih;
+ struct ppc_intr_handler *ppc_ih;
struct intr_event *event, *orphan;
int error = 0;
- int created_event = 0;
/*
* Work around a race where more than one CPU may be registering
* handlers on the same IRQ at the same time.
*/
- ih = &intr_handlers[irq];
+ ppc_ih = &intr_handlers[irq];
mtx_lock_spin(&intr_table_lock);
- event = ih->ih_event;
+ event = ppc_ih->ih_event;
mtx_unlock_spin(&intr_table_lock);
if (event == NULL) {
error = intr_event_create(&event, (void *)irq, 0,
@@ -216,103 +191,83 @@
mtx_lock_spin(&intr_table_lock);
- if (ih->ih_event == NULL) {
- ih->ih_event = event;
- created_event++;
+ if (ppc_ih->ih_event == NULL) {
+ ppc_ih->ih_event = event;
mtx_unlock_spin(&intr_table_lock);
} else {
orphan = event;
- event = ih->ih_event;
+ event = ppc_ih->ih_event;
mtx_unlock_spin(&intr_table_lock);
intr_event_destroy(orphan);
}
}
- /* XXX: Should probably fix support for multiple FAST. */
- if (flags & INTR_FAST)
- flags |= INTR_EXCL;
error = intr_event_add_handler(event, name, handler, arg,
intr_priority(flags), flags, cookiep);
-
- if ((flags & INTR_FAST) == 0 || error) {
- intr_setup(irq, sched_ithd, ih, flags);
- error = 0;
- }
-
if (error)
return (error);
- if (flags & INTR_FAST)
- intr_setup(irq, handler, arg, flags);
+ intrcnt_register(ppc_ih);
- intrcnt_register(ih);
-
return (0);
}
int
inthand_remove(u_int irq, void *cookie)
{
- struct ppc_intr_handler *ih;
- int error;
+
+ return(intr_event_remove_handler(cookie));
+}
- error = intr_event_remove_handler(cookie);
+void
+intr_handle(u_int irq)
+{
+ struct ppc_intr_handler *ppc_ih = &intr_handlers[irq];
+ struct intr_event *ie = ppc_ih->ih_event;
+ struct intr_handler *ih;
+ int error, thread;
- if (error == 0) {
- ih = &intr_handlers[irq];
+ if (ie == NULL) {
+ intr_stray_handler(ppc_ih);
+ return;
+ }
- mtx_lock_spin(&intr_table_lock);
+ atomic_add_long(ppc_ih->ih_count, 1);
- if (ih->ih_event == NULL) {
- intr_setup(irq, intr_stray_handler, ih, 0);
- } else {
- intr_setup(irq, sched_ithd, ih, 0);
+ critical_enter();
+ /* Execute fast interrupt handlers directly. */
+ thread = 0;
+ TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
+ if (!(ih->ih_flags & IH_FAST)) {
+ thread = 1;
+ continue;
}
-
- mtx_unlock_spin(&intr_table_lock);
+ CTR3(KTR_INTR, "%s: executing handler %p(%p)", __func__,
+ ih->ih_handler, ih->ih_argument);
+ ih->ih_handler(ih->ih_argument);
}
+ critical_exit();
+
+ /* Schedule a heavyweight interrupt process. */
+ if (thread)
+ error = intr_event_schedule_thread(ie);
- return (error);
+ if (error == EINVAL)
+ intr_stray_handler(ppc_ih);
}
-void
-intr_handle(u_int irq)
-{
- atomic_add_long(intr_handlers[irq].ih_count, 1);
- intr_handlers[irq].ih_func(intr_handlers[irq].ih_arg);
-
- /* XXX wrong thing when using pre-emption ? */
- if ((intr_handlers[irq].ih_flags & INTR_FAST) != 0)
- irq_enable(irq);
-}
-
static void
intr_stray_handler(void *cookie)
{
- struct ppc_intr_handler *ih;
+ struct ppc_intr_handler *ppc_ih = cookie;
- ih = (struct ppc_intr_handler *)cookie;
+ if (*intr_handlers[ppc_ih->ih_irq].ih_straycount < MAX_STRAY_LOG) {
+ printf("stray irq %d\n", ppc_ih->ih_irq);
- if (*intr_handlers[ih->ih_irq].ih_straycount < MAX_STRAY_LOG) {
- printf("stray irq %d\n", ih->ih_irq);
-
- atomic_add_long(intr_handlers[ih->ih_irq].ih_straycount, 1);
- if (*intr_handlers[ih->ih_irq].ih_straycount >= MAX_STRAY_LOG)
+ atomic_add_long(intr_handlers[ppc_ih->ih_irq].ih_straycount, 1);
+ if (*intr_handlers[ppc_ih->ih_irq].ih_straycount >= MAX_STRAY_LOG)
printf("got %d stray irq %d's: not logging anymore\n",
- MAX_STRAY_LOG, ih->ih_irq);
+ MAX_STRAY_LOG, ppc_ih->ih_irq);
}
}
-static void
-sched_ithd(void *cookie)
-{
- struct ppc_intr_handler *ih;
- int error;
-
- ih = (struct ppc_intr_handler *)cookie;
-
- error = intr_event_schedule_thread(ih->ih_event);
-
- if (error == EINVAL)
- intr_stray_handler(ih);
-}
More information about the p4-projects
mailing list