summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2006-02-15 18:23:03 +0000
committersam <sam@FreeBSD.org>2006-02-15 18:23:03 +0000
commitd5150c595406f404b66660d920f5bcba653ccf5c (patch)
treea116c85727b95d8465ddfb25f65566578daad257
parentbb3f45c5b86c1f25a92ba535e1b3f8e17904b38d (diff)
downloadFreeBSD-src-d5150c595406f404b66660d920f5bcba653ccf5c.zip
FreeBSD-src-d5150c595406f404b66660d920f5bcba653ccf5c.tar.gz
o handle fatal errors directly instead of via the task queue
o temporarily dump some h/w state for diagnosis; this will be removed once some issues are resolved MFC after: 2 weeks
-rw-r--r--sys/dev/ath/if_ath.c22
-rw-r--r--sys/dev/ath/if_athvar.h4
2 files changed, 16 insertions, 10 deletions
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 28308c60..b8d6105 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -394,7 +394,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
TASK_INIT(&sc->sc_rxtask, 0, ath_rx_proc, sc);
TASK_INIT(&sc->sc_rxorntask, 0, ath_rxorn_proc, sc);
- TASK_INIT(&sc->sc_fataltask, 0, ath_fatal_proc, sc);
TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc);
TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc);
TASK_INIT(&sc->sc_radartask, 0, ath_radar_proc, sc);
@@ -745,15 +744,9 @@ ath_intr(void *arg)
DPRINTF(sc, ATH_DEBUG_INTR, "%s: status 0x%x\n", __func__, status);
status &= sc->sc_imask; /* discard unasked for bits */
if (status & HAL_INT_FATAL) {
- /*
- * Fatal errors are unrecoverable. Typically
- * these are caused by DMA errors. Unfortunately
- * the exact reason is not (presently) returned
- * by the hal.
- */
sc->sc_stats.ast_hardware++;
ath_hal_intrset(ah, 0); /* disable intr's until reset */
- taskqueue_enqueue(sc->sc_tq, &sc->sc_fataltask);
+ ath_fatal_proc(sc, 0);
} else if (status & HAL_INT_RXORN) {
sc->sc_stats.ast_rxorn++;
ath_hal_intrset(ah, 0); /* disable intr's until reset */
@@ -812,8 +805,21 @@ ath_fatal_proc(void *arg, int pending)
{
struct ath_softc *sc = arg;
struct ifnet *ifp = sc->sc_ifp;
+ u_int32_t *state;
+ u_int32_t len;
if_printf(ifp, "hardware error; resetting\n");
+ /*
+ * Fatal errors are unrecoverable. Typically these
+ * are caused by DMA errors. Collect h/w state from
+ * the hal so we can diagnose what's going on.
+ */
+ if (ath_hal_getfatalstate(sc->sc_ah, &state, &len)) {
+ KASSERT(len >= 6*sizeof(u_int32_t), ("len %u bytes", len));
+ if_printf(ifp, "0x%08x 0x%08x 0x%08x, 0x%08x 0x%08x 0x%08x\n",
+ state[0], state[1] , state[2], state[3],
+ state[4], state[5]);
+ }
ath_reset(ifp);
}
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index b131e2a..cb9e95c 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -251,8 +251,6 @@ struct ath_softc {
int sc_rx_th_len;
u_int sc_monpass; /* frames to pass in mon.mode */
- struct task sc_fataltask; /* fatal int processing */
-
struct ath_descdma sc_rxdma; /* RX descriptos */
ath_bufhead sc_rxbuf; /* receive buffer */
u_int32_t *sc_rxlink; /* link ptr in last RX desc */
@@ -419,6 +417,8 @@ void ath_intr(void *);
#define ath_hal_getdiagstate(_ah, _id, _indata, _insize, _outdata, _outsize) \
((*(_ah)->ah_getDiagState)((_ah), (_id), \
(_indata), (_insize), (_outdata), (_outsize)))
+#define ath_hal_getfatalstate(_ah, _outdata, _outsize) \
+ ath_hal_getdiagstate(_ah, 27, NULL, 0, (void **)(_outdata), _outsize)
#define ath_hal_setuptxqueue(_ah, _type, _irq) \
((*(_ah)->ah_setupTxQueue)((_ah), (_type), (_irq)))
#define ath_hal_resettxqueue(_ah, _q) \
OpenPOWER on IntegriCloud