void altera_sdcard_start(struct altera_sdcard_softc *sc) { ALTERA_SDCARD_LOCK_ASSERT(sc); KASSERT(sc->as_state == ALTERA_SDCARD_STATE_IDLE, ("%s: starting when not IDLE", __func__)); taskqueue_cancel_timeout(sc->as_taskqueue, &sc->as_task, NULL); altera_sdcard_nextio(sc); #ifdef ALTERA_SDCARD_FAST_SIM altera_sdcard_task_io(sc); #endif altera_sdcard_task_rechedule(sc); }
/* * Because the Altera SD Card IP Core doesn't support interrupts, we do all * asynchronous work from a timeout. Poll at two different rates -- an * infrequent check for card insertion status changes, and a frequent one for * I/O completion. The task should never start in DETACHED, as that would * imply that a previous instance failed to cancel rather than reschedule. */ void altera_sdcard_task(void *arg, int pending) { struct altera_sdcard_softc *sc; sc = arg; KASSERT(sc->as_state != ALTERA_SDCARD_STATE_DETACHED, ("%s: already in detached", __func__)); ALTERA_SDCARD_LOCK(sc); switch (sc->as_state) { case ALTERA_SDCARD_STATE_NOCARD: altera_sdcard_task_nocard(sc); break; case ALTERA_SDCARD_STATE_BADCARD: altera_sdcard_task_badcard(sc); break; case ALTERA_SDCARD_STATE_IDLE: altera_sdcard_task_idle(sc); break; case ALTERA_SDCARD_STATE_IO: altera_sdcard_task_io(sc); break; default: panic("%s: invalid enter state %d", __func__, sc->as_state); } /* * If we have transitioned to DETACHED, signal the detach thread and * cancel the timeout-driven task. Otherwise reschedule on an * appropriate timeout. */ if (sc->as_state == ALTERA_SDCARD_STATE_DETACHED) ALTERA_SDCARD_CONDVAR_SIGNAL(sc); else altera_sdcard_task_rechedule(sc); ALTERA_SDCARD_UNLOCK(sc); }