summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2006-03-27 20:54:16 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2006-03-27 20:54:16 +0000
commit6cffdef835d86daf8477e98e9359981e16ac6a15 (patch)
tree29403d7555ceb11111c2507776da6909f71f5d3c
parent0b3afe78c850fc2a1d45b91dd761e2e6efa1704c (diff)
fixes interrupts processing.
should fix a panic reported by Karel Gardas.
-rw-r--r--sys/dev/ic/rt2560.c10
-rw-r--r--sys/dev/ic/rt2661.c15
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]);