FreeBSD/sys/dev/altera/sdcard/altera_sdcard_io.c
/*
 * Handle completed I/O.  ASR is passed in to avoid reading it more than once.
 * Return 1 if the I/O is actually complete (success, or retry limit
 * exceeded), or 0 if not.
 */
Handle completed I/O.  ASR is passed in to avoid reading it more than once.
Return 1 if the I/O is actually complete (success, or retry limit
exceeded), or 0 if not.
Handle completed I / O . ASR is passed in to avoid reading it more than once . Return 1 if the I / O is actually complete ( success or retry limit exceeded ) or 0 if not .
int
altera_sdcard_io_complete(struct altera_sdcard_softc *sc, uint16_t asr)
{
	struct bio *bp;
	uint16_t rr1, mask;
	int error;
	ALTERA_SDCARD_LOCK_ASSERT(sc);
	KASSERT(!(asr & ALTERA_SDCARD_ASR_CMDINPROGRESS),
	    ("%s: still in progress", __func__));
	KASSERT(asr & ALTERA_SDCARD_ASR_CARDPRESENT,
	    ("%s: card removed", __func__));
	bp = sc->as_currentbio;
	error = 0;
	rr1 = altera_sdcard_read_rr1(sc);
	switch (bp->bio_cmd) {
	case BIO_READ:
		mask = ALTERA_SDCARD_RR1_ERRORMASK;
		if (altera_sdcard_ignore_crc_errors)
			mask &= ~ALTERA_SDCARD_RR1_COMMANDCRCFAILED;
		if (asr & ALTERA_SDCARD_ASR_CMDTIMEOUT)
			error = EIO;
		else if ((asr & ALTERA_SDCARD_ASR_CMDDATAERROR) &&
		    (rr1 & mask))
			error = EIO;
		else
			error = 0;
		break;
	case BIO_WRITE:
		if (asr & ALTERA_SDCARD_ASR_CMDTIMEOUT)
			error = EIO;
		else
			error = 0;
		break;
	default:
		break;
	}
	if (error) {
		sc->as_retriesleft--;
		if (sc->as_retriesleft == 0 || bootverbose)
			device_printf(sc->as_dev, "%s: %s operation block %ju "
			    "length %ju failed; asr 0x%08x (rr1: 0x%04x)%s\n",
			    __func__, bp->bio_cmd == BIO_READ ? "BIO_READ" :
			    (bp->bio_cmd == BIO_WRITE ? "BIO_WRITE" :
			    "unknown"),
			    bp->bio_pblkno, bp->bio_bcount, asr, rr1,
			    sc->as_retriesleft != 0 ? " retrying" : "");
		if (sc->as_retriesleft != 0) {
			sc->as_flags |= ALTERA_SDCARD_FLAG_IOERROR;
			altera_sdcard_io_start_internal(sc, bp);
			return (0);
		}
		sc->as_flags &= ~ALTERA_SDCARD_FLAG_IOERROR;
	} else {
		if (sc->as_flags & ALTERA_SDCARD_FLAG_IOERROR) {
			device_printf(sc->as_dev, "%s: %s operation block %ju"
			    " length %ju succeeded after %d retries\n",
			    __func__, bp->bio_cmd == BIO_READ ? "BIO_READ" :
			    (bp->bio_cmd == BIO_WRITE ? "write" : "unknown"),
			    bp->bio_pblkno, bp->bio_bcount,
			    ALTERA_SDCARD_RETRY_LIMIT - sc->as_retriesleft);
			sc->as_flags &= ~ALTERA_SDCARD_FLAG_IOERROR;
		}
		switch (bp->bio_cmd) {
		case BIO_READ:
			altera_sdcard_read_rxtx_buffer(sc, bp->bio_data,
			    bp->bio_bcount);
			break;
		case BIO_WRITE:
			break;
		default:
			panic("%s: unsupported I/O operation %d", __func__,
			    bp->bio_cmd);
		}
		bp->bio_resid = 0;
		error = 0;
	}
	biofinish(bp, NULL, error);
	sc->as_currentbio = NULL;
	return (1);
}
int altera_sdcard_io_complete ( struct altera_sdcard_softc * sc , uint16_t asr ) { struct bio * bp ; uint16_t rr1 , mask ; int error ; ALTERA_SDCARD_LOCK_ASSERT ( sc ) ; KASSERT ( ! ( asr & ALTERA_SDCARD_ASR_CMDINPROGRESS ) , ( " " , __func__ ) ) ; KASSERT ( asr & ALTERA_SDCARD_ASR_CARDPRESENT , ( " " , __func__ ) ) ; bp = sc -> as_currentbio ; error = 0 ; rr1 = altera_sdcard_read_rr1 ( sc ) ; switch ( bp -> bio_cmd ) { case BIO_READ : mask = ALTERA_SDCARD_RR1_ERRORMASK ; if ( altera_sdcard_ignore_crc_errors ) mask &= ~ ALTERA_SDCARD_RR1_COMMANDCRCFAILED ; if ( asr & ALTERA_SDCARD_ASR_CMDTIMEOUT ) error = EIO ; else if ( ( asr & ALTERA_SDCARD_ASR_CMDDATAERROR ) && ( rr1 & mask ) ) error = EIO ; else error = 0 ; break ; case BIO_WRITE : if ( asr & ALTERA_SDCARD_ASR_CMDTIMEOUT ) error = EIO ; else error = 0 ; break ; default : break ; } if ( error ) { sc -> as_retriesleft -- ; if ( sc -> as_retriesleft == 0 || bootverbose ) device_printf ( sc -> as_dev , " " " \n " , __func__ , bp -> bio_cmd == BIO_READ ? " " : ( bp -> bio_cmd == BIO_WRITE ? " " : " " ) , bp -> bio_pblkno , bp -> bio_bcount , asr , rr1 , sc -> as_retriesleft != 0 ? " " : " " ) ; if ( sc -> as_retriesleft != 0 ) { sc -> as_flags |= ALTERA_SDCARD_FLAG_IOERROR ; altera_sdcard_io_start_internal ( sc , bp ) ; return ( 0 ) ; } sc -> as_flags &= ~ ALTERA_SDCARD_FLAG_IOERROR ; } else { if ( sc -> as_flags & ALTERA_SDCARD_FLAG_IOERROR ) { device_printf ( sc -> as_dev , " " " \n " , __func__ , bp -> bio_cmd == BIO_READ ? " " : ( bp -> bio_cmd == BIO_WRITE ? " " : " " ) , bp -> bio_pblkno , bp -> bio_bcount , ALTERA_SDCARD_RETRY_LIMIT - sc -> as_retriesleft ) ; sc -> as_flags &= ~ ALTERA_SDCARD_FLAG_IOERROR ; } switch ( bp -> bio_cmd ) { case BIO_READ : altera_sdcard_read_rxtx_buffer ( sc , bp -> bio_data , bp -> bio_bcount ) ; break ; case BIO_WRITE : break ; default : panic ( " " , __func__ , bp -> bio_cmd ) ; } bp -> bio_resid = 0 ; error = 0 ; } biofinish ( bp , NULL , error ) ; sc -> as_currentbio = NULL ; return ( 1 ) ; }
Handle completed I/O.
Handle completed I / O .
/*-
	 * Handle I/O retries if an error is returned by the device.  Various
	 * quirks handled in the process:
	 *
	 * 1. ALTERA_SDCARD_ASR_CMDDATAERROR is ignored for BIO_WRITE.
	 * 2. ALTERA_SDCARD_RR1_COMMANDCRCFAILED is optionally ignored for
	 *    BIO_READ.
	 */ /*
		 * This attempt experienced an error; possibly retry.
		 */ /*
		 * Successful I/O completion path.
		 */