예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
	}
}