Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-4]: src/sys/arch/sun3/dev Make "dma" a real device so it can at...
details: https://anonhg.NetBSD.org/src/rev/81c3895b0ff6
branches: netbsd-1-4
changeset: 468117:81c3895b0ff6
user: gwr <gwr%NetBSD.org@localhost>
date: Thu Apr 08 04:46:42 1999 +0000
description:
Make "dma" a real device so it can attach before esp.
Also pull in some changes from the sparc version.
diffstat:
sys/arch/sun3/dev/dma.c | 393 +++++++++++++++++++++++++++++++++++++++++++++
sys/arch/sun3/dev/dmareg.h | 81 +++++++++
sys/arch/sun3/dev/dmavar.h | 60 ++++++
sys/arch/sun3/dev/esp.c | 355 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 889 insertions(+), 0 deletions(-)
diffs (truncated from 905 to 300 lines):
diff -r 895b4aedf359 -r 81c3895b0ff6 sys/arch/sun3/dev/dma.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sun3/dev/dma.c Thu Apr 08 04:46:42 1999 +0000
@@ -0,0 +1,393 @@
+/* $NetBSD: dma.c,v 1.10.2.2 1999/04/08 04:46:42 gwr Exp $ */
+
+/*
+ * Copyright (c) 1994 Paul Kranenburg. All rights reserved.
+ * Copyright (c) 1994 Peter Galbavy. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Peter Galbavy.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/errno.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+
+#include <machine/autoconf.h>
+#include <machine/dvma.h>
+
+#include <dev/scsipi/scsi_all.h>
+#include <dev/scsipi/scsipi_all.h>
+#include <dev/scsipi/scsiconf.h>
+
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
+
+#include <sun3/dev/dmareg.h>
+#include <sun3/dev/dmavar.h>
+
+#define MAX_DMA_SZ 0x01000000 /* 16MB */
+
+static int dmamatch __P((struct device *, struct cfdata *, void *));
+static void dmaattach __P((struct device *, struct device *, void *));
+
+struct cfattach dma_ca = {
+ sizeof(struct dma_softc), dmamatch, dmaattach
+};
+
+extern struct cfdriver dma_cd;
+
+static int
+dmamatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct confargs *ca = aux;
+
+ /*
+ * Check for the DMA registers.
+ */
+ if (bus_peek(ca->ca_bustype, ca->ca_paddr, 4) == -1)
+ return (0);
+
+ /* If default ipl, fill it in. */
+ if (ca->ca_intpri == -1)
+ ca->ca_intpri = 2;
+
+ return (1);
+}
+
+static void
+dmaattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ struct dma_softc *sc = (void *)self;
+ int id;
+
+#if 0
+ /* indirect functions */
+ sc->intr = espdmaintr;
+ sc->setup = dma_setup;
+ sc->reset = dma_reset;
+#endif
+
+ /*
+ * Map in the registers.
+ */
+ sc->sc_regs = bus_mapin(ca->ca_bustype, ca->ca_paddr,
+ sizeof(struct dma_regs));
+ sc->sc_rev = DMACSR(sc) & D_DEV_ID;
+ id = (sc->sc_rev >> 28) & 0xf;
+ printf(": rev %d\n", id);
+
+ /*
+ * Make sure the DMA chip is supported revision.
+ * The Sun3/80 used only the old rev zero chip,
+ * so the initialization has been simplified.
+ */
+ switch (sc->sc_rev) {
+ case DMAREV_0:
+ case DMAREV_1:
+ break;
+ default:
+ panic("unsupported dma rev");
+ }
+}
+
+/*
+ * This is called by espattach to get our softc.
+ */
+struct dma_softc *
+espdmafind(int unit)
+{
+ if (unit < 0 || unit >= dma_cd.cd_ndevs ||
+ dma_cd.cd_devs[unit] == NULL)
+ panic("no dma");
+ return (dma_cd.cd_devs[unit]);
+}
+
+#define DMAWAIT(SC, COND, MSG, DONTPANIC) do if (COND) { \
+ int count = 100000; \
+ while ((COND) && --count > 0) DELAY(5); \
+ if (count == 0) { \
+ printf("%s: line %d: CSR = 0x%x\n", \
+ __FILE__, __LINE__, DMACSR(SC)); \
+ if (DONTPANIC) \
+ printf(MSG); \
+ else \
+ panic(MSG); \
+ } \
+} while (0)
+
+#define DMA_DRAIN(sc, dontpanic) do { \
+ /* \
+ * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \
+ * and "drain" bits while it is still thinking about a \
+ * request. \
+ * other revs: D_R_PEND bit reads as 0 \
+ */ \
+ DMAWAIT(sc, DMACSR(sc) & D_R_PEND, "R_PEND", dontpanic); \
+ /* \
+ * Select drain bit (always rev 0,1) \
+ * also clears errors and D_TC flag \
+ */ \
+ DMACSR(sc) |= D_DRAIN; \
+ /* \
+ * Wait for draining to finish \
+ */ \
+ DMAWAIT(sc, DMACSR(sc) & D_PACKCNT, "DRAINING", dontpanic); \
+} while(0)
+
+#define DMA_FLUSH(sc, dontpanic) do { \
+ /* \
+ * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \
+ * and "drain" bits while it is still thinking about a \
+ * request. \
+ * other revs: D_R_PEND bit reads as 0 \
+ */ \
+ DMAWAIT(sc, DMACSR(sc) & D_R_PEND, "R_PEND", dontpanic); \
+ DMACSR(sc) &= ~(D_WRITE|D_EN_DMA); \
+ DMACSR(sc) |= D_FLUSH; \
+} while(0)
+
+void
+dma_reset(sc)
+ struct dma_softc *sc;
+{
+
+ DMA_FLUSH(sc, 1);
+ DMACSR(sc) |= D_RESET; /* reset DMA */
+ DELAY(200); /* what should this be ? */
+ /*DMAWAIT1(sc); why was this here? */
+ DMACSR(sc) &= ~D_RESET; /* de-assert reset line */
+ DELAY(5); /* allow a few ticks to settle */
+
+ /*
+ * Get transfer burst size from (?) and plug it into the
+ * controller registers. This is needed on the Sun4m...
+ * Do we need it too? Apparently not, because the 3/80
+ * always has the old, REV zero DMA chip.
+ */
+ DMACSR(sc) |= D_INT_EN; /* enable interrupts */
+
+ sc->sc_active = 0;
+}
+
+
+#define DMAMAX(a) (MAX_DMA_SZ - ((a) & (MAX_DMA_SZ-1)))
+
+/*
+ * setup a dma transfer
+ */
+int
+dma_setup(sc, addr, len, datain, dmasize)
+ struct dma_softc *sc;
+ caddr_t *addr;
+ size_t *len;
+ int datain;
+ size_t *dmasize; /* IN-OUT */
+{
+ u_int32_t csr;
+
+ DMA_FLUSH(sc, 0);
+
+#if 0
+ DMACSR(sc) &= ~D_INT_EN;
+#endif
+ sc->sc_dmaaddr = addr;
+ sc->sc_dmalen = len;
+
+ NCR_DMA(("%s: start %d@%p,%d\n", sc->sc_dev.dv_xname,
+ *sc->sc_dmalen, *sc->sc_dmaaddr, datain ? 1 : 0));
+
+ /*
+ * the rules say we cannot transfer more than the limit
+ * of this DMA chip (64k for old and 16Mb for new),
+ * and we cannot cross a 16Mb boundary.
+ */
+ *dmasize = sc->sc_dmasize =
+ min(*dmasize, DMAMAX((size_t) *sc->sc_dmaaddr));
+
+ NCR_DMA(("dma_setup: dmasize = %d\n", sc->sc_dmasize));
+
+ /* Program the DMA address */
+ if (sc->sc_dmasize) {
+ /*
+ * Use dvma mapin routines to map the buffer into DVMA space.
+ */
+ sc->sc_dvmaaddr = *sc->sc_dmaaddr;
+ sc->sc_dvmakaddr = dvma_mapin(sc->sc_dvmaaddr,
+ sc->sc_dmasize, 0);
+ if (sc->sc_dvmakaddr == NULL)
+ panic("dma: cannot allocate DVMA address");
+ sc->sc_dmasaddr = dvma_kvtopa(sc->sc_dvmakaddr, BUS_OBIO);
+ DMADDR(sc) = sc->sc_dmasaddr;
+ } else {
+ /* XXX: What is this about? -gwr */
+ DMADDR(sc) = (u_int32_t) *sc->sc_dmaaddr;
+ }
+
+ /* We never have DMAREV_ESC. */
+
+ /* Setup DMA control register */
+ csr = DMACSR(sc);
+ if (datain)
+ csr |= D_WRITE;
+ else
+ csr &= ~D_WRITE;
+ csr |= D_INT_EN;
+ DMACSR(sc) = csr;
+
+ return 0;
+}
+
+/*
+ * Pseudo (chained) interrupt from the esp driver to kick the
+ * current running DMA transfer. I am relying on espintr() to
+ * pickup and clean errors for now
+ *
+ * return 1 if it was a DMA continue.
+ */
+int
+espdmaintr(sc)
+ struct dma_softc *sc;
+{
+ struct ncr53c9x_softc *nsc = sc->sc_esp;
+ char bits[64];
+ int trans, resid;
+ u_int32_t csr;
+
+ csr = DMACSR(sc);
+
+ NCR_DMA(("%s: intr: addr 0x%x, csr %s\n",
+ sc->sc_dev.dv_xname, DMADDR(sc),
+ bitmask_snprintf(csr, DMACSRBITS, bits, sizeof(bits))));
+
+ if (csr & D_ERR_PEND) {
+ DMACSR(sc) &= ~D_EN_DMA; /* Stop DMA */
+ DMACSR(sc) |= D_FLUSH;
Home |
Main Index |
Thread Index |
Old Index