diff options
author | imp <imp@FreeBSD.org> | 2005-10-29 03:27:43 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2005-10-29 03:27:43 +0000 |
commit | 5fe80693f50ce3d182d75e002cf1a5a1434c859b (patch) | |
tree | 9fee77bb2a8fc072f0d060c669eb6c067a56adf5 | |
parent | 3882c07f39e7810e935bd93281385109a74c6c45 (diff) | |
download | FreeBSD-src-5fe80693f50ce3d182d75e002cf1a5a1434c859b.zip FreeBSD-src-5fe80693f50ce3d182d75e002cf1a5a1434c859b.tar.gz |
Shut down the card bus bridge hardware on detach. Before we'd just
free the resoruces w/o actually turning off the interrupts. This lead
to interrupt storms if you were to insert a card after kldunloading
the driver.
-rw-r--r-- | sys/dev/pccbb/pccbb.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index 9363238..7fa803a 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -300,12 +300,18 @@ cbb_detach(device_t brdev) if (error > 0) return (ENXIO); - mtx_lock(&sc->mtx); - /* - * XXX do we teardown all the ones still registered to guard against - * XXX buggy client drivers? - */ - bus_teardown_intr(brdev, sc->irq_res, sc->intrhand); + /* Turn off the interrupts */ + cbb_set(sc, CBB_SOCKET_MASK, 0); + + /* reset 16-bit pcmcia bus */ + exca_clrb(&sc->exca[0], EXCA_INTR, EXCA_INTR_RESET); + + /* turn off power */ + cbb_power(brdev, CARD_OFF); + + /* Ack the interrupt */ + cbb_set(sc, CBB_SOCKET_EVENT, 0xffffffff); + /* * Wait for the thread to die. kthread_exit will do a wakeup * on the event thread's struct thread * so that we know it is @@ -314,6 +320,8 @@ cbb_detach(device_t brdev) * the event thread happens only in kthread_exit, we don't * need to loop here. */ + mtx_lock(&sc->mtx); + bus_teardown_intr(brdev, sc->irq_res, sc->intrhand); sc->flags |= CBB_KTHREAD_DONE; if (sc->flags & CBB_KTHREAD_RUNNING) { cv_broadcast(&sc->cv); |