The following reply was made to PR kernel/6465; it has been noted by GNATS.
From: Miod Vallat <m...@online.fr> To: James Boyle <james.bo...@canonic.net> Cc: gn...@openbsd.org Subject: Re: kernel/6465: panic: ifconfig tsec1 down during a special? case Date: Tue, 14 Sep 2010 22:40:23 +0000 Does the following diff help? Index: if_tsec.c =================================================================== RCS file: /cvs/src/sys/arch/socppc/dev/if_tsec.c,v retrieving revision 1.28 diff -u -p -r1.28 if_tsec.c --- if_tsec.c 21 Dec 2009 19:58:57 -0000 1.28 +++ if_tsec.c 14 Sep 2010 22:39:52 -0000 @@ -271,6 +271,8 @@ struct tsec_softc { int sc_rx_cons; struct timeout sc_tick; + + int sc_dma_stopped; }; #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) @@ -1001,6 +1003,7 @@ tsec_up(struct tsec_softc *sc) ecntrl = tsec_read(sc, TSEC_ECNTRL); tsec_write(sc, TSEC_ECNTRL, ecntrl | TSEC_ECNTRL_R100M); + sc->sc_dma_stopped = 0; dmactrl = tsec_read(sc, TSEC_DMACTRL); dmactrl |= TSEC_DMACTRL_TDSEN; dmactrl |= TSEC_DMACTRL_TBDSEN; @@ -1201,28 +1204,33 @@ tsec_stop_dma(struct tsec_softc *sc) uint32_t dmactrl, ievent; int n; - /* Stop DMA. */ - dmactrl = tsec_read(sc, TSEC_DMACTRL); - dmactrl |= TSEC_DMACTRL_GTS; - tsec_write(sc, TSEC_DMACTRL, dmactrl); + if (sc->sc_dma_stopped == 0) { + /* Stop DMA. */ + dmactrl = tsec_read(sc, TSEC_DMACTRL); + dmactrl |= TSEC_DMACTRL_GTS; + tsec_write(sc, TSEC_DMACTRL, dmactrl); + + for (n = 0; n < 100; n++) { + ievent = tsec_read(sc, TSEC_IEVENT); + if (ievent & TSEC_IEVENT_GTSC) + break; + } + KASSERT(n != 100); - for (n = 0; n < 100; n++) { - ievent = tsec_read(sc, TSEC_IEVENT); - if (ievent & TSEC_IEVENT_GTSC) - break; + dmactrl = tsec_read(sc, TSEC_DMACTRL); + dmactrl |= TSEC_DMACTRL_GRS; + tsec_write(sc, TSEC_DMACTRL, dmactrl); + + for (n = 0; n < 100; n++) { + ievent = tsec_read(sc, TSEC_IEVENT); + if (ievent & TSEC_IEVENT_GRSC) + break; + } + KASSERT(n != 100); } - KASSERT(n != 100); - dmactrl = tsec_read(sc, TSEC_DMACTRL); - dmactrl |= TSEC_DMACTRL_GRS; - tsec_write(sc, TSEC_DMACTRL, dmactrl); - - for (n = 0; n < 100; n++) { - ievent = tsec_read(sc, TSEC_IEVENT); - if (ievent & TSEC_IEVENT_GRSC) - break; - } - KASSERT(n != 100); + sc->sc_dma_stopped = 1; +} } struct tsec_dmamem *