diff options
author | jhb <jhb@FreeBSD.org> | 2003-11-03 22:42:58 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2003-11-03 22:42:58 +0000 |
commit | da7c66355beba4150683e5aecb471f329fc5fef2 (patch) | |
tree | 840bd73e1af90ae3e0f5f4fcef6a2a1b8f507923 /sys/kern | |
parent | 1d8b4454d78121464a62813d12aa200d0111f99d (diff) | |
download | FreeBSD-src-da7c66355beba4150683e5aecb471f329fc5fef2.zip FreeBSD-src-da7c66355beba4150683e5aecb471f329fc5fef2.tar.gz |
Don't require INTR_FAST handlers to be exclusive in the MI layer. Instead,
let the MD code choose whether or not to implement such a policy. The new
i386 interrupt code allows multiple FAST handlers for a given source for
example. However, the code does not allow FAST and non-FAST handlers to be
mixed.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_intr.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index a0c2bdc..0e05df8 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -250,8 +250,6 @@ ithread_add_handler(struct ithd* ithread, const char *name, if (ithread == NULL || name == NULL || handler == NULL) return (EINVAL); - if ((flags & INTR_FAST) !=0) - flags |= INTR_EXCL; ih = malloc(sizeof(struct intrhand), M_ITHREAD, M_WAITOK | M_ZERO); ih->ih_handler = handler; @@ -260,7 +258,7 @@ ithread_add_handler(struct ithd* ithread, const char *name, ih->ih_ithread = ithread; ih->ih_pri = pri; if (flags & INTR_FAST) - ih->ih_flags = IH_FAST | IH_EXCLUSIVE; + ih->ih_flags = IH_FAST; else if (flags & INTR_EXCL) ih->ih_flags = IH_EXCLUSIVE; if (flags & INTR_MPSAFE) @@ -269,11 +267,17 @@ ithread_add_handler(struct ithd* ithread, const char *name, ih->ih_flags |= IH_ENTROPY; mtx_lock(&ithread->it_lock); - if ((flags & INTR_EXCL) !=0 && !TAILQ_EMPTY(&ithread->it_handlers)) - goto fail; - if (!TAILQ_EMPTY(&ithread->it_handlers) && - (TAILQ_FIRST(&ithread->it_handlers)->ih_flags & IH_EXCLUSIVE) != 0) + if ((flags & INTR_EXCL) != 0 && !TAILQ_EMPTY(&ithread->it_handlers)) goto fail; + if (!TAILQ_EMPTY(&ithread->it_handlers)) { + temp_ih = TAILQ_FIRST(&ithread->it_handlers); + if (temp_ih->ih_flags & IH_EXCLUSIVE) + goto fail; + if ((ih->ih_flags & IH_FAST) && !(temp_ih->ih_flags & IH_FAST)) + goto fail; + if (!(ih->ih_flags & IH_FAST) && (temp_ih->ih_flags & IH_FAST)) + goto fail; + } TAILQ_FOREACH(temp_ih, &ithread->it_handlers, ih_next) if (temp_ih->ih_pri > ih->ih_pri) |