summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/kern/kern_intr.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/kern/kern_intr.c')
-rw-r--r--freebsd/sys/kern/kern_intr.c580
1 files changed, 8 insertions, 572 deletions
diff --git a/freebsd/sys/kern/kern_intr.c b/freebsd/sys/kern/kern_intr.c
index aa896467..8f6c2a6d 100644
--- a/freebsd/sys/kern/kern_intr.c
+++ b/freebsd/sys/kern/kern_intr.c
@@ -63,9 +63,6 @@ __FBSDID("$FreeBSD$");
#ifndef __rtems__
#include <machine/md_var.h>
#else /* __rtems__ */
- #ifdef INTR_FILTER
- #error INTR_FILTER is currently not suppported with RTEMS
- #endif
#include <machine/rtems-bsd-thread.h>
#define RTEMSBSD_SWI_WAKEUP_EVENT RTEMS_EVENT_31
#undef ticks
@@ -115,26 +112,13 @@ static struct mtx event_lock;
MTX_SYSINIT(intr_event_list, &event_lock, "intr event list", MTX_DEF);
static void intr_event_update(struct intr_event *ie);
-#ifdef INTR_FILTER
-static int intr_event_schedule_thread(struct intr_event *ie,
- struct intr_thread *ithd);
-static int intr_filter_loop(struct intr_event *ie,
- struct trapframe *frame, struct intr_thread **ithd);
-static struct intr_thread *ithread_create(const char *name,
- struct intr_handler *ih);
-#else
static int intr_event_schedule_thread(struct intr_event *ie);
static struct intr_thread *ithread_create(const char *name);
-#endif
#ifndef __rtems__
static void ithread_destroy(struct intr_thread *ithread);
#endif /* __rtems__ */
static void ithread_execute_handlers(struct proc *p,
struct intr_event *ie);
-#ifdef INTR_FILTER
-static void priv_ithread_execute_handler(struct proc *p,
- struct intr_handler *ih);
-#endif
static void ithread_loop(void *);
static void ithread_update(struct intr_thread *ithd);
#ifndef __rtems__
@@ -534,7 +518,6 @@ intr_event_destroy(struct intr_event *ie)
}
#endif /* __rtems__ */
-#ifndef INTR_FILTER
static struct intr_thread *
ithread_create(const char *name)
{
@@ -565,36 +548,6 @@ ithread_create(const char *name)
CTR2(KTR_INTR, "%s: created %s", __func__, name);
return (ithd);
}
-#else
-#ifndef __rtems__
-static struct intr_thread *
-ithread_create(const char *name, struct intr_handler *ih)
-{
-#ifdef __rtems__
- struct proc *intrproc;
-#endif /* __rtems__ */
- struct intr_thread *ithd;
- struct thread *td;
- int error;
-
- ithd = malloc(sizeof(struct intr_thread), M_ITHREAD, M_WAITOK | M_ZERO);
-
- error = kproc_kthread_add(ithread_loop, ih, &intrproc,
- &td, RFSTOPPED | RFHIGHPID,
- 0, "intr", "%s", name);
- if (error)
- panic("kproc_create() failed with %d", error);
- thread_lock(td);
- sched_class(td, PRI_ITHD);
- TD_SET_IWAIT(td);
- thread_unlock(td);
- td->td_pflags |= TDP_ITHREAD;
- ithd->it_thread = td;
- CTR2(KTR_INTR, "%s: created %s", __func__, name);
- return (ithd);
-}
-#endif /* __rtems__ */
-#endif
#ifndef __rtems__
static void
@@ -614,7 +567,6 @@ ithread_destroy(struct intr_thread *ithread)
}
#endif /* __rtems__ */
-#ifndef INTR_FILTER
int
intr_event_add_handler(struct intr_event *ie, const char *name,
driver_filter_t filter, driver_intr_t handler, void *arg, u_char pri,
@@ -688,92 +640,6 @@ intr_event_add_handler(struct intr_event *ie, const char *name,
*cookiep = ih;
return (0);
}
-#else
-#ifndef __rtems__
-int
-intr_event_add_handler(struct intr_event *ie, const char *name,
- driver_filter_t filter, driver_intr_t handler, void *arg, u_char pri,
- enum intr_type flags, void **cookiep)
-{
- struct intr_handler *ih, *temp_ih;
- struct intr_thread *it;
-
- if (ie == NULL || name == NULL || (handler == NULL && filter == NULL))
- return (EINVAL);
-
- /* Allocate and populate an interrupt handler structure. */
- ih = malloc(sizeof(struct intr_handler), M_ITHREAD, M_WAITOK | M_ZERO);
- ih->ih_filter = filter;
- ih->ih_handler = handler;
- ih->ih_argument = arg;
- strlcpy(ih->ih_name, name, sizeof(ih->ih_name));
- ih->ih_event = ie;
- ih->ih_pri = pri;
- if (flags & INTR_EXCL)
- ih->ih_flags = IH_EXCLUSIVE;
- if (flags & INTR_MPSAFE)
- ih->ih_flags |= IH_MPSAFE;
- if (flags & INTR_ENTROPY)
- ih->ih_flags |= IH_ENTROPY;
-
- /* We can only have one exclusive handler in a event. */
- mtx_lock(&ie->ie_lock);
- if (!TAILQ_EMPTY(&ie->ie_handlers)) {
- if ((flags & INTR_EXCL) ||
- (TAILQ_FIRST(&ie->ie_handlers)->ih_flags & IH_EXCLUSIVE)) {
- mtx_unlock(&ie->ie_lock);
- free(ih, M_ITHREAD);
- return (EINVAL);
- }
- }
-
- /* For filtered handlers, create a private ithread to run on. */
- if (filter != NULL && handler != NULL) {
- mtx_unlock(&ie->ie_lock);
- it = ithread_create("intr: newborn", ih);
- mtx_lock(&ie->ie_lock);
- it->it_event = ie;
- ih->ih_thread = it;
- ithread_update(it); /* XXX - do we really need this?!?!? */
- } else { /* Create the global per-event thread if we need one. */
- while (ie->ie_thread == NULL && handler != NULL) {
- if (ie->ie_flags & IE_ADDING_THREAD)
- msleep(ie, &ie->ie_lock, 0, "ithread", 0);
- else {
- ie->ie_flags |= IE_ADDING_THREAD;
- mtx_unlock(&ie->ie_lock);
- it = ithread_create("intr: newborn", ih);
- mtx_lock(&ie->ie_lock);
- ie->ie_flags &= ~IE_ADDING_THREAD;
- ie->ie_thread = it;
- it->it_event = ie;
- ithread_update(it);
- wakeup(ie);
- }
- }
- }
-
- /* Add the new handler to the event in priority order. */
- TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) {
- if (temp_ih->ih_pri > ih->ih_pri)
- break;
- }
- if (temp_ih == NULL)
- TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next);
- else
- TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
- intr_event_update(ie);
-
- CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name,
- ie->ie_name);
- mtx_unlock(&ie->ie_lock);
-
- if (cookiep != NULL)
- *cookiep = ih;
- return (0);
-}
-#endif /* __rtems__ */
-#endif
#ifndef __rtems__
/*
@@ -892,7 +758,6 @@ _intr_drain(int irq)
#endif /* __rtems__ */
-#ifndef INTR_FILTER
#ifndef __rtems__
int
intr_event_remove_handler(void *cookie)
@@ -997,9 +862,6 @@ intr_event_schedule_thread(struct intr_event *ie)
struct intr_thread *it;
struct thread *td;
struct thread *ctd;
-#ifndef __rtems__
- struct proc *p;
-#endif /* __rtems__ */
/*
* If no ithread or no handlers, then we have a stray interrupt.
@@ -1011,9 +873,6 @@ intr_event_schedule_thread(struct intr_event *ie)
ctd = curthread;
it = ie->ie_thread;
td = it->it_thread;
-#ifndef __rtems__
- p = td->td_proc;
-#endif /* __rtems__ */
/*
* If any of the handlers for this ithread claim to be good
@@ -1026,7 +885,7 @@ intr_event_schedule_thread(struct intr_event *ie)
}
#ifndef __rtems__
- KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name));
+ KASSERT(td->td_proc != NULL, ("ithread %s has no process", ie->ie_name));
#endif /* __rtems__ */
/*
@@ -1042,13 +901,13 @@ intr_event_schedule_thread(struct intr_event *ie)
thread_lock(td);
#ifndef __rtems__
if (TD_AWAITING_INTR(td)) {
- CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
+ CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, td->td_proc->p_pid,
td->td_name);
TD_CLR_IWAIT(td);
sched_add(td, SRQ_INTR);
} else {
CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d",
- __func__, p->p_pid, td->td_name, it->it_need, td->td_state);
+ __func__, td->td_proc->p_pid, td->td_name, it->it_need, td->td_state);
}
#else /* __rtems__ */
/* Send event to wake the thread up.
@@ -1061,174 +920,6 @@ intr_event_schedule_thread(struct intr_event *ie)
return (0);
}
-#else
-#ifndef __rtems__
-int
-intr_event_remove_handler(void *cookie)
-{
- struct intr_handler *handler = (struct intr_handler *)cookie;
- struct intr_event *ie;
- struct intr_thread *it;
-#ifdef INVARIANTS
- struct intr_handler *ih;
-#endif
-#ifdef notyet
- int dead;
-#endif
-
- if (handler == NULL)
- return (EINVAL);
- ie = handler->ih_event;
- KASSERT(ie != NULL,
- ("interrupt handler \"%s\" has a NULL interrupt event",
- handler->ih_name));
- mtx_lock(&ie->ie_lock);
- CTR3(KTR_INTR, "%s: removing %s from %s", __func__, handler->ih_name,
- ie->ie_name);
-#ifdef INVARIANTS
- TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next)
- if (ih == handler)
- goto ok;
- mtx_unlock(&ie->ie_lock);
- panic("interrupt handler \"%s\" not found in interrupt event \"%s\"",
- ih->ih_name, ie->ie_name);
-ok:
-#endif
- /*
- * If there are no ithreads (per event and per handler), then
- * just remove the handler and return.
- * XXX: Note that an INTR_FAST handler might be running on another CPU!
- */
- if (ie->ie_thread == NULL && handler->ih_thread == NULL) {
- TAILQ_REMOVE(&ie->ie_handlers, handler, ih_next);
- mtx_unlock(&ie->ie_lock);
- free(handler, M_ITHREAD);
- return (0);
- }
-
- /* Private or global ithread? */
- it = (handler->ih_thread) ? handler->ih_thread : ie->ie_thread;
- /*
- * If the interrupt thread is already running, then just mark this
- * handler as being dead and let the ithread do the actual removal.
- *
- * During a cold boot while cold is set, msleep() does not sleep,
- * so we have to remove the handler here rather than letting the
- * thread do it.
- */
- thread_lock(it->it_thread);
- if (!TD_AWAITING_INTR(it->it_thread) && !cold) {
- handler->ih_flags |= IH_DEAD;
-
- /*
- * Ensure that the thread will process the handler list
- * again and remove this handler if it has already passed
- * it on the list.
- *
- * The release part of the following store ensures
- * that the update of ih_flags is ordered before the
- * it_need setting. See the comment before
- * atomic_cmpset_acq(&ithd->it_need, ...) operation in
- * the ithread_execute_handlers().
- */
- atomic_store_rel_int(&it->it_need, 1);
- } else
- TAILQ_REMOVE(&ie->ie_handlers, handler, ih_next);
- thread_unlock(it->it_thread);
- while (handler->ih_flags & IH_DEAD)
- msleep(handler, &ie->ie_lock, 0, "iev_rmh", 0);
- /*
- * At this point, the handler has been disconnected from the event,
- * so we can kill the private ithread if any.
- */
- if (handler->ih_thread) {
- ithread_destroy(handler->ih_thread);
- handler->ih_thread = NULL;
- }
- intr_event_update(ie);
-#ifdef notyet
- /*
- * XXX: This could be bad in the case of ppbus(8). Also, I think
- * this could lead to races of stale data when servicing an
- * interrupt.
- */
- dead = 1;
- TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
- if (handler != NULL) {
- dead = 0;
- break;
- }
- }
- if (dead) {
- ithread_destroy(ie->ie_thread);
- ie->ie_thread = NULL;
- }
-#endif
- mtx_unlock(&ie->ie_lock);
- free(handler, M_ITHREAD);
- return (0);
-}
-
-static int
-intr_event_schedule_thread(struct intr_event *ie, struct intr_thread *it)
-{
- struct intr_entropy entropy;
- struct thread *td;
- struct thread *ctd;
-#ifndef __rtems__
- struct proc *p;
-#endif /* __rtems__ */
-
- /*
- * If no ithread or no handlers, then we have a stray interrupt.
- */
- if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers) || it == NULL)
- return (EINVAL);
-
- ctd = curthread;
- td = it->it_thread;
-#ifndef __rtems__
- p = td->td_proc;
-#endif /* __rtems__ */
-
- /*
- * If any of the handlers for this ithread claim to be good
- * sources of entropy, then gather some.
- */
- if (ie->ie_flags & IE_ENTROPY) {
- entropy.event = (uintptr_t)ie;
- entropy.td = ctd;
- random_harvest_queue(&entropy, sizeof(entropy), 2, RANDOM_INTERRUPT);
- }
-
- KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name));
-
- /*
- * Set it_need to tell the thread to keep running if it is already
- * running. Then, lock the thread and see if we actually need to
- * put it on the runqueue.
- *
- * Use store_rel to arrange that the store to ih_need in
- * swi_sched() is before the store to it_need and prepare for
- * transfer of this order to loads in the ithread.
- */
- atomic_store_rel_int(&it->it_need, 1);
- thread_lock(td);
- if (TD_AWAITING_INTR(td)) {
- CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid,
- td->td_name);
- TD_CLR_IWAIT(td);
- sched_add(td, SRQ_INTR);
- } else {
- CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d",
- __func__, p->p_pid, td->td_name, it->it_need, td->td_state);
- }
- thread_unlock(td);
-
- return (0);
-}
-#endif /* __rtems__ */
-#endif
/*
* Allow interrupt event binding for software interrupt handlers -- a no-op,
@@ -1283,7 +974,7 @@ swi_sched(void *cookie, int flags)
struct intr_handler *ih = (struct intr_handler *)cookie;
struct intr_event *ie = ih->ih_event;
struct intr_entropy entropy;
- int error;
+ int error __unused;
CTR3(KTR_INTR, "swi_sched: %s %s need=%d", ie->ie_name, ih->ih_name,
ih->ih_need);
@@ -1303,11 +994,7 @@ swi_sched(void *cookie, int flags)
#ifndef __rtems__
VM_CNT_INC(v_soft);
#endif /* __rtems__ */
-#ifdef INTR_FILTER
- error = intr_event_schedule_thread(ie, ie->ie_thread);
-#else
error = intr_event_schedule_thread(ie);
-#endif
KASSERT(error == 0, ("stray software interrupt"));
}
}
@@ -1326,38 +1013,6 @@ swi_remove(void *cookie)
return (intr_event_remove_handler(cookie));
}
-#ifdef INTR_FILTER
-static void
-priv_ithread_execute_handler(struct proc *p, struct intr_handler *ih)
-{
- struct intr_event *ie;
-
- ie = ih->ih_event;
- /*
- * If this handler is marked for death, remove it from
- * the list of handlers and wake up the sleeper.
- */
- if (ih->ih_flags & IH_DEAD) {
- mtx_lock(&ie->ie_lock);
- TAILQ_REMOVE(&ie->ie_handlers, ih, ih_next);
- ih->ih_flags &= ~IH_DEAD;
- wakeup(ih);
- mtx_unlock(&ie->ie_lock);
- return;
- }
-
- /* Execute this handler. */
- CTR6(KTR_INTR, "%s: pid %d exec %p(%p) for %s flg=%x",
- __func__, p->p_pid, (void *)ih->ih_handler, ih->ih_argument,
- ih->ih_name, ih->ih_flags);
-
- if (!(ih->ih_flags & IH_MPSAFE))
- mtx_lock(&Giant);
- ih->ih_handler(ih->ih_argument);
- if (!(ih->ih_flags & IH_MPSAFE))
- mtx_unlock(&Giant);
-}
-#endif
#endif /* __rtems__ */
/*
@@ -1461,7 +1116,6 @@ ithread_execute_handlers(struct proc *p, struct intr_event *ie)
ie->ie_post_ithread(ie->ie_source);
}
-#ifndef INTR_FILTER
/*
* This is the main code for interrupt threads.
*/
@@ -1571,7 +1225,7 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame)
struct intr_handler *ih;
struct trapframe *oldframe;
struct thread *td;
- int error, ret, thread;
+ int ret, thread;
td = curthread;
@@ -1644,233 +1298,15 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame)
/* Schedule the ithread if needed. */
if (thread) {
- error = intr_event_schedule_thread(ie);
- KASSERT(error == 0, ("bad stray interrupt"));
- }
- critical_exit();
- td->td_intr_nesting_level--;
- return (0);
-}
-#endif /* __rtems__ */
-#else
-#ifndef __rtems__
-/*
- * This is the main code for interrupt threads.
- */
-static void
-ithread_loop(void *arg)
-{
- struct intr_thread *ithd;
- struct intr_handler *ih;
- struct intr_event *ie;
- struct thread *td;
- struct proc *p;
- int priv;
- int wake;
-
- td = curthread;
- p = td->td_proc;
- ih = (struct intr_handler *)arg;
- priv = (ih->ih_thread != NULL) ? 1 : 0;
- ithd = (priv) ? ih->ih_thread : ih->ih_event->ie_thread;
- KASSERT(ithd->it_thread == td,
- ("%s: ithread and proc linkage out of sync", __func__));
- ie = ithd->it_event;
- ie->ie_count = 0;
- wake = 0;
-
- /*
- * As long as we have interrupts outstanding, go through the
- * list of handlers, giving each one a go at it.
- */
- for (;;) {
- /*
- * If we are an orphaned thread, then just die.
- */
- if (ithd->it_flags & IT_DEAD) {
- CTR3(KTR_INTR, "%s: pid %d (%s) exiting", __func__,
- p->p_pid, td->td_name);
- free(ithd, M_ITHREAD);
- kthread_exit();
- }
+ int error __unused;
- /*
- * Service interrupts. If another interrupt arrives while
- * we are running, it will set it_need to note that we
- * should make another pass.
- *
- * The load_acq part of the following cmpset ensures
- * that the load of ih_need in ithread_execute_handlers()
- * is ordered after the load of it_need here.
- */
- while (atomic_cmpset_acq_int(&ithd->it_need, 1, 0) != 0) {
- if (priv)
- priv_ithread_execute_handler(p, ih);
- else
- ithread_execute_handlers(p, ie);
- }
- WITNESS_WARN(WARN_PANIC, NULL, "suspending ithread");
- mtx_assert(&Giant, MA_NOTOWNED);
-
- /*
- * Processed all our interrupts. Now get the sched
- * lock. This may take a while and it_need may get
- * set again, so we have to check it again.
- */
- thread_lock(td);
- if (atomic_load_acq_int(&ithd->it_need) == 0 &&
- (ithd->it_flags & (IT_DEAD | IT_WAIT)) == 0) {
- TD_SET_IWAIT(td);
- ie->ie_count = 0;
- mi_switch(SW_VOL | SWT_IWAIT, NULL);
- }
- if (ithd->it_flags & IT_WAIT) {
- wake = 1;
- ithd->it_flags &= ~IT_WAIT;
- }
- thread_unlock(td);
- if (wake) {
- wakeup(ithd);
- wake = 0;
- }
- }
-}
-
-/*
- * Main loop for interrupt filter.
- *
- * Some architectures (i386, amd64 and arm) require the optional frame
- * parameter, and use it as the main argument for fast handler execution
- * when ih_argument == NULL.
- *
- * Return value:
- * o FILTER_STRAY: No filter recognized the event, and no
- * filter-less handler is registered on this
- * line.
- * o FILTER_HANDLED: A filter claimed the event and served it.
- * o FILTER_SCHEDULE_THREAD: No filter claimed the event, but there's at
- * least one filter-less handler on this line.
- * o FILTER_HANDLED |
- * FILTER_SCHEDULE_THREAD: A filter claimed the event, and asked for
- * scheduling the per-handler ithread.
- *
- * In case an ithread has to be scheduled, in *ithd there will be a
- * pointer to a struct intr_thread containing the thread to be
- * scheduled.
- */
-
-static int
-intr_filter_loop(struct intr_event *ie, struct trapframe *frame,
- struct intr_thread **ithd)
-{
- struct intr_handler *ih;
- void *arg;
- int ret, thread_only;
-
- ret = 0;
- thread_only = 0;
- TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
- /*
- * Execute fast interrupt handlers directly.
- * To support clock handlers, if a handler registers
- * with a NULL argument, then we pass it a pointer to
- * a trapframe as its argument.
- */
- arg = ((ih->ih_argument == NULL) ? frame : ih->ih_argument);
-
- CTR5(KTR_INTR, "%s: exec %p/%p(%p) for %s", __func__,
- ih->ih_filter, ih->ih_handler, arg, ih->ih_name);
-
- if (ih->ih_filter != NULL)
- ret = ih->ih_filter(arg);
- else {
- thread_only = 1;
- continue;
- }
- KASSERT(ret == FILTER_STRAY ||
- ((ret & (FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) != 0 &&
- (ret & ~(FILTER_SCHEDULE_THREAD | FILTER_HANDLED)) == 0),
- ("%s: incorrect return value %#x from %s", __func__, ret,
- ih->ih_name));
- if (ret & FILTER_STRAY)
- continue;
- else {
- *ithd = ih->ih_thread;
- return (ret);
- }
- }
-
- /*
- * No filters handled the interrupt and we have at least
- * one handler without a filter. In this case, we schedule
- * all of the filter-less handlers to run in the ithread.
- */
- if (thread_only) {
- *ithd = ie->ie_thread;
- return (FILTER_SCHEDULE_THREAD);
- }
- return (FILTER_STRAY);
-}
-
-/*
- * Main interrupt handling body.
- *
- * Input:
- * o ie: the event connected to this interrupt.
- * o frame: some archs (i.e. i386) pass a frame to some.
- * handlers as their main argument.
- * Return value:
- * o 0: everything ok.
- * o EINVAL: stray interrupt.
- */
-int
-intr_event_handle(struct intr_event *ie, struct trapframe *frame)
-{
- struct intr_thread *ithd;
- struct trapframe *oldframe;
- struct thread *td;
- int thread;
-
- ithd = NULL;
- td = curthread;
-
- if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers))
- return (EINVAL);
-
- td->td_intr_nesting_level++;
- thread = 0;
- critical_enter();
- oldframe = td->td_intr_frame;
- td->td_intr_frame = frame;
- thread = intr_filter_loop(ie, frame, &ithd);
- if (thread & FILTER_HANDLED) {
- if (ie->ie_post_filter != NULL)
- ie->ie_post_filter(ie->ie_source);
- } else {
- if (ie->ie_pre_ithread != NULL)
- ie->ie_pre_ithread(ie->ie_source);
+ error = intr_event_schedule_thread(ie);
+ KASSERT(error == 0, ("bad stray interrupt"));
}
- td->td_intr_frame = oldframe;
critical_exit();
-
- /* Interrupt storm logic */
- if (thread & FILTER_STRAY) {
- ie->ie_count++;
- if (ie->ie_count < intr_storm_threshold)
- printf("Interrupt stray detection not present\n");
- }
-
- /* Schedule an ithread if needed. */
- if (thread & FILTER_SCHEDULE_THREAD) {
- if (intr_event_schedule_thread(ie, ithd) != 0)
- panic("%s: impossible stray interrupt", __func__);
- }
td->td_intr_nesting_level--;
return (0);
}
-#endif /* __rtems__ */
-#endif
-#ifndef __rtems__
#ifdef DDB
/*