From 644793ee79abf455660ba9c8b8fb4eb3deb24b91 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Wed, 4 May 2016 18:38:58 +0000 Subject: Use BUS_DMA_OVERRUN to cope with the broken DMA engine of the Davicom DM9102 found on some Sun sparc64 machines. This fixes the unrecoverable DMA errors people have been seeing ever since dlg@ made changes to the pool code that changes the memory layout. --- sys/dev/ic/dc.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/sys/dev/ic/dc.c b/sys/dev/ic/dc.c index d68af6ace33..714b3a51473 100644 --- a/sys/dev/ic/dc.c +++ b/sys/dev/ic/dc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dc.c,v 1.150 2016/04/13 10:49:26 mpi Exp $ */ +/* $OpenBSD: dc.c,v 1.151 2016/05/04 18:38:57 kettenis Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -122,6 +122,18 @@ #include +/* + * The Davicom DM9102 has a broken DMA engine that reads beyond the + * end of the programmed transfer. Architectures with a proper IOMMU + * (such as sparc64) will trap on this access. To avoid having to + * copy each transmitted mbuf to guarantee enough trailing space, + * those architectures should implement BUS_DMA_OVERRUN that takes + * appropriate action to tolerate this behaviour. + */ +#ifndef BUS_DMA_OVERRUN +#define BUS_DMA_OVERRUN 0 +#endif + int dc_intr(void *); struct dc_type *dc_devtype(void *); int dc_newbuf(struct dc_softc *, int, struct mbuf *); @@ -2583,13 +2595,13 @@ dc_start(struct ifnet *ifp) map = sc->sc_tx_sparemap; switch (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, - BUS_DMA_NOWAIT)) { + BUS_DMA_NOWAIT | BUS_DMA_OVERRUN)) { case 0: break; case EFBIG: if (m_defrag(m, M_DONTWAIT) == 0 && bus_dmamap_load_mbuf(sc->sc_dmat, map, m, - BUS_DMA_NOWAIT) == 0) + BUS_DMA_NOWAIT | BUS_DMA_OVERRUN) == 0) break; /* FALLTHROUGH */ -- cgit v1.2.3