diff options
Diffstat (limited to 'sys/dev/isa')
-rw-r--r-- | sys/dev/isa/isadma.c | 177 | ||||
-rw-r--r-- | sys/dev/isa/isadmareg.h | 22 |
2 files changed, 75 insertions, 124 deletions
diff --git a/sys/dev/isa/isadma.c b/sys/dev/isa/isadma.c index 7bef4d3a49c..0a36155e369 100644 --- a/sys/dev/isa/isadma.c +++ b/sys/dev/isa/isadma.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isadma.c,v 1.12 1996/12/11 22:38:06 niklas Exp $ */ +/* $OpenBSD: isadma.c,v 1.13 1996/12/12 00:21:59 niklas Exp $ */ /* $NetBSD: isadma.c,v 1.19 1996/04/29 20:03:26 christos Exp $ */ #include <sys/param.h> @@ -12,7 +12,6 @@ #include <vm/vm.h> -#include <machine/bus.h> #include <machine/pio.h> #include <dev/isa/isareg.h> @@ -28,17 +27,13 @@ struct dma_info { struct isadma_seg phys[1]; }; -static struct isadma_softc *isadma_sc; /*XXX ugly */ static struct dma_info dma_info[8]; static u_int8_t dma_finished; -/* - * high byte of address is stored in this port (offset IO_DMAPG) for i-th - * dma channel - */ -static short dmapageport[2][4] = { - {0x7, 0x3, 0x1, 0x2}, - {0xf, 0xb, 0x9, 0xa} +/* high byte of address is stored in this port for i-th dma channel */ +static int dmapageport[2][4] = { + {0x87, 0x83, 0x81, 0x82}, + {0x8f, 0x8b, 0x89, 0x8a} }; static u_int8_t dmamode[4] = { @@ -52,14 +47,6 @@ int isadmamatch __P((struct device *, void *, void *)); void isadmaattach __P((struct device *, struct device *, void *)); int isadmaprint __P((void *, const char *)); -struct isadma_softc { - struct device sc_dev; - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh1; - bus_space_handle_t sc_ioh2; - bus_space_handle_t sc_dmapageioh[2][4]; -}; - struct cfattach isadma_ca = { sizeof(struct device), isadmamatch, isadmaattach }; @@ -85,25 +72,7 @@ isadmaattach(parent, self, aux) struct device *parent, *self; void *aux; { - struct isadma_softc *sc = (void *)self; - struct isa_attach_args *ia = aux; - bus_space_tag_t iot; - int i; - printf("\n"); - iot = sc->sc_iot = ia->ia_iot; - if (bus_space_map(iot, IO_DMA1, DMA_NREGS(1), 0, &sc->sc_ioh1)) - panic("isadmaattach: couldn't map I/O ports at IO_DMA1"); - if (bus_space_map(iot, IO_DMA2, DMA_NREGS(2), 0, &sc->sc_ioh2)) - panic("isadmaattach: couldn't map I/O ports at IO_DMA2"); - - /* XXX the constants below is a bit ugly, I know... */ - for (i = 0; i < 8; i++) { - if (bus_space_map(iot, IO_DMAPG + dmapageport[i % 2][i / 2], 1, - 0, &sc->sc_dmapageioh[i % 2][i / 2])) - panic("isadmaattach: couldn't map DMA page I/O port"); - } - isadma_sc = sc; } /* @@ -114,10 +83,6 @@ void isadma_cascade(chan) int chan; { - struct isadma_softc *sc = isadma_sc; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh; - int dma_unit; #ifdef ISADMA_DEBUG if (chan < 0 || chan > 7) @@ -126,16 +91,14 @@ isadma_cascade(chan) /* set dma channel mode, and set dma channel mode */ if ((chan & 4) == 0) { - ioh = sc->sc_ioh1; - dma_unit = 1; + outb(DMA1_MODE, chan | DMA37MD_CASCADE); + outb(DMA1_SMSK, chan); } else { - ioh = sc->sc_ioh2; chan &= 3; - dma_unit = 2; + + outb(DMA2_MODE, chan | DMA37MD_CASCADE); + outb(DMA2_SMSK, chan); } - bus_space_write_1(iot, ioh, DMA_MODE(dma_unit), - chan | DMA37MD_CASCADE); - bus_space_write_1(iot, ioh, DMA_SMSK(dma_unit), chan); } /* @@ -149,13 +112,9 @@ isadma_start(addr, nbytes, chan, flags) int chan; int flags; { - struct isadma_softc *sc = isadma_sc; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh; struct dma_info *di; int waport; int mflags; - int dma_unit; #ifdef ISADMA_DEBUG if (chan < 0 || chan > 7 || @@ -194,46 +153,52 @@ isadma_start(addr, nbytes, chan, flags) * Program one of DMA channels 0..3. These are * byte mode channels. */ - ioh = sc->sc_ioh1; - dma_unit = 1; + /* set dma channel mode, and reset address ff */ + outb(DMA1_MODE, chan | dmamode[flags]); + outb(DMA1_FFC, 0); + + /* send start address */ + waport = DMA1_CHN(chan); + outb(dmapageport[0][chan], di->phys[0].addr>>16); + outb(waport, di->phys[0].addr); + outb(waport, di->phys[0].addr>>8); + + /* send count */ + outb(waport + 1, --nbytes); + outb(waport + 1, nbytes>>8); + + /* unmask channel */ + outb(DMA1_SMSK, chan | DMA37SM_CLEAR); } else { /* * Program one of DMA channels 4..7. These are * word mode channels. */ - ioh = sc->sc_ioh2; - dma_unit = 2; - chan &= 3; + /* set dma channel mode, and reset address ff */ + outb(DMA2_MODE, (chan & 3) | dmamode[flags]); + outb(DMA2_FFC, 0); + + /* send start address */ + waport = DMA2_CHN(chan & 3); + outb(dmapageport[1][chan], di->phys[0].addr>>16); + outb(waport, di->phys[0].addr>>1); + outb(waport, di->phys[0].addr>>9); + + /* send count */ nbytes >>= 1; + outb(waport + 2, --nbytes); + outb(waport + 2, nbytes>>8); + + /* unmask channel */ + outb(DMA2_SMSK, (chan & 3) | DMA37SM_CLEAR); } - /* set dma channel mode, and reset address ff */ - bus_space_write_1(iot, ioh, DMA_MODE(dma_unit), chan | dmamode[flags]); - bus_space_write_1(iot, ioh, DMA_FFC(dma_unit), 0); - - /* send start address */ - waport = DMA_CHN(dma_unit, chan); - bus_space_write_1(iot, sc->sc_dmapageioh[dma_unit - 1][chan], 0, - di->phys[0].addr>>16); - bus_space_write_1(iot, ioh, waport, di->phys[0].addr); - bus_space_write_1(iot, ioh, waport, di->phys[0].addr>>8); - - /* send count */ - bus_space_write_1(iot, ioh, waport + dma_unit, --nbytes & 0xff); - bus_space_write_1(iot, ioh, waport + dma_unit, nbytes >> 8); - - /* unmask channel */ - bus_space_write_1(iot, ioh, DMA_SMSK(dma_unit), chan | DMA37SM_CLEAR); } void isadma_abort(chan) int chan; { - struct isadma_softc *sc = isadma_sc; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh; struct dma_info *di; - int dma_unit; #ifdef ISADMA_DEBUG if (chan < 0 || chan > 7) @@ -247,15 +212,11 @@ isadma_abort(chan) } /* mask channel */ - if ((chan & 4) == 0) { - ioh = sc->sc_ioh1; - dma_unit = 1; - } else { - ioh = sc->sc_ioh2; - chan &= 3; - dma_unit = 2; - } - bus_space_write_1(iot, ioh, DMA_SMSK(dma_unit), DMA37SM_SET | chan); + if ((chan & 4) == 0) + outb(DMA1_SMSK, DMA37SM_SET | chan); + else + outb(DMA2_SMSK, DMA37SM_SET | (chan & 3)); + isadma_unmap(di->addr, di->nbytes, 1, di->phys); di->active = 0; } @@ -264,10 +225,6 @@ int isadma_finished(chan) int chan; { - struct isadma_softc *sc = isadma_sc; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh; - int dma_unit; #ifdef ISADMA_DEBUG if (chan < 0 || chan > 7) @@ -275,15 +232,11 @@ isadma_finished(chan) #endif /* check that the terminal count was reached */ - if ((chan & 4) == 0) { - ioh = sc->sc_ioh1; - dma_unit = 1; - } else { - ioh = sc->sc_ioh2; - chan &= 3; - dma_unit = 2; - } - dma_finished |= bus_space_read_1(iot, ioh, DMA_SR(dma_unit)) & 0x0f; + if ((chan & 4) == 0) + dma_finished |= inb(DMA1_SR) & 0x0f; + else + dma_finished |= (inb(DMA2_SR) & 0x0f) << 4; + return ((dma_finished & (1 << chan)) != 0); } @@ -291,10 +244,6 @@ void isadma_done(chan) int chan; { - struct isadma_softc *sc = isadma_sc; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh; - int dma_unit; struct dma_info *di; u_char tc; @@ -310,23 +259,19 @@ isadma_done(chan) } /* check that the terminal count was reached */ - if ((chan & 4) == 0) { - ioh = sc->sc_ioh1; - dma_unit = 1; - } else { - ioh = sc->sc_ioh2; - chan &= 3; - dma_unit = 2; - } - tc = bus_space_read_1(iot, ioh, DMA_SR(dma_unit)) & (1 << chan); - + if ((chan & 4) == 0) + tc = inb(DMA1_SR) & (1 << chan); + else + tc = inb(DMA2_SR) & (1 << (chan & 3)); if (tc == 0) /* XXX probably should panic or something */ - log(LOG_ERR, "dma channel %d not finished\n", - dma_unit == 1 ? chan : (chan | 4)); + log(LOG_ERR, "dma channel %d not finished\n", chan); /* mask channel */ - bus_space_write_1(iot, ioh, DMA_SMSK(dma_unit), DMA37SM_SET | chan); + if ((chan & 4) == 0) + outb(DMA1_SMSK, DMA37SM_SET | chan); + else + outb(DMA2_SMSK, DMA37SM_SET | (chan & 3)); /* XXX Will this do what we want with DMAMODE_LOOP? */ if (di->flags & DMAMODE_READ) diff --git a/sys/dev/isa/isadmareg.h b/sys/dev/isa/isadmareg.h index a534b64671d..47744042425 100644 --- a/sys/dev/isa/isadmareg.h +++ b/sys/dev/isa/isadmareg.h @@ -1,15 +1,21 @@ -/* $OpenBSD: isadmareg.h,v 1.2 1996/11/29 22:55:02 niklas Exp $ */ /* $NetBSD: isadmareg.h,v 1.4 1995/06/28 04:31:48 cgd Exp $ */ #include <dev/ic/i8237reg.h> /* - * Register definitions for the DMA controllers + * Register definitions for DMA controller 1 (channels 0..3): */ -#define DMA_CHN(u, c) ((u) * (2 * (c))) /* addr reg for channel c */ -#define DMA_SR(u) ((u) * 8) /* status register */ -#define DMA_SMSK(u) ((u) * 10) /* single mask register */ -#define DMA_MODE(u) ((u) * 11) /* mode register */ -#define DMA_FFC(u) ((u) * 12) /* clear first/last FF */ +#define DMA1_CHN(c) (IO_DMA1 + 1*(2*(c))) /* addr reg for channel c */ +#define DMA1_SR (IO_DMA1 + 1*8) /* status register */ +#define DMA1_SMSK (IO_DMA1 + 1*10) /* single mask register */ +#define DMA1_MODE (IO_DMA1 + 1*11) /* mode register */ +#define DMA1_FFC (IO_DMA1 + 1*12) /* clear first/last FF */ -#define DMA_NREGS(u) ((u) * 13) /* XXX true? */ +/* + * Register definitions for DMA controller 2 (channels 4..7): + */ +#define DMA2_CHN(c) (IO_DMA2 + 2*(2*(c))) /* addr reg for channel c */ +#define DMA2_SR (IO_DMA2 + 2*8) /* status register */ +#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */ +#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */ +#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */ |