From d3fde971f3528926e84ea051a99417a80417f473 Mon Sep 17 00:00:00 2001 From: Owain Ainsworth Date: Wed, 10 Dec 2008 20:26:57 +0000 Subject: 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. --- sys/arch/i386/isa/isa_machdep.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'sys/arch/i386/isa') 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 -- cgit v1.2.3