FreeBSD/sys/kern/kern_intr.c
/* 
 * 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.
 */
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.
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) {
		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);
		}
	}
	if (thread_only) {
		*ithd = ie->ie_thread;
		return (FILTER_SCHEDULE_THREAD);
	}
	return (FILTER_STRAY);
}
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 ) { arg = ( ( ih -> ih_argument == NULL ) ? frame : ih -> ih_argument ) ; CTR5 ( KTR_INTR , " " , __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 ) , ( " " , __func__ , ret , ih -> ih_name ) ) ; if ( ret & FILTER_STRAY ) continue ; else { * ithd = ih -> ih_thread ; return ( ret ) ; } } if ( thread_only ) { * ithd = ie -> ie_thread ; return ( FILTER_SCHEDULE_THREAD ) ; } return ( FILTER_STRAY ) ; }
Main loop for interrupt filter.
Main loop for interrupt filter .
/*
		 * 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.
		 */ /*
	 * 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.
	 */