summaryrefslogtreecommitdiffstats
path: root/sys/dev/pccbb
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2005-10-29 03:27:43 +0000
committerimp <imp@FreeBSD.org>2005-10-29 03:27:43 +0000
commit5fe80693f50ce3d182d75e002cf1a5a1434c859b (patch)
tree9fee77bb2a8fc072f0d060c669eb6c067a56adf5 /sys/dev/pccbb
parent3882c07f39e7810e935bd93281385109a74c6c45 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys/dev/pccbb')
-rw-r--r--sys/dev/pccbb/pccbb.c20
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);
OpenPOWER on IntegriCloud