diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-05-04 18:38:58 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-05-04 18:38:58 +0000 |
commit | 644793ee79abf455660ba9c8b8fb4eb3deb24b91 (patch) | |
tree | 57b821ecdaeb102d9e12cd51176a7ecaf62c4eac | |
parent | b7964a1c70be9a48dfcff83ed2e2ee6126acf550 (diff) |
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.
-rw-r--r-- | sys/dev/ic/dc.c | 18 |
1 files 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 <dev/ic/dcreg.h> +/* + * 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 */ |