Author: marius
Date: Sat Mar 26 22:39:23 2011
New Revision: 220046
URL: http://svn.freebsd.org/changeset/base/220046

Log:
  Wait until the DMA engine is stopped before unmapping buffers and
  descriptors, which fixes DMA errors seen on sparc64.
  
  Obtained from:        OpenBSD
  MFC after:    1 week

Modified:
  head/sys/dev/dc/if_dc.c

Modified: head/sys/dev/dc/if_dc.c
==============================================================================
--- head/sys/dev/dc/if_dc.c     Sat Mar 26 21:32:10 2011        (r220045)
+++ head/sys/dev/dc/if_dc.c     Sat Mar 26 22:39:23 2011        (r220046)
@@ -3917,7 +3917,7 @@ dc_stop(struct dc_softc *sc)
        struct dc_list_data *ld;
        struct dc_chain_data *cd;
        int i;
-       uint32_t ctl;
+       uint32_t ctl, isr;
 
        DC_LOCK_ASSERT(sc);
 
@@ -3932,6 +3932,30 @@ dc_stop(struct dc_softc *sc)
        ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
        DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_RX_ON | DC_NETCFG_TX_ON));
+
+       for (i = 0; i < DC_TIMEOUT; i++) {
+               isr = CSR_READ_4(sc, DC_ISR);
+               if ((isr & DC_ISR_TX_IDLE ||
+                   (isr & DC_ISR_TX_STATE) == DC_TXSTATE_RESET) &&
+                   (isr & DC_ISR_RX_STATE) == DC_RXSTATE_STOPPED)
+                       break;
+               DELAY(10);
+       }
+
+       if (i == DC_TIMEOUT) {
+               if (!((isr & DC_ISR_TX_IDLE) ||
+                   (isr & DC_ISR_TX_STATE) == DC_TXSTATE_RESET) &&
+                   !DC_IS_ASIX(sc) && !DC_IS_DAVICOM(sc))
+                       device_printf(sc->dc_dev,
+                           "%s: failed to force tx to idle state\n",
+                           __func__);
+               if (!((isr & DC_ISR_RX_STATE) == DC_RXSTATE_STOPPED) &&
+                   !DC_HAS_BROKEN_RXSTATE(sc))
+                       device_printf(sc->dc_dev,
+                           "%s: failed to force rx to idle state\n",
+                           __func__);
+       }
+
        CSR_WRITE_4(sc, DC_IMR, 0x00000000);
        CSR_WRITE_4(sc, DC_TXADDR, 0x00000000);
        CSR_WRITE_4(sc, DC_RXADDR, 0x00000000);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to