diff options
author | gallatin <gallatin@FreeBSD.org> | 2003-04-10 20:32:29 +0000 |
---|---|---|
committer | gallatin <gallatin@FreeBSD.org> | 2003-04-10 20:32:29 +0000 |
commit | 798a01c63fd2ef56c68a97300484838da3f8643a (patch) | |
tree | 2aecda8b3513679222195a4642ac38fa0cb5b32a /sys/alpha | |
parent | 526c3912c0d2321a2bcb25de11e0b2e6abb7fd18 (diff) | |
download | FreeBSD-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.c | 30 |
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; } |