FreeBSD/sys/sparc64/sbus/lsi64854.c
/*
 * Pseudo (chained) interrupt to le(4) driver to handle DMA errors
 */
Pseudo (chained) interrupt to le(4) driver to handle DMA errors
Pseudo ( chained ) interrupt to le ( 4 ) driver to handle DMA errors
static int
lsi64854_enet_intr(void *arg)
{
	struct lsi64854_softc *sc = arg;
	uint32_t csr;
	int i, rv;
	csr = L64854_GCSR(sc);
	rv = ((csr & E_INT_PEND) != 0) ? 1 : 0;
	if (csr & (E_ERR_PEND | E_SLAVE_ERR)) {
		device_printf(sc->sc_dev, "error: csr=%b\n", csr,
		    EDMACSR_BITS);
		csr &= ~L64854_EN_DMA;	
		csr |= E_INVALIDATE | E_SLAVE_ERR;
		L64854_SCSR(sc, csr);
		sc->sc_dodrain = 1;
		return (-1);
	}
	if (sc->sc_dodrain) {
		i = 10;
		csr |= E_DRAIN;
		L64854_SCSR(sc, csr);
		while (i-- > 0 && (L64854_GCSR(sc) & E_DRAINING))
			DELAY(1);
		sc->sc_dodrain = 0;
	}
	return (rv);
}
static int lsi64854_enet_intr ( void * arg ) { struct lsi64854_softc * sc = arg ; uint32_t csr ; int i , rv ; csr = L64854_GCSR ( sc ) ; rv = ( ( csr & E_INT_PEND ) != 0 ) ? 1 : 0 ; if ( csr & ( E_ERR_PEND | E_SLAVE_ERR ) ) { device_printf ( sc -> sc_dev , " \n " , csr , EDMACSR_BITS ) ; csr &= ~ L64854_EN_DMA ; csr |= E_INVALIDATE | E_SLAVE_ERR ; L64854_SCSR ( sc , csr ) ; sc -> sc_dodrain = 1 ; return ( -1 ) ; } if ( sc -> sc_dodrain ) { i = 10 ; csr |= E_DRAIN ; L64854_SCSR ( sc , csr ) ; while ( i -- > 0 && ( L64854_GCSR ( sc ) & E_DRAINING ) ) DELAY ( 1 ) ; sc -> sc_dodrain = 0 ; } return ( rv ) ; }
Pseudo (chained) interrupt to le(4) driver to handle DMA errors
Pseudo ( chained ) interrupt to le ( 4 ) driver to handle DMA errors
/* If the DMA logic shows an interrupt, claim it */ /* Stop DMA. */ /* Invalidate the queue; SLAVE_ERR bit is write-to-clear */ /* Will be drained with the LE_C0_IDON interrupt. */ /* XXX - is this necessary with E_DSBL_WR_INVAL on? */