diff options
author | sam <sam@FreeBSD.org> | 2006-02-15 18:23:03 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2006-02-15 18:23:03 +0000 |
commit | d5150c595406f404b66660d920f5bcba653ccf5c (patch) | |
tree | a116c85727b95d8465ddfb25f65566578daad257 | |
parent | bb3f45c5b86c1f25a92ba535e1b3f8e17904b38d (diff) | |
download | FreeBSD-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.c | 22 | ||||
-rw-r--r-- | sys/dev/ath/if_athvar.h | 4 |
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) \ |