diff options
author | piso <piso@FreeBSD.org> | 2007-05-31 19:25:35 +0000 |
---|---|---|
committer | piso <piso@FreeBSD.org> | 2007-05-31 19:25:35 +0000 |
commit | 42dfc7815053cf9eda064a398dd5f2e1efa583ca (patch) | |
tree | 970cc806d49c2592d85b73107b989311f414b03f /sys/amd64 | |
parent | e12a0ce02fe36373a2610fcdbf80521f4613b504 (diff) | |
download | FreeBSD-src-42dfc7815053cf9eda064a398dd5f2e1efa583ca.zip FreeBSD-src-42dfc7815053cf9eda064a398dd5f2e1efa583ca.tar.gz |
In some particular cases (like in pccard and pccbb), the real device
handler is wrapped in a couple of functions - a filter wrapper and an
ithread wrapper. In this case (and just in this case), the filter
wrapper could ask the system to schedule the ithread and mask the
interrupt source if the wrapped handler is composed of just an ithread
handler: modify the "old" interrupt code to make it support
this situation, while the "new" interrupt code is already ok.
Discussed with: jhb
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/intr_machdep.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/amd64/amd64/intr_machdep.c b/sys/amd64/amd64/intr_machdep.c index 2864868..6ed8c80 100644 --- a/sys/amd64/amd64/intr_machdep.c +++ b/sys/amd64/amd64/intr_machdep.c @@ -310,7 +310,7 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame) struct thread *td; struct intr_event *ie; struct intr_handler *ih; - int error, vector, thread; + int error, vector, thread, ret; td = curthread; @@ -356,6 +356,7 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame) * a trapframe as its argument. */ td->td_intr_nesting_level++; + ret = 0; thread = 0; critical_enter(); TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) { @@ -367,9 +368,17 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame) ih->ih_filter, ih->ih_argument == NULL ? frame : ih->ih_argument, ih->ih_name); if (ih->ih_argument == NULL) - ih->ih_filter(frame); + ret = ih->ih_filter(frame); else - ih->ih_filter(ih->ih_argument); + ret = ih->ih_filter(ih->ih_argument); + /* + * Wrapper handler special case: see + * i386/intr_machdep.c::intr_execute_handlers() + */ + if (!thread) { + if (ret == FILTER_SCHEDULE_THREAD) + thread = 1; + } } /* |