summaryrefslogtreecommitdiff
path: root/sys/arch/i386/isa
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2008-12-10 20:26:57 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2008-12-10 20:26:57 +0000
commitd3fde971f3528926e84ea051a99417a80417f473 (patch)
tree858d51b896a2d852e7760005ba9e60691c94bae0 /sys/arch/i386/isa
parent0d3e35763368238aa860947c2387a4e7ce5965ab (diff)
both x86 platforms isa bus_dma implementations handle bus_dmamap_sync
incorrectly. The spec (manpage) states that using two PRE or two POST ops together is entirely valid, but mixing pre and post is invalid. The way this was handled before with a switch statement meant that only individual commands actually would be recognised, so move to just checking the commands indidually using "if (op & $command)". Additionally, add a DIAGNOSTIC check and panic for the mixing of pre and post operations (this is done on several other architectures already). tested by several people; thanks! ok dlg@, kettenis@, "the diff made sense" deraadt.
Diffstat (limited to 'sys/arch/i386/isa')
-rw-r--r--sys/arch/i386/isa/isa_machdep.c30
1 files changed, 10 insertions, 20 deletions
diff --git a/sys/arch/i386/isa/isa_machdep.c b/sys/arch/i386/isa/isa_machdep.c
index 75ee160842b..fa7074aae44 100644
--- a/sys/arch/i386/isa/isa_machdep.c
+++ b/sys/arch/i386/isa/isa_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isa_machdep.c,v 1.64 2008/12/03 15:46:06 oga Exp $ */
+/* $OpenBSD: isa_machdep.c,v 1.65 2008/12/10 20:26:56 oga Exp $ */
/* $NetBSD: isa_machdep.c,v 1.22 1997/06/12 23:57:32 thorpej Exp $ */
/*-
@@ -890,15 +890,14 @@ _isa_bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
panic("_isa_bus_dmamap_sync: bad length");
}
#endif
-
- switch (op) {
- case BUS_DMASYNC_PREREAD:
- /*
- * Nothing to do for pre-read.
- */
- break;
-
- case BUS_DMASYNC_PREWRITE:
+#ifdef DIAGNOSTIC
+ if ((op & (BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE)) != 0 &&
+ (op & (BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE)) != 0)
+ panic("_isa_bus_dmamap_sync: mix PRE and POST");
+#endif /* DIAGNOSTIC */
+
+ /* PREREAD and POSTWRITE are no-ops */
+ if (op & BUS_DMASYNC_PREWRITE) {
/*
* If we're bouncing this transfer, copy the
* caller's buffer to the bounce buffer.
@@ -907,9 +906,7 @@ _isa_bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
bcopy((char *)cookie->id_origbuf + offset,
cookie->id_bouncebuf + offset,
len);
- break;
-
- case BUS_DMASYNC_POSTREAD:
+ } else if (op & BUS_DMASYNC_POSTREAD) {
/*
* If we're bouncing this transfer, copy the
* bounce buffer to the caller's buffer.
@@ -918,13 +915,6 @@ _isa_bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset,
bcopy((char *)cookie->id_bouncebuf + offset,
cookie->id_origbuf + offset,
len);
- break;
-
- case BUS_DMASYNC_POSTWRITE:
- /*
- * Nothing to do for post-write.
- */
- break;
}
#if 0