diff options
author | imp <imp@FreeBSD.org> | 2002-10-08 03:53:52 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2002-10-08 03:53:52 +0000 |
commit | 2af88da4a811029879c8a1c6e91242798f884bd2 (patch) | |
tree | 21c09f86317dea542887a668ebca7dfb6eaeea58 /sys/dev/pccbb | |
parent | cb71b7bb0741a154adbd7c00af22d7b19d38f7b3 (diff) | |
download | FreeBSD-src-2af88da4a811029879c8a1c6e91242798f884bd2.zip FreeBSD-src-2af88da4a811029879c8a1c6e91242798f884bd2.tar.gz |
Make kldunload cbb work:
o Implement the thread killing interlock as described by jhb in arch@
while talking to markm.
o Hold Giant around cbb_insert()/cbb_remove(). Deep in the belly of
the vm code we panic if we don't hold this when we activate the memory
for reading the CIS.
o If we had to do the kludge alloc, then do a kludge free.
Diffstat (limited to 'sys/dev/pccbb')
-rw-r--r-- | sys/dev/pccbb/pccbb.c | 39 |
1 files changed, 17 insertions, 22 deletions
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index d0e7282..d0b4067 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -732,20 +732,18 @@ cbb_detach(device_t brdev) sc->flags |= CBB_KTHREAD_DONE; if (sc->flags & CBB_KTHREAD_RUNNING) { cv_broadcast(&sc->cv); - mtx_unlock(&sc->mtx); - DEVPRINTF((brdev, "waiting for kthread exit...")); - error = tsleep(sc, PWAIT, "cbb-detach-wait", 60 * hz); - if (error) - DPRINTF(("timeout\n")); - else - DPRINTF(("done\n")); - } else { - mtx_unlock(&sc->mtx); + msleep(sc->event_thread, &sc->mtx, PWAIT, "cbbun", 0); } + mtx_unlock(&sc->mtx); bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res); - bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, - sc->base_res); + if (sc->flags & CBB_KLUDGE_ALLOC) + bus_generic_release_resource(device_get_parent(brdev), + brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, + sc->base_res); + else + bus_release_resource(brdev, SYS_RES_MEMORY, + CBBR_SOCKBASE, sc->base_res); mtx_destroy(&sc->mtx); cv_destroy(&sc->cv); return (0); @@ -898,10 +896,11 @@ cbb_event_thread(void *arg) int err; /* - * We take out Giant here because we drop it in tsleep - * and need it for kthread_exit, which drops it. + * We take out Giant here because we need it deep, down in + * the bowels of the vm system for mapping the memory we need + * to read the CIS. We also need it for kthread_exit, which + * drops it. */ - mtx_lock(&Giant); sc->flags |= CBB_KTHREAD_RUNNING; while (1) { /* @@ -913,10 +912,13 @@ cbb_event_thread(void *arg) break; status = cbb_get(sc, CBB_SOCKET_STATE); + mtx_lock(&Giant); if ((status & CBB_SOCKET_STAT_CD) == 0) cbb_insert(sc); else cbb_removal(sc); + mtx_unlock(&Giant); + /* * Wait until it has been 1s since the last time we * get an interrupt. We handle the rest of the interrupt @@ -931,14 +933,7 @@ cbb_event_thread(void *arg) mtx_unlock(&sc->mtx); } sc->flags &= ~CBB_KTHREAD_RUNNING; - /* - * XXX I think there's a race here. If we wakeup in the other - * thread before kthread_exit is called and this routine returns, - * and that thread causes us to be unmapped, then we are setting - * ourselves up for a panic. Make sure that I check out - * jhb's crash.c for a fix. - */ - wakeup(sc); + mtx_lock(&Giant); kthread_exit(0); } |