sync with netbsd; working ncr5380 driver, saner vsbus code
authorbjc <bjc@openbsd.org>
Thu, 27 Apr 2000 00:52:07 +0000 (00:52 +0000)
committerbjc <bjc@openbsd.org>
Thu, 27 Apr 2000 00:52:07 +0000 (00:52 +0000)
sys/arch/vax/vsa/ncr.c
sys/arch/vax/vsa/vsbus.c

index 242e658..075c37f 100644 (file)
@@ -1,16 +1,12 @@
-/*     $OpenBSD: ncr.c,v 1.4 1999/01/11 05:12:09 millert Exp $ */
-/*     $NetBSD: ncr.c,v 1.8 1997/02/26 22:29:12 gwr Exp $      */
+/*     $NetBSD: ncr.c,v 1.26 2000/03/25 15:27:57 tsutsui Exp $ */
 
-/* #define DEBUG       /* */
-/* #define TRACE       /* */
-/* #define POLL_MODE   /* */
-#define USE_VMAPBUF
-
-/*
- * Copyright (c) 1995 David Jones, Gordon W. Ross
- * Copyright (c) 1994 Adam Glass
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Adam Glass, David Jones, Gordon W. Ross, and Jens A. Nilsson.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 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. The name of the authors may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- * 4. All advertising materials mentioning features or use of this software
+ * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
- *     This product includes software developed by
- *     Adam Glass, David Jones, and Gordon Ross
+ *       This product includes software developed by the NetBSD
+ *       Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
  */
 
 /*
- * This file contains only the machine-dependent parts of the
- * Sun3 SCSI driver.  (Autoconfig stuff and DMA functions.)
- * The machine-independent parts are in ncr5380sbc.c
- *
- * Supported hardware includes:
- * Sun SCSI-3 on OBIO (Sun3/50,Sun3/60)
- * Sun SCSI-3 on VME (Sun3/160,Sun3/260)
- *
- * Could be made to support the Sun3/E if someone wanted to.
- *
- * Note:  Both supported variants of the Sun SCSI-3 adapter have
- * some really unusual "features" for this driver to deal with,
- * generally related to the DMA engine.         The OBIO variant will
- * ignore any attempt to write the FIFO count register while the
- * SCSI bus is in DATA_IN or DATA_OUT phase.  This is dealt with
- * by setting the FIFO count early in COMMAND or MSG_IN phase.
+ * This file contains the machine-dependent parts of the NCR-5380
+ * controller. The machine-independent parts are in ncr5380sbc.c.
  *
- * The VME variant has a bit to enable or disable the DMA engine,
- * but that bit also gates the interrupt line from the NCR5380!
- * Therefore, in order to get any interrupt from the 5380, (i.e.
- * for reselect) one must clear the DMA engine transfer count and
- * then enable DMA.  This has the further complication that you
- * CAN NOT touch the NCR5380 while the DMA enable bit is set, so
- * we have to turn DMA back off before we even look at the 5380.
+ * Note: Only PIO transfers for now which implicates very bad
+ * performance. DMA support will come soon.
  *
- * What wonderfully whacky hardware this is!
+ * Jens A. Nilsson.
  *
- * Credits, history:
- *
- * David Jones wrote the initial version of this module, which
- * included support for the VME adapter only. (no reselection).
- *
- * Gordon Ross added support for the OBIO adapter, and re-worked
- * both the VME and OBIO code to support disconnect/reselect.
- * (Required figuring out the hardware "features" noted above.)
- *
- * The autoconfiguration boilerplate came from Adam Glass.
- *
- * VS2000:
+ * Credits:
+ * 
+ * This code is based on arch/sun3/dev/si*
+ * Written by David Jones, Gordon Ross, and Adam Glass.
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/errno.h>
 #include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/file.h>
-#include <sys/stat.h> 
-#include <sys/ioctl.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
 #include <sys/buf.h>
+#include <sys/disk.h>
 #include <sys/proc.h>
 #include <sys/user.h>
-#include <sys/map.h>
-#include <sys/device.h>
-#include <sys/dkstat.h> 
-#include <sys/disklabel.h>
-#include <sys/disk.h>
-#include <sys/syslog.h>
 
-/* #include <sys/errno.h> */
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
 
 #include <scsi/scsi_all.h>
 #include <scsi/scsi_debug.h>
 #include <scsi/scsiconf.h>
-
-#include <machine/uvax.h>
-#include <machine/ka410.h>
-#include <machine/ka43.h>
-#include <machine/vsbus.h>     /* struct confargs */
+#include <scsi/sdvar.h>
 
 #include <dev/ic/ncr5380reg.h>
 #include <dev/ic/ncr5380var.h>
 
-#define trace(x)
-#define debug(x)
+#include <machine/cpu.h>
+#include <machine/vsbus.h>
+#include <machine/bus.h>
+#include <machine/sid.h>
+#include <machine/scb.h>
 
-#ifndef NCR5380_CSRBITS
-#define NCR5380_CSRBITS \
-       "\020\010DEND\007DREQ\006PERR\005IREQ\004MTCH\003DCON\002ATN\001ACK"
-#endif
+#define MIN_DMA_LEN 128
 
-#ifndef NCR5380_BUSCSRBITS
-#define NCR5380_BUSCSRBITS \
-       "\020\010RST\007BSY\006REQ\005MSG\004C/D\003I/O\002SEL\001DBP"
-#endif
-
-#include "ncr.h"
-
-#ifdef DDB
-#define integrate
-#else
-#define integrate static
-#endif
-
-/*
- * Transfers smaller than this are done using PIO
- * (on assumption they're not worth DMA overhead)
- */
-#define MIN_DMA_LEN 128 
-
-/*
- * Transfers lager than 65535 bytes need to be split-up.
- * (Some of the FIFO logic has only 16 bits counters.)
- * Make the size an integer multiple of the page size
- * to avoid buf/cluster remap problems.         (paranoid?)
- *
- * bertram: VS2000 has an DMA-area which is 16KB, thus
- * have a maximum DMA-size of 16KB...
- */
-#ifdef DMA_SHARED
-#define MAX_DMA_LEN    0x2000          /* (8 * 1024) */
-#define DMA_ADDR_HBYTE 0x20
-#define DMA_ADDR_LBYTE 0x00
-#else
-#define MAX_DMA_LEN    0x4000          /* (16 * 1024) */
-#define DMA_ADDR_HBYTE 0x00
-#define DMA_ADDR_LBYTE 0x00
-#endif
-
-#ifdef DEBUG
-int si_debug = 3;
-static int si_link_flags = 0 /* | SDEV_DB2 */ ;
-#endif
-
-/*
- * This structure is used to keep track of mappedpwd DMA requests.
- * Note: combined the UDC command block with this structure, so
- * the array of these has to be in DVMA space.
- */
 struct si_dma_handle {
-       int             dh_flags;
-#define SIDH_BUSY      1               /* This DH is in use */
-#define SIDH_OUT       2               /* DMA does data out (write) */
-#define SIDH_PHYS      4
-#define SIDH_DONE      8
-       u_char *        dh_addr;        /* KVA of start of buffer */
-       int             dh_maplen;      /* Length of KVA mapping. */
-       u_char *        dh_dvma;        /* VA of buffer in DVMA space */
-       int             dh_xlen;
+       int     dh_flags;
+#define SIDH_BUSY      1
+#define SIDH_OUT       2
+       caddr_t dh_addr;
+       int     dh_len;
+       struct  proc *dh_proc;
 };
 
-/*
- * The first structure member has to be the ncr5380_softc
- * so we can just cast to go back and fourth between them.
- */
 struct si_softc {
-       struct ncr5380_softc    ncr_sc;
-       volatile struct si_regs *sc_regs;       /* do we really need this? */
-
-       struct si_dma_handle    *sc_dma;
-       struct confargs         *sc_cfargs;     
-
-       int     sc_xflags;      /* ka410/ka43: resid, sizeof(areg) */
-
-       char    *sc_dbase;
-       int     sc_dsize;
-       
-       volatile char   *sc_dareg;
-       volatile short  *sc_dcreg;
-       volatile char   *sc_ddreg;
-       volatile int    sc_dflags;
-       
-#define VSDMA_LOCKED   0x80    /* */
-#define VSDMA_WANTED   0x40    /* */
-#define VSDMA_IWANTED  0x20
-#define VSDMA_BLOCKED  0x10
-#define VSDMA_DMABUSY  0x08    /* DMA in progress */
-#define VSDMA_REGBUSY  0x04    /* accessing registers */
-#define VSDMA_WRBUF    0x02    /* writing to bounce-buffer */
-#define VSDMA_RDBUF    0x01    /* reading from bounce-buffer */
-
-#define VSDMA_STATUS   0xF0
-#define VSDMA_LCKTYPE  0x0F
-
-#ifdef POLL_MODE
-       volatile u_char *intreq;
-       volatile u_char *intclr;
-       volatile u_char *intmsk;
-       volatile int    intbit;
-#endif
+       struct  ncr5380_softc   ncr_sc;
+       caddr_t ncr_addr;
+       int     ncr_off;
+       int     ncr_dmaaddr;
+       int     ncr_dmacount;
+       int     ncr_dmadir;
+
+       /* Pointers to bus_space */
+       bus_space_tag_t     sc_regt;
+       bus_space_handle_t  sc_regh;
+
+       struct  si_dma_handle ncr_dma[SCI_OPENINGS];
 };
 
-extern int cold;       /* enable polling while cold-flag set */
-
-/* Options.  Interesting values are: 1,3,7 */
-int si_options = 3;    /* bertram: 3 or 7 ??? */
-#define SI_ENABLE_DMA  1       /* Use DMA (maybe polled) */
-#define SI_DMA_INTR    2       /* DMA completion interrupts */
-#define SI_DO_RESELECT 4       /* Allow disconnect/reselect */
-
-#define DMA_DIR_IN  1
-#define DMA_DIR_OUT 0
-
-/* How long to wait for DMA before declaring an error. */
-int si_dma_intr_timo = 500;    /* ticks (sec. X 100) */
-
-integrate char si_name[] = "ncr";
-integrate int  si_match();
-integrate void si_attach();
-integrate int  si_intr __P((void *));
-
-integrate void si_minphys __P((struct buf *bp));
-integrate void si_reset_adapter __P((struct ncr5380_softc *sc));
-
-void si_dma_alloc __P((struct ncr5380_softc *));
-void si_dma_free __P((struct ncr5380_softc *));
-void si_dma_poll __P((struct ncr5380_softc *));
-
-void si_intr_on __P((struct ncr5380_softc *));
-void si_intr_off __P((struct ncr5380_softc *));
-
-int si_dmaLockBus __P((struct ncr5380_softc *, int));
-int si_dmaToggleLock __P((struct ncr5380_softc *, int, int));
-int si_dmaReleaseBus __P((struct ncr5380_softc *, int));
-
-void si_dma_setup __P((struct ncr5380_softc *));
-void si_dma_start __P((struct ncr5380_softc *));
-void si_dma_eop __P((struct ncr5380_softc *));
-void si_dma_stop __P((struct ncr5380_softc *));
-
-static struct scsi_adapter     si_ops = {
-       ncr5380_scsi_cmd,               /* scsi_cmd()           */
-       si_minphys,                     /* scsi_minphys()       */
-       NULL,                           /* open_target_lu()     */
-       NULL,                           /* close_target_lu()    */
+static int si_match __P((struct device *, void *, void *));
+static void si_attach __P((struct device *, struct device *, void *));
+static void si_minphys __P((struct buf *));
+
+static void si_dma_alloc __P((struct ncr5380_softc *));
+static void si_dma_free __P((struct ncr5380_softc *));
+static void si_dma_setup __P((struct ncr5380_softc *));
+static void si_dma_start __P((struct ncr5380_softc *));
+static void si_dma_poll __P((struct ncr5380_softc *));
+static void si_dma_eop __P((struct ncr5380_softc *));
+static void si_dma_stop __P((struct ncr5380_softc *));
+
+#define NCR5380_READ(sc, reg)  bus_space_read_1(sc->sc_regt,           \
+       0, sc->ncr_sc.reg)
+#define NCR5380_WRITE(sc, reg, val)    bus_space_write_1(sc->sc_regt,  \
+       0, sc->ncr_sc.reg, val)
+
+struct scsi_adapter    si_ops = {
+       ncr5380_scsi_cmd,       /* scsi_cmd()       */
+       si_minphys,         /* scsi_minphys()   */
+       NULL,               /* open_target_lu() */
+       NULL,               /* close_target_lu()    */
 };
 
-/* This is copied from julian's bt driver */
-/* "so we have a default dev struct for our link struct." */
-static struct scsi_device si_dev = {
-       NULL,           /* Use default error handler.       */
-       NULL,           /* Use default start handler.           */
-       NULL,           /* Use default async handler.       */
-       NULL,           /* Use default "done" routine.      */
+struct scsi_device     si_dev = {
+       NULL,           /* use default error handler */
+       NULL,           /* no start function */
+       NULL,           /* no async handler */
+       NULL            /* use default done routine */
 };
 
-
-struct cfdriver ncr_cd = {
-       NULL, si_name, DV_DULL
-};
 struct cfattach ncr_ca = {
-       sizeof(struct si_softc), si_match, si_attach,
+       sizeof(struct si_softc), si_match, si_attach
 };
 
-void
-dk_establish(p,q)
-       struct disk *p;
-       struct device *q;
-{
-#if 0
-       printf ("faking dk_establish()...\n");
-#endif
-}
-
-
-integrate int
-si_match(parent, match, aux)
-       struct device   *parent;
-       void            *match, *aux;
-{
-       struct cfdata   *cf = match;
-       struct confargs *ca = aux;
-
-       trace(("ncr_match(0x%x, %d, %s)\n", parent, cf->cf_unit, ca->ca_name));
-
-       if (strcmp(ca->ca_name, "ncr") &&
-           strcmp(ca->ca_name, "ncr5380") &&
-           strcmp(ca->ca_name, "NCR5380"))
-               return (0);
+struct cfdriver ncr_cd = {
+       NULL, "ncr", DV_DULL
+};
 
-       /*
-        * we just define it being there ...
-        */
-       return (1);
-}
+extern struct cfdriver sd_cd;
 
-integrate void
-si_set_portid(pid,port)
-       int pid;
-       int port;
+static int
+si_match(parent, cf, aux)
+       struct device *parent;
+       void *cf;
+       void *aux;
 {
-       struct {
-         u_long    :2;
-         u_long id0:3;
-         u_long id1:3;
-         u_long    :26;
-       } *p;
-
-#ifdef DEBUG
-       int *ip;
-       ip = (void*)uvax_phys2virt(KA410_SCSIPORT);
-       p = (void*)uvax_phys2virt(KA410_SCSIPORT);
-       printf("scsi-id: (%x/%d) %d / %d\n", *ip, *ip, p->id0, p->id1);
-#endif
-
-       p = (void*)uvax_phys2virt(KA410_SCSIPORT);
-       switch (port) {
-       case 0:
-               p->id0 = pid;
-               printf(": scsi-id %d\n", p->id0);
-               break;
-       case 1:
-               p->id1 = pid;
-               printf(": scsi-id %d\n", p->id1);
-               break;
-       default:
-               printf("invalid port-number %d\n", port);
-       }
+       struct vsbus_attach_args *va = aux;
+       volatile char *si_csr = (char *) va->va_addr;
+
+       if (vax_boardtype == VAX_BTYP_49)
+               return 0;
+       /* This is the way Linux autoprobes the interrupt MK-990321 */
+       si_csr[12] = 0;
+       si_csr[16] = 0x80;
+       si_csr[0] = 0x80;
+       si_csr[4] = 5; /* 0xcf */
+       DELAY(100000);
+       return 1;
 }
 
-integrate void
+static void
 si_attach(parent, self, aux)
        struct device   *parent, *self;
        void            *aux;
 {
+       struct vsbus_attach_args *va = aux;
+       struct vsbus_softc *vsc = (struct vsbus_softc *)parent;
        struct si_softc *sc = (struct si_softc *) self;
-       struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *)sc;
-       volatile struct si_regs *regs;
-       struct confargs *ca = aux;
-       int i;
-       int *ip = aux;;
+       struct ncr5380_softc *ncr_sc = &sc->ncr_sc;
 
-       trace (("ncr_attach(0x%x, 0x%x, %s)\n", parent, self, ca->ca_name));
-
-       /*
-        *
-        */
-#ifdef POLL_MODE
-       sc->intreq = (void*)uvax_phys2virt(KA410_INTREQ);
-       sc->intmsk = (void*)uvax_phys2virt(KA410_INTMSK);
-       sc->intclr = (void*)uvax_phys2virt(KA410_INTCLR);
-       sc->intbit = ca->ca_intbit;
-#endif
-
-       sc->sc_cfargs = ca;     /* needed for interrupt-setup */
-
-       regs = (void*)uvax_phys2virt(ca->ca_ioaddr);
-
-       sc->sc_dareg = (void*)uvax_phys2virt(ca->ca_dareg);
-       sc->sc_dcreg = (void*)uvax_phys2virt(ca->ca_dcreg);
-       sc->sc_ddreg = (void*)uvax_phys2virt(ca->ca_ddreg);
-       sc->sc_dbase = (void*)uvax_phys2virt(ca->ca_dbase);
-       sc->sc_dsize = ca->ca_dsize;
-       sc->sc_dflags = 4;      /* XXX */
-       sc->sc_xflags = ca->ca_dflag;   /* should/will be renamed */
-       /*
-        * Fill in the prototype scsi_link.
-        */
-#ifndef __OpenBSD__
-       ncr_sc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE;
-#endif
-       ncr_sc->sc_link.adapter_softc = sc;
-       ncr_sc->sc_link.adapter_target = ca->ca_idval;
-       ncr_sc->sc_link.adapter = &si_ops;
-       ncr_sc->sc_link.device = &si_dev;
+       printf("\n");
 
-       si_set_portid(ca->ca_idval, ncr_sc->sc_dev.dv_unit);
+       /* enable interrupts on vsbus too */
+       scb_vecalloc(va->va_cvec, (void (*)(void *)) ncr5380_intr, sc, SCB_ISTACK);
+       vsc->sc_mask |= 1 << (va->va_maskno-1); 
 
        /*
-        * Initialize fields used by the MI code
+        * DMA area mapin.
+        * On VS3100, split the 128K block between the two devices.
+        * On VS2000, don't care for now.
         */
-       ncr_sc->sci_r0 = (void*)&regs->sci.sci_r0;
-       ncr_sc->sci_r1 = (void*)&regs->sci.sci_r1;
-       ncr_sc->sci_r2 = (void*)&regs->sci.sci_r2;
-       ncr_sc->sci_r3 = (void*)&regs->sci.sci_r3;
-       ncr_sc->sci_r4 = (void*)&regs->sci.sci_r4;
-       ncr_sc->sci_r5 = (void*)&regs->sci.sci_r5;
-       ncr_sc->sci_r6 = (void*)&regs->sci.sci_r6;
-       ncr_sc->sci_r7 = (void*)&regs->sci.sci_r7;
+#define DMASIZE (64*1024)
+       if (vax_boardtype != VAX_BTYP_410) {
+               if (va->va_paddr & 0x100) /* Magic */
+                       sc->ncr_off = DMASIZE;
+               sc->ncr_addr = (caddr_t)uvm_km_valloc(kernel_map, DMASIZE);
+               
+               ioaccess((vaddr_t)sc->ncr_addr,
+                   0x202d0000 + sc->ncr_off, DMASIZE/VAX_NBPG);
 
-       /*
-        * MD function pointers used by the MI code.
-        */
+               /*
+                * MD function pointers used by the MI code.
+                */
+               ncr_sc->sc_dma_alloc = si_dma_alloc;
+               ncr_sc->sc_dma_free  = si_dma_free;
+               ncr_sc->sc_dma_setup = si_dma_setup;
+               ncr_sc->sc_dma_start = si_dma_start;
+               ncr_sc->sc_dma_poll  = si_dma_poll;
+               ncr_sc->sc_dma_eop   = si_dma_eop;
+               ncr_sc->sc_dma_stop  = si_dma_stop;
+
+               /* DMA control register offsets */
+               sc->ncr_dmaaddr = 32;   /* DMA address in buffer, longword */
+               sc->ncr_dmacount = 64;  /* DMA count register */
+               sc->ncr_dmadir = 68;    /* Direction of DMA transfer */
+       }
        ncr_sc->sc_pio_out = ncr5380_pio_out;
        ncr_sc->sc_pio_in =  ncr5380_pio_in;
-       ncr_sc->sc_dma_alloc = si_dma_alloc;
-       ncr_sc->sc_dma_free  = si_dma_free;
-       ncr_sc->sc_dma_poll  = si_dma_poll;     /* si_dma_poll not used! */
-       ncr_sc->sc_intr_on   = si_intr_on;      /* vsbus_unlockDMA; */
-       ncr_sc->sc_intr_off  = si_intr_off;     /* vsbus_lockDMA; */
-
-       ncr_sc->sc_dma_setup = NULL;            /* si_dma_setup not used! */
-       ncr_sc->sc_dma_start = si_dma_start;
-       ncr_sc->sc_dma_eop   = NULL;    
-       ncr_sc->sc_dma_stop  = si_dma_stop;
 
-       ncr_sc->sc_flags = 0;
-#ifndef __OpenBSD__
-       if ((si_options & SI_DO_RESELECT) == 0)
-               ncr_sc->sc_no_disconnect = 0xff;
-#endif
-       if ((si_options & SI_DMA_INTR) == 0)
-               ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
        ncr_sc->sc_min_dma_len = MIN_DMA_LEN;
 
        /*
-        * Initialize fields used only here in the MD code.
+        * Initialize fields used by the MI code.
         */
-       i = SCI_OPENINGS * sizeof(struct si_dma_handle);
-       sc->sc_dma = (struct si_dma_handle *) malloc(i);
-       if (sc->sc_dma == NULL)
-               panic("si: dvma_malloc failed");
-       for (i = 0; i < SCI_OPENINGS; i++)
-               sc->sc_dma[i].dh_flags = 0;
-
-       sc->sc_regs = regs;
-       
-#ifdef DEBUG
-       if (si_debug)
-               printf("si: Set TheSoftC=%x TheRegs=%x\n", sc, regs);
-       ncr_sc->sc_link.flags |= si_link_flags;
-#endif
+/*     sc->sc_regt =  Unused on VAX */
+       sc->sc_regh = vax_map_physmem(va->va_paddr, 1);
+
+       /* Register offsets */
+       ncr_sc->sci_r0 = (void *)sc->sc_regh;
+       ncr_sc->sci_r1 = (void *)sc->sc_regh+4;
+       ncr_sc->sci_r2 = (void *)sc->sc_regh+8;
+       ncr_sc->sci_r3 = (void *)sc->sc_regh+12;
+       ncr_sc->sci_r4 = (void *)sc->sc_regh+16;
+       ncr_sc->sci_r5 = (void *)sc->sc_regh+20;
+       ncr_sc->sci_r6 = (void *)sc->sc_regh+24;
+       ncr_sc->sci_r7 = (void *)sc->sc_regh+28;
+
+       ncr_sc->sc_no_disconnect = 0xff;
+
+       ncr_sc->sc_link.adapter_softc = sc;
+       ncr_sc->sc_link.adapter_target = 7;
+       ncr_sc->sc_link.adapter = &si_ops;
+       ncr_sc->sc_link.device = &si_dev;
 
        /*
-        *  Initialize si board itself.
+        * Initialize si board itself.
         */
-       si_reset_adapter(ncr_sc);
        ncr5380_init(ncr_sc);
        ncr5380_reset_scsibus(ncr_sc);
-       config_found(self, &(ncr_sc->sc_link), scsiprint);
-
-       /* 
-        * Now ready for interrupts. 
-        */
-       vsbus_intr_register(sc->sc_cfargs, si_intr, (void *)sc);
-       vsbus_intr_enable(sc->sc_cfargs);
+       config_found(&(ncr_sc->sc_dev), &(ncr_sc->sc_link), scsiprint);
 }
 
-integrate void
-si_minphys(struct buf *bp)
-{
-       debug(("minphys: blkno=%d, bcount=%d, data=0x%x, flags=%x\n",
-             bp->b_blkno, bp->b_bcount, bp->b_data, bp->b_flags));
-
-       if (bp->b_bcount > MAX_DMA_LEN) {
-#ifdef DEBUG
-               if (si_debug) {
-                       printf("si_minphys len = 0x%x.\n", bp->b_bcount);
-#ifdef DDB
-                       Debugger();
-#endif
-               }
-#endif
-               bp->b_bcount = MAX_DMA_LEN;
-       }
-       return (minphys(bp));
-}
-
-
-#define CSR_WANT (SI_CSR_SBC_IP | SI_CSR_DMA_IP | \
-       SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR )
-
-static int si_intrCount = 0;
-static int lastCSR = 0;
-
-integrate int
-si_intr(arg)
-       void *arg; 
-{
-       struct ncr5380_softc *ncr_sc = arg;
-       struct si_softc *sc = arg;
-       int count, claimed;
-
-       count = ++si_intrCount;
-       trace(("%s: si-intr(%d).....\n", ncr_sc->sc_dev.dv_xname, count));
-
-#ifdef DEBUG
-       /*
-        * Each DMA interrupt is followed by one spurious(?) interrupt.
-        * if (ncr_sc->sc_state & NCR_WORKING == 0) we know, that the
-        * interrupt was not claimed by the higher-level routine, so that
-        * it might be save to ignore these...
-        */
-       if ((ncr_sc->sc_state & NCR_DOINGDMA) == 0) {
-               printf("spurious(%d): %x, %d, status=%b\n", count,
-                      sc->sc_dflags, ncr_sc->sc_ncmds,
-                      *ncr_sc->sci_csr, NCR5380_CSRBITS);
-       }
-#endif
-       /*
-        * If there was a DMA operation in progress, now it's no longer
-        * active, since whatever caused the interrupt also interrupted
-        * the DMA operation. Thus accessing the registers now doesn't
-        * harm anything which is not yet broken...
-        */
-       debug(("si_intr(status: %x, dma-count: %d)\n", 
-              *ncr_sc->sci_csr, *sc->sc_dcreg));
-
-       /*
-        * First check for DMA errors / incomplete transfers
-        * If operation was read/data-in, the copy data from buffer
-        */
-       if (ncr_sc->sc_state & NCR_DOINGDMA) {
-               struct sci_req *sr = ncr_sc->sc_current;
-               struct si_dma_handle *dh = sr->sr_dma_hand;
-               int resid, ntrans;
-
-               resid = *sc->sc_dcreg;
-               if (resid == 1 && sc->sc_xflags) {
-                 debug(("correcting resid...\n"));
-                 resid = 0;
-               }
-               ntrans = dh->dh_xlen + resid;
-               if (resid == 0) {
-                       if ((dh->dh_flags & SIDH_OUT) == 0) {
-                               si_dmaToggleLock(ncr_sc,
-                                                VSDMA_DMABUSY, VSDMA_RDBUF);
-                               bcopy(sc->sc_dbase, dh->dh_dvma, ntrans);
-                               si_dmaToggleLock(ncr_sc,
-                                                VSDMA_RDBUF, VSDMA_DMABUSY);
-                               dh->dh_flags |= SIDH_DONE;
-                       }
-               }
-               else {
-#ifdef DEBUG
-                       int csr = *ncr_sc->sci_csr;
-                       printf("DMA incomplete (%d/%d) status = %b\n",
-                              ntrans, resid, csr, NCR5380_CSRBITS);
-                       if(csr != lastCSR) {
-                               int k = (csr & ~lastCSR) | (~csr & lastCSR);
-                               debug(("Changed status bits: %b\n",
-                                      k, NCR5380_CSRBITS));
-                               lastCSR = csr & 0xFF;
-                       }
-#endif
-                       printf("DMA incomplete: ntrans=%d/%d, lock=%x\n", 
-                              ntrans, dh->dh_xlen, sc->sc_dflags);
-                       ncr_sc->sc_state |= NCR_ABORTING;
-               }
-
-               if ((sc->sc_dflags & VSDMA_BLOCKED) == 0) {
-                       printf("not blocked during DMA.\n");
-               }
-               sc->sc_dflags &= ~VSDMA_BLOCKED;
-               si_dmaReleaseBus(ncr_sc, VSDMA_DMABUSY);
-       }
-       if ((sc->sc_dflags & VSDMA_BLOCKED) != 0) {
-               printf("blocked while not doing DMA.\n");
-               sc->sc_dflags &= ~VSDMA_BLOCKED;
-       }
-
-       /*
-        * Now, whatever it was, let the ncr5380sbc routine handle it...
-        */
-       claimed = ncr5380_intr(ncr_sc);
-#ifdef DEBUG
-       if (!claimed) {
-               printf("si_intr: spurious from SBC\n");
-               if (si_debug & 4) {
-                       Debugger();     /* XXX */
-               }
-       }
-#endif
-       trace(("%s: si-intr(%d) done, claimed=%d\n", 
-              ncr_sc->sc_dev.dv_xname, count, claimed));
-       return (claimed);
-}
-
-
-integrate void
-si_reset_adapter(struct ncr5380_softc *ncr_sc)
+/*
+ * Adjust the max transfer size. The DMA buffer is only 16k on VS2000.
+ */
+static void
+si_minphys(bp)
+       struct buf *bp;
 {
-       struct si_softc *sc = (struct si_softc *)ncr_sc;
-       volatile struct si_regs *si = sc->sc_regs;
-
-#ifdef DEBUG
-       if (si_debug) {
-               printf("si_reset_adapter\n");
-       }
-#endif
-       SCI_CLR_INTR(ncr_sc);
+       if ((vax_boardtype == VAX_BTYP_410) && (bp->b_bcount > (16*1024)))
+               bp->b_bcount = (16*1024);
+       else if (bp->b_bcount > MAXPHYS)
+               bp->b_bcount = MAXPHYS;
 }
 
-
-/*****************************************************************
- * Common functions for DMA
- ****************************************************************/
-
-/*
- * Allocate a DMA handle and put it in sc->sc_dma.  Prepare
- * for DMA transfer.  On the Sun3, this means mapping the buffer
- * into DVMA space.  dvma_mapin() flushes the cache for us.
- */
 void
 si_dma_alloc(ncr_sc)
        struct ncr5380_softc *ncr_sc;
@@ -628,418 +268,70 @@ si_dma_alloc(ncr_sc)
        struct si_softc *sc = (struct si_softc *)ncr_sc;
        struct sci_req *sr = ncr_sc->sc_current;
        struct scsi_xfer *xs = sr->sr_xs;
-       struct buf *bp = sr->sr_xs->bp;
        struct si_dma_handle *dh;
-       int i, xlen;
-       u_long addr;
+       int xlen, i;
 
-       trace (("si_dma_alloc()\n"));
-
-#ifdef DIAGNOSTIC
+#ifdef DIAGNOSTIC
        if (sr->sr_dma_hand != NULL)
                panic("si_dma_alloc: already have DMA handle");
 #endif
 
-       addr = (u_long) ncr_sc->sc_dataptr;
-       debug(("addr=%x, dataptr=%x\n", addr, ncr_sc->sc_dataptr));
+       /* Polled transfers shouldn't allocate a DMA handle. */
+       if (sr->sr_flags & SR_IMMED)
+               return;
+
        xlen = ncr_sc->sc_datalen;
 
        /* Make sure our caller checked sc_min_dma_len. */
        if (xlen < MIN_DMA_LEN)
-               panic("si_dma_alloc: xlen=0x%x", xlen);
+               panic("si_dma_alloc: len=0x%x\n", xlen);
 
        /*
-        * Never attempt single transfers of more than 63k, because
-        * our count register may be only 16 bits (an OBIO adapter).
-        * This should never happen since already bounded by minphys().
-        * XXX - Should just segment these...
+        * Find free PDMA handle.  Guaranteed to find one since we
+        * have as many PDMA handles as the driver has processes.
+        * (instances?)
         */
-       if (xlen > MAX_DMA_LEN) {
-#ifdef DEBUG
-               printf("si_dma_alloc: excessive xlen=0x%x\n", xlen);
-               Debugger();
-#endif
-               ncr_sc->sc_datalen = xlen = MAX_DMA_LEN;
-       }
-
-       /* Find free DMA handle.  Guaranteed to find one since we have
-          as many DMA handles as the driver has processes. */
-       for (i = 0; i < SCI_OPENINGS; i++) {
-               if ((sc->sc_dma[i].dh_flags & SIDH_BUSY) == 0)
+        for (i = 0; i < SCI_OPENINGS; i++) {
+               if ((sc->ncr_dma[i].dh_flags & SIDH_BUSY) == 0)
                        goto found;
        }
-       panic("si: no free DMA handles.");
+       panic("sbc: no free PDMA handles");
 found:
-
-       dh = &sc->sc_dma[i];
+       dh = &sc->ncr_dma[i];
        dh->dh_flags = SIDH_BUSY;
-       dh->dh_addr = (u_char*) addr;
-       dh->dh_maplen  = xlen;
-       dh->dh_xlen  = xlen;
-       dh->dh_dvma = 0;
+       dh->dh_addr = ncr_sc->sc_dataptr;
+       dh->dh_len = xlen;
+       dh->dh_proc = xs->bp->b_proc;
 
-       /* Copy the "write" flag for convenience. */
+       /* Remember dest buffer parameters */
        if (xs->flags & SCSI_DATA_OUT)
                dh->dh_flags |= SIDH_OUT;
 
-#if 1
-       /*
-        * If the buffer has the flag B_PHYS, the the address specified
-        * in the buffer is a user-space address and we need to remap
-        * this address into kernel space so that using this buffer
-        * within the interrupt routine will work.
-        * If it's already a kernel space address, we need to make sure
-        * that all pages are in-core. the mapin() routine takes care
-        * of that.
-        */
-       if (bp && (bp->b_flags & B_PHYS))
-               dh->dh_flags |= SIDH_PHYS;
-#endif
-       
-       if (!bp) {
-               printf("ncr.c: struct buf *bp is null-pointer.\n");
-               dh->dh_flags = 0;
-               return;
-       }
-       if (bp->b_bcount < 0 || bp->b_bcount > MAX_DMA_LEN) {
-               printf("ncr.c: invalid bcount %d (0x%x)\n", 
-                      bp->b_bcount, bp->b_bcount);
-               dh->dh_flags = 0;
-               return;
-       }
-       dh->dh_dvma = bp->b_data;
-#if 0
-       /*
-        * mapping of user-space addresses is no longer neccessary, now
-        * that the vmapbuf/vunmapbuf routines exist. Now the higher-level
-        * driver already cares for the mapping!
-        */
-       if (bp->b_flags & B_PHYS) {
-               xdebug(("not mapping in... %x/%x %x\n", bp->b_saveaddr, 
-                       bp->b_data, bp->b_bcount));
-#ifdef USE_VMAPBUF
-               dh->dh_addr = bp->b_data;
-               dh->dh_maplen = bp->b_bcount;
-               vmapbuf(bp, bp->b_bcount);
-               dh->dh_dvma = bp->b_data;
-#else
-               dh->dh_dvma = (u_char*)vsdma_mapin(bp);
-#endif
-               xdebug(("addr %x, maplen %d, dvma %x, bcount %d, dir %s\n", 
-                      dh->dh_addr, dh->dh_maplen, dh->dh_dvma, bp->b_bcount,
-                      (dh->dh_flags & SIDH_OUT ? "OUT" : "IN")));
-       }
-#endif
-       /* success */
        sr->sr_dma_hand = dh;
-
-       return;
 }
 
-
 void
 si_dma_free(ncr_sc)
        struct ncr5380_softc *ncr_sc;
 {
-       struct si_softc *sc = (struct si_softc *)ncr_sc;
        struct sci_req *sr = ncr_sc->sc_current;
-       struct scsi_xfer *xs = sr->sr_xs;
-       struct buf *bp = sr->sr_xs->bp;
        struct si_dma_handle *dh = sr->sr_dma_hand;
 
-       trace (("si_dma_free()\n"));
-
-#ifdef DIAGNOSTIC
-       if (dh == NULL)
-               panic("si_dma_free: no DMA handle");
-#endif
-
-       if (ncr_sc->sc_state & NCR_DOINGDMA)
-               panic("si_dma_free: free while in progress");
-
-       if (dh->dh_flags & SIDH_BUSY) {
-#if 0
-               debug(("bp->b_flags=0x%x\n", bp->b_flags));
-               if (bp->b_flags & B_PHYS) {
-#ifdef USE_VMAPBUF
-                       printf("not unmapping(%x/%x %x/%x %d/%d)...\n", 
-                              dh->dh_addr, dh->dh_dvma,
-                              bp->b_saveaddr, bp->b_data,
-                              bp->b_bcount, dh->dh_maplen);
-                       /* vunmapbuf(bp, dh->dh_maplen); */
-                       printf("done.\n");
-#endif
-                       dh->dh_dvma = 0;
-               }
-#endif
+       if (dh->dh_flags & SIDH_BUSY)
                dh->dh_flags = 0;
-       }
-       sr->sr_dma_hand = NULL;
-}
-
-
-/*
- * REGBUSY and DMABUSY won't collide since the higher-level driver
- * issues intr_on/intr_off before/after doing DMA. The only problem
- * is to handle RDBUF/WRBUF wrt REGBUSY/DMABUSY
- *
- * There might be race-conditions, but for now we don't care for them...
- */
-int 
-si_dmaLockBus(ncr_sc, lt)
-       struct ncr5380_softc *ncr_sc;
-       int lt;                 /* Lock-Type */
-{
-       struct si_softc *sc = (void*)ncr_sc;
-       int timeout = 200;      /* wait .2 seconds max. */
-
-       trace(("si_dmaLockBus(%x), cold: %d, current: %x\n", 
-              lt, cold, sc->sc_dflags));
-
-#ifdef POLL_MODE
-       if (cold)
-               return (0);
-#endif
-
-       if ((ncr_sc->sc_current != NULL) && (lt == VSDMA_REGBUSY)) {
-               printf("trying to use regs while sc_current is set.\n");
-               printf("lt=%x, fl=%x, cur=%x\n", 
-                      lt, sc->sc_dflags, ncr_sc->sc_current);
-       }
-       if ((ncr_sc->sc_current == NULL) && (lt != VSDMA_REGBUSY)) {
-               printf("trying to use/prepare DMA without current.\n");
-               printf("lt=%x, fl=%x, cur=%x\n", 
-                      lt, sc->sc_dflags, ncr_sc->sc_current);
-       }
-
-       if ((sc->sc_dflags & VSDMA_LOCKED) == 0) {
-               struct si_softc *sc = (struct si_softc *)ncr_sc;
-               sc->sc_dflags |= VSDMA_WANTED;
-               vsbus_lockDMA(sc->sc_cfargs);
-               sc->sc_dflags = VSDMA_LOCKED | lt;
-               return (0);
-       }
-
-#if 1
-       while ((sc->sc_dflags & VSDMA_LCKTYPE) != lt) {
-               debug(("busy wait(1)...\n"));
-               if (--timeout == 0) {
-                       printf("timeout in busy-wait(%x %x)\n",
-                              lt, sc->sc_dflags);
-                       sc->sc_dflags &= ~VSDMA_LCKTYPE;
-                       break;
-               }
-               delay(1000);
-       }
-       debug(("busy wait(1) done.\n"));
-       sc->sc_dflags |= lt;
-
-#else
-       if ((sc->sc_dflags & VSDMA_LCKTYPE) != lt) {
-               switch (lt) {
-
-               case VSDMA_RDBUF:
-                       /* sc->sc_dflags |= VSDMA_IWANTED; */
-                       debug(("busy wait(1)...\n"));
-                       while (sc->sc_dflags & 
-                              (VSDMA_WRBUF | VSDMA_DMABUSY)) {
-                               if (--timeout == 0) {
-                                       printf("timeout in busy-wait(1)\n");
-                                       sc->sc_dflags &= ~VSDMA_WRBUF;
-                                       sc->sc_dflags &= ~VSDMA_DMABUSY;
-                               }
-                               delay(1000);
-                       }
-                       /* sc->sc_dflags &= ~VSDMA_IWANTED; */
-                       debug(("busy wait(1) done.\n"));
-                       sc->sc_dflags |= lt;
-                       break;
-
-               case VSDMA_WRBUF:
-                       /* sc->sc_dflags |= VSDMA_IWANTED; */
-                       debug(("busy wait(2)...\n"));
-                       while (sc->sc_dflags & 
-                              (VSDMA_RDBUF | VSDMA_DMABUSY)) {
-                               if (--timeout == 0) {
-                                       printf("timeout in busy-wait(2)\n");
-                                       sc->sc_dflags &= ~VSDMA_RDBUF;
-                                       sc->sc_dflags &= ~VSDMA_DMABUSY;
-                               }
-                               delay(1000);
-                       }
-                       /* sc->sc_dflags &= ~VSDMA_IWANTED; */
-                       debug(("busy wait(2) done.\n"));
-                       sc->sc_dflags |= lt;
-                       break;
-
-               case VSDMA_DMABUSY:
-                       /* sc->sc_dflags |= VSDMA_IWANTED; */
-                       debug(("busy wait(3)...\n"));
-                       while (sc->sc_dflags & 
-                              (VSDMA_RDBUF | VSDMA_WRBUF)) {
-                               if (--timeout == 0) {
-                                       printf("timeout in busy-wait(3)\n");
-                                       sc->sc_dflags &= ~VSDMA_RDBUF;
-                                       sc->sc_dflags &= ~VSDMA_WRBUF;
-                               }
-                               delay(1000);
-                       }
-                       /* sc->sc_dflags &= ~VSDMA_IWANTED; */
-                       debug(("busy wait(3) done.\n"));
-                       sc->sc_dflags |= lt;
-                       break;
-
-               case VSDMA_REGBUSY:
-                       /* sc->sc_dflags |= VSDMA_IWANTED; */
-                       debug(("busy wait(4)...\n"));
-                       while (sc->sc_dflags & 
-                              (VSDMA_RDBUF | VSDMA_WRBUF | VSDMA_DMABUSY)) {
-                               if (--timeout == 0) {
-                                       printf("timeout in busy-wait(4)\n");
-                                       sc->sc_dflags &= ~VSDMA_RDBUF;
-                                       sc->sc_dflags &= ~VSDMA_WRBUF;
-                                       sc->sc_dflags &= ~VSDMA_DMABUSY;
-                               }
-                               delay(1000);
-                       }
-                       /* sc->sc_dflags &= ~VSDMA_IWANTED; */
-                       debug(("busy wait(4) done.\n"));
-                       sc->sc_dflags |= lt;
-                       break;
-
-               default:
-                       printf("illegal lockType %x in si_dmaLockBus()\n");
-               }
-       }
        else
-               printf("already locked. (%x/%x)\n", lt, sc->sc_dflags);
-#endif
-       if (sc->sc_dflags & lt) /* successfully locked for this type */
-               return (0);
-
-       printf("spurious %x in si_dmaLockBus(%x)\n", lt, sc->sc_dflags);
-}
-
-/*
- * the lock of this type is no longer needed. If all (internal) locks are
- * released, release the DMA bus.
- */
-int 
-si_dmaReleaseBus(ncr_sc, lt)
-       struct ncr5380_softc *ncr_sc;
-       int lt;                 /* Lock-Type */
-{
-       struct si_softc *sc = (void*)ncr_sc;
-
-       trace(("si_dmaReleaseBus(%x), cold: %d, current: %x\n", 
-              lt, cold, sc->sc_dflags));
-
-#ifdef POLL_MODE
-       if (cold)
-               return (0);
-#endif
-
-       if ((sc->sc_dflags & VSDMA_LCKTYPE) == lt) {
-               sc->sc_dflags &= ~lt;
-       }
-       else
-               printf("trying to release %x while flags = %x\n", lt,
-                      sc->sc_dflags);
-
-       if (sc->sc_dflags == VSDMA_LOCKED) {    /* no longer needed */
-               struct si_softc *sc = (struct si_softc *)ncr_sc;
-               vsbus_unlockDMA(sc->sc_cfargs);
-               sc->sc_dflags = 0;
-               return (0);
-       }
-}
+               printf("si_dma_free: free'ing unused buffer\n");
 
-/*
- * Just toggle the type of lock without releasing the lock...
- * This is usually needed before/after bcopy() to/from DMA-buffer
- */
-int 
-si_dmaToggleLock(ncr_sc, lt1, lt2)
-       struct ncr5380_softc *ncr_sc;
-       int lt1, lt2;           /* Lock-Type */
-{
-       struct si_softc *sc = (void*)ncr_sc;
-
-#ifdef POLL_MODE
-       if (cold)
-               return (0);
-#endif
-
-       if (((sc->sc_dflags & lt1) != 0) &&
-           ((sc->sc_dflags & lt2) == 0)) {
-               sc->sc_dflags |= lt2;
-               sc->sc_dflags &= ~lt1;
-               return (0);
-       }
-       printf("cannot toggle locking from %x to %x (current = %x)\n",
-              lt1, lt2, sc->sc_dflags);
-}
-
-/*
- * This is called when the bus is going idle,
- * so we want to enable the SBC interrupts.
- * That is controlled by the DMA enable!
- * Who would have guessed!
- * What a NASTY trick!
- */
-void
-si_intr_on(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
-{
-       si_dmaReleaseBus(ncr_sc, VSDMA_REGBUSY);
-}
-
-/*
- * This is called when the bus is idle and we are
- * about to start playing with the SBC chip.
- *
- * VS2000 note: we have four kinds of access which are mutually exclusive: 
- * - access to the NCR5380 registers
- * - access to the HDC9224 registers
- * - access to the DMA area 
- * - doing DMA
- */
-void
-si_intr_off(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
-{
-       si_dmaLockBus(ncr_sc, VSDMA_REGBUSY);
+       sr->sr_dma_hand = NULL;
 }
 
-/*****************************************************************
- * VME functions for DMA
- ****************************************************************/
-
-
-/*
- * This function is called during the COMMAND or MSG_IN phase
- * that preceeds a DATA_IN or DATA_OUT phase, in case we need
- * to setup the DMA engine before the bus enters a DATA phase.
- *
- * XXX: The VME adapter appears to suppress SBC interrupts
- * when the FIFO is not empty or the FIFO count is non-zero!
- *
- * On the VME version we just clear the DMA count and address
- * here (to make sure it stays idle) and do the real setup
- * later, in dma_start.
- */
 void
 si_dma_setup(ncr_sc)
        struct ncr5380_softc *ncr_sc;
 {
-       trace (("si_dma_setup(ncr_sc) !!!\n"));
-
-       /*
-        * VS2000: nothing to do ...
-        */
+       /* Do nothing here */
 }
 
-
 void
 si_dma_start(ncr_sc)
        struct ncr5380_softc *ncr_sc;
@@ -1047,125 +339,66 @@ si_dma_start(ncr_sc)
        struct si_softc *sc = (struct si_softc *)ncr_sc;
        struct sci_req *sr = ncr_sc->sc_current;
        struct si_dma_handle *dh = sr->sr_dma_hand;
-       volatile struct si_regs *si = sc->sc_regs;
-       long data_pa;
-       int xlen;
-
-       trace(("si_dma_start(%x)\n", sr->sr_dma_hand));
-
-       /*
-        * we always transfer from/to base of DMA-area,
-        * thus the DMA-address is always the same, only size
-        * and direction matter/differ on VS2000
-        */
-
-       debug(("ncr_sc->sc_datalen = %d\n", ncr_sc->sc_datalen));
-       xlen = ncr_sc->sc_datalen;
-       dh->dh_xlen = xlen;
 
        /*
-        * VS2000 has a fixed 16KB-area where DMA is restricted to. 
-        * All DMA-addresses are relative to this base: KA410_DMA_BASE
-        * Thus we need to copy the data into this area when writing,
-        * or copy from this area when reading. (kind of bounce-buffer)
+        * Set the VAX-DMA-specific registers, and copy the data if
+        * it is directed "outbound".
         */
-
-       /* Set direction (send/recv) */
        if (dh->dh_flags & SIDH_OUT) {
-               /*
-                * We know that we are called while intr_off (regs locked)
-                * thus we toggle the lock from REGBUSY to WRBUF
-                * also we set the BLOCKIT flag, so that the locking of
-                * the DMA bus won't be released to the HDC9224...
-                */
-               debug(("preparing msg-out (bcopy)\n"));
-               si_dmaToggleLock(ncr_sc, VSDMA_REGBUSY, VSDMA_WRBUF);
-               bcopy(dh->dh_dvma, sc->sc_dbase, xlen);
-               si_dmaToggleLock(ncr_sc, VSDMA_WRBUF, VSDMA_REGBUSY);
-               *sc->sc_ddreg = DMA_DIR_OUT;
-       } 
-       else {
-               debug(("preparing data-in (bzero)\n"));
-               /* bzero(sc->sc_dbase, xlen); */
-               *sc->sc_ddreg = DMA_DIR_IN;
-       }
-       sc->sc_dflags |= VSDMA_BLOCKED;
-
-       *sc->sc_dareg = DMA_ADDR_HBYTE; /* high byte (6 bits) */
-       *sc->sc_dareg = DMA_ADDR_LBYTE; /* low byte */
-       *sc->sc_dcreg = 0 - xlen; /* bertram XXX */
-
-#ifdef DEBUG
-       if (si_debug & 2) {
-               printf("si_dma_start: dh=0x%x, pa=0x%x, xlen=%d, creg=0x%x\n",
-                          dh, data_pa, xlen, *sc->sc_dcreg);
-       }
-#endif
-
-#ifdef POLL_MODE
-       debug(("dma_start: cold=%d\n", cold));
-       if (cold) {
-               *sc->intmsk &= ~sc->intbit;
-               *sc->intclr = sc->intbit;
+               if ((vaddr_t)dh->dh_addr & KERNBASE)
+                       bcopy(dh->dh_addr, sc->ncr_addr, dh->dh_len);
+               else
+                       vsbus_copyfromproc(dh->dh_proc, dh->dh_addr,
+                           sc->ncr_addr, dh->dh_len);
+               bus_space_write_1(sc->sc_regt, sc->sc_regh,
+                   sc->ncr_dmadir, 0);
+       } else {
+               bus_space_write_1(sc->sc_regt, sc->sc_regh,
+                   sc->ncr_dmadir, 1);
        }
-       else
-               *sc->intmsk |= sc->intbit;
-#endif
+       bus_space_write_4(sc->sc_regt, sc->sc_regh,
+           sc->ncr_dmacount, -dh->dh_len);
+       bus_space_write_4(sc->sc_regt, sc->sc_regh,
+           sc->ncr_dmaaddr, sc->ncr_off);
        /*
-        * Acknowledge the phase change.  (After DMA setup!)
-        * Put the SBIC into DMA mode, and start the transfer.
+        * Now from the 5380-internal DMA registers.
         */
-       si_dmaToggleLock(ncr_sc, VSDMA_REGBUSY, VSDMA_DMABUSY);
        if (dh->dh_flags & SIDH_OUT) {
-               *ncr_sc->sci_tcmd = PHASE_DATA_OUT;
-               SCI_CLR_INTR(ncr_sc);
-               *ncr_sc->sci_icmd = SCI_ICMD_DATA;
-               *ncr_sc->sci_mode |= (SCI_MODE_DMA | SCI_MODE_DMA_IE);
-               *ncr_sc->sci_dma_send = 0;      /* start it */
+               NCR5380_WRITE(sc, sci_tcmd, PHASE_DATA_OUT);
+               NCR5380_WRITE(sc, sci_icmd, SCI_ICMD_DATA);
+               NCR5380_WRITE(sc, sci_mode, NCR5380_READ(sc, sci_mode)
+                   | SCI_MODE_DMA | SCI_MODE_DMA_IE);
+               NCR5380_WRITE(sc, sci_dma_send, 0);
        } else {
-               *ncr_sc->sci_tcmd = PHASE_DATA_IN;
-               SCI_CLR_INTR(ncr_sc);
-               *ncr_sc->sci_icmd = 0;
-               *ncr_sc->sci_mode |= (SCI_MODE_DMA | SCI_MODE_DMA_IE);
-               *ncr_sc->sci_irecv = 0; /* start it */
+               NCR5380_WRITE(sc, sci_tcmd, PHASE_DATA_IN);
+               NCR5380_WRITE(sc, sci_icmd, 0);
+               NCR5380_WRITE(sc, sci_mode, NCR5380_READ(sc, sci_mode)
+                   | SCI_MODE_DMA | SCI_MODE_DMA_IE);
+               NCR5380_WRITE(sc, sci_irecv, 0);
        }
        ncr_sc->sc_state |= NCR_DOINGDMA;
-       /*
-        * having a delay (eg. printf) here, seems to solve the problem.
-        * Isn't that strange ????
-        * Maybe the higher-level driver accesses one of the registers of
-        * the controller while DMA is in progress. Having a long enough
-        * delay here might prevent/delay this access until DMA bus is
-        * free again...
-        *
-        * The instruction ++++ printf("DMA started.\n"); ++++ 
-        * is long/slow enough, to make the SSCI driver work. Thus we
-        * try to find a delay() long/slow enough to do the same. The
-        * argument to this delay is relative to the transfer-count.
-        */
-       delay(3*xlen/4);                /* XXX solve this problem!!! XXX */
-
-#ifdef DEBUG
-       if (si_debug & 2) {
-               printf("si_dma_start: started, flags=0x%x\n",
-                          ncr_sc->sc_state);
-       }
-#endif
 }
 
-
+/*
+ * When?
+ */
 void
-si_vme_dma_eop(ncr_sc)
+si_dma_poll(ncr_sc)
        struct ncr5380_softc *ncr_sc;
 {
-       trace (("si_vme_dma_eop() !!!\n"));
-       /* Not needed - DMA was stopped prior to examining sci_csr */
+       printf("si_dma_poll\n");
 }
 
 /*
- * si_dma_stop() has now become almost a nop-routine, since DMA-buffer
- * has already been read within si_intr(), so there's nothing left to do.
+ * When?
  */
+void
+si_dma_eop(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       printf("si_dma_eop\n");
+}
+
 void
 si_dma_stop(ncr_sc)
        struct ncr5380_softc *ncr_sc;
@@ -1173,120 +406,61 @@ si_dma_stop(ncr_sc)
        struct si_softc *sc = (struct si_softc *)ncr_sc;
        struct sci_req *sr = ncr_sc->sc_current;
        struct si_dma_handle *dh = sr->sr_dma_hand;
-       volatile struct si_regs *si = sc->sc_regs;
-       int resid, ntrans;
+       int count, i;
 
-       if ((ncr_sc->sc_state & NCR_DOINGDMA) == 0) {
-#ifdef DEBUG
-               printf("si_dma_stop: dma not running\n");
-#endif
-               return;
-       }
-       ncr_sc->sc_state &= ~NCR_DOINGDMA;
-
-       /* Note that timeout may have set the error flag. */
-       if (ncr_sc->sc_state & NCR_ABORTING) {
-               printf("si_dma_stop: timeout?\n");
-               goto out;
-       }
+       if (ncr_sc->sc_state & NCR_DOINGDMA) 
+               ncr_sc->sc_state &= ~NCR_DOINGDMA;
 
        /*
-        * Now try to figure out how much actually transferred
+        * Sometimes the FIFO buffer isn't drained when the
+        * interrupt is posted. Just loop here and hope that
+        * it will drain soon.
         */
-       si_dmaLockBus(ncr_sc, VSDMA_DMABUSY);
-       si_dmaToggleLock(ncr_sc, VSDMA_DMABUSY, VSDMA_REGBUSY);
-       resid = *sc->sc_dcreg;
-       /* 
-        * XXX: don't correct at two places !!! 
-        */
-       if (resid == 1 && sc->sc_xflags) {      
-               resid = 0;
-       }
-       ntrans = dh->dh_xlen + resid;
-       if (resid != 0) 
-               printf("resid=%d, xlen=%d, ntrans=%d\n", 
-                      resid, dh->dh_xlen, ntrans);
-
-#ifdef DEBUG
-       if (si_debug & 2) {
-               printf("si_dma_stop: resid=0x%x ntrans=0x%x\n",
-                      resid, ntrans);
-       }
-#endif
-
-       if (ntrans < MIN_DMA_LEN) {
-               printf("si: fifo count: 0x%x\n", resid);
-               ncr_sc->sc_state |= NCR_ABORTING;
-               goto out;
+       for (i = 0; i < 20000; i++) {
+               count = bus_space_read_4(sc->sc_regt,
+                   sc->sc_regh, sc->ncr_dmacount);
+               if (count == 0)
+                       break;
+               DELAY(100);
        }
-       if (ntrans > ncr_sc->sc_datalen)
-               panic("si_dma_stop: excess transfer");
+       if (count == 0) {
+               if (((dh->dh_flags & SIDH_OUT) == 0)) {
+                       if ((vaddr_t)dh->dh_addr & KERNBASE)
+                               bcopy(sc->ncr_addr, dh->dh_addr, dh->dh_len);
+                       else
+                               vsbus_copytoproc(dh->dh_proc, sc->ncr_addr,
+                                   dh->dh_addr, dh->dh_len);
 
-       /*
-        * On VS2000 in case of a READ-operation, we must now copy 
-        * the buffer-contents to the destination-address!
-        */
-       if ((dh->dh_flags & SIDH_OUT) == 0 &&
-           (dh->dh_flags & SIDH_DONE) == 0) {
-               printf("DMA buffer not yet copied.\n");
-               si_dmaToggleLock(ncr_sc, VSDMA_REGBUSY, VSDMA_RDBUF);
-               bcopy(sc->sc_dbase, dh->dh_dvma, ntrans);
-               si_dmaToggleLock(ncr_sc, VSDMA_RDBUF, VSDMA_REGBUSY);
+               }
+               ncr_sc->sc_dataptr += dh->dh_len;
+               ncr_sc->sc_datalen -= dh->dh_len;
        }
-       si_dmaReleaseBus(ncr_sc, VSDMA_REGBUSY);
-
-       /* Adjust data pointer */
-       ncr_sc->sc_dataptr += ntrans;
-       ncr_sc->sc_datalen -= ntrans;
-
-out:
-       si_dmaLockBus(ncr_sc, VSDMA_DMABUSY);
 
-       /* Put SBIC back in PIO mode. */
-       *ncr_sc->sci_mode &= ~(SCI_MODE_DMA | SCI_MODE_DMA_IE);
-       *ncr_sc->sci_icmd = 0;
-
-       si_dmaReleaseBus(ncr_sc, VSDMA_DMABUSY);
+       NCR5380_WRITE(sc, sci_mode, NCR5380_READ(sc, sci_mode) &
+           ~(SCI_MODE_DMA | SCI_MODE_DMA_IE));
+       NCR5380_WRITE(sc, sci_icmd, 0);
 }
 
-/*
- * Poll (spin-wait) for DMA completion.
- * Called right after xx_dma_start(), and
- * xx_dma_stop() will be called next.
- */
-void
-si_dma_poll(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
+int 
+sd_getdev (adaptor, controller, part, unit, uname) 
+       int adaptor, controller, part, unit;
+       char **uname;
 {
-       struct si_softc *sc = (struct si_softc *)ncr_sc;
-       struct sci_req *sr = ncr_sc->sc_current;
-       struct si_dma_handle *dh = sr->sr_dma_hand;
-       int i, timeout;
-
-       if (! cold) 
-               printf("spurious call of DMA-poll ???");
-
-#ifdef POLL_MODE
-
-       delay(10000);
-       trace(("si_dma_poll(%x)\n", *sc->sc_dcreg));
+       struct sd_softc *sd;
+       struct scsi_link *sl;
+       int i;
 
-       /*
-        * interrupt-request has been cleared by dma_start, thus
-        * we do nothing else but wait for the intreq to reappear...
-        */
+       for (i = 0; i < sd_cd.cd_ndevs; i++) {
+               if ((sd = sd_cd.cd_devs[i]) == 0)
+                       continue;
 
-       timeout = 5000;
-       for (i=0; i<timeout; i++) {
-               if (*sc->intreq & sc->intbit)
-                       break;
-               delay(100);
-       }
-       if ((*sc->intreq & sc->intbit) == 0) {
-               printf("si: DMA timeout (while polling)\n");
-               /* Indicate timeout as MI code would. */
-               sr->sr_flags |= SR_OVERDUE;
+               sl = sd->sc_link;
+               if (sl->target == unit && sl->scsibus == adaptor && 
+                       sl->lun == part) {
+                       *uname = sd->sc_dev.dv_xname;
+                       return i;
+               }
        }
-#endif
-       return;
+       return -1;
 }
+
index 0137c29..d66f4ed 100644 (file)
@@ -1,7 +1,7 @@
-/*     $OpenBSD: vsbus.c,v 1.3 1997/09/10 12:08:37 maja Exp $ */
-/*     $NetBSD: vsbus.c,v 1.6 1997/03/22 23:05:31 ragge Exp $ */
+/*     $OpenBSD: vsbus.c,v 1.4 2000/04/27 00:52:07 bjc Exp $ */
+/*     $NetBSD: vsbus.c,v 1.20 1999/10/22 21:10:12 ragge Exp $ */
 /*
- * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
+ * Copyright (c) 1996, 1999 Ludd, University of Lule}, Sweden.
  * All rights reserved.
  *
  * This code is derived from software contributed to Ludd by Bertram Barth.
 #include <sys/syslog.h>
 #include <sys/stat.h>
 
+#include <vm/vm.h>
+
+#define        _VAX_BUS_DMA_PRIVATE
+#include <machine/bus.h>
 #include <machine/pte.h>
 #include <machine/sid.h>
 #include <machine/scb.h>
 
 #include <machine/uvax.h>
 #include <machine/ka410.h>
+#include <machine/ka420.h>
 #include <machine/ka43.h>
 
 #include <machine/vsbus.h>
 
-#define trace(x)
-#define debug(x)
-
-int    vsbus_match     __P((struct device *, void *, void *));
+int            vsbus_match             __P((struct device *, struct cfdata *, void *));
 void   vsbus_attach    __P((struct device *, struct device *, void *));
-int    vsbus_print     __P((void *, const char *));
+int            vsbus_print             __P((void *, const char *));
+int            vsbus_search    __P((struct device *, void *, void *));
 
 void   ka410_attach    __P((struct device *, struct device *, void *));
 void   ka43_attach     __P((struct device *, struct device *, void *));
 
-struct cfdriver vsbus_cd = { 
-       NULL, "vsbus", DV_DULL 
-};
-struct cfattach vsbus_ca = { 
-       sizeof(struct device), vsbus_match, vsbus_attach
+struct vax_bus_dma_tag vsbus_bus_dma_tag = {
+       0,
+       0,
+       0,
+       0,
+       0,
+       0,
+       _bus_dmamap_create,
+       _bus_dmamap_destroy,
+       _bus_dmamap_load,
+       _bus_dmamap_load_mbuf,
+       _bus_dmamap_load_uio,
+       _bus_dmamap_load_raw,
+       _bus_dmamap_unload,
+       _bus_dmamap_sync,
+       _bus_dmamem_alloc,
+       _bus_dmamem_free,
+       _bus_dmamem_map,
+       _bus_dmamem_unmap,
+       _bus_dmamem_mmap,
 };
 
-/*
-void   vsbus_intr_register __P((struct confargs *ca, int (*)(void*), void*));
-void   vsbus_intr_unregister __P((struct confargs *));
-*/
-
-void   vsbus_intr_dispatch __P((int i));
-
-#define VSBUS_MAXDEVS  8
-#define VSBUS_MAXINTR  8
-
-struct confargs *vsbus_devs = NULL;
-
-#ifdef VAX410
-struct confargs ka410_devs[] = {
-       /* name         intslot intpri intvec   intbit  ioaddr  */
-       { "dc",         7,      7,      0x2C0,  (1<<7), KA410_SER_BASE, 
-                       6,      6,      0x2C4,  (1<<6), 0x01,           },
-       { "dc (xmit)",  6,      6,      0x2C4,  (1<<6), KA410_SER_BASE, },
-       { "le",         5,      5,      0x250,  (1<<5), KA410_LAN_BASE, 
-                       KA410_NWA_BASE, 0x00,                           },
-       { "ncr",        1,      1,      0x3F8,  (1<<1), KA410_SCS_BASE,
-                       KA410_SCS_DADR, KA410_SCS_DCNT, KA410_SCS_DDIR,
-                       KA410_DMA_BASE, KA410_DMA_SIZE, 0x00,   0x07,   },
-       { "hdc",        0,      0,      0x3FC,  (1<<0), KA410_DKC_BASE, 
-                       0, 0, 0, 
-                       KA410_DMA_BASE, KA410_DMA_SIZE, 0x00,           },
-#if 0
-       { "dc (recv)",  7,      7,      0x2C0,  (1<<7), KA410_SER_BASE, },
-       { "dc (xmit)",  6,      6,      0x2C4,  (1<<6), KA410_SER_BASE, },
-       { "hdc9224",    0,      0,      0x3FC,  (1<<0), KA410_DKC_BASE, },
-       { "ncr5380",    1,      1,      0x3F8,  (1<<1), KA410_SCS_BASE, },
-       { "am7990",     5,      5,      0x250,  (1<<5), KA410_LAN_BASE, },
-       { "NETOPT",     4,      4,      0x254,  (1<<4), KA410_LAN_BASE, },
-#endif
-       { "" },
+struct cfattach vsbus_ca = { 
+       sizeof(struct vsbus_softc), (cfmatch_t)vsbus_match, vsbus_attach
 };
 
-/*
- * It would be better if we could use the (provided) system config
- * information for each CPU instead of this.
- */
-struct confargs ka420_devs[] = {
-       { "le",         5,      5,      0x250,  (1<<5), KA410_LAN_BASE,
-               KA410_NWA_BASE, 0x00,                                   },
-       { "ncr",        1,      1,      0x3F8,  (1<<1), KA410_SCS_BASE,
-                       KA410_SCS_DADR, KA410_SCS_DCNT, KA410_SCS_DDIR,
-                       KA410_DMA_BASE, KA410_DMA_SIZE, 0x00,   0x07,   },
-       { "ncr",        0,      0,      0x3FC,  (1<<0), 0x200C0180,
-                       0x200C01A0,     0x200C01C0,     0x200C01C4,
-                       KA410_DMA_BASE, KA410_DMA_SIZE, 0x00,   0x07,   },
-       { "" },
+struct  cfdriver vsbus_cd = {
+           NULL, "vsbus", DV_DULL
 };
-#endif
 
-#ifdef VAX43
-struct confargs ka43_devs[] = {
-       /* name         intslot intpri intvec   intbit  ioaddr  */
-       { "dc",         7,      7,      0x2C0,  (1<<7), KA43_SER_BASE,  
-                       6,      6,      0x2C4,  (1<<6), 0x01,           },
-       { "dc (xmit)",  6,      6,      0x2C4,  (1<<6), KA43_SER_BASE,  },
-       { "le",         5,      5,      0x250,  (1<<5), KA43_LAN_BASE,  
-                       KA43_NWA_BASE,  0x00,                           },
-       { "ncr",        1,      1,      0x3F8,  (1<<1), KA43_SC1_BASE,
-                       KA43_SC1_DADR,  KA43_SC1_DCNT,  KA43_SC1_DDIR,  
-                       KA43_DMA_BASE,  KA43_DMA_SIZE,  0x01,   0x06,   },
-       { "ncr",        0,      0,      0x3FC,  (1<<0), KA43_SC2_BASE,
-                       KA43_SC2_DADR,  KA43_SC2_DCNT,  KA43_SC2_DDIR,
-                       KA43_DMA_BASE,  KA43_DMA_SIZE,  0x01,   0x06,   },
-#if 0
-       { "le (2nd)",   4,      4,      0x254,  (1<<4), 0x???,          },
-       { "NETOPT",     4,      4,      0x254,  (1<<4), 0x???,          },
-#endif
-       { "" },
-};
-#endif
+/* dummy interrupt handler for use during autoconf */
+void
+vsbus_intr(arg)
+       void *arg;
+{
+       return;
+}
 
 int
 vsbus_print(aux, name)
        void *aux;
        const char *name;
 {
-       struct confargs *ca = aux;
-
-       trace(("vsbus_print(%x, %s)\n", ca->ca_name, name));
+       struct vsbus_attach_args *va = aux;
 
-       if (name) {
-               printf ("device %s at %s", ca->ca_name, name);
-               return (UNSUPP);
-       }
-       return (UNCONF); 
+       printf(" csr 0x%lx vec 0x%x ipl %x maskbit %d", va->va_paddr,
+           va->va_cvec & 511, va->va_br, va->va_maskno - 1);
+       return(UNCONF); 
 }
 
 int
 vsbus_match(parent, cf, aux)
        struct  device  *parent;
-       void    *cf;
+       struct  cfdata  *cf;
        void    *aux;
 {
-       struct bp_conf *bp = aux;
-       
-       trace(("vsbus_match: bp->type = \"%s\"\n", bp->type));
-
-       if (strcmp(bp->type, "vsbus"))
-               return 0;
-       /*
-        * on machines which can have it, the vsbus is always there
-        */
-       if ((vax_bustype & VAX_VSBUS) == 0)
-               return (0);
-
-       return (1);
-}
-
-#if 1  /*------------------------------------------------------------*/
-#if 1
-#define REG(name)      short name; short X##name##X;
-#else
-#define REG(name)      int name;
-#endif
-static volatile struct {/* base address of DZ-controller: 0x200A0000 */
-  REG(csr);            /* 00 Csr: control/status register */
-  REG(rbuf);           /* 04 Rbuf/Lpr: receive buffer/line param reg. */
-  REG(tcr);            /* 08 Tcr: transmit console register */
-  REG(tdr);            /* 0C Msr/Tdr: modem status reg/transmit data reg */
-  REG(lpr0);           /* 10 Lpr0: */
-  REG(lpr1);           /* 14 Lpr0: */
-  REG(lpr2);           /* 18 Lpr0: */
-  REG(lpr3);           /* 1C Lpr0: */
-} *dz = (void*)0x200A0000; 
-extern int dzcnrint();
-extern int dzcntint();
-int hardclock_count = 0;
-int
-ka410_consintr_enable()
-{
-       vsbus_intr_enable(&ka410_devs[0]);
-       vsbus_intr_enable(&ka410_devs[1]);
-}
-
-int
-ka410_consRecv_intr(p)
-       void *p;
-{
-  /* printf("ka410_consRecv_intr: hc-count=%d\n", hardclock_count); */
-  dzcnrint();
-  /* printf("gencnrint() returned.\n"); */
-  return(0);
-}
-
-int
-ka410_consXmit_intr(p)
-       void *p;
-{
-  /* printf("ka410_consXmit_intr: hc-count=%d\n", hardclock_count); */
-  dzcntint();
-  /* printf("gencntint() returned.\n"); */
-  return(0);
+       if (vax_bustype == VAX_VSBUS)
+               return 1;
+       return 0;
 }
-#endif /*------------------------------------------------------------*/
 
 void
 vsbus_attach(parent, self, aux)
        struct  device  *parent, *self;
        void    *aux;
 {
-       struct confargs *ca;
-       int i;
+       struct  vsbus_softc *sc = (void *)self;
+       int             discard;
+       vaddr_t temp;
 
        printf("\n");
-       trace (("vsbus_attach()\n"));
 
        switch (vax_boardtype) {
-       case VAX_BTYP_420:
-               vsbus_devs = ka420_devs;
-               break;
-
-       case VAX_BTYP_410:
-               vsbus_devs = ka410_devs;
-               break;
-
-       case VAX_BTYP_43:
-       case VAX_BTYP_46:
        case VAX_BTYP_49:
-#ifdef VAX43
-               vsbus_devs = ka43_devs;
-#endif
+               temp = vax_map_physmem(0x25c00000, 1);
+               sc->sc_intreq = (char *)temp + 12;
+               sc->sc_intclr = (char *)temp + 12;
+               sc->sc_intmsk = (char *)temp + 8;
                break;
 
        default:
-               printf ("unsupported boardtype 0x%x in vsbus_attach()\n",
-                       vax_boardtype);
-               return;
+               temp = vax_map_physmem(VS_REGS, 1);
+               sc->sc_intreq = (char *)temp + 15;
+               sc->sc_intclr = (char *)temp + 15;
+               sc->sc_intmsk = (char *)temp + 12;
+               break;
        }
 
        /*
-        * first setup interrupt-table, so that devices can register
-        * their interrupt-routines...
+        * First: find which interrupts we won't care about.
+        * There are interrupts that interrupt on a periodic basic
+        * that we don't want to interfere with the rest of the 
+        * interrupt probing.
         */
-       vsbus_intr_setup();     
+       *sc->sc_intmsk = 0;
+       *sc->sc_intclr = 0xff;
+       DELAY(1000000); /* Wait a second */
+       sc->sc_mask = discard = *sc->sc_intreq;
+       printf("%s: interrupt mask %x\n", self->dv_xname, discard);
 
        /*
         * now check for all possible devices on this "bus"
         */
-       for (i=0; i<VSBUS_MAXDEVS; i++) {
-               ca = &vsbus_devs[i];
-               if (*ca->ca_name == '\0')
-                       break;
-               config_found(self, (void*)ca, vsbus_print);
-       }
+       config_search(vsbus_search, self, NULL);
 
-       /*
-        * as long as there's no working DZ-driver, we use this dummy
-        */
-       vsbus_intr_register(&ka410_devs[0], ka410_consRecv_intr, NULL);
-       vsbus_intr_register(&ka410_devs[1], ka410_consXmit_intr, NULL);
+       *sc->sc_intmsk = sc->sc_mask ^ discard;
 }
 
-#define VSBUS_MAX_INTR 8       /* 64? */
-/*
- * interrupt service routines are given an int as argument, which is
- * pushed onto stack as LITERAL. Thus the value is between 0-63.
- * This array of 64 might be oversized for now, but it's all which 
- * ever will be possible.
- */
-struct vsbus_ivec {
-       struct ivec_dsp intr_vec;               /* this is referenced in SCB */
-       int             intr_count;             /* keep track of interrupts */
-       int             intr_flags;             /* valid, etc. */
-       void            (*enab)(int);           /* enable interrupt */
-       void            (*disab)(int);          /* disable interrupt */
-       void            (*prep)(int);           /* need pre-processing? */
-       int             (*handler)(void*);      /* isr-routine to call */
-       void            *hndlarg;               /* args to this routine */
-       void            (*postp)(int);          /* need post-processing? */
-} vsbus_ivtab[VSBUS_MAX_INTR];
-
-/*
- * 
- */
 int
-vsbus_intr_setup()
+vsbus_search(parent, cfd, aux)
+       struct device   *parent;
+       void    *cfd;
+       void    *aux;
 {
-       int i;
-       struct vsbus_ivec *ip;
-       extern struct ivec_dsp idsptch;         /* subr.s */
-
-       for (i=0; i<VSBUS_MAX_INTR; i++) {
-               ip = &vsbus_ivtab[i];
-               bcopy(&idsptch, &ip->intr_vec, sizeof(struct ivec_dsp));
-               ip->intr_vec.pushlarg = i;
-               ip->intr_vec.hoppaddr = vsbus_intr_dispatch;
-               ip->intr_count = 0;
-               ip->intr_flags = 0;
-               ip->enab = NULL;
-               ip->disab = NULL;
-               ip->postp = NULL;
-       }
-       switch (vax_boardtype) {
-       case VAX_BTYP_410:
-       case VAX_BTYP_420:
-       case VAX_BTYP_43:
-       case VAX_BTYP_46:
-       case VAX_BTYP_49:
-               ka410_intr_setup();
-               return(0);
-       default:
-               printf("unsupported board-type 0x%x in vsbus_intr_setup()\n",
-                       vax_boardtype);
-               return(1);
-       }
+       struct  vsbus_softc             *sc = (void *)parent;
+       struct  vsbus_attach_args       va;
+       struct  cfdata  *cf = cfd;
+       int     i, vec, br;
+       u_char  c;
+
+       va.va_paddr = cf->cf_loc[0];
+       va.va_addr = vax_map_physmem(va.va_paddr, 1);
+       va.va_dmat = &vsbus_bus_dma_tag;
+
+       *sc->sc_intmsk = 0;
+       *sc->sc_intclr = 0xff;
+       scb_vecref(0, 0); /* Clear vector ref */
+
+       va.va_ivec = vsbus_intr;
+       i = (*cf->cf_attach->ca_match) (parent, cf, &va);
+       vax_unmap_physmem(va.va_addr, 1);
+       c = *sc->sc_intreq & ~sc->sc_mask;
+       if (i == 0)
+               goto forgetit;
+       if (i > 10)
+               c = sc->sc_mask; /* Fooling interrupt */
+       else if (c == 0)
+               goto forgetit;
+
+       va.va_maskno = ffs((u_int)c);
+
+       *sc->sc_intmsk = c;
+       DELAY(1000);
+       *sc->sc_intmsk = 0;
+
+       i = scb_vecref(&vec, &br);
+       if (i == 0)
+               goto fail;
+       if (vec == 0)
+               goto fail;
+       
+       scb_vecalloc(vec, va.va_ivec, va.va_vecarg, SCB_ISTACK);
+       va.va_br = br;
+       va.va_cvec = vec;
+       va.confargs = aux;              
+
+       config_attach(parent, cf, &va, vsbus_print);
+       return 1;
+
+fail:
+       printf("%s%d at %s csr %x %s\n",
+           cf->cf_driver->cd_name, cf->cf_unit, parent->dv_xname,
+           cf->cf_loc[0], (i ? "zero vector" : "didn't interrupt"));
+forgetit:
+       return 0;
 }
 
-int
-vsbus_intr_register(ca, handler, arg)
-       struct confargs *ca;
-       int (*handler)(void*);
-       void *arg;
-{
-       /* struct device *dev = arg; */
-       int i = ca->ca_intslot;
-       struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
-       trace (("vsbus_intr_register(%s/%d)\n", ca->ca_name, ca->ca_intslot));
-
-       ip->handler = handler;
-       ip->hndlarg = arg;
-}
+static volatile struct dma_lock {
+    int dl_locked;
+    int dl_wanted;
+    void    *dl_owner;
+    int dl_count;
+} dmalock = { 0, 0, NULL, 0 };
 
 int
-vsbus_intr_enable(ca)
-       struct confargs *ca;
+vsbus_lockDMA(ca)
+    struct confargs *ca;
 {
-       int i = ca->ca_intslot;
-       struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
-       trace (("vsbus_intr_enable(%s/%d)\n", ca->ca_name, ca->ca_intslot));
+    while (dmalock.dl_locked) {
+        dmalock.dl_wanted++;
+        sleep((caddr_t)&dmalock, PRIBIO);   /* PLOCK or PRIBIO ? */
+        dmalock.dl_wanted--;
+    }
+    dmalock.dl_locked++;
+    dmalock.dl_owner = ca;
+
+    /*
+     * no checks yet, no timeouts, nothing...
+     */
 
-       /* XXX check for valid handler etc. !!! */
-       if (ip->handler == NULL) {
-               printf("interrupts for \"%s\"(%d) not enabled: null-handler\n",
-                     ca->ca_name, ca->ca_intslot);
-               return;
-       }
-
-       ip->enab(i);
+#ifdef DEBUG
+    if ((++dmalock.dl_count % 1000) == 0)
+        printf("%d locks, owner: %s\n", dmalock.dl_count, ca->ca_name);
+#endif
+    return (0);
 }
 
 int
-vsbus_intr_disable(ca)
-       struct confargs *ca;
+vsbus_unlockDMA(ca)
+    struct confargs *ca;
 {
-       int i = ca->ca_intslot;
-       struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
-       trace (("vsbus_intr_disable(%s/%d)\n", ca->ca_name, i));
-
-       ip->disab(i);
+    if (dmalock.dl_locked != 1 || dmalock.dl_owner != ca) {
+        printf("locking-problem: %d, %s\n", dmalock.dl_locked,
+               (dmalock.dl_owner ? dmalock.dl_owner : "null"));
+        dmalock.dl_locked = 0;
+        return (-1);
+    }
+    dmalock.dl_owner = NULL;
+    dmalock.dl_locked = 0;
+    if (dmalock.dl_wanted) {
+        wakeup((caddr_t)&dmalock);
+    }
+    return (0);
 }
 
-int 
-vsbus_intr_unregister(ca)
-       struct confargs *ca;
-{
-       int i = ca->ca_intslot;
-       struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
-       trace (("vsbus_intr_unregister(%s/%d)\n", ca->ca_name, i));
-
-       ip->handler = NULL;
-       ip->hndlarg = NULL;
-}
-
-void
-vsbus_intr_dispatch(i)
-       register int i;
-{
-       register struct vsbus_ivec *ip = &vsbus_ivtab[i];
-
-       trace (("vsbus_intr_dispatch(%d)", i));
-       
-       if (i < VSBUS_MAX_INTR && ip->handler != NULL) {
-               ip->intr_count++;
-               debug (("intr-count[%d] = %d\n", i, ip->intr_count));
-               (ip->handler)(ip->hndlarg);
-               if (ip->postp)
-                       (ip->postp)(i);
-               return;
-       }
-
-       if (i < 0 || i >= VSBUS_MAX_INTR) {
-               printf ("stray interrupt %d on vsbus.\n", i);
-               return;
-       }
-
-       if (!ip->handler) {
-               printf ("unhandled interrupt %d on vsbus.\n", i);
-               return;
-       }
-}
 
 /*
- * These addresses are invalid and will be updated/corrected by
- * ka410_intr_setup(), but having them this way helps debugging
+ * Sets a new interrupt mask. Returns the old one.
+ * Works like spl functions.
  */
-static volatile u_char *ka410_intmsk = (void*)KA410_INTMSK;
-static volatile u_char *ka410_intreq = (void*)KA410_INTREQ;
-static volatile u_char *ka410_intclr = (void*)KA410_INTCLR;
-
-static void
-ka410_intr_enable(i)
-       int i;
+unsigned char
+vsbus_setmask(mask)
+       unsigned char mask;
 {
-       trace (("ka410_intr_enable(%d)\n", i));
-       *ka410_intmsk |= (1<<i);
-}
-
-static void
-ka410_intr_disable(i)
-       int i;
-{
-       trace (("ka410_intr_disable(%d)\n", i));
-       *ka410_intmsk &= ~(1<<i);
-}
+       struct vsbus_softc *sc = vsbus_cd.cd_devs[0];
+       unsigned char ch;
 
-static void
-ka410_intr_clear(i)
-       int i;
-{
-       trace (("ka410_intr_clear(%d)\n", i));
-       *ka410_intclr = (1<<i);
-}
-
-ka410_intr_setup()
-{
-       int i;
-       struct vsbus_ivec *ip;
-       void **scbP = (void*)scb;
-
-       trace (("ka410_intr_setup()\n"));
-
-       ka410_intmsk = (void*)uvax_phys2virt(KA410_INTMSK);
-       ka410_intreq = (void*)uvax_phys2virt(KA410_INTREQ);
-       ka410_intclr = (void*)uvax_phys2virt(KA410_INTCLR);
-
-       *ka410_intmsk = 0;              /* disable all interrupts */
-       *ka410_intclr = 0xFF;           /* clear all old interrupts */
-
-       /*
-        * insert the VS2000-specific routines into ivec-table...
-        */
-       for (i=0; i<8; i++) {
-               ip = &vsbus_ivtab[i];
-               ip->enab  = ka410_intr_enable;
-               ip->disab = ka410_intr_disable;
-               /* ip->postp = ka410_intr_clear; bertram XXX */
-       }
-       /*
-        * ...and register the interrupt-vectors in SCB
-        */
-       scbP[IVEC_DC/4] = &vsbus_ivtab[0].intr_vec;
-       scbP[IVEC_SC/4] = &vsbus_ivtab[1].intr_vec;
-       scbP[IVEC_VS/4] = &vsbus_ivtab[2].intr_vec;
-       scbP[IVEC_VF/4] = &vsbus_ivtab[3].intr_vec;
-       scbP[IVEC_NS/4] = &vsbus_ivtab[4].intr_vec;
-       scbP[IVEC_NP/4] = &vsbus_ivtab[5].intr_vec;
-       scbP[IVEC_ST/4] = &vsbus_ivtab[6].intr_vec;
-       scbP[IVEC_SR/4] = &vsbus_ivtab[7].intr_vec;
+       ch = *sc->sc_intmsk;
+       *sc->sc_intmsk = mask;
+       return ch;
 }
 
 /*
- *
- *
+ * Clears the interrupts in mask.
  */
-
-static volatile struct dma_lock {
-       int     dl_locked;
-       int     dl_wanted;
-       void    *dl_owner;
-       int     dl_count;
-} dmalock = { 0, 0, NULL, 0 };
-
-int
-vsbus_lockDMA(ca)
-       struct confargs *ca;
+void
+vsbus_clrintr(mask)
+       unsigned char mask;
 {
-       while (dmalock.dl_locked) {
-               dmalock.dl_wanted++;
-               sleep((caddr_t)&dmalock, PRIBIO);       /* PLOCK or PRIBIO ? */
-               dmalock.dl_wanted--;
-       }
-       dmalock.dl_locked++;
-       dmalock.dl_owner = ca;
-
-       /*
-        * no checks yet, no timeouts, nothing...
-        */
-
-#ifdef DEBUG
-       if ((++dmalock.dl_count % 1000) == 0)
-               printf("%d locks, owner: %s\n", dmalock.dl_count, ca->ca_name);
-#endif
-       return (0);
-}
+       struct vsbus_softc *sc = vsbus_cd.cd_devs[0];
 
-int 
-vsbus_unlockDMA(ca)
-       struct confargs *ca;
-{
-       if (dmalock.dl_locked != 1 || dmalock.dl_owner != ca) {
-               printf("locking-problem: %d, %s\n", dmalock.dl_locked,
-                      (dmalock.dl_owner ? dmalock.dl_owner : "null"));
-               dmalock.dl_locked = 0;
-               return (-1);
-       }
-       dmalock.dl_owner = NULL;
-       dmalock.dl_locked = 0;
-       if (dmalock.dl_wanted) {
-               wakeup((caddr_t)&dmalock);
-       }
-       return (0);
+       *sc->sc_intclr = mask;
 }
 
-/*----------------------------------------------------------------------*/
-#if 0
 /*
- * small set of routines needed for mapping when doing pseudo-DMA,
- * quasi-DMA or virtual-DMA (choose whatever name you like).
- *
- * Once I know how VS3100 is doing real DMA (I hope it does), this
- * should be rewritten to present a general interface...
- *
+ * Copy data from/to a user process' space from the DMA area.
+ * Use the physical memory directly.
  */
-
-extern u_long uVAX_physmap;
-
-u_long
-vsdma_mapin(bp, len)
-       struct buf *bp;
+void
+vsbus_copytoproc(p, from, to, len)
+       struct proc *p;
+       caddr_t from, to;
        int len;
 {
-       pt_entry_t *pte;        /* pointer to Page-Table-Entry */
-       struct pcb *pcb;        /* pointer to Process-Controll-Block */
-       pt_entry_t *xpte;
-       caddr_t addr;
-       int pgoff;              /* offset into 1st page */
-       int pgcnt;              /* number of pages needed */
-       int pfnum;
-       int i;
-
-       trace(("mapin(bp=%x, bp->data=%x)\n", bp, bp->b_data));
-
-       addr = bp->b_data;
-       pgoff = (int)bp->b_data & PGOFSET;      /* get starting offset */
-       pgcnt = btoc(bp->b_bcount + pgoff) + 1; /* one more than needed */
-       
-       /*
-        * Get a pointer to the pte pointing out the first virtual address.
-        * Use different ways in kernel and user space.
-        */
-       if ((bp->b_flags & B_PHYS) == 0) {
-               pte = kvtopte(addr);
-       } else {
-               pcb = bp->b_proc->p_vmspace->vm_pmap.pm_pcb;
-               pte = uvtopte(addr, pcb);
+       struct pte *pte;
+       paddr_t pa;
+
+       pte = uvtopte(TRUNC_PAGE(to), (&p->p_addr->u_pcb));
+       if ((vaddr_t)to & PGOFSET) {
+               int cz = ROUND_PAGE(to) - (vaddr_t)to;
+
+               pa = (pte->pg_pfn << VAX_PGSHIFT) | (NBPG - cz) | KERNBASE;
+               bcopy(from, (caddr_t)pa, min(cz, len));
+               from += cz;
+               to += cz;
+               len -= cz;
+               pte += 8; /* XXX */
        }
-
-       /*
-        * When we are doing DMA to user space, be sure that all pages
-        * we want to transfer to are mapped. WHY DO WE NEED THIS???
-        * SHOULDN'T THEY ALWAYS BE MAPPED WHEN DOING THIS???
-        */
-       for (i=0; i<(pgcnt-1); i++) {
-               if ((pte + i)->pg_pfn == 0) {
-                       int rv;
-                       rv = vm_fault(&bp->b_proc->p_vmspace->vm_map,
-                                     (unsigned)addr + i * NBPG,
-                                     VM_PROT_READ|VM_PROT_WRITE, FALSE);
-                       if (rv)
-                               panic("vs-DMA to nonexistent page, %d", rv);
-               }
-       }
-
-       /*
-        * now insert new mappings for this memory area into kernel's
-        * mapping-table
-        */
-       xpte = kvtopte(uVAX_physmap);
-       while (--pgcnt > 0) {
-               pfnum = pte->pg_pfn;
-               if (pfnum == 0)
-                       panic("vsbus: zero entry");
-               *(int *)xpte++ = *(int *)pte++;
+       while (len > 0) {
+               pa = (pte->pg_pfn << VAX_PGSHIFT) | KERNBASE;
+               bcopy(from, (caddr_t)pa, min(NBPG, len));
+               from += NBPG;
+               to += NBPG;
+               len -= NBPG;
+               pte += 8; /* XXX */
        }
-       *(int *)xpte = 0;       /* mark last mapped page as invalid! */
-
-       debug(("uVAX: 0x%x\n", uVAX_physmap + pgoff));
-
-       return (uVAX_physmap + pgoff);  /* ??? */
 }
-#endif
-/*----------------------------------------------------------------------*/
-/*
- * Here follows some currently(?) unused stuff. Someday this should be removed
- */
 
-#if 0
-/*
- * Configure devices on VS2000/KA410 directly attached to vsbus
- */
 void
-ka410_attach(parent, self, aux)
-       struct device *parent;
-       struct device *self;
-       void *aux;
+vsbus_copyfromproc(p, from, to, len)
+       struct proc *p;
+       caddr_t from, to;
+       int len;
 {
-       struct confargs *ca;
-       int i;
-
-       for (i=0; i<KA410_MAXDEVS; i++) {
-               ca = &ka410_devs[i];
-               if (*ca->ca_name == '\0')
-                       break;
-               config_found(self, (void*)ca, vsbus_print);
+       struct pte *pte;
+       paddr_t pa;
+
+       pte = uvtopte(TRUNC_PAGE(from), (&p->p_addr->u_pcb));
+       if ((vaddr_t)from & PGOFSET) {
+               int cz = ROUND_PAGE(from) - (vaddr_t)from;
+
+               pa = (pte->pg_pfn << VAX_PGSHIFT) | (NBPG - cz) | KERNBASE;
+               bcopy((caddr_t)pa, to, min(cz, len));
+               from += cz;
+               to += cz;
+               len -= cz;
+               pte += 8; /* XXX */
+       }
+       while (len > 0) {
+               pa = (pte->pg_pfn << VAX_PGSHIFT) | KERNBASE;
+               bcopy((caddr_t)pa, to, min(NBPG, len));
+               from += NBPG;
+               to += NBPG;
+               len -= NBPG;
+               pte += 8; /* XXX */
        }
-       /*
-        * as long as there's no real DZ-driver, we used this dummy
-        */
-       vsbus_intr_register(&ka410_devs[0], ka410_consRecv_intr, NULL);
-       vsbus_intr_register(&ka410_devs[1], ka410_consXmit_intr, NULL);
 }
-
-#endif