static void altera_sdcard_task_io(struct altera_sdcard_softc *sc) { uint16_t asr; ALTERA_SDCARD_LOCK_ASSERT(sc); KASSERT(sc->as_currentbio != NULL, ("%s: no current I/O", __func__)); #ifdef ALTERA_SDCARD_FAST_SIM recheck: #endif asr = altera_sdcard_read_asr(sc); /* * Check for unexpected card removal during an I/O. */ if (!(asr & ALTERA_SDCARD_ASR_CARDPRESENT)) { altera_sdcard_disk_remove(sc); if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ) sc->as_state = ALTERA_SDCARD_STATE_DETACHED; else sc->as_state = ALTERA_SDCARD_STATE_NOCARD; return; } /* * If the I/O isn't complete, remain in the IO state without further * action, even if DETACHREQ is in flight. */ if (asr & ALTERA_SDCARD_ASR_CMDINPROGRESS) return; /* * Handle various forms of I/O completion, successful and otherwise. * The I/O layer may restart the transaction if an error occurred, in * which case remain in the IO state and reschedule. */ if (!altera_sdcard_io_complete(sc, asr)) return; /* * Now that I/O is complete, process detach requests in preference to * starting new I/O. */ if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ) { sc->as_state = ALTERA_SDCARD_STATE_DETACHED; return; } /* * Finally, either start the next I/O or transition to the IDLE state. */ if (bioq_first(&sc->as_bioq) != NULL) { altera_sdcard_nextio(sc); #ifdef ALTERA_SDCARD_FAST_SIM goto recheck; #endif } else sc->as_state = ALTERA_SDCARD_STATE_IDLE; }
static void altera_sdcard_task_nocard(struct altera_sdcard_softc *sc) { ALTERA_SDCARD_LOCK_ASSERT(sc); /* * Handle device driver detach. */ if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ) { sc->as_state = ALTERA_SDCARD_STATE_DETACHED; return; } /* * If there is no card insertion, remain in NOCARD. */ if (!(altera_sdcard_read_asr(sc) & ALTERA_SDCARD_ASR_CARDPRESENT)) return; /* * Read the CSD -- it may contain values that the driver can't handle, * either because of an unsupported version/feature, or because the * card is misbehaving. This triggers a transition to * ALTERA_SDCARD_STATE_BADCARD. We rely on the CSD read to print a * banner about how the card is problematic, since it has more * information. The bad card state allows us to print that banner * once rather than each time we notice the card is there, and still * bad. */ if (altera_sdcard_read_csd(sc) != 0) { sc->as_state = ALTERA_SDCARD_STATE_BADCARD; return; } /* * Process card insertion and upgrade to the IDLE state. */ altera_sdcard_disk_insert(sc); sc->as_state = ALTERA_SDCARD_STATE_IDLE; }
static void altera_sdcard_task_badcard(struct altera_sdcard_softc *sc) { ALTERA_SDCARD_LOCK_ASSERT(sc); /* * Handle device driver detach. */ if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ) { sc->as_state = ALTERA_SDCARD_STATE_DETACHED; return; } /* * Handle safe card removal -- no teardown is required, just a state * transition. */ if (!(altera_sdcard_read_asr(sc) & ALTERA_SDCARD_ASR_CARDPRESENT)) sc->as_state = ALTERA_SDCARD_STATE_NOCARD; }
static void altera_sdcard_task_idle(struct altera_sdcard_softc *sc) { ALTERA_SDCARD_LOCK_ASSERT(sc); /* * Handle device driver detach. */ if (sc->as_flags & ALTERA_SDCARD_FLAG_DETACHREQ) { sc->as_state = ALTERA_SDCARD_STATE_DETACHED; return; } /* * Handle safe card removal. */ if (!(altera_sdcard_read_asr(sc) & ALTERA_SDCARD_ASR_CARDPRESENT)) { altera_sdcard_disk_remove(sc); sc->as_state = ALTERA_SDCARD_STATE_NOCARD; } }