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 *

Reply via email to