diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2006-03-27 20:54:16 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2006-03-27 20:54:16 +0000 |
commit | 6cffdef835d86daf8477e98e9359981e16ac6a15 (patch) | |
tree | 29403d7555ceb11111c2507776da6909f71f5d3c | |
parent | 0b3afe78c850fc2a1d45b91dd761e2e6efa1704c (diff) |
fixes interrupts processing.
should fix a panic reported by Karel Gardas.
-rw-r--r-- | sys/dev/ic/rt2560.c | 10 | ||||
-rw-r--r-- | sys/dev/ic/rt2661.c | 15 |
2 files changed, 23 insertions, 2 deletions
diff --git a/sys/dev/ic/rt2560.c b/sys/dev/ic/rt2560.c index 29619229467..1701faa529c 100644 --- a/sys/dev/ic/rt2560.c +++ b/sys/dev/ic/rt2560.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2560.c,v 1.13 2006/03/25 22:41:43 djm Exp $ */ +/* $OpenBSD: rt2560.c,v 1.14 2006/03/27 20:54:15 damien Exp $ */ /*- * Copyright (c) 2005, 2006 @@ -1480,11 +1480,16 @@ int rt2560_intr(void *arg) { struct rt2560_softc *sc = arg; + struct ifnet *ifp = &sc->sc_ic.ic_if; uint32_t r; /* disable interrupts */ RAL_WRITE(sc, RT2560_CSR8, 0xffffffff); + /* don't re-enable interrupts if we're shutting down */ + if (!(ifp->if_flags & IFF_RUNNING)) + return 0; + r = RAL_READ(sc, RT2560_CSR7); RAL_WRITE(sc, RT2560_CSR7, r); @@ -2851,6 +2856,9 @@ rt2560_stop(struct ifnet *ifp, int disable) /* disable interrupts */ RAL_WRITE(sc, RT2560_CSR8, 0xffffffff); + /* clear any pending interrupt */ + RAL_WRITE(sc, RT2560_CSR7, 0xffffffff); + /* reset Tx and Rx rings */ rt2560_reset_tx_ring(sc, &sc->txq); rt2560_reset_tx_ring(sc, &sc->atimq); diff --git a/sys/dev/ic/rt2661.c b/sys/dev/ic/rt2661.c index 34a8b21db1b..0fd7fa8a48c 100644 --- a/sys/dev/ic/rt2661.c +++ b/sys/dev/ic/rt2661.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2661.c,v 1.14 2006/03/25 22:41:43 djm Exp $ */ +/* $OpenBSD: rt2661.c,v 1.15 2006/03/27 20:54:15 damien Exp $ */ /*- * Copyright (c) 2006 @@ -1047,6 +1047,10 @@ rt2661_tx_intr(struct rt2661_softc *sc) data = &txq->data[txq->stat]; rn = (struct rt2661_node *)data->ni; + /* if no frame has been sent, ignore */ + if (rn == NULL) + continue; + switch (RT2661_TX_RESULT(val)) { case RT2661_TX_SUCCESS: retrycnt = RT2661_TX_RETRYCNT(val); @@ -1319,12 +1323,17 @@ int rt2661_intr(void *arg) { struct rt2661_softc *sc = arg; + struct ifnet *ifp = &sc->sc_ic.ic_if; uint32_t r1, r2; /* disable MAC and MCU interrupts */ RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f); RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff); + /* don't re-enable interrupts if we're shutting down */ + if (!(ifp->if_flags & IFF_RUNNING)) + return 0; + r1 = RAL_READ(sc, RT2661_INT_SOURCE_CSR); RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, r1); @@ -2728,6 +2737,10 @@ rt2661_stop(struct ifnet *ifp, int disable) RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f); RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff); + /* clear any pending interrupt */ + RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff); + RAL_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, 0xffffffff); + /* reset Tx and Rx rings */ rt2661_reset_tx_ring(sc, &sc->txq[0]); rt2661_reset_tx_ring(sc, &sc->txq[1]); |