static void ieee80211_swscan_detach(struct ieee80211com *ic) { struct ieee80211_scan_state *ss = ic->ic_scan; if (ss != NULL) { scan_signal(ss, ISCAN_ABORT); ieee80211_draintask(ic, &SCAN_PRIVATE(ss)->ss_scan_start); taskqueue_drain_timeout(ic->ic_tq, &SCAN_PRIVATE(ss)->ss_scan_curchan); KASSERT((ic->ic_flags & IEEE80211_F_SCAN) == 0, ("scan still running")); /* * For now, do the ss_ops detach here rather * than ieee80211_scan_detach(). * * I'll figure out how to cleanly split things up * at a later date. */ if (ss->ss_ops != NULL) { ss->ss_ops->scan_detach(ss); ss->ss_ops = NULL; } ic->ic_scan = NULL; IEEE80211_FREE(SCAN_PRIVATE(ss), M_80211_SCAN); } }
void altera_sdcard_detach(struct altera_sdcard_softc *sc) { KASSERT(sc->as_taskqueue != NULL, ("%s: taskqueue not present", __func__)); /* * Winding down the driver on detach is a bit complex. Update the * flags to indicate that a detach has been requested, and then wait * for in-progress I/O to wind down before continuing. */ ALTERA_SDCARD_LOCK(sc); sc->as_flags |= ALTERA_SDCARD_FLAG_DETACHREQ; while (sc->as_state != ALTERA_SDCARD_STATE_DETACHED) ALTERA_SDCARD_CONDVAR_WAIT(sc); ALTERA_SDCARD_UNLOCK(sc); /* * Now wait for the possibly still executing taskqueue to drain. In * principle no more events will be scheduled as we've transitioned to * a detached state, but there might still be a request in execution. */ while (taskqueue_cancel_timeout(sc->as_taskqueue, &sc->as_task, NULL)) taskqueue_drain_timeout(sc->as_taskqueue, &sc->as_task); /* * Simulate a disk removal if one is present to deal with any pending * or queued I/O. */ if (sc->as_disk != NULL) altera_sdcard_disk_remove(sc); KASSERT(bioq_first(&sc->as_bioq) == NULL, ("%s: non-empty bioq", __func__)); /* * Free any remaining allocated resources. */ taskqueue_free(sc->as_taskqueue); sc->as_taskqueue = NULL; ALTERA_SDCARD_CONDVAR_DESTROY(sc); ALTERA_SDCARD_LOCK_DESTROY(sc); }