summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authorgallatin <gallatin@FreeBSD.org>2003-04-10 20:32:29 +0000
committergallatin <gallatin@FreeBSD.org>2003-04-10 20:32:29 +0000
commit798a01c63fd2ef56c68a97300484838da3f8643a (patch)
tree2aecda8b3513679222195a4642ac38fa0cb5b32a /sys/alpha
parent526c3912c0d2321a2bcb25de11e0b2e6abb7fd18 (diff)
downloadFreeBSD-src-798a01c63fd2ef56c68a97300484838da3f8643a.zip
FreeBSD-src-798a01c63fd2ef56c68a97300484838da3f8643a.tar.gz
Enable loadable modules to be unloaded on alphas with shared isa
interrupts by only disabling the interrupt in hardware if the handler being removed is the only handler.
Diffstat (limited to 'sys/alpha')
-rw-r--r--sys/alpha/isa/isa.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/sys/alpha/isa/isa.c b/sys/alpha/isa/isa.c
index d6ddebc..ec1de88 100644
--- a/sys/alpha/isa/isa.c
+++ b/sys/alpha/isa/isa.c
@@ -389,17 +389,29 @@ isa_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie)
{
struct isa_intr *ii = cookie;
+ struct intrhand *ih, *handler = (struct intrhand *)ii->ih;
+ struct ithd *ithread = handler->ih_ithread;
+ int num_handlers = 0;
+
+ mtx_lock(&ithread->it_lock);
+ TAILQ_FOREACH(ih, &ithread->it_handlers, ih_next)
+ num_handlers++;
+ mtx_unlock(&ithread->it_lock);
+
+ /* only disable the interrupt in hardware if there are no
+ other handlers sharing it */
+
+ if (num_handlers == 1) {
+ mtx_lock_spin(&icu_lock);
+ isa_intr_disable(irq->r_start);
+ mtx_unlock_spin(&icu_lock);
+ if (platform.isa_teardown_intr) {
+ platform.isa_teardown_intr(dev, child, irq,
+ cookie);
+ return 0;
+ }
- mtx_lock_spin(&icu_lock);
- isa_intr_disable(irq->r_start);
- mtx_unlock_spin(&icu_lock);
-
- if (platform.isa_teardown_intr) {
- platform.isa_teardown_intr(dev, child, irq, cookie);
- return 0;
}
-
alpha_teardown_intr(ii->ih);
-
return 0;
}
OpenPOWER on IntegriCloud