summaryrefslogtreecommitdiff
path: root/sys/dev/ic/dc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic/dc.c')
-rw-r--r--sys/dev/ic/dc.c18
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 */