sync with 0430.
authormickey <mickey@openbsd.org>
Fri, 3 May 1996 16:02:09 +0000 (16:02 +0000)
committermickey <mickey@openbsd.org>
Fri, 3 May 1996 16:02:09 +0000 (16:02 +0000)
87 files changed:
sys/arch/sun3/dev/bw2.c
sys/arch/sun3/dev/cg2.c
sys/arch/sun3/dev/cg4.c
sys/arch/sun3/dev/eeprom.c
sys/arch/sun3/dev/idprom.c
sys/arch/sun3/dev/if_ie.c
sys/arch/sun3/dev/if_ie.h
sys/arch/sun3/dev/if_ie_obio.c [new file with mode: 0644]
sys/arch/sun3/dev/if_ie_subr.c
sys/arch/sun3/dev/if_ie_subr.h
sys/arch/sun3/dev/if_ie_vmes.c [new file with mode: 0644]
sys/arch/sun3/dev/if_iereg.h [new file with mode: 0644]
sys/arch/sun3/dev/if_ievar.h [new file with mode: 0644]
sys/arch/sun3/dev/if_le.c
sys/arch/sun3/dev/if_le.h
sys/arch/sun3/dev/if_le_subr.c
sys/arch/sun3/dev/if_le_subr.h
sys/arch/sun3/dev/if_lereg.h
sys/arch/sun3/dev/kd.c
sys/arch/sun3/dev/memerr.c [new file with mode: 0644]
sys/arch/sun3/dev/memerr.h [new file with mode: 0644]
sys/arch/sun3/dev/ncr5380.doc
sys/arch/sun3/dev/ncr5380reg.h
sys/arch/sun3/dev/ncr5380sbc.c
sys/arch/sun3/dev/ncr5380var.h
sys/arch/sun3/dev/ncr_si.c
sys/arch/sun3/dev/ncr_sireg.h
sys/arch/sun3/dev/obctl.c
sys/arch/sun3/dev/obio.c
sys/arch/sun3/dev/obmem.c
sys/arch/sun3/dev/prom.c
sys/arch/sun3/dev/rd_root.c
sys/arch/sun3/dev/scsi_5380.h
sys/arch/sun3/dev/scsi_defs.h
sys/arch/sun3/dev/scsi_sunsi.h
sys/arch/sun3/dev/si.c
sys/arch/sun3/dev/si_obio.c [new file with mode: 0644]
sys/arch/sun3/dev/si_vme.c [new file with mode: 0644]
sys/arch/sun3/dev/sireg.h [new file with mode: 0644]
sys/arch/sun3/dev/sivar.h [new file with mode: 0644]
sys/arch/sun3/dev/vme.c
sys/arch/sun3/dev/xd.c
sys/arch/sun3/dev/xdreg.h
sys/arch/sun3/dev/xdvar.h
sys/arch/sun3/dev/xy.c
sys/arch/sun3/dev/zs.c
sys/arch/sun3/dev/zs_kgdb.c
sys/arch/sun3/include/autoconf.h
sys/arch/sun3/include/dvma.h
sys/arch/sun3/include/obio.h
sys/arch/sun3/include/param.h
sys/arch/sun3/include/pmap.h
sys/arch/sun3/include/psl.h
sys/arch/sun3/include/z8530var.h
sys/arch/sun3/stand/libsa/SRT1.c
sys/arch/sun3/stand/libsa/dev_disk.c
sys/arch/sun3/stand/libsa/dvma.c
sys/arch/sun3/stand/libsa/exec_sun.c
sys/arch/sun3/stand/libsa/netif.h
sys/arch/sun3/stand/libsa/netif_sun.c
sys/arch/sun3/stand/libsa/panic.c
sys/arch/sun3/stand/libsa/promboot.c
sys/arch/sun3/stand/libsa/promdev.c
sys/arch/sun3/stand/netboot/conf.c
sys/arch/sun3/stand/netboot/dev_net.c
sys/arch/sun3/stand/netboot/version.c
sys/arch/sun3/stand/tapeboot/version.c
sys/arch/sun3/sun3/autoconf.c
sys/arch/sun3/sun3/clock.c
sys/arch/sun3/sun3/conf.c
sys/arch/sun3/sun3/db_machdep.c
sys/arch/sun3/sun3/db_memrw.c [new file with mode: 0644]
sys/arch/sun3/sun3/disksubr.c
sys/arch/sun3/sun3/dvma.c
sys/arch/sun3/sun3/fpu.c
sys/arch/sun3/sun3/genassym.c
sys/arch/sun3/sun3/intreg.c [new file with mode: 0644]
sys/arch/sun3/sun3/isr.c
sys/arch/sun3/sun3/locore.s
sys/arch/sun3/sun3/machdep.c
sys/arch/sun3/sun3/mainbus.c [new file with mode: 0644]
sys/arch/sun3/sun3/pmap.c
sys/arch/sun3/sun3/stub.c
sys/arch/sun3/sun3/sun3_startup.c
sys/arch/sun3/sun3/trap.c
sys/arch/sun3/sun3/vector.c
sys/arch/sun3/sun3/vm_machdep.c

index 6825a69..3207e8d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: bw2.c,v 1.5 1995/11/10 21:59:30 gwr Exp $      */
+/*     $NetBSD: bw2.c,v 1.6 1996/03/17 02:03:41 thorpej Exp $  */
 
 /*
  * Copyright (c) 1992, 1993
@@ -81,9 +81,13 @@ struct bw2_softc {
 static void    bw2attach __P((struct device *, struct device *, void *));
 static int     bw2match __P((struct device *, void *, void *));
 
-struct cfdriver bwtwocd = {
-       NULL, "bwtwo", bw2match, bw2attach,
-       DV_DULL, sizeof(struct bw2_softc) };
+struct cfattach bwtwo_ca = {
+       sizeof(struct bw2_softc), bw2match, bw2attach
+};
+
+struct cfdriver bwtwo_cd = {
+       NULL, "bwtwo", DV_DULL
+};
 
 /* XXX we do not handle frame buffer interrupts */
 
@@ -184,7 +188,7 @@ bw2open(dev, flags, mode, p)
 {
        int unit = minor(dev);
 
-       if (unit >= bwtwocd.cd_ndevs || bwtwocd.cd_devs[unit] == NULL)
+       if (unit >= bwtwo_cd.cd_ndevs || bwtwo_cd.cd_devs[unit] == NULL)
                return (ENXIO);
        return (0);
 }
@@ -207,7 +211,7 @@ bw2ioctl(dev, cmd, data, flags, p)
        int flags;
        struct proc *p;
 {
-       struct bw2_softc *sc = bwtwocd.cd_devs[minor(dev)];
+       struct bw2_softc *sc = bwtwo_cd.cd_devs[minor(dev)];
 
        return (fbioctlfb(&sc->sc_fb, cmd, data));
 }
@@ -221,7 +225,7 @@ bw2mmap(dev, off, prot)
        dev_t dev;
        int off, prot;
 {
-       struct bw2_softc *sc = bwtwocd.cd_devs[minor(dev)];
+       struct bw2_softc *sc = bwtwo_cd.cd_devs[minor(dev)];
 
        if (off & PGOFSET)
                return (-1);
index e89a0e7..765274e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: cg2.c,v 1.4 1995/04/10 07:05:57 mycroft Exp $  */
+/*     $NetBSD: cg2.c,v 1.5 1996/03/17 02:03:43 thorpej Exp $  */
 
 /*
  * Copyright (c) 1992, 1993
@@ -94,9 +94,13 @@ struct cg2_softc {
 static void    cg2attach __P((struct device *, struct device *, void *));
 static int     cg2match __P((struct device *, void *, void *));
 
-struct cfdriver cgtwocd = {
-       NULL, "cgtwo", cg2match, cg2attach,
-       DV_DULL, sizeof(struct cg2_softc) };
+struct cfattach cgtwo_ca = {
+       sizeof(struct cg2_softc), cg2match, cg2attach
+};
+
+struct cfdriver cgtwo_cd = {
+       NULL, "cgtwo", DV_DULL
+};
 
 /* frame buffer generic driver */
 int cg2open(), cg2close(), cg2mmap();
@@ -196,7 +200,7 @@ cg2open(dev, flags, mode, p)
 {
        int unit = minor(dev);
 
-       if (unit >= cgtwocd.cd_ndevs || cgtwocd.cd_devs[unit] == NULL)
+       if (unit >= cgtwo_cd.cd_ndevs || cgtwo_cd.cd_devs[unit] == NULL)
                return (ENXIO);
        return (0);
 }
@@ -219,7 +223,7 @@ cg2ioctl(dev, cmd, data, flags, p)
        int flags;
        struct proc *p;
 {
-       struct cg2_softc *sc = cgtwocd.cd_devs[minor(dev)];
+       struct cg2_softc *sc = cgtwo_cd.cd_devs[minor(dev)];
 
        return (fbioctlfb(&sc->sc_fb, cmd, data));
 }
@@ -233,7 +237,7 @@ cg2mmap(dev, off, prot)
        dev_t dev;
        int off, prot;
 {
-       struct cg2_softc *sc = cgtwocd.cd_devs[minor(dev)];
+       struct cg2_softc *sc = cgtwo_cd.cd_devs[minor(dev)];
        int realoff;
 
        if (off & PGOFSET)
index c281583..99f4ed8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: cg4.c,v 1.6 1995/04/13 21:51:34 gwr Exp $      */
+/*     $NetBSD: cg4.c,v 1.7 1996/03/17 02:03:45 thorpej Exp $  */
 
 /*
  * Copyright (c) 1992, 1993
@@ -87,9 +87,13 @@ struct cg4_softc {
 static void    cg4attach __P((struct device *, struct device *, void *));
 static int     cg4match __P((struct device *, void *, void *));
 
-struct cfdriver cgfourcd = {
-       NULL, "cgfour", cg4match, cg4attach,
-       DV_DULL, sizeof(struct cg4_softc) };
+struct cfattach cgfour_ca = {
+       sizeof(struct cg4_softc), cg4match, cg4attach
+};
+
+struct cfdriver cgfour_cd = {
+       NULL, "cgfour", DV_DULL
+};
 
 /* frame buffer generic driver */
 int cg4open(), cg4close(), cg4mmap();
@@ -208,7 +212,7 @@ cg4open(dev, flags, mode, p)
 {
        int unit = minor(dev);
 
-       if (unit >= cgfourcd.cd_ndevs || cgfourcd.cd_devs[unit] == NULL)
+       if (unit >= cgfour_cd.cd_ndevs || cgfour_cd.cd_devs[unit] == NULL)
                return (ENXIO);
        return (0);
 }
@@ -231,7 +235,7 @@ cg4ioctl(dev, cmd, data, flags, p)
        int flags;
        struct proc *p;
 {
-       struct cg4_softc *sc = cgfourcd.cd_devs[minor(dev)];
+       struct cg4_softc *sc = cgfour_cd.cd_devs[minor(dev)];
 
        return (fbioctlfb(&sc->sc_fb, cmd, data));
 }
@@ -260,7 +264,7 @@ cg4mmap(dev, off, prot)
        register int off;
        int prot;
 {
-       struct cg4_softc *sc = cgfourcd.cd_devs[minor(dev)];
+       struct cg4_softc *sc = cgfour_cd.cd_devs[minor(dev)];
        register int physbase;
 
        if (off & PGOFSET)
index e0d096d..b8ecd04 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: eeprom.c,v 1.6 1995/05/24 20:47:41 gwr Exp $   */
+/*     $NetBSD: eeprom.c,v 1.8 1996/03/26 15:16:06 gwr Exp $   */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
@@ -55,12 +55,16 @@ static int ee_update(caddr_t buf, int off, int cnt);
 static char *eeprom_va;
 static int ee_busy, ee_want;
 
-int eeprom_match __P((struct device *, void *vcf, void *args));
-void eeprom_attach __P((struct device *, struct device *, void *));
+static int  eeprom_match __P((struct device *, void *vcf, void *args));
+static void eeprom_attach __P((struct device *, struct device *, void *));
 
-struct cfdriver eepromcd = {
-       NULL, "eeprom", eeprom_match, eeprom_attach,
-       DV_DULL, sizeof(struct device), 0 };
+struct cfattach eeprom_ca = {
+       sizeof(struct device), eeprom_match, eeprom_attach
+};
+
+struct cfdriver eeprom_cd = {
+       NULL, "eeprom", DV_DULL
+};
 
 /* Called very early by internal_configure. */
 void eeprom_init()
@@ -69,24 +73,38 @@ void eeprom_init()
        ee_console = ((struct eeprom *)eeprom_va)->eeConsole;
 }
 
-int eeprom_match(parent, vcf, args)
+static int
+eeprom_match(parent, vcf, args)
     struct device *parent;
     void *vcf, *args;
 {
     struct cfdata *cf = vcf;
        struct confargs *ca = args;
+       int pa;
 
        /* This driver only supports one unit. */
        if (cf->cf_unit != 0)
                return (0);
+
+       if ((pa = cf->cf_paddr) == -1) {
+               /* Use our default PA. */
+               pa = OBIO_EEPROM;
+       } else {
+               /* Validate the given PA. */
+               if (pa != OBIO_EEPROM)
+                       return (0);
+       }
+       if (pa != ca->ca_paddr)
+               return (0);
+
        if (eeprom_va == NULL)
                return (0);
-       if (ca->ca_paddr == -1)
-               ca->ca_paddr = OBIO_EEPROM;
+
        return (1);
 }
 
-void eeprom_attach(parent, self, args)
+static void
+eeprom_attach(parent, self, args)
        struct device *parent;
        struct device *self;
        void *args;
index 53de1b5..7dd0917 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: idprom.c,v 1.10 1995/02/11 20:57:11 gwr Exp $  */
+/*     $NetBSD: idprom.c,v 1.12 1996/03/26 15:16:09 gwr Exp $  */
 
 /*
  * Copyright (c) 1993 Adam Glass
@@ -51,51 +51,6 @@ extern long hostid;  /* in kern_sysctl.c */
  */
 struct idprom identity_prom;
 
-static int  idprom_match __P((struct device *, void *vcf, void *args));
-static void idprom_attach __P((struct device *, struct device *, void *));
-
-struct cfdriver idpromcd = {
-       NULL, "idprom", idprom_match, idprom_attach,
-       DV_DULL, sizeof(struct device), 0 };
-
-int idprom_match(parent, vcf, args)
-       struct device *parent;
-       void *vcf, *args;
-{
-       struct cfdata *cf = vcf;
-
-       /* This driver only supports one unit. */
-       if (cf->cf_unit != 0)
-               return (0);
-
-       return (1);
-}
-
-void idprom_attach(parent, self, args)
-       struct device *parent;
-       struct device *self;
-       void *args;
-{
-       struct idprom *idp;
-       union {
-               long l;
-               char c[4];
-       } id;
-
-       /*
-        * Construct the hostid from the idprom contents.
-        * This appears to be the way SunOS does it.
-        */
-       idp = &identity_prom;
-       id.c[0] = idp->idp_machtype;
-       id.c[1] = idp->idp_serialnum[0];
-       id.c[2] = idp->idp_serialnum[1];
-       id.c[3] = idp->idp_serialnum[2];
-       hostid = id.l;
-
-       printf(" hostid 0x%x\n", id.l);
-}
-
 int idpromopen(dev, oflags, devtype, p)
        dev_t dev;
        int oflags;
@@ -141,6 +96,10 @@ int idprom_init()
        struct idprom *idp;
        char *src, *dst;
        int len, x, xorsum;
+       union {
+               long l;
+               char c[4];
+       } hid;
 
        idp = &identity_prom;
        dst = (char*)idp;
@@ -162,6 +121,17 @@ int idprom_init()
                mon_printf("idprom_fetch: bad version=%d\n", idp->idp_format);
                return -1;
        }
+
+       /*
+        * Construct the hostid from the idprom contents.
+        * This appears to be the way SunOS does it.
+        */
+       hid.c[0] = idp->idp_machtype;
+       hid.c[1] = idp->idp_serialnum[0];
+       hid.c[2] = idp->idp_serialnum[1];
+       hid.c[3] = idp->idp_serialnum[2];
+       hostid = hid.l;
+
        return 0;
 }
 
index 10ecdf0..eafc268 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ie.c,v 1.6 1995/12/24 02:30:48 mycroft Exp $ */
+/*     $NetBSD: if_ie.c,v 1.10 1996/03/26 22:04:14 gwr Exp $ */
 
 /*-
  * Copyright (c) 1993, 1994, 1995 Charles Hannum.
 #include <machine/pmap.h>
 
 #include "i82586.h"
-#include "if_ie.h"
-#include "if_ie_subr.h"
+#include "if_iereg.h"
+#include "if_ievar.h"
 
 static struct mbuf *last_not_for_us;
 
@@ -178,8 +178,6 @@ static int command_and_wait __P((struct ie_softc *, int,
     void volatile *, int));
 static void ierint __P((struct ie_softc *));
 static void ietint __P((struct ie_softc *));
-static int ieget __P((struct ie_softc *, struct mbuf **,
-                     struct ether_header *, int *));
 static void setup_bufs __P((struct ie_softc *));
 static int mc_setup __P((struct ie_softc *, void *));
 static void mc_reset __P((struct ie_softc *));
@@ -190,13 +188,12 @@ int     in_ierint = 0;
 int     in_ietint = 0;
 #endif
 
-void    ie_attach();
 
-struct cfdriver iecd = {
-       NULL, "ie", ie_md_match, ie_attach,
-       DV_IFNET, sizeof(struct ie_softc),
+struct cfdriver ie_cd = {
+       NULL, "ie", DV_IFNET
 };
 
+
 /*
  * address generation macros
  *   MK_24 = KVA -> 24 bit address in SUN byte order
@@ -265,21 +262,32 @@ ie_ack(sc, mask)
  * then modified beyond recognition...
  */
 void
-ie_attach(parent, self, aux)
-       struct device *parent, *self;
-       void   *aux;
+ie_attach(sc)
+       struct ie_softc *sc;
 {
-       struct ie_softc *sc = (void *) self;
        struct ifnet *ifp = &sc->sc_if;
+       int off;
 
-       /*
-        * Do machine-dependent parts of attach.
-        */
-       ie_md_attach(parent, self, aux);
+       /* MD code has done its part before calling this. */
        printf(" hwaddr %s\n", ether_sprintf(sc->sc_addr));
 
+       /* Allocate from end of buffer space for ISCP, SCB */
+       off = sc->buf_area_sz;
+       off &= ~3;
+
+       /* Space for ISCP */
+       off -= sizeof(*sc->iscp);
+       sc->iscp = (volatile void *) (sc->buf_area + off);
+
+       /* Space for SCB */
+       off -= sizeof(*sc->scb);
+       sc->scb  = (volatile void *) (sc->buf_area + off);
+
+       /* Remainder is for buffers, etc. */
+       sc->buf_area_sz = off;
+
        /*
-        * Setup for transmit/receive
+        * Setup RAM for transmit/receive
         */
        if (ie_setupram(sc) == 0) {
                printf(": RAM CONFIG FAILED!\n");
@@ -291,7 +299,7 @@ ie_attach(parent, self, aux)
         * Initialize and attach S/W interface
         */
        ifp->if_unit = sc->sc_dev.dv_unit;
-       ifp->if_name = iecd.cd_name;
+       ifp->if_name = ie_cd.cd_name;
        ifp->if_start = iestart;
        ifp->if_ioctl = ieioctl;
        ifp->if_watchdog = iewatchdog;
@@ -314,7 +322,7 @@ void
 iewatchdog(unit)
        short   unit;
 {
-       struct ie_softc *sc = iecd.cd_devs[unit];
+       struct ie_softc *sc = ie_cd.cd_devs[unit];
 
        log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
        ++sc->sc_arpcom.ac_if.if_oerrors;
@@ -500,18 +508,26 @@ ietint(sc)
 /*
  * Compare two Ether/802 addresses for equality, inlined and
  * unrolled for speed.  I'd love to have an inline assembler
- * version of this...
+ * version of this...   XXX: Who wanted that? mycroft?
+ * I wrote one, but the following is just as efficient.
+ * This expands to 10 short m68k instructions! -gwr
+ * Note: use this like bcmp()
  */
-static inline int
-ether_equal(one, two)
+static inline u_short
+ether_cmp(one, two)
        u_char *one, *two;
 {
+       register u_short *a = (u_short *) one;
+       register u_short *b = (u_short *) two;
+       register u_short diff;
 
-       if (one[0] != two[0] || one[1] != two[1] || one[2] != two[2] ||
-           one[3] != two[3] || one[4] != two[4] || one[5] != two[5])
-               return 0;
-       return 1;
+       diff  = *a++ - *b++;
+       diff |= *a++ - *b++;
+       diff |= *a++ - *b++;
+
+       return (diff);
 }
+#define        ether_equal !ether_cmp
 
 /*
  * Check for a valid address.  to_bpf is filled in with one of the following:
@@ -1026,7 +1042,7 @@ void
 iestart(ifp)
        struct ifnet *ifp;
 {
-       struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
+       struct ie_softc *sc = ie_cd.cd_devs[ifp->if_unit];
        struct mbuf *m0, *m;
        u_char *buffer;
        u_short len;
@@ -1545,7 +1561,7 @@ ieioctl(ifp, cmd, data)
        u_long  cmd;
        caddr_t data;
 {
-       struct ie_softc *sc = iecd.cd_devs[ifp->if_unit];
+       struct ie_softc *sc = ie_cd.cd_devs[ifp->if_unit];
        struct ifaddr *ifa = (struct ifaddr *) data;
        struct ifreq *ifr = (struct ifreq *) data;
        int     s, error = 0;
index 5e5ed58..e69de29 100644 (file)
@@ -1,163 +0,0 @@
-/*     $NetBSD: if_ie.h,v 1.1 1994/12/12 18:59:09 gwr Exp $ */
-
-/*
- * if_sunie.h
- *
- * sun's ie interface
- */
-
-/*
- * programming notes:
- *
- * the ie chip operates in a 24 bit address space.
- *
- * most ie interfaces appear to be divided into two parts:
- *      - generic 586 stuff
- *      - board specific
- *
- * generic:
- *     the generic stuff of the ie chip is all done with data structures
- *     that live in the chip's memory address space.   the chip expects
- *     its main data structure (the sys conf ptr -- SCP) to be at a fixed
- *     address in its 24 bit space: 0xfffff4
- *
- *      the SCP points to another structure called the ISCP.
- *      the ISCP points to another structure called the SCB.
- *     the SCB has a status field, a linked list of "commands", and
- *     a linked list of "receive buffers".   these are data structures that
- *     live in memory, not registers.
- *
- * board:
- *     to get the chip to do anything, you first put a command in the
- *     command data structure list.   then you have to signal "attention"
- *     to the chip to get it to look at the command.   how you
- *     signal attention depends on what board you have... on PC's
- *     there is an i/o port number to do this, on sun's there is a
- *     register bit you toggle.
- *
- *     to get data from the chip you program it to interrupt...
- *
- *
- * sun issues:
- *
- *      there are 3 kinds of sun "ie" interfaces:
- *        1 - a VME/multibus card
- *        2 - an on-board interface (sun3's, sun-4/100's, and sun-4/200's)
- *        3 - another VME board called the 3E
- *
- *     the VME boards lives in vme16 space.   only 16 and 8 bit accesses
- *     are allowed, so functions that copy data must be aware of this.
- *
- *     the chip is an intel chip.  this means that the byte order
- *     on all the "short"s in the chip's data structures is wrong.
- *     so, constants described in the intel docs are swapped for the sun.
- *     that means that any buffer pointers you give the chip must be
- *     swapped to intel format.   yuck.
- *
- *   VME/multibus interface:
- *     for the multibus interface the board ignores the top 4 bits
- *     of the chip address.   the multibus interface seems to have its
- *     own MMU like page map (without protections or valid bits, etc).
- *     there are 256 pages of physical memory on the board (each page
- *     is 1024 bytes).   there are 1024 slots in the page map.  so,
- *     a 1024 byte page takes up 10 bits of address for the offset,
- *     and if there are 1024 slots in the page that is another 10 bits
- *     of the address.   that makes a 20 bit address, and as stated
- *     earlier the board ignores the top 4 bits, so that accounts
- *     for all 24 bits of address.
- *
- *     note that the last entry of the page map maps the top of the
- *     24 bit address space and that the SCP is supposed to be at
- *     0xfffff4 (taking into account allignment).   so,
- *     for multibus, that entry in the page map has to be used for the SCP.
- *
- *     the page map effects BOTH how the ie chip sees the
- *     memory, and how the host sees it.
- *
- *     the page map is part of the "register" area of the board
- *
- *   on-board interface:
- *
- *     <fill in useful info later>
- *
- *
- *   VME3E interface:
- *
- *     <fill in useful info later>
- *
- */
-
-/*
- * PART 1: VME/multibus defs
- */
-#define IEVME_PAGESIZE 1024    /* bytes */
-#define IEVME_PAGSHIFT 10      /* bits */
-#define IEVME_NPAGES   256     /* number of pages on chip */
-#define IEVME_MAPSZ    1024    /* number of entries in the map */
-
-/*
- * PTE for the page map
- */
-#define IEVME_SBORDR 0x8000    /* sun byte order */
-#define IEVME_IBORDR 0x0000    /* intel byte ordr */
-
-#define IEVME_P2MEM  0x2000    /* memory is on P2 */
-#define IEVME_OBMEM  0x0000    /* memory is on board */
-
-#define IEVME_PGMASK 0x0fff    /* gives the physical page frame number */
-
-struct ievme {
-       u_short pgmap[IEVME_MAPSZ];
-       u_short xxx[32];        /* prom */
-       u_short status;         /* see below for bits */
-       u_short xxx2;           /* filler */
-       u_short pectrl;         /* parity control (see below) */
-       u_short peaddr;         /* low 16 bits of address */
-};
-
-/*
- * status bits
- */
-#define IEVME_RESET 0x8000     /* reset board */
-#define IEVME_ONAIR 0x4000     /* go out of loopback 'on-air' */
-#define IEVME_ATTEN 0x2000     /* attention */
-#define IEVME_IENAB 0x1000     /* interrupt enable */
-#define IEVME_PEINT 0x0800     /* parity error interrupt enable */
-#define IEVME_PERR  0x0200     /* parity error flag */
-#define IEVME_INT   0x0100     /* interrupt flag */
-#define IEVME_P2EN  0x0020     /* enable p2 bus */
-#define IEVME_256K  0x0010     /* 256kb rams */
-#define IEVME_HADDR 0x000f     /* mask for bits 17-20 of address */
-
-/*
- * parity control
- */
-#define IEVME_PARACK 0x0100    /* parity error ack */
-#define IEVME_PARSRC 0x0080    /* parity error source */
-#define IEVME_PAREND 0x0040    /* which end of the data got the error */
-#define IEVME_PARADR 0x000f    /* mask to get bits 17-20 of parity address */
-
-
-/*
- * PART 2: the on-board interface
- */
-struct ieob {
-       u_char  obctrl;
-};
-#define IEOB_NORSET 0x80       /* don't reset the board */
-#define IEOB_ONAIR  0x40       /* put us on the air */
-#define IEOB_ATTEN  0x20       /* attention! */
-#define IEOB_IENAB  0x10       /* interrupt enable */
-#define IEOB_XXXXX  0x08       /* free bit */
-#define IEOB_XCVRL2 0x04       /* level 2 transceiver? */
-#define IEOB_BUSERR 0x02       /* bus error */
-#define IEOB_INT    0x01       /* interrupt */
-
-/*
- * PART 3: the 3E board
- */
-
-/*
- * not supported (yet?)
- */
-
diff --git a/sys/arch/sun3/dev/if_ie_obio.c b/sys/arch/sun3/dev/if_ie_obio.c
new file mode 100644 (file)
index 0000000..a163ea4
--- /dev/null
@@ -0,0 +1,214 @@
+/*     $NetBSD: if_ie_obio.c,v 1.2 1996/03/26 22:04:19 gwr Exp $       */
+
+/*
+ * Copyright (c) 1994 Gordon W. Ross
+ * 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 Gordon Ross
+ * 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.
+ */
+
+/*
+ * Machine-dependent glue for the Intel Ethernet (ie) driver.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#endif
+
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+#include <machine/dvma.h>
+#include <machine/isr.h>
+#include <machine/obio.h>
+#include <machine/idprom.h>
+#include <machine/vmparam.h>
+
+#include "i82586.h"
+#include "if_iereg.h"
+#include "if_ievar.h"
+
+static void ie_obreset __P((struct ie_softc *));
+static void ie_obattend __P((struct ie_softc *));
+static void ie_obrun __P((struct ie_softc *));
+
+/*
+ * New-style autoconfig attachment
+ */
+
+static int  ie_obio_match __P((struct device *, void *, void *));
+static void ie_obio_attach __P((struct device *, struct device *, void *));
+
+struct cfattach ie_obio_ca = {
+       sizeof(struct ie_softc), ie_obio_match, ie_obio_attach
+};
+
+
+static int
+ie_obio_match(parent, vcf, args)
+       struct device *parent;
+       void *vcf, *args;
+{
+       struct cfdata *cf = vcf;
+       struct confargs *ca = args;
+       int pa, x;
+
+#ifdef DIAGNOSTIC
+       if (ca->ca_bustype != BUS_OBIO) {
+               printf("ie_obio_match: bustype %d?\n", ca->ca_bustype);
+               return (0);
+       }
+#endif
+
+       /*
+        * OBIO match functions may be called for every possible
+        * physical address, so match only our physical address.
+        */
+       if ((pa = cf->cf_paddr) == -1) {
+               /* Use our default PA. */
+               pa = OBIO_INTEL_ETHER;
+       }
+       if (pa != ca->ca_paddr)
+               return (0);
+
+       x = bus_peek(ca->ca_bustype, ca->ca_paddr, 1);
+       return (x != -1);
+}
+
+void
+ie_obio_attach(parent, self, args)
+       struct device *parent;
+       struct device *self;
+       void *args;
+{
+       struct ie_softc *sc = (void *) self;
+       struct cfdata *cf = self->dv_cfdata;
+       struct confargs *ca = args;
+       int intpri;
+
+       /* Default interrupt level. */
+       if ((intpri = cf->cf_intpri) == -1)
+               intpri = 3;
+       printf(" level %d", intpri);
+
+       sc->hard_type = IE_OBIO;
+       sc->reset_586 = ie_obreset;
+       sc->chan_attn = ie_obattend;
+       sc->run_586 = ie_obrun;
+       sc->sc_bcopy = bcopy;
+       sc->sc_bzero = bzero;
+
+       /*
+        * The on-board "ie" just uses main memory, so
+        * we can choose how much memory to give it.
+        * XXX: Would like to use less than 64K...
+        */
+       sc->sc_msize = 0x8000; /* MEMSIZE 32K */
+
+       /* Map in the control registers. */
+       sc->sc_reg = obio_alloc(ca->ca_paddr, OBIO_INTEL_ETHER_SIZE);
+
+       /* Allocate "shared" memory (in DVMA space). */
+       sc->sc_maddr = dvma_malloc(sc->sc_msize);
+       if (sc->sc_maddr == NULL)
+               panic(": not enough dvma space");
+
+       /*
+        * The on-board "ie" is wired-up such that its
+        * memory access goes to the high 16 megabytes
+        * of the on-board memory space (on-board DVMA).
+        */
+       sc->sc_iobase = (caddr_t)DVMA_OBIO_SLAVE_BASE;
+
+       /*
+        * Set the System Configuration Pointer (SCP).
+        * Its location is system-dependent because the
+        * i82586 reads it from a fixed physical address.
+        * On this hardware, the i82586 address maps to
+        * a 24-bit offset in on-board DVMA space. The
+        * SCP happens to fall in a page used by the
+        * PROM monitor, which the PROM knows about.
+        */
+       sc->scp = (volatile void *) (sc->sc_iobase + IE_SCP_ADDR);
+
+       /*
+        * The rest of ram is used for buffers.
+        */
+       sc->buf_area    = sc->sc_maddr;
+       sc->buf_area_sz = sc->sc_msize;
+
+       /* Set the ethernet address. */
+       idprom_etheraddr(sc->sc_addr);
+
+       /* Do machine-independent parts of attach. */
+       ie_attach(sc);
+
+       /* Install interrupt handler. */
+       isr_add_autovect(ie_intr, (void *)sc, intpri);
+}
+
+
+/*
+ * onboard ie support
+ */
+void
+ie_obreset(sc)
+       struct ie_softc *sc;
+{
+       volatile struct ieob *ieo = (struct ieob *) sc->sc_reg;
+       ieo->obctrl = 0;
+       delay(100);                     /* XXX could be shorter? */
+       ieo->obctrl = IEOB_NORSET;
+}
+void
+ie_obattend(sc)
+       struct ie_softc *sc;
+{
+       volatile struct ieob *ieo = (struct ieob *) sc->sc_reg;
+
+       ieo->obctrl |= IEOB_ATTEN;      /* flag! */
+       ieo->obctrl &= ~IEOB_ATTEN;     /* down. */
+}
+
+void
+ie_obrun(sc)
+       struct ie_softc *sc;
+{
+       volatile struct ieob *ieo = (struct ieob *) sc->sc_reg;
+
+       ieo->obctrl |= (IEOB_ONAIR|IEOB_IENAB|IEOB_NORSET);
+}
+
index 71af716..e69de29 100644 (file)
@@ -1,366 +0,0 @@
-/*     $NetBSD: if_ie_subr.c,v 1.7 1995/09/26 04:02:04 gwr Exp $       */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * 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 Gordon Ross
- * 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.
- */
-
-/*
- * Machine-dependent glue for the Intel Ethernet (ie) driver.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/device.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <net/if.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#endif
-
-#include <machine/autoconf.h>
-#include <machine/cpu.h>
-#include <machine/dvma.h>
-#include <machine/isr.h>
-#include <machine/obio.h>
-#include <machine/idprom.h>
-#include <machine/vmparam.h>
-
-#include "i82586.h"
-#include "if_ie.h"
-#include "if_ie_subr.h"
-
-static void ie_obreset __P((struct ie_softc *));
-static void ie_obattend __P((struct ie_softc *));
-static void ie_obrun __P((struct ie_softc *));
-static void ie_vmereset __P((struct ie_softc *));
-static void ie_vmeattend __P((struct ie_softc *));
-static void ie_vmerun __P((struct ie_softc *));
-
-/*
- * zero/copy functions: OBIO can use the normal functions, but VME
- *    must do only byte or half-word (16 bit) accesses...
- */
-static void wcopy(), wzero();
-
-int
-ie_md_match(parent, vcf, args)
-       struct device *parent;
-       void *vcf, *args;
-{
-       struct cfdata *cf = vcf;
-       struct confargs *ca = args;
-       int x, sz;
-
-       switch (ca->ca_bustype) {
-
-       case BUS_OBIO:
-               if (ca->ca_paddr == -1)
-                       ca->ca_paddr = OBIO_INTEL_ETHER;
-               sz = 1;
-               break;
-
-       case BUS_VME16:
-               /* No default VME address. */
-               if (ca->ca_paddr == -1)
-                       return(0);
-               sz = 2;
-               break;
-
-       default:
-               return (0);
-       }
-
-       /* Default interrupt level. */
-       if (ca->ca_intpri == -1)
-               ca->ca_intpri = 3;
-
-       x = bus_peek(ca->ca_bustype, ca->ca_paddr, sz);
-       return (x != -1);
-}
-
-void
-ie_md_attach(parent, self, args)
-       struct device *parent;
-       struct device *self;
-       void *args;
-{
-       struct ie_softc *sc = (void *) self;
-       struct confargs *ca = args;
-       caddr_t mem, reg;
-
-       /*
-        * *note*: we don't detect the difference between a VME3E and
-        * a multibus/vme card.   if you want to use a 3E you'll have
-        * to fix this.
-        */
-
-       switch (ca->ca_bustype) {
-       case BUS_OBIO:
-               sc->hard_type = IE_OBIO;
-               sc->reset_586 = ie_obreset;
-               sc->chan_attn = ie_obattend;
-               sc->run_586 = ie_obrun;
-               sc->sc_bcopy = bcopy;
-               sc->sc_bzero = bzero;
-               sc->sc_iobase = (caddr_t)DVMA_OBIO_SLAVE_BASE;
-               sc->sc_msize = MEMSIZE;
-
-               /* Map in the control register. */
-               reg = obio_alloc(ca->ca_paddr, OBIO_INTEL_ETHER_SIZE);
-               if (reg == NULL)
-                       panic(": not enough obio space\n");
-               sc->sc_reg = reg;
-
-               /* Allocate "shared" memory (DVMA space). */
-               mem = dvma_malloc(sc->sc_msize);
-               if (mem == NULL)
-                       panic(": not enough dvma space");
-               sc->sc_maddr = mem;
-
-               /* This is a FIXED address, in a page left by the PROM. */
-               sc->scp = (volatile struct ie_sys_conf_ptr *)
-                   (sc->sc_iobase + IE_SCP_ADDR);
-
-               /* Install interrupt handler. */
-               isr_add_autovect(ie_intr, (void *)sc, ca->ca_intpri);
-
-               break;
-
-       case BUS_VME16: {
-               volatile struct ievme *iev;
-               u_long  rampaddr;
-               int     lcv;
-
-               sc->hard_type = IE_VME;
-               sc->reset_586 = ie_vmereset;
-               sc->chan_attn = ie_vmeattend;
-               sc->run_586 = ie_vmerun;
-               sc->sc_bcopy = wcopy;
-               sc->sc_bzero = wzero;
-               sc->sc_msize = MEMSIZE;
-               sc->sc_reg = bus_mapin(ca->ca_bustype, ca->ca_paddr,
-                                                          sizeof(struct ievme));
-
-               iev = (volatile struct ievme *) sc->sc_reg;
-               /* top 12 bits */
-               rampaddr = ca->ca_paddr & 0xfff00000;
-               /* 4 more */
-               rampaddr |= ((iev->status & IEVME_HADDR) << 16);
-               sc->sc_maddr = bus_mapin(ca->ca_bustype, rampaddr, sc->sc_msize);
-               sc->sc_iobase = sc->sc_maddr;
-               iev->pectrl = iev->pectrl | IEVME_PARACK; /* clear to start */
-
-               sc->scp = (volatile struct ie_sys_conf_ptr *)
-                   (sc->sc_iobase + (IE_SCP_ADDR & (IEVME_PAGESIZE - 1)));
-
-               /*
-                * set up mappings, direct map except for last page
-                * which is mapped at zero and at high address (for
-                * scp), zero ram
-                */
-
-               for (lcv = 0; lcv < IEVME_MAPSZ - 1; lcv++)
-                       iev->pgmap[lcv] = IEVME_SBORDR | IEVME_OBMEM | lcv;
-               iev->pgmap[IEVME_MAPSZ - 1] = IEVME_SBORDR | IEVME_OBMEM | 0;
-               (sc->sc_bzero)(sc->sc_maddr, sc->sc_msize);
-
-               isr_add_vectored(ie_intr, (void *)sc,
-                                                ca->ca_intpri,
-                                                ca->ca_intvec);
-               break;
-       }
-
-       default:
-               printf("unknown\n");
-               return;
-       }
-
-       /*
-        * set up pointers to data structures and buffer area.
-        */
-       sc->iscp = (volatile struct ie_int_sys_conf_ptr *)
-           sc->sc_maddr;
-       sc->scb = (volatile struct ie_sys_ctl_block *)
-           sc->sc_maddr + sizeof(struct ie_int_sys_conf_ptr);
-
-       /*
-        * rest of first page is unused, rest of ram
-        * for buffers
-        */
-       sc->buf_area = sc->sc_maddr + IEVME_PAGESIZE;
-       sc->buf_area_sz = sc->sc_msize - IEVME_PAGESIZE;
-
-       idprom_etheraddr(sc->sc_addr); /* ethernet addr */
-}
-
-
-/*
- * MULTIBUS/VME support
- */
-void 
-ie_vmereset(sc)
-       struct ie_softc *sc;
-{
-       volatile struct ievme *iev = (struct ievme *) sc->sc_reg;
-       iev->status = IEVME_RESET;
-       delay(100);             /* XXX could be shorter? */
-       iev->status = 0;
-}
-
-void 
-ie_vmeattend(sc)
-       struct ie_softc *sc;
-{
-       volatile struct ievme *iev = (struct ievme *) sc->sc_reg;
-
-       iev->status |= IEVME_ATTEN;     /* flag! */
-       iev->status &= ~IEVME_ATTEN;    /* down. */
-}
-
-void 
-ie_vmerun(sc)
-       struct ie_softc *sc;
-{
-       volatile struct ievme *iev = (struct ievme *) sc->sc_reg;
-
-       iev->status |= (IEVME_ONAIR | IEVME_IENAB | IEVME_PEINT);
-}
-
-/*
- * onboard ie support
- */
-void
-ie_obreset(sc)
-       struct ie_softc *sc;
-{
-       volatile struct ieob *ieo = (struct ieob *) sc->sc_reg;
-       ieo->obctrl = 0;
-       delay(100);                     /* XXX could be shorter? */
-       ieo->obctrl = IEOB_NORSET;
-}
-void
-ie_obattend(sc)
-       struct ie_softc *sc;
-{
-       volatile struct ieob *ieo = (struct ieob *) sc->sc_reg;
-
-       ieo->obctrl |= IEOB_ATTEN;      /* flag! */
-       ieo->obctrl &= ~IEOB_ATTEN;     /* down. */
-}
-
-void
-ie_obrun(sc)
-       struct ie_softc *sc;
-{
-       volatile struct ieob *ieo = (struct ieob *) sc->sc_reg;
-
-       ieo->obctrl |= (IEOB_ONAIR|IEOB_IENAB|IEOB_NORSET);
-}
-
-/*
- * wcopy/wzero - like bcopy/bzero but largest access is 16-bits,
- * and also does byte swaps...
- * XXX - Would be nice to have asm versions in some library...
- */
-
-static void
-wzero(vb, l)
-       void *vb;
-       u_int l;
-{
-       u_char *b = vb;
-       u_char *be = b + l;
-       u_short *sp;
-
-       if (l == 0)
-               return;
-
-       /* front, */
-       if ((u_long)b & 1)
-               *b++ = 0;
-
-       /* back, */
-       if (b != be && ((u_long)be & 1) != 0) {
-               be--;
-               *be = 0;
-       }
-
-       /* and middle. */
-       sp = (u_short *)b;
-       while (sp != (u_short *)be)
-               *sp++ = 0;
-}
-
-static void
-wcopy(vb1, vb2, l)
-       const void *vb1;
-       void *vb2;
-       u_int l;
-{
-       const u_char *b1e, *b1 = vb1;
-       u_char *b2 = vb2;
-       u_short *sp;
-       int bstore = 0;
-
-       if (l == 0)
-               return;
-
-       /* front, */
-       if ((u_long)b1 & 1) {
-               *b2++ = *b1++;
-               l--;
-       }
-
-       /* middle, */
-       sp = (u_short *)b1;
-       b1e = b1 + l;
-       if (l & 1)
-               b1e--;
-       bstore = (u_long)b2 & 1;
-
-       while (sp < (u_short *)b1e) {
-               if (bstore) {
-                       b2[1] = *sp & 0xff;
-                       b2[0] = *sp >> 8;
-               } else
-                       *((short *)b2) = *sp;
-               sp++;
-               b2 += 2;
-       }
-
-       /* and back. */
-       if (l & 1)
-               *b2 = *b1e;
-}
index ed67388..e69de29 100644 (file)
@@ -1,124 +0,0 @@
-/*     $NetBSD: if_ie_subr.h,v 1.5 1995/02/13 22:23:56 gwr Exp $       */
-
-/*
- * Machine-dependent glue for the Intel Ethernet (ie) driver.
- */
-
-#define B_PER_F         3      /* number of buffers to allocate per frame */
-#define        MXFRAMES        300     /* max number of frames to allow for receive */
-#define        MXRXBUF (MXFRAMES*B_PER_F)      /* max number of buffers to allocate */
-#define        IE_RBUF_SIZE    256     /* size of each buffer, MUST BE POWER OF TWO */
-#define        NTXBUF          2       /* number of transmit buffer/command pairs */
-#define        IE_TBUF_SIZE    1536    /* length of transmit buffer */
-
-#define MEMSIZE 0x10000
-
-enum ie_hardware {
-       IE_VME,                 /* multibus to VME ie card */
-       IE_OBIO,                /* on board */
-       IE_VME3E,               /* sun 3e VME card */
-       IE_UNKNOWN
-};
-
-/*
- * Ethernet status, per interface.
- *
- * hardware addresses/sizes to know (all KVA):
- *   sc_iobase = base of chip's 24 bit address space
- *   sc_maddr  = base address of chip RAM as stored in ie_base of iscp
- *   sc_msize  = size of chip's RAM
- *   sc_reg    = address of card dependent registers
- *
- * the chip uses two types of pointers: 16 bit and 24 bit
- *   16 bit pointers are offsets from sc_maddr/ie_base
- *      KVA(16 bit offset) = offset + sc_maddr
- *   24 bit pointers are offset from sc_iobase in KVA
- *      KVA(24 bit address) = address + sc_iobase
- *
- * on the vme/multibus we have the page map to control where ram appears
- * in the address space.   we choose to have RAM start at 0 in the
- * 24 bit address space.   this means that sc_iobase == sc_maddr!
- * to get the phyiscal address of the board's RAM you must take the
- * top 12 bits of the physical address of the register address
- * and or in the 4 bits from the status word as bits 17-20 (remember that
- * the board ignores the chip's top 4 address lines).
- * For example:
- *   if the register is @ 0xffe88000, then the top 12 bits are 0xffe00000.
- *   to get the 4 bits from the the status word just do status & IEVME_HADDR.
- *   suppose the value is "4".   Then just shift it left 16 bits to get
- *   it into bits 17-20 (e.g. 0x40000).    Then or it to get the
- *   address of RAM (in our example: 0xffe40000).   see the attach routine!
- *
- * In the onboard ie interface, the 24 bit address space is hardwired
- * to be 0xff000000 -> 0xffffffff of KVA.   this means that sc_iobase
- * will be 0xff000000.   sc_maddr will be where ever we allocate RAM
- * in KVA.    note that since the SCP is at a fixed address it means
- * that we have to use some memory at a fixed KVA for the SCP.
- * The Sun PROM leaves a page for us at the end of KVA space.
- */
-struct ie_softc {
-       struct device sc_dev;   /* device structure */
-
-       struct arpcom sc_arpcom;/* system arpcom structure */
-#define        sc_if   sc_arpcom.ac_if                 /* network-visible interface */
-#define        sc_addr sc_arpcom.ac_enaddr             /* hardware Ethernet address */
-
-       caddr_t sc_iobase;      /* KVA of base of 24bit addr space */
-       caddr_t sc_maddr;       /* KVA of base of chip's RAM */
-       u_int   sc_msize;       /* how much RAM we have/use */
-       caddr_t sc_reg;         /* KVA of card's register */
-
-       enum ie_hardware hard_type;     /* card type */
-       void    (*reset_586)(); /* card dependent reset function */
-       void    (*chan_attn)(); /* card dependent attn function */
-       void    (*run_586)();   /* card dependent "go on-line" function */
-       void (*sc_bcopy) __P((const void *, void *, u_int));
-       void (*sc_bzero) __P((void *, u_int));
-
-       int     want_mcsetup;   /* flag for multicast setup */
-       int     promisc;        /* are we in promisc mode? */
-
-       /*
-        * pointers to the 3 major control structures
-        */
-       volatile struct ie_sys_conf_ptr *scp;
-       volatile struct ie_int_sys_conf_ptr *iscp;
-       volatile struct ie_sys_ctl_block *scb;
-
-       /*
-        * pointer and size of a block of KVA where the buffers
-        * are to be allocated from
-        */
-       caddr_t buf_area;
-       int     buf_area_sz;
-
-       /*
-        * the actual buffers (recv and xmit)
-        */
-       volatile struct ie_recv_frame_desc *rframes[MXFRAMES];
-       volatile struct ie_recv_buf_desc *rbuffs[MXRXBUF];
-       volatile char *cbuffs[MXRXBUF];
-       int     rfhead, rftail, rbhead, rbtail;
-
-       volatile struct ie_xmit_cmd *xmit_cmds[NTXBUF];
-       volatile struct ie_xmit_buf *xmit_buffs[NTXBUF];
-       u_char *xmit_cbuffs[NTXBUF];
-       int xmit_busy;
-       int xmit_free;
-       int xchead, xctail;
-
-       struct ie_en_addr mcast_addrs[MAXMCAST + 1];
-       int     mcast_count;
-
-       int nframes;      /* number of frames in use */
-       int nrxbuf;       /* number of recv buffs in use */
-
-#ifdef IEDEBUG
-       int     sc_debug;
-#endif
-};
-
-
-extern int  ie_md_match(struct device *, void *, void *args);
-extern void ie_md_attach(struct device *, struct device *, void *);
-extern int  ie_intr(void *);
diff --git a/sys/arch/sun3/dev/if_ie_vmes.c b/sys/arch/sun3/dev/if_ie_vmes.c
new file mode 100644 (file)
index 0000000..575f0e3
--- /dev/null
@@ -0,0 +1,305 @@
+/*     $NetBSD: if_ie_vmes.c,v 1.2 1996/03/26 22:04:28 gwr Exp $       */
+
+/*
+ * Copyright (c) 1994 Gordon W. Ross
+ * 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 Gordon Ross
+ * 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.
+ */
+
+/*
+ * Machine-dependent glue for the Intel Ethernet (ie) driver.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#endif
+
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+#include <machine/dvma.h>
+#include <machine/isr.h>
+#include <machine/idprom.h>
+#include <machine/vmparam.h>
+
+#include "i82586.h"
+#include "if_iereg.h"
+#include "if_ievar.h"
+
+static void ie_vmereset __P((struct ie_softc *));
+static void ie_vmeattend __P((struct ie_softc *));
+static void ie_vmerun __P((struct ie_softc *));
+
+/*
+ * zero/copy functions: OBIO can use the normal functions, but VME
+ *    must do only byte or half-word (16 bit) accesses...
+ */
+static void wcopy(), wzero();
+
+/*
+ * New-style autoconfig attachment
+ */
+
+static int  ie_vmes_match __P((struct device *, void *, void *));
+static void ie_vmes_attach __P((struct device *, struct device *, void *));
+
+struct cfattach ie_vmes_ca = {
+       sizeof(struct ie_softc), ie_vmes_match, ie_vmes_attach
+};
+
+
+static int
+ie_vmes_match(parent, vcf, args)
+       struct device *parent;
+       void *vcf, *args;
+{
+       struct confargs *ca = args;
+       int x, sz;
+
+#ifdef DIAGNOSTIC
+       if (ca->ca_bustype != BUS_VME16) {
+               printf("ie_vmes_match: bustype %d?\n", ca->ca_bustype);
+               return (0);
+       }
+#endif
+
+       /* No default VME address. */
+       if (ca->ca_paddr == -1)
+               return(0);
+
+       /* Default interrupt level. */
+       if (ca->ca_intpri == -1)
+               ca->ca_intpri = 3;
+
+       x = bus_peek(ca->ca_bustype, ca->ca_paddr, 2);
+       return (x != -1);
+}
+
+/*
+ * *note*: we don't detect the difference between a VME3E and
+ * a multibus/vme card.   if you want to use a 3E you'll have
+ * to fix this.
+ */
+void
+ie_vmes_attach(parent, self, args)
+       struct device *parent;
+       struct device *self;
+       void *args;
+{
+       struct ie_softc *sc = (void *) self;
+       struct confargs *ca = args;
+       volatile struct ievme *iev;
+       u_long  rampaddr;
+       int     lcv, off;
+
+       sc->hard_type = IE_VME;
+       sc->reset_586 = ie_vmereset;
+       sc->chan_attn = ie_vmeattend;
+       sc->run_586 = ie_vmerun;
+       sc->sc_bcopy = wcopy;
+       sc->sc_bzero = wzero;
+
+       /*
+        * There is 64K of memory on the VME board.
+        * (determined by hardware - NOT configurable!)
+        */
+       sc->sc_msize = 0x10000; /* MEMSIZE 64K */
+
+       /* Map in the board control regs. */
+       sc->sc_reg = bus_mapin(ca->ca_bustype, ca->ca_paddr,
+                                                  sizeof(struct ievme));
+       iev = (volatile struct ievme *) sc->sc_reg;
+
+       /*
+        * Find and map in the board memory.
+        */
+       /* top 12 bits */
+       rampaddr = ca->ca_paddr & 0xfff00000;
+       /* 4 more */
+       rampaddr |= ((iev->status & IEVME_HADDR) << 16);
+       sc->sc_maddr = bus_mapin(ca->ca_bustype, rampaddr, sc->sc_msize);
+
+       /*
+        * On this hardware, the i82586 address is just
+        * masked to 16 bits, so sc_iobase == sc_maddr
+        */
+       sc->sc_iobase = sc->sc_maddr;
+
+       /*
+        * Set up on-board mapping registers for linear map.
+        */
+       iev->pectrl |= IEVME_PARACK; /* clear to start */
+       for (lcv = 0; lcv < IEVME_MAPSZ; lcv++)
+               iev->pgmap[lcv] = IEVME_SBORDR | IEVME_OBMEM | lcv;
+       (sc->sc_bzero)(sc->sc_maddr, sc->sc_msize);
+
+       /*
+        * Set the System Configuration Pointer (SCP).
+        * Its location is system-dependent because the
+        * i82586 reads it from a fixed physical address.
+        * On this hardware, the i82586 address is just
+        * masked down to 16 bits, so the SCP is found
+        * at the end of the RAM on the VME board.
+        */
+       off = IE_SCP_ADDR & 0xFFFF;
+       sc->scp = (volatile void *) (sc->sc_maddr + off);
+
+       /*
+        * The rest of ram is used for buffers, etc.
+        */
+       sc->buf_area = sc->sc_maddr;
+       sc->buf_area_sz = off;
+
+       /* Set the ethernet address. */
+       idprom_etheraddr(sc->sc_addr);
+
+       /* Do machine-independent parts of attach. */
+       ie_attach(sc);
+
+       /* Install interrupt handler. */
+       isr_add_vectored(ie_intr, (void *)sc,
+               ca->ca_intpri, ca->ca_intvec);
+}
+
+
+/*
+ * MULTIBUS/VME support
+ */
+void 
+ie_vmereset(sc)
+       struct ie_softc *sc;
+{
+       volatile struct ievme *iev = (struct ievme *) sc->sc_reg;
+       iev->status = IEVME_RESET;
+       delay(100);             /* XXX could be shorter? */
+       iev->status = 0;
+}
+
+void 
+ie_vmeattend(sc)
+       struct ie_softc *sc;
+{
+       volatile struct ievme *iev = (struct ievme *) sc->sc_reg;
+
+       iev->status |= IEVME_ATTEN;     /* flag! */
+       iev->status &= ~IEVME_ATTEN;    /* down. */
+}
+
+void 
+ie_vmerun(sc)
+       struct ie_softc *sc;
+{
+       volatile struct ievme *iev = (struct ievme *) sc->sc_reg;
+
+       iev->status |= (IEVME_ONAIR | IEVME_IENAB | IEVME_PEINT);
+}
+
+/*
+ * wcopy/wzero - like bcopy/bzero but largest access is 16-bits,
+ * and also does byte swaps...
+ * XXX - Would be nice to have asm versions in some library...
+ */
+
+static void
+wzero(vb, l)
+       void *vb;
+       u_int l;
+{
+       u_char *b = vb;
+       u_char *be = b + l;
+       u_short *sp;
+
+       if (l == 0)
+               return;
+
+       /* front, */
+       if ((u_long)b & 1)
+               *b++ = 0;
+
+       /* back, */
+       if (b != be && ((u_long)be & 1) != 0) {
+               be--;
+               *be = 0;
+       }
+
+       /* and middle. */
+       sp = (u_short *)b;
+       while (sp != (u_short *)be)
+               *sp++ = 0;
+}
+
+static void
+wcopy(vb1, vb2, l)
+       const void *vb1;
+       void *vb2;
+       u_int l;
+{
+       const u_char *b1e, *b1 = vb1;
+       u_char *b2 = vb2;
+       u_short *sp;
+       int bstore = 0;
+
+       if (l == 0)
+               return;
+
+       /* front, */
+       if ((u_long)b1 & 1) {
+               *b2++ = *b1++;
+               l--;
+       }
+
+       /* middle, */
+       sp = (u_short *)b1;
+       b1e = b1 + l;
+       if (l & 1)
+               b1e--;
+       bstore = (u_long)b2 & 1;
+
+       while (sp < (u_short *)b1e) {
+               if (bstore) {
+                       b2[1] = *sp & 0xff;
+                       b2[0] = *sp >> 8;
+               } else
+                       *((short *)b2) = *sp;
+               sp++;
+               b2 += 2;
+       }
+
+       /* and back. */
+       if (l & 1)
+               *b2 = *b1e;
+}
diff --git a/sys/arch/sun3/dev/if_iereg.h b/sys/arch/sun3/dev/if_iereg.h
new file mode 100644 (file)
index 0000000..5986a89
--- /dev/null
@@ -0,0 +1,163 @@
+/*     $NetBSD: if_iereg.h,v 1.1 1994/12/12 18:59:09 gwr Exp $ */
+
+/*
+ * if_sunie.h
+ *
+ * sun's ie interface
+ */
+
+/*
+ * programming notes:
+ *
+ * the ie chip operates in a 24 bit address space.
+ *
+ * most ie interfaces appear to be divided into two parts:
+ *      - generic 586 stuff
+ *      - board specific
+ *
+ * generic:
+ *     the generic stuff of the ie chip is all done with data structures
+ *     that live in the chip's memory address space.   the chip expects
+ *     its main data structure (the sys conf ptr -- SCP) to be at a fixed
+ *     address in its 24 bit space: 0xfffff4
+ *
+ *      the SCP points to another structure called the ISCP.
+ *      the ISCP points to another structure called the SCB.
+ *     the SCB has a status field, a linked list of "commands", and
+ *     a linked list of "receive buffers".   these are data structures that
+ *     live in memory, not registers.
+ *
+ * board:
+ *     to get the chip to do anything, you first put a command in the
+ *     command data structure list.   then you have to signal "attention"
+ *     to the chip to get it to look at the command.   how you
+ *     signal attention depends on what board you have... on PC's
+ *     there is an i/o port number to do this, on sun's there is a
+ *     register bit you toggle.
+ *
+ *     to get data from the chip you program it to interrupt...
+ *
+ *
+ * sun issues:
+ *
+ *      there are 3 kinds of sun "ie" interfaces:
+ *        1 - a VME/multibus card
+ *        2 - an on-board interface (sun3's, sun-4/100's, and sun-4/200's)
+ *        3 - another VME board called the 3E
+ *
+ *     the VME boards lives in vme16 space.   only 16 and 8 bit accesses
+ *     are allowed, so functions that copy data must be aware of this.
+ *
+ *     the chip is an intel chip.  this means that the byte order
+ *     on all the "short"s in the chip's data structures is wrong.
+ *     so, constants described in the intel docs are swapped for the sun.
+ *     that means that any buffer pointers you give the chip must be
+ *     swapped to intel format.   yuck.
+ *
+ *   VME/multibus interface:
+ *     for the multibus interface the board ignores the top 4 bits
+ *     of the chip address.   the multibus interface seems to have its
+ *     own MMU like page map (without protections or valid bits, etc).
+ *     there are 256 pages of physical memory on the board (each page
+ *     is 1024 bytes).   there are 1024 slots in the page map.  so,
+ *     a 1024 byte page takes up 10 bits of address for the offset,
+ *     and if there are 1024 slots in the page that is another 10 bits
+ *     of the address.   that makes a 20 bit address, and as stated
+ *     earlier the board ignores the top 4 bits, so that accounts
+ *     for all 24 bits of address.
+ *
+ *     note that the last entry of the page map maps the top of the
+ *     24 bit address space and that the SCP is supposed to be at
+ *     0xfffff4 (taking into account allignment).   so,
+ *     for multibus, that entry in the page map has to be used for the SCP.
+ *
+ *     the page map effects BOTH how the ie chip sees the
+ *     memory, and how the host sees it.
+ *
+ *     the page map is part of the "register" area of the board
+ *
+ *   on-board interface:
+ *
+ *     <fill in useful info later>
+ *
+ *
+ *   VME3E interface:
+ *
+ *     <fill in useful info later>
+ *
+ */
+
+/*
+ * PART 1: VME/multibus defs
+ */
+#define IEVME_PAGESIZE 1024    /* bytes */
+#define IEVME_PAGSHIFT 10      /* bits */
+#define IEVME_NPAGES   256     /* number of pages on chip */
+#define IEVME_MAPSZ    1024    /* number of entries in the map */
+
+/*
+ * PTE for the page map
+ */
+#define IEVME_SBORDR 0x8000    /* sun byte order */
+#define IEVME_IBORDR 0x0000    /* intel byte ordr */
+
+#define IEVME_P2MEM  0x2000    /* memory is on P2 */
+#define IEVME_OBMEM  0x0000    /* memory is on board */
+
+#define IEVME_PGMASK 0x0fff    /* gives the physical page frame number */
+
+struct ievme {
+       u_short pgmap[IEVME_MAPSZ];
+       u_short xxx[32];        /* prom */
+       u_short status;         /* see below for bits */
+       u_short xxx2;           /* filler */
+       u_short pectrl;         /* parity control (see below) */
+       u_short peaddr;         /* low 16 bits of address */
+};
+
+/*
+ * status bits
+ */
+#define IEVME_RESET 0x8000     /* reset board */
+#define IEVME_ONAIR 0x4000     /* go out of loopback 'on-air' */
+#define IEVME_ATTEN 0x2000     /* attention */
+#define IEVME_IENAB 0x1000     /* interrupt enable */
+#define IEVME_PEINT 0x0800     /* parity error interrupt enable */
+#define IEVME_PERR  0x0200     /* parity error flag */
+#define IEVME_INT   0x0100     /* interrupt flag */
+#define IEVME_P2EN  0x0020     /* enable p2 bus */
+#define IEVME_256K  0x0010     /* 256kb rams */
+#define IEVME_HADDR 0x000f     /* mask for bits 17-20 of address */
+
+/*
+ * parity control
+ */
+#define IEVME_PARACK 0x0100    /* parity error ack */
+#define IEVME_PARSRC 0x0080    /* parity error source */
+#define IEVME_PAREND 0x0040    /* which end of the data got the error */
+#define IEVME_PARADR 0x000f    /* mask to get bits 17-20 of parity address */
+
+
+/*
+ * PART 2: the on-board interface
+ */
+struct ieob {
+       u_char  obctrl;
+};
+#define IEOB_NORSET 0x80       /* don't reset the board */
+#define IEOB_ONAIR  0x40       /* put us on the air */
+#define IEOB_ATTEN  0x20       /* attention! */
+#define IEOB_IENAB  0x10       /* interrupt enable */
+#define IEOB_XXXXX  0x08       /* free bit */
+#define IEOB_XCVRL2 0x04       /* level 2 transceiver? */
+#define IEOB_BUSERR 0x02       /* bus error */
+#define IEOB_INT    0x01       /* interrupt */
+
+/*
+ * PART 3: the 3E board
+ */
+
+/*
+ * not supported (yet?)
+ */
+
diff --git a/sys/arch/sun3/dev/if_ievar.h b/sys/arch/sun3/dev/if_ievar.h
new file mode 100644 (file)
index 0000000..a68c514
--- /dev/null
@@ -0,0 +1,121 @@
+/*     $NetBSD: if_ievar.h,v 1.6 1996/03/26 14:38:33 gwr Exp $ */
+
+/*
+ * Machine-dependent glue for the Intel Ethernet (ie) driver.
+ */
+
+#define B_PER_F         3      /* number of buffers to allocate per frame */
+#define        MXFRAMES        256     /* max number of frames to allow for receive */
+#define        MXRXBUF (MXFRAMES*B_PER_F)      /* max number of buffers to allocate */
+#define        IE_RBUF_SIZE    256     /* size of each buffer, MUST BE POWER OF TWO */
+#define        NTXBUF          2       /* number of transmit buffer/command pairs */
+#define        IE_TBUF_SIZE    (3*512) /* length of transmit buffer */
+
+enum ie_hardware {
+       IE_VME,                 /* multibus to VME ie card */
+       IE_OBIO,                /* on board */
+       IE_VME3E,               /* sun 3e VME card */
+       IE_UNKNOWN
+};
+
+/*
+ * Ethernet status, per interface.
+ *
+ * hardware addresses/sizes to know (all KVA):
+ *   sc_iobase = base of chip's 24 bit address space
+ *   sc_maddr  = base address of chip RAM as stored in ie_base of iscp
+ *   sc_msize  = size of chip's RAM
+ *   sc_reg    = address of card dependent registers
+ *
+ * the chip uses two types of pointers: 16 bit and 24 bit
+ *   16 bit pointers are offsets from sc_maddr/ie_base
+ *      KVA(16 bit offset) = offset + sc_maddr
+ *   24 bit pointers are offset from sc_iobase in KVA
+ *      KVA(24 bit address) = address + sc_iobase
+ *
+ * on the vme/multibus we have the page map to control where ram appears
+ * in the address space.   we choose to have RAM start at 0 in the
+ * 24 bit address space.   this means that sc_iobase == sc_maddr!
+ * to get the phyiscal address of the board's RAM you must take the
+ * top 12 bits of the physical address of the register address
+ * and or in the 4 bits from the status word as bits 17-20 (remember that
+ * the board ignores the chip's top 4 address lines).
+ * For example:
+ *   if the register is @ 0xffe88000, then the top 12 bits are 0xffe00000.
+ *   to get the 4 bits from the the status word just do status & IEVME_HADDR.
+ *   suppose the value is "4".   Then just shift it left 16 bits to get
+ *   it into bits 17-20 (e.g. 0x40000).    Then or it to get the
+ *   address of RAM (in our example: 0xffe40000).   see the attach routine!
+ *
+ * In the onboard ie interface, the 24 bit address space is hardwired
+ * to be 0xff000000 -> 0xffffffff of KVA.   this means that sc_iobase
+ * will be 0xff000000.   sc_maddr will be where ever we allocate RAM
+ * in KVA.    note that since the SCP is at a fixed address it means
+ * that we have to use some memory at a fixed KVA for the SCP.
+ * The Sun PROM leaves a page for us at the end of KVA space.
+ */
+struct ie_softc {
+       struct device sc_dev;   /* device structure */
+
+       struct arpcom sc_arpcom;/* system arpcom structure */
+#define        sc_if   sc_arpcom.ac_if                 /* network-visible interface */
+#define        sc_addr sc_arpcom.ac_enaddr             /* hardware Ethernet address */
+
+       caddr_t sc_iobase;      /* KVA of base of 24bit addr space */
+       caddr_t sc_maddr;       /* KVA of base of chip's RAM */
+       u_int   sc_msize;       /* how much RAM we have/use */
+       caddr_t sc_reg;         /* KVA of card's register */
+
+       enum ie_hardware hard_type;     /* card type */
+       void    (*reset_586)(); /* card dependent reset function */
+       void    (*chan_attn)(); /* card dependent attn function */
+       void    (*run_586)();   /* card dependent "go on-line" function */
+       void (*sc_bcopy) __P((const void *, void *, u_int));
+       void (*sc_bzero) __P((void *, u_int));
+
+       int     want_mcsetup;   /* flag for multicast setup */
+       int     promisc;        /* are we in promisc mode? */
+
+       /*
+        * pointers to the 3 major control structures
+        */
+       volatile struct ie_sys_conf_ptr *scp;
+       volatile struct ie_int_sys_conf_ptr *iscp;
+       volatile struct ie_sys_ctl_block *scb;
+
+       /*
+        * pointer and size of a block of KVA where the buffers
+        * are to be allocated from
+        */
+       caddr_t buf_area;
+       int     buf_area_sz;
+
+       /*
+        * the actual buffers (recv and xmit)
+        */
+       volatile struct ie_recv_frame_desc *rframes[MXFRAMES];
+       volatile struct ie_recv_buf_desc *rbuffs[MXRXBUF];
+       volatile char *cbuffs[MXRXBUF];
+       int     rfhead, rftail, rbhead, rbtail;
+
+       volatile struct ie_xmit_cmd *xmit_cmds[NTXBUF];
+       volatile struct ie_xmit_buf *xmit_buffs[NTXBUF];
+       u_char *xmit_cbuffs[NTXBUF];
+       int xmit_busy;
+       int xmit_free;
+       int xchead, xctail;
+
+       struct ie_en_addr mcast_addrs[MAXMCAST + 1];
+       int     mcast_count;
+
+       int nframes;      /* number of frames in use */
+       int nrxbuf;       /* number of recv buffs in use */
+
+#ifdef IEDEBUG
+       int     sc_debug;
+#endif
+};
+
+
+extern void    ie_attach __P((struct ie_softc *));
+extern int  ie_intr __P((void *));
index 7ce0b32..10d21fc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_le.c,v 1.24 1995/12/10 08:46:05 mycroft Exp $       */
+/*     $NetBSD: if_le.c,v 1.28 1996/04/22 02:25:54 christos Exp $      */
 
 /*-
  * Copyright (c) 1995 Charles M. Hannum.  All rights reserved.
 #define        LE_NEED_BUF_CONTIG
 #include <dev/ic/am7990var.h>
 
-#define        LE_SOFTC(unit)  lecd.cd_devs[unit]
+#define        LE_SOFTC(unit)  le_cd.cd_devs[unit]
 #define        LE_DELAY(x)     DELAY(x)
 
-int    lematch __P((struct device *, void *, void *));
-void   leattach __P((struct device *, struct device *, void *));
+static int     le_match __P((struct device *, void *, void *));
+static void    le_attach __P((struct device *, struct device *, void *));
 int    leintr __P((void *));
 
-struct cfdriver lecd = {
-       NULL, "le", lematch, leattach, DV_IFNET, sizeof(struct le_softc)
+struct cfattach le_ca = {
+       sizeof(struct le_softc), le_match, le_attach
 };
 
+struct cfdriver le_cd = {
+       NULL, "le", DV_IFNET
+};
+
+integrate void
+lehwinit(sc)
+       struct le_softc *sc;
+{
+}
+
 integrate void
 lewrcsr(sc, port, val)
        struct le_softc *sc;
@@ -104,17 +114,24 @@ lerdcsr(sc, port)
 } 
 
 int
-lematch(parent, match, aux)
+le_match(parent, vcf, aux)
        struct device *parent;
-       void *match, *aux;
+       void *vcf, *aux;
 {
+       struct cfdata *cf = vcf;
        struct confargs *ca = aux;
-       int x;
-
-       if (ca->ca_paddr == -1)
-               ca->ca_paddr = OBIO_AMD_ETHER;
-       if (ca->ca_intpri == -1)
-               ca->ca_intpri = 3;
+       int pa, x;
+
+       /*
+        * OBIO match functions may be called for every possible
+        * physical address, so match only our physical address.
+        */
+       if ((pa = cf->cf_paddr) == -1) {
+               /* Use our default PA. */
+               pa = OBIO_AMD_ETHER;
+       }
+       if (pa != ca->ca_paddr)
+               return (0);
 
        /* The peek returns -1 on bus error. */
        x = bus_peek(ca->ca_bustype, ca->ca_paddr, 1);
@@ -122,33 +139,66 @@ lematch(parent, match, aux)
 }
 
 void
-leattach(parent, self, aux)
+le_attach(parent, self, aux)
        struct device *parent, *self;
        void *aux;
 {
        struct le_softc *sc = (void *)self;
+       struct cfdata *cf = self->dv_cfdata;
        struct confargs *ca = aux;
+       int intpri;
+
+       /* Default interrupt level. */
+       if ((intpri = cf->cf_intpri) == -1)
+               intpri = 3;
+       printf(" level %d", intpri);
 
        sc->sc_r1 = (struct lereg1 *)
            obio_alloc(ca->ca_paddr, OBIO_AMD_ETHER_SIZE);
-       sc->sc_mem = dvma_malloc(MEMSIZE);
-       sc->sc_conf3 = LE_C3_BSWP;
+
+       sc->sc_memsize = 0x4000;        /* 16K */
+       sc->sc_mem = dvma_malloc(sc->sc_memsize);
        sc->sc_addr = (u_long)sc->sc_mem & 0xffffff;
-       sc->sc_memsize = MEMSIZE;
+       sc->sc_conf3 = LE_C3_BSWP;
 
        idprom_etheraddr(sc->sc_arpcom.ac_enaddr);
 
-       sc->sc_copytodesc = copytobuf_contig;
-       sc->sc_copyfromdesc = copyfrombuf_contig;
-       sc->sc_copytobuf = copytobuf_contig;
-       sc->sc_copyfrombuf = copyfrombuf_contig;
-       sc->sc_zerobuf = zerobuf_contig;
+       sc->sc_copytodesc = am7990_copytobuf_contig;
+       sc->sc_copyfromdesc = am7990_copyfrombuf_contig;
+       sc->sc_copytobuf = am7990_copytobuf_contig;
+       sc->sc_copyfrombuf = am7990_copyfrombuf_contig;
+       sc->sc_zerobuf = am7990_zerobuf_contig;
 
-       sc->sc_arpcom.ac_if.if_name = lecd.cd_name;
+       sc->sc_arpcom.ac_if.if_name = le_cd.cd_name;
        leconfig(sc);
 
        /* Install interrupt handler. */
-       isr_add_autovect(leintr, (void *)sc, ca->ca_intpri);
+       isr_add_autovect(leintr, (void *)sc, intpri);
 }
 
+/*
+ * Compare two Ether/802 addresses for equality, inlined and
+ * unrolled for speed.  I'd love to have an inline assembler
+ * version of this...   XXX: Who wanted that? mycroft?
+ * I wrote one, but the following is just as efficient.
+ * This expands to 10 short m68k instructions! -gwr
+ * Note: use this like bcmp()
+ */
+static inline u_short
+ether_cmp(one, two)
+       u_char *one, *two;
+{
+       register u_short *a = (u_short *) one;
+       register u_short *b = (u_short *) two;
+       register u_short diff;
+
+       diff  = *a++ - *b++;
+       diff |= *a++ - *b++;
+       diff |= *a++ - *b++;
+
+       return (diff);
+}
+
+#define        ETHER_CMP ether_cmp
+
 #include <dev/ic/am7990.c>
index da03421..e69de29 100644 (file)
@@ -1,28 +0,0 @@
-/*     $NetBSD: if_le.h,v 1.6 1995/01/03 15:43:38 gwr Exp $    */
-
-/*
- * Ethernet software status per interface.
- *
- * Each interface is referenced by a network interface structure,
- * arpcom, which the routing code uses to locate the interface.
- * This structure contains the output queue for the interface,
- * its address, ...
- */
-struct le_softc {
-       struct  device sc_dev;          /* base device */
-       struct  arpcom sc_ac;           /* common Ethernet structures */
-#define        sc_if           sc_ac.ac_if             /* network-visible interface */
-#define        sc_enaddr       sc_ac.ac_enaddr         /* hardware Ethernet address */
-
-       volatile struct le_regs *sc_regs;       /* LANCE registers */
-       void *sc_mem;           /* Shared RAM */
-
-       volatile struct init_block *sc_init;    /* Lance init. block */
-       volatile struct mds *sc_rd, *sc_td;
-       u_char  *sc_rbuf, *sc_tbuf;
-       int     sc_last_rd, sc_last_td;
-       int     sc_no_td;
-#ifdef LEDEBUG
-       int     sc_debug;
-#endif
-};
index c7649b4..e69de29 100644 (file)
@@ -1,108 +0,0 @@
-/*     $NetBSD: if_le_subr.c,v 1.12 1995/09/26 04:02:05 gwr Exp $      */
-
-/*
- * Copyright (c) 1994 Gordon W. Ross
- * Copyright (c) 1993 Adam Glass
- * 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 Adam Glass.
- * 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 Adam Glass ``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 Adam Glass 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.
- */
-
-/*
- * Machine-dependent glue for the LANCE Ethernet (le) driver.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/device.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <net/if.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/if_ether.h>
-#endif
-
-#include <machine/autoconf.h>
-#include <machine/cpu.h>
-#include <machine/dvma.h>
-#include <machine/isr.h>
-#include <machine/obio.h>
-#include <machine/idprom.h>
-
-#include "if_lereg.h"
-#include "if_le.h"
-#include "if_le_subr.h"
-
-int
-le_md_match(parent, vcf, args)
-       struct device *parent;
-       void *vcf, *args;
-{
-       struct cfdata *cf = vcf;
-       struct confargs *ca = args;
-       int x;
-
-       if (ca->ca_paddr == -1)
-               ca->ca_paddr = OBIO_AMD_ETHER;
-       if (ca->ca_intpri == -1)
-               ca->ca_intpri = 3;
-
-       /* The peek returns -1 on bus error. */
-       x = bus_peek(ca->ca_bustype, ca->ca_paddr, 1);
-       return (x != -1);
-}
-
-void
-le_md_attach(parent, self, args)
-       struct device *parent;
-       struct device *self;
-       void *args;
-{
-       struct le_softc *sc = (void *) self;
-       struct confargs *ca = args;
-       caddr_t p;
-
-       /* register access */
-       sc->sc_regs = (struct le_regs *)
-               obio_alloc(ca->ca_paddr, OBIO_AMD_ETHER_SIZE);
-       if (sc->sc_regs == NULL)
-               panic(": not enough obio space\n");
-
-       /* allocate "shared" memory */
-       sc->sc_mem = dvma_malloc(MEMSIZE);
-       if (sc->sc_mem == NULL)
-               panic(": not enough dvma space");
-
-       /* Install interrupt handler. */
-       isr_add_autovect(leintr, (void *)sc, ca->ca_intpri);
-       idprom_etheraddr(sc->sc_enaddr); /* ethernet addr */
-}
index c2cb658..e69de29 100644 (file)
@@ -1,8 +0,0 @@
-/*     $NetBSD: if_le_subr.h,v 1.7 1995/01/03 15:43:40 gwr Exp $       */
-
-/* One might also set: LE_ACON | LE_BCON */
-#define        LE_CONF3 (LE_BSWP)
-
-extern int  le_md_match(struct device *, void *, void *args);
-extern void le_md_attach(struct device *, struct device *, void *);
-extern int  leintr(void *);
index 07580be..01ac6fd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_lereg.h,v 1.11 1995/12/10 08:46:07 mycroft Exp $    */
+/*     $NetBSD: if_lereg.h,v 1.12 1996/03/26 14:42:20 gwr Exp $        */
 
 /*
  * Copyright (c) 1982, 1990 The Regents of the University of California.
@@ -35,8 +35,6 @@
  *     @(#)if_lereg.h  7.1 (Berkeley) 5/8/90
  */
 
-#define MEMSIZE 0x4000
-
 /*
  * LANCE registers.
  */
index 61307b5..862b831 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: kd.c,v 1.14 1996/01/24 22:40:20 gwr Exp $      */
+/*     $NetBSD: kd.c,v 1.16 1996/04/26 18:36:54 gwr Exp $      */
 
 /*
  * Copyright (c) 1994, 1995 Gordon W. Ross
@@ -329,10 +329,7 @@ kd_later(tpaddr)
 
        s = spltty();
        tp->t_state &= ~TS_BUSY;
-       if (tp->t_line)
                (*linesw[tp->t_line].l_start)(tp);
-       else
-               kdstart(tp);
        splx(s);
 }
 
@@ -360,7 +357,8 @@ static void kd_putfb(tp)
 }
 
 /*
- * Our "interrupt" routine for input.
+ * Our "interrupt" routine for input. This is called by
+ * the keyboard driver (dev/sun/kbd.c) at spltty.
  */
 void
 kd_input(c)
@@ -376,7 +374,7 @@ kd_input(c)
     if ((tp->t_state & TS_ISOPEN) == 0)
                return;
 
-       ttyinput(c, kd->kd_tty);
+       (*linesw[tp->t_line].l_rint)(c, tp);
 }
 
 
diff --git a/sys/arch/sun3/dev/memerr.c b/sys/arch/sun3/dev/memerr.c
new file mode 100644 (file)
index 0000000..e71b10f
--- /dev/null
@@ -0,0 +1,249 @@
+/*     $NetBSD: memerr.c,v 1.2 1996/04/07 05:47:28 gwr Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Lawrence Berkeley Laboratory.
+ *
+ * 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 the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *     @(#)memreg.c    8.1 (Berkeley) 6/11/93
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+#include <machine/obio.h>
+#include <machine/pte.h>
+
+#include <sun3/dev/memerr.h>
+/* #include <sun3/dev/eccreg.h> - not yet */
+
+#define        ME_PRI  7       /* Interrupt level (NMI) */
+
+extern unsigned char cpu_machine_id;
+
+enum memerr_type { ME_PAR = 0, ME_ECC = 1 };
+
+struct memerr_softc {
+       struct device sc_dev;
+       struct memerr *sc_reg;
+       enum memerr_type sc_type;
+       char *sc_typename;      /* "Parity" or "ECC" */
+       char *sc_csrbits;       /* how to print csr bits */
+       /* XXX: counters? */
+};
+
+static int  memerr_match __P((struct device *, void *vcf, void *args));
+static void memerr_attach __P((struct device *, struct device *, void *));
+static int  memerr_interrupt __P((void *));
+static void memerr_correctable __P((struct memerr_softc *));
+
+struct cfattach memerr_ca = {
+       sizeof(struct memerr_softc), memerr_match, memerr_attach
+};
+
+struct cfdriver memerr_cd = {
+       NULL, "memerr", DV_DULL
+};
+
+
+static int
+memerr_match(parent, vcf, args)
+    struct device *parent;
+    void *vcf, *args;
+{
+    struct cfdata *cf = vcf;
+       struct confargs *ca = args;
+       int pa, x;
+
+       /* This driver only supports one unit. */
+       if (cf->cf_unit != 0)
+               return (0);
+
+       if ((pa = cf->cf_paddr) == -1) {
+               /* Use our default PA. */
+               pa = OBIO_MEMERR;
+       }
+       if (pa != ca->ca_paddr)
+               return (0);
+
+       /* The peek returns -1 on bus error. */
+       x = bus_peek(ca->ca_bustype, ca->ca_paddr, 1);
+       return (x != -1);
+}
+
+static void
+memerr_attach(parent, self, args)
+       struct device *parent;
+       struct device *self;
+       void *args;
+{
+       struct memerr_softc *sc = (void *)self;
+       struct confargs *ca = args;
+       struct memerr *mer;
+
+       mer = (struct memerr *)
+           obio_alloc(ca->ca_paddr, sizeof(*mer));
+       if (mer == NULL)
+               panic(": can not map register");
+       sc->sc_reg = mer;
+
+       /*
+        * Which type of memory subsystem do we have?
+        */
+       switch (cpu_machine_id) {
+       case SUN3_MACH_160:             /* XXX: correct? */
+       case SUN3_MACH_260:
+               sc->sc_type = ME_ECC;
+               sc->sc_typename = "ECC";
+               sc->sc_csrbits = ME_ECC_STR;
+               break;
+
+       default:
+               sc->sc_type = ME_PAR;
+               sc->sc_typename = "Parity";
+               sc->sc_csrbits = ME_PAR_STR;
+               break;
+       }
+
+       printf(" (%s memory)\n", sc->sc_typename);
+
+       /* Install interrupt handler. */
+       isr_add_autovect(memerr_interrupt, (void *)sc, ME_PRI);
+
+       /* Enable error interrupt (and checking). */
+       if (sc->sc_type == ME_PAR)
+               mer->me_csr = ME_CSR_IENA | ME_PAR_CHECK;
+       else {
+               /*
+                * XXX:  Some day, figure out how to decode
+                * correctable errors and set ME_ECC_CE_ENA
+                * here so we can log them...
+                */
+               mer->me_csr = ME_CSR_IENA; /* | ME_ECC_CE_ENA */
+       }
+}
+
+/*****************************************************************
+ * Functions for ECC memory
+ *****************************************************************/
+
+static int
+memerr_interrupt(arg)
+       void *arg;
+{
+       struct memerr_softc *sc = arg;
+       volatile struct memerr *me = sc->sc_reg;
+       u_char csr, ctx, err;
+       u_int pa, va;
+       int pte;
+
+       csr = me->me_csr;
+       if ((csr & ME_CSR_IPEND) == 0)
+               return (0);
+
+       va = me->me_vaddr;
+       ctx = (va >> 28) & 0xF;
+       va &= 0x0FFFffff;
+       pte = get_pte(va);
+       pa = PG_PA(pte);
+
+       printf("\nMemory error on %s cycle!\n",
+               (ctx & 8) ? "DVMA" : "CPU");
+       printf(" ctx=%d, vaddr=0x%x, paddr=0x%x\n",
+                  (ctx & 7), va, pa);
+       printf(" csr=%b\n", csr, sc->sc_csrbits);
+
+       /*
+        * If we have parity-checked memory, there is
+        * not much to be done.  Any error is fatal.
+        */
+       if (sc->sc_type == ME_PAR) {
+               if (csr & ME_PAR_EMASK) {
+                       /* Parity errors are fatal. */
+                       goto die;
+               }
+               /* The IPEND bit was set, but no error bits. */
+               goto noerror;
+       }
+
+       /*
+        * We have ECC memory.  More complicated...
+        */
+       if (csr & (ME_ECC_WBTMO | ME_ECC_WBERR)) {
+               printf(" write-back failed, pte=0x%x\n", pte);
+               goto die;
+       }
+       if (csr & ME_ECC_UE) {
+               printf(" uncorrectable ECC error\n");
+               goto die;
+       }
+       if (csr & ME_ECC_CE) {
+               /* Just log this and continue. */
+               memerr_correctable(sc);
+               goto recover;
+       }
+       /* The IPEND bit was set, but no error bits. */
+       goto noerror;
+
+die:
+       panic("all bets are off...");
+
+noerror:
+       printf("memerr: no error bits set?\n");
+
+recover:
+       /* Clear the error by writing the address register. */
+       me->me_vaddr = 0;
+       return (1);
+}
+
+/*
+ * Announce (and log) a correctable ECC error.
+ * Need to look at the ECC syndrome register on
+ * the memory board that caused the error...
+ */
+void
+memerr_correctable(sc)
+       struct memerr_softc *sc;
+{
+       /* XXX: Not yet... */
+}
diff --git a/sys/arch/sun3/dev/memerr.h b/sys/arch/sun3/dev/memerr.h
new file mode 100644 (file)
index 0000000..9fafbaf
--- /dev/null
@@ -0,0 +1,95 @@
+/*     $NetBSD: memerr.h,v 1.1 1996/03/26 14:57:44 gwr Exp $ */
+
+/*
+ * Copyright (c) 1992, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Lawrence Berkeley Laboratory.
+ *
+ * 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 the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ *     @(#)memreg.h    8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * Sun3 memory error register.
+ *
+ * All Sun3 memory systems use either parity checking or
+ * Error Correction Coding (ECC).  A memory error causes
+ * the Memory Error Register (MER) to latch information
+ * about the location and type of error, and if the MER
+ * interrupt is enabled, generateds a level 7 interrupt.
+ * The latched information persists (even if more errors
+ * occur) until the MER is cleared by a write (at mer_er).
+ */
+
+
+struct memerr {
+       volatile u_char me_csr;         /* MER control/status reg. */
+       volatile u_char me__pad[3];
+       volatile u_int  me_vaddr;
+};
+
+/*
+ * Bits in me_csr common between ECC/parity memory systems:
+ */
+#define        ME_CSR_IPEND    0x80    /* (ro) error interrupt pending */
+#define        ME_CSR_IENA     0x40    /* (rw) error interrupt enable */
+
+/*
+ *  Bits in me_csr on parity-checked memory system:
+ */
+#define ME_PAR_TEST    0x20    /* (rw) write inverse parity */
+#define ME_PAR_CHECK   0x10    /* (rw) enable parity checking */
+#define ME_PAR_ERR3    0x08    /* (ro) parity error in <24..31> */
+#define ME_PAR_ERR2    0x04    /* (ro) parity error in <16..23> */
+#define ME_PAR_ERR1    0x02    /* (ro) parity error in <8..15> */
+#define ME_PAR_ERR0    0x01    /* (ro) parity error in <0..7> */
+#define        ME_PAR_EMASK    0x0F    /* (ro) mask of above four */
+#define ME_PAR_STR     "\20\10IPEND\7IENA\6TEST\5CHK\4ERR3\3ERR2\2ERR1\1ERR0"
+
+/*
+ *  Bits in me_csr on an ECC memory system:
+ */
+#define ME_ECC_BUSLK   0x20    /* (rw) hold memory bus mastership */
+#define ME_ECC_CE_ENA  0x10    /* (rw) enable CE recording */
+#define        ME_ECC_WBTMO    0x08    /* (ro) write-back timeout */
+#define        ME_ECC_WBERR    0x04    /* (ro) write-back error */
+#define ME_ECC_UE              0x02    /* (ro) UE, uncorrectable error  */
+#define ME_ECC_CE              0x01    /* (ro) CE, correctable (single bit) error */
+#define        ME_ECC_EMASK    0x0F    /* (ro) mask for some ECC error occuring */
+#define ME_ECC_STR     "\20\10IPEND\7IENA\6BUSLK\5CE_ENA\4TMOUT\3WBERR\2UE\1CE"
+
index 82b8c72..e69de29 100644 (file)
@@ -1,146 +0,0 @@
-MI 5380 driver
-==============
-
-(What?  Documentation?  Is this guy nuts? :-)
-
-Reselection
------------
-
-This driver will permit reselection on non-polled commands if
-sc->sc_flags & NCR5380_PERMIT_RESELECT is 1.  This permits enabling of
-reselection on a per-device basis.
-
-Disconnect/reselect is never permitted for polled commands.
-
-
-
-Interfacing the driver to MD code
----------------------------------
-
-/sys/dev/ic/ncr5380.c is now stand-alone.  DON'T include it after your
-MD stuff!
-
-This allows for more than one 5380-based SCSI board in your system.  This is
-a real possibility for Amiga generic kernels.
-
-Your driver's softc structure must have an instance of struct ncr5380_softc
-as the first thing in the structure.  The MD code must initialize the
-following:
-
-sci_*: pointers to the 5380 registers.  All accesses are done through
-  these pointers.  This indirection allows the driver to work with
-  boards that map the 5380 on even addresses only or do other
-  wierdnesses.
-
-int (*sc_pio_out)(sc, phase, datalen, data)
-int (*sc_pio_in)(sc, phase, datalen, data)
-  These point to functions that do programmed I/O transfers to the bus and
-  from the bus, respectively.  Arguments:
-
-  sc            points to the softc
-  phase         the current SCSI bus phase
-  datalen       length of data to transfer
-  data          pointer to the buffer
-
-  Both functions must return the number of bytes successfully transferred.
-  A transfer operation must be aborted if the target requests a different
-  phase before the transfer completes.
-
-  If you have no special requirements, you can point these to
-  ncr5380_pio_out() and ncr5380_pio_in() respectively.  If your board
-  can do pseudo-DMA, then you might want to point these to functions
-  that use this feature.
-
-void (*sc_dma_alloc)(sc)
-  This function is called to set up a DMA transfer.  You must create and
-  return a "DMA handle" in sc->sc_dma_hand which identifies the DMA transfer.
-  The driver will pass you your DMA handle in sc->sc_dma_hand for future
-  operations.  The contents of the DMA handle are immaterial to the MI
-  code - the DMA handle is for your bookkeeping only.  Usually, you
-  create a structure and point to it here.
-
-  For example, you can record the mapped and unmapped addresses of the
-  buffer.  The Sun driver places an Am9516 UDC control block in the DMA
-  handle.
-
-  If for some reason you decide not to do DMA for the transfer, make
-  sc->sc_dma_hand NULL.  This might happen if the proposed transfer is
-  misaligned, or in the wrong type of memory, or...
-
-void (*sc_dma_start)(sc)
-  This function starts the transfer.
-
-void (*sc_dma_stop)(sc)
-  This function stops a transfer.  sc->sc_datalen and sc->sc_dataptr must
-  be updated to reflect the portion of the DMA already done.
-
-void (*sc_dma_eop)(sc)
-  This function is called when the 5380 signals EOP.  Either continue
-  the DMA or stop the DMA.
-
-void (*sc_dma_free)(sc)
-  This function frees the current DMA handle.
-
-u_char *sc_dataptr;
-int sc_datalen;
-  These variables form the active SCSI data pointer.  DMA code must start
-  DMA at the location given, and update the pointer/length in response to
-  DMA operations.
-
-u_short sc_dma_flags;
-  See ncr5380var.h
-
-
-
-Writing your DMA code
----------------------
-
-DMA on a system with protected or virtual memory is always a problem.  Even
-though a disk transfer may be logically contiguous, the physical pages backing
-the transfer may not be.  There are two common solutions to this problem:
-
-DMA chains: the DMA is broken up into a list of contiguous segments.  The first
-segment is submitted to the DMA controller, and when it completes, the second
-segment is submitted, without stopping the 5380.  This is what the sc_dma_eop()
-function can do efficiently - if you have a DMA chain, it can quickly load up
-the next link in the chain.  The sc_dma_alloc() function builds the chain and
-sc_dma_free() releases any resources you used to build it.
-
-DVMA: Direct Virtual Memory Access.  In this scheme, DMA requests go through
-the MMU.  Although you can't page fault, you can program the MMU to remap
-things so the DMA controller sees contiguous data.  In this mode, sc_dma_alloc()
-is used to map the transfer into the address space reserved for DVMA and
-sc_dma_free() is used to unmap it.
-
-
-Interrupts
-----------
-
-ncr5380_sbc_intr() must be called when the 5380 interrupts the host.
-
-You must write an interrupt routine pretty much from scratch to check for
-things generated by MD hardware.
-
-
-Known problems
---------------
-
-I'm getting this out now so that other ports can hack on it and integrate it.
-
-The sun3, DMA/Interrupt appears to be working now, but needs testing.
-
-Polled commands submitted while non-polled commands are in progress are not
-handled correctly.  This can happen if reselection is enabled and a new disk
-is mounted while an I/O is in progress on another disk. 
-
-The problem is: what to do if you get reselected while doing the selection
-for the polled command?  Currently, the driver busy waits for the non-polled
-command to complete, but this is bogus.  I need to complete the non-polled
-command in polled mode, then do the polled command.
-
-
-Timeouts in the driver are EXTREMELY sensitive to the characteristics of the
-local implementation of delay().  The Sun3 version delays for a minimum of 5us.
-However, the driver must assume that delay(1) will delay only 1us.  For this
-reason, performance on the Sun3 sucks in some places.
-
index 5b7f7be..e69de29 100644 (file)
@@ -1,160 +0,0 @@
-/*     $NetBSD: ncr5380reg.h,v 1.2 1995/11/17 23:27:41 gwr Exp $       */
-
-/* 
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * HISTORY (mach3)
- * Revision 2.3  91/08/24  12:25:10  af
- *     Moved padding of regmap in impl file.
- *     [91/08/02  04:22:39  af]
- * 
- * Revision 2.2  91/06/19  16:28:35  rvb
- *     From the NCR data sheets
- *     "NCR 5380 Family, SCSI Protocol Controller Data Manual"
- *     NCR Microelectronics Division, Colorado Spring, 6/98 T01891L
- *     [91/04/21            af]
- * 
- */
-
-/*
- *     File: scsi_5380.h
- *     Author: Alessandro Forin, Carnegie Mellon University
- *     Date:   5/91
- *
- *     Defines for the NCR 5380 (SCSI chip), aka Am5380
- */
-
-/*
- * Register map:  Note not declared here anymore!
- * All the 5380 registers are accessed through individual
- * pointers initialized by MD code.  This allows the 5380
- * MI functions to be shared between MD drivers that have
- * different padding between the registers (i.e. amiga).
- */
-#if 0  /* example only */
-struct ncr5380regs {
-       volatile u_char sci_r0;
-       volatile u_char sci_r1;
-       volatile u_char sci_r2;
-       volatile u_char sci_r3;
-       volatile u_char sci_r4;
-       volatile u_char sci_r5;
-       volatile u_char sci_r6;
-       volatile u_char sci_r7;
-};
-#endif
-
-/*
- * Machine-independent code uses these names:
- */
-#define        sci_data        sci_r0  /* r:  Current data */
-#define        sci_odata       sci_r0  /* w:  Out data */
-
-#define        sci_icmd        sci_r1  /* rw: Initiator command */
-#define        sci_mode        sci_r2  /* rw: Mode */
-#define        sci_tcmd        sci_r3  /* rw: Target command */
-
-#define        sci_bus_csr     sci_r4  /* r:  Bus Status */
-#define sci_sel_enb sci_r4     /* w:  Select enable */
-
-#define        sci_csr          sci_r5 /* r:  Status */
-#define sci_dma_send sci_r5    /* w:  Start dma send data */
-
-#define        sci_idata       sci_r6  /* r:  Input data */
-#define        sci_trecv       sci_r6  /* w:  Start dma receive, target */
-
-#define        sci_iack        sci_r7  /* r:  Interrupt Acknowledge  */
-#define sci_irecv      sci_r7  /* w:  Start dma receive, initiator */
-
-
-/*
- * R1: Initiator command register
- */
-#define SCI_ICMD_DATA          0x01            /* rw: Assert data bus   */
-#define SCI_ICMD_ATN           0x02            /* rw: Assert ATN signal */
-#define SCI_ICMD_SEL           0x04            /* rw: Assert SEL signal */
-#define SCI_ICMD_BSY           0x08            /* rw: Assert BSY signal */
-#define SCI_ICMD_ACK           0x10            /* rw: Assert ACK signal */
-#define SCI_ICMD_LST           0x20            /* r:  Lost arbitration */
-#define SCI_ICMD_DIFF  SCI_ICMD_LST            /* w:  Differential cable */
-#define SCI_ICMD_AIP           0x40            /* r:  Arbitration in progress */
-#define SCI_ICMD_TEST  SCI_ICMD_AIP            /* w:  Test mode */
-#define SCI_ICMD_RST           0x80            /* rw: Assert RST signal */
-/* Bits to keep when doing read/modify/write (leave out RST) */
-#define SCI_ICMD_RMASK         0x1F
-
-
-/*
- * R2: Mode register
- */
-#define SCI_MODE_ARB           0x01            /* rw: Start arbitration */
-#define SCI_MODE_DMA           0x02            /* rw: Enable DMA xfers */
-#define SCI_MODE_MONBSY                0x04            /* rw: Monitor BSY signal */
-#define SCI_MODE_DMA_IE                0x08            /* rw: Enable DMA complete interrupt */
-#define SCI_MODE_PERR_IE       0x10            /* rw: Interrupt on parity errors */
-#define SCI_MODE_PAR_CHK       0x20            /* rw: Check parity */
-#define SCI_MODE_TARGET                0x40            /* rw: Target mode (Initiator if 0) */
-#define SCI_MODE_BLOCKDMA      0x80            /* rw: Block-mode DMA handshake */
-
-
-/*
- * R3: Target command register
- */
-#define SCI_TCMD_IO            0x01            /* rw: Assert I/O signal */
-#define SCI_TCMD_CD            0x02            /* rw: Assert C/D signal */
-#define SCI_TCMD_MSG           0x04            /* rw: Assert MSG signal */
-#define SCI_TCMD_PHASE_MASK    0x07            /* r:  Mask for current bus phase */
-#define SCI_TCMD_REQ           0x08            /* rw: Assert REQ signal */
-#define        SCI_TCMD_LAST_SENT      0x80            /* ro: Last byte was xferred
-                                                *     (not on 5380/1) */
-
-#define        SCI_TCMD_PHASE(x)               ((x) & 0x7)
-
-/*
- * R4: Current (SCSI) Bus status (.sci_bus_csr)
- */
-#define SCI_BUS_DBP            0x01            /* r:  Data Bus parity */
-#define SCI_BUS_SEL            0x02            /* r:  SEL signal */
-#define SCI_BUS_IO             0x04            /* r:  I/O signal */
-#define SCI_BUS_CD             0x08            /* r:  C/D signal */
-#define SCI_BUS_MSG            0x10            /* r:  MSG signal */
-#define SCI_BUS_REQ            0x20            /* r:  REQ signal */
-#define SCI_BUS_BSY            0x40            /* r:  BSY signal */
-#define SCI_BUS_RST            0x80            /* r:  RST signal */
-
-#define        SCI_BUS_PHASE(x)        (((x) >> 2) & 7)
-
-/*
- * R5: Bus and Status register (.sci_csr)
- */
-#define SCI_CSR_ACK            0x01            /* r:  ACK signal */
-#define SCI_CSR_ATN            0x02            /* r:  ATN signal */
-#define SCI_CSR_DISC           0x04            /* r:  Disconnected (BSY==0) */
-#define SCI_CSR_PHASE_MATCH    0x08            /* r:  Bus and SCI_TCMD match */
-#define SCI_CSR_INT            0x10            /* r:  Interrupt request */
-#define SCI_CSR_PERR           0x20            /* r:  Parity error */
-#define SCI_CSR_DREQ           0x40            /* r:  DMA request */
-#define SCI_CSR_DONE           0x80            /* r:  DMA count is zero */
index 3060cbb..e69de29 100644 (file)
-/*     $NetBSD: ncr5380sbc.c,v 1.2 1995/11/17 23:27:45 gwr Exp $       */
-
-/*
- * Copyright (c) 1995 David Jones, Gordon W. Ross
- * Copyright (c) 1994 Jarle Greipsland
- * 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. 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
- *    must display the following acknowledgement:
- *      This product includes software developed by
- *      David Jones and Gordon Ross
- *
- * 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 is a machine-independent driver for the NCR5380
- * SCSI Bus Controller (SBC), also known as the Am5380.
- *
- * This code should work with any memory-mapped 5380,
- * and can be shared by multiple adapters that address
- * the 5380 with different register offset spacings.
- * (This can happen on the atari, for example.)
- * For porting/design info. see: ncr5380.doc
- *
- * Credits, history:
- *
- * David Jones is the author of most of the code that now
- * appears in this file, and was the architect of the
- * current overall structure (MI/MD code separation, etc.)
- *
- * Gordon Ross integrated the message phase code, added lots of
- * comments about what happens when and why (re. SCSI spec.),
- * debugged some reentrance problems, and added several new
- * "hooks" needed for the Sun3 "si" adapters.
- *
- * The message in/out code was taken nearly verbatim from
- * the aic6360 driver by Jarle Greipsland.
- *
- * Several other NCR5380 drivers were used for reference
- * while developing this driver, including work by:
- *   The Alice Group (mac68k port) namely:
- *       Allen K. Briggs, Chris P. Caputo, Michael L. Finch,
- *       Bradley A. Grantham, and Lawrence A. Kesteloot
- *   Michael L. Hitch (amiga drivers: sci.c)
- *   Leo Weppelman (atari driver: ncr5380.c)
- * There are others too.  Thanks, everyone.
- */
-
-#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/buf.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-
-#include <scsi/scsi_all.h>
-#include <scsi/scsi_debug.h>
-#include <scsi/scsi_message.h>
-#include <scsi/scsiconf.h>
-
-#define DEBUG XXX
-
-#if 0  /* XXX - not yet... */
-#include <dev/ic/ncr5380reg.h>
-#include <dev/ic/ncr5380var.h>
-#else
-#include "ncr5380reg.h"
-#include "ncr5380var.h"
-#endif
-
-static int     ncr5380_wait_req __P((struct ncr5380_softc *));
-static int     ncr5380_wait_not_req __P((struct ncr5380_softc *));
-
-static void    ncr5380_sched __P((struct ncr5380_softc *));
-static void    ncr5380_done __P((struct ncr5380_softc *));
-
-static int     ncr5380_select
-       __P((struct ncr5380_softc *, struct sci_req *));
-static void    ncr5380_reselect __P((struct ncr5380_softc *));
-
-static int     ncr5380_msg_in __P((struct ncr5380_softc *));
-static int     ncr5380_msg_out __P((struct ncr5380_softc *));
-static int     ncr5380_data_xfer __P((struct ncr5380_softc *, int));
-static int     ncr5380_command __P((struct ncr5380_softc *));
-static int     ncr5380_status __P((struct ncr5380_softc *));
-static void    ncr5380_machine __P((struct ncr5380_softc *));
-
-/*
- * Action flags returned by the info_tranfer functions:
- * (These determine what happens next.)
- */
-#define ACT_CONTINUE   0x00    /* No flags: expect another phase */
-#define ACT_DISCONNECT 0x01    /* Target is disconnecting */
-#define ACT_CMD_DONE   0x02    /* Need to call scsi_done() */
-#define ACT_RESET_BUS  0x04    /* Need bus reset (cmd timeout) */
-#define ACT_WAIT_DMA   0x10    /* Wait for DMA to complete */
-
-/*****************************************************************
- * Debugging stuff
- *****************************************************************/
-
-#ifdef DDB
-int Debugger();
-#else
-/* This is used only in recoverable places. */
-#define Debugger() printf("Debug: ncr5380.c:%d\n", __LINE__)
-#endif
-
-#ifdef DEBUG
-
-#define        NCR_DBG_BREAK   1
-#define        NCR_DBG_CMDS    2
-int ncr5380_debug = NCR_DBG_BREAK;
-#define        NCR_BREAK() \
-       do { if (ncr5380_debug & NCR_DBG_BREAK) Debugger(); } while (0)
-static void ncr5380_show_scsi_cmd __P((struct scsi_xfer *));
-static void ncr5380_show_sense __P((struct scsi_xfer *));
-#else  /* DEBUG */
-#define        NCR_BREAK()             /* nada */
-#define ncr5380_show_scsi_cmd(xs) /* nada */
-#define ncr5380_show_sense(xs) /* nada */
-#endif /* DEBUG */
-
-static char *
-phase_names[8] = {
-       "DATA_OUT",
-       "DATA_IN",
-       "COMMAND",
-       "STATUS",
-       "UNSPEC1",
-       "UNSPEC2",
-       "MSG_OUT",
-       "MSG_IN",
-};
-
-/*****************************************************************
- * Actual chip control
- *****************************************************************/
-
-/*
- * XXX: These timeouts might need to be tuned...
- */
-
-/* This one is used when waiting for a phase change. (X100uS.) */
-int ncr5380_wait_phase_timo = 1000 * 10 * 300; /* 5 min. */
-
-/* These are used in the following inline functions. */
-int ncr5380_wait_req_timo = 1000 * 50; /* X2 = 100 mS. */
-int ncr5380_wait_nrq_timo = 1000 * 25; /* X2 =  50 mS. */
-
-/* Return zero on success. */
-static __inline__ int ncr5380_wait_req(sc)
-       struct ncr5380_softc *sc;
-{
-       register int timo = ncr5380_wait_req_timo;
-       for (;;) {
-               if (*sc->sci_bus_csr & SCI_BUS_REQ) {
-                       timo = 0;       /* return 0 */
-                       break;
-               }
-               if (--timo < 0)
-                       break;  /* return -1 */
-               delay(2);
-       }
-       return (timo);
-}
-
-/* Return zero on success. */
-static __inline__ int ncr5380_wait_not_req(sc)
-       struct ncr5380_softc *sc;
-{
-       register int timo = ncr5380_wait_nrq_timo;
-       for (;;) {
-               if ((*sc->sci_bus_csr & SCI_BUS_REQ) == 0) {
-                       timo = 0;       /* return 0 */
-                       break;
-               }
-               if (--timo < 0)
-                       break;  /* return -1 */
-               delay(2);
-       }
-       return (timo);
-}
-
-/* Ask the target for a MSG_OUT phase. */
-static __inline__ void
-ncr_sched_msgout(sc, msg_code)
-       struct ncr5380_softc *sc;
-       int msg_code;
-{
-       /* First time, raise ATN line. */
-       if (sc->sc_msgpriq == 0) {
-               register u_char icmd;
-               icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
-               *sc->sci_icmd = icmd | SCI_ICMD_ATN;
-               delay(2);
-       }
-       sc->sc_msgpriq |= msg_code;
-}
-
-
-int
-ncr5380_pio_out(sc, phase, count, data)
-       struct ncr5380_softc *sc;
-       int phase, count;
-       unsigned char           *data;
-{
-       register u_char         icmd;
-       register int            resid;
-       register int            error;
-
-       icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
-
-       icmd |= SCI_ICMD_DATA;
-       *sc->sci_icmd = icmd;
-
-       resid = count;
-       while (resid > 0) {
-               if (!SCI_BUSY(sc)) {
-                       NCR_TRACE("pio_out: lost BSY, resid=%d\n", resid);
-                       break;
-               }
-               if (ncr5380_wait_req(sc)) {
-                       NCR_TRACE("pio_out: no REQ, resid=%d\n", resid);
-                       break;
-               }
-               if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
-                       break;
-
-               /* Put the data on the bus. */
-               *sc->sci_odata = *data++;
-
-               /* Tell the target it's there. */
-               icmd |= SCI_ICMD_ACK;
-               *sc->sci_icmd = icmd;
-
-               /* Wait for target to get it. */
-               error = ncr5380_wait_not_req(sc);
-
-               /* OK, it's got it (or we gave up waiting). */
-               icmd &= ~SCI_ICMD_ACK;
-               *sc->sci_icmd = icmd;
-
-               if (error) {
-                       NCR_TRACE("pio_out: stuck REQ, resid=%d\n", resid);
-                       break;
-               }
-
-               --resid;
-       }
-
-       /* Stop driving the data bus. */
-       icmd &= ~SCI_ICMD_DATA;
-       *sc->sci_icmd = icmd;
-
-       return (count - resid);
-}
-
-
-int
-ncr5380_pio_in(sc, phase, count, data)
-       struct ncr5380_softc *sc;
-       int phase, count;
-       unsigned char                   *data;
-{
-       register u_char         icmd;
-       register int            resid;
-       register int            error;
-
-       icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
-
-       resid = count;
-       while (resid > 0) {
-               if (!SCI_BUSY(sc)) {
-                       NCR_TRACE("pio_in: lost BSY, resid=%d\n", resid);
-                       break;
-               }
-               if (ncr5380_wait_req(sc)) {
-                       NCR_TRACE("pio_in: no REQ, resid=%d\n", resid);
-                       break;
-               }
-               /* A phase change is not valid until AFTER REQ rises! */
-               if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
-                       break;
-
-               /* Read the data bus. */
-               *data++ = *sc->sci_data;
-
-               /* Tell target we got it. */
-               icmd |= SCI_ICMD_ACK;
-               *sc->sci_icmd = icmd;
-
-               /* Wait for target to drop REQ... */
-               error = ncr5380_wait_not_req(sc);
-
-               /* OK, we can drop ACK. */
-               icmd &= ~SCI_ICMD_ACK;
-               *sc->sci_icmd = icmd;
-
-               if (error) {
-                       NCR_TRACE("pio_in: stuck REQ, resid=%d\n", resid);
-                       break;
-               }
-
-               --resid;
-       }
-
-       return (count - resid);
-}
-
-
-void
-ncr5380_init(sc)
-       struct ncr5380_softc *sc;
-{
-       int i, j;
-
-#ifdef DEBUG
-       ncr5380_debug_sc = sc;
-#endif
-
-       for (i = 0; i < SCI_OPENINGS; i++)
-               sc->sc_ring[i].sr_xs = NULL;
-       for (i = 0; i < 8; i++)
-               for (j = 0; j < 8; j++)
-                       sc->sc_matrix[i][j] = NULL;
-
-       sc->sc_link.openings = 2;       /* XXX - Not SCI_OPENINGS */
-       sc->sc_prevphase = PHASE_INVALID;
-       sc->sc_state = NCR_IDLE;
-
-       *sc->sci_tcmd = PHASE_INVALID;
-       *sc->sci_icmd = 0;
-       *sc->sci_mode = 0;
-       *sc->sci_sel_enb = 0;
-       SCI_CLR_INTR(sc);
-
-       /* XXX: Enable reselect interrupts... */
-       *sc->sci_sel_enb = 0x80;
-
-       /* Another hack (Er.. hook!) for the sun3 si: */
-       if (sc->sc_intr_on) {
-               NCR_TRACE("init: intr ON\n", 0);
-               sc->sc_intr_on(sc);
-       }
-}
-
-
-void
-ncr5380_reset_scsibus(sc)
-       struct ncr5380_softc *sc;
-{
-
-       NCR_TRACE("reset_scsibus, cur=0x%x\n",
-                         (long) sc->sc_current);
-
-       *sc->sci_icmd = SCI_ICMD_RST;
-       delay(500);
-       *sc->sci_icmd = 0;
-
-       *sc->sci_mode = 0;
-       *sc->sci_tcmd = PHASE_INVALID;
-
-       SCI_CLR_INTR(sc);
-       /* XXX - Need long delay here! */
-       delay(100000);
-
-       /* XXX - Need to cancel disconnected requests. */
-}
-
-
-/*
- * Interrupt handler for the SCSI Bus Controller (SBC)
- * This may also called for a DMA timeout (at splbio).
- */
-int
-ncr5380_intr(sc)
-       struct ncr5380_softc *sc;
-{
-       int claimed = 0;
-
-       /*
-        * Do not touch SBC regs here unless sc_current == NULL
-        * or it will complain about "register conflict" errors.
-        * Instead, just let ncr5380_machine() deal with it.
-        */
-       NCR_TRACE("intr: top, state=%d\n", sc->sc_state);
-
-       if (sc->sc_state == NCR_IDLE) {
-               /*
-                * Might be reselect.  ncr5380_reselect() will check,
-                * and set up the connection if so.  This will verify
-                * that sc_current == NULL at the beginning...
-                */
-
-               /* Another hack (Er.. hook!) for the sun3 si: */
-               if (sc->sc_intr_off) {
-                       NCR_TRACE("intr: for reselect, intr off\n", 0);
-                   sc->sc_intr_off(sc);
-               }
-
-               ncr5380_reselect(sc);
-       }
-
-       /*
-        * The remaining documented interrupt causes are phase mismatch and
-        * disconnect.  In addition, the sunsi controller may produce a state
-        * where SCI_CSR_DONE is false, yet DMA is complete.
-        *
-        * The procedure in all these cases is to let ncr5380_machine()
-        * figure out what to do next.
-        */
-       if (sc->sc_state & NCR_WORKING) {
-               NCR_TRACE("intr: call machine, cur=0x%x\n",
-                                 (long) sc->sc_current);
-               /* This will usually free-up the nexus. */
-               ncr5380_machine(sc);
-               NCR_TRACE("intr: machine done, cur=0x%x\n",
-                                 (long) sc->sc_current);
-               claimed = 1;
-       }
-
-       /* Maybe we can run some commands now... */
-       if (sc->sc_state == NCR_IDLE) {
-               NCR_TRACE("intr: call sched, cur=0x%x\n",
-                                 (long) sc->sc_current);
-               ncr5380_sched(sc);
-               NCR_TRACE("intr: sched done, cur=0x%x\n",
-                                 (long) sc->sc_current);
-       }
-
-       return claimed;
-}
-
-
-/*
- * Abort the current command (i.e. due to timeout)
- */
-void
-ncr5380_abort(sc)
-       struct ncr5380_softc *sc;
-{
-
-       /*
-        * Finish it now.  If DMA is in progress, we
-        * can not call ncr_sched_msgout() because
-        * that hits the SBC (avoid DMA conflict).
-        */
-
-       /* Another hack (Er.. hook!) for the sun3 si: */
-       if (sc->sc_intr_off) {
-               NCR_TRACE("abort: intr off\n", 0);
-               sc->sc_intr_off(sc);
-       }
-
-       sc->sc_state |= NCR_ABORTING;
-       if ((sc->sc_state & NCR_DOINGDMA) == 0) {
-               ncr_sched_msgout(sc, SEND_ABORT);
-       }
-       NCR_TRACE("abort: call machine, cur=0x%x\n",
-                         (long) sc->sc_current);
-       ncr5380_machine(sc);
-       NCR_TRACE("abort: machine done, cur=0x%x\n",
-                         (long) sc->sc_current);
-
-       /* Another hack (Er.. hook!) for the sun3 si: */
-       if (sc->sc_intr_on) {
-               NCR_TRACE("abort: intr ON\n", 0);
-           sc->sc_intr_on(sc);
-       }
-}
-
-/*
- * Timeout handler, scheduled for each SCSI command.
- */
-void
-ncr5380_cmd_timeout(arg)
-       void *arg;
-{
-       struct sci_req *sr = arg;
-       struct scsi_xfer *xs;
-       struct scsi_link *sc_link;
-       struct ncr5380_softc *sc;
-       int s;
-
-       s = splbio();
-
-       /* Get all our variables... */
-       xs = sr->sr_xs;
-       if (xs == NULL) {
-               printf("ncr5380_cmd_timeout: no scsi_xfer\n");
-               goto out;
-       }
-       sc_link = xs->sc_link;
-       sc = sc_link->adapter_softc;
-
-       printf("%s: cmd timeout, targ=%d, lun=%d\n",
-                  sc->sc_dev.dv_xname,
-                  sr->sr_target, sr->sr_lun);
-
-       /*
-        * Mark the overdue job as failed, and arrange for
-        * ncr5380_machine to terminate it.  If the victim
-        * is the current job, call ncr5380_machine() now.
-        * Otherwise arrange for ncr5380_sched() to do it.
-        */
-       sr->sr_flags |= SR_OVERDUE;
-       if (sc->sc_current == sr) {
-               NCR_TRACE("cmd_tmo: call abort, sr=0x%x\n", (long) sr);
-               ncr5380_abort(sc);
-       } else {
-               /*
-                * The driver may be idle, or busy with another job.
-                * Arrange for ncr5380_sched() to do the deed.
-                */
-               NCR_TRACE("cmd_tmo: clear matrix, t/l=0x%02x\n",
-                                 (sr->sr_target << 4) | sr->sr_lun);
-               sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
-       }
-
-       /*
-        * We may have aborted the current job, or may have
-        * already been idle. In either case, we should now
-        * be idle, so try to start another job.
-        */
-       if (sc->sc_state == NCR_IDLE) {
-               NCR_TRACE("cmd_tmo: call sched, cur=0x%x\n",
-                                 (long) sc->sc_current);
-               ncr5380_sched(sc);
-               NCR_TRACE("cmd_tmo: sched done, cur=0x%x\n",
-                                 (long) sc->sc_current);
-       }
-
-out:
-       splx(s);
-}
-
-
-/*****************************************************************
- * Interface to higher level
- *****************************************************************/
-
-
-/*
- * Enter a new SCSI command into the "issue" queue, and
- * if there is work to do, start it going.
- *
- * WARNING:  This can be called recursively!
- * (see comment in ncr5380_done)
- */
-int
-ncr5380_scsi_cmd(xs)
-       struct scsi_xfer *xs;
-{
-       struct  ncr5380_softc *sc;
-       struct sci_req  *sr;
-       int s, rv, i, flags;
-       extern int cold;                /* XXX */
-
-       sc = xs->sc_link->adapter_softc;
-
-       flags = xs->flags;
-       /*
-        * XXX: Hack: During autoconfig, force polling mode.
-        * Needed as long as sdsize() can be called while cold,
-        * otherwise timeouts will never call back (grumble).
-        */
-       if (cold)
-               flags |= SCSI_POLL;
-
-       if (sc->sc_flags & NCR5380_FORCE_POLLING)
-               flags |= SCSI_POLL;
-
-       if (flags & SCSI_DATA_UIO)
-               panic("ncr5380: scsi data uio requested");
-
-       s = splbio();
-
-       if (flags & SCSI_POLL) {
-               /* Terminate any current command. */
-               sr = sc->sc_current;
-               if (sr) {
-                       printf("%s: polled request aborting %d/%d\n",
-                                  sc->sc_dev.dv_xname,
-                                  sr->sr_target, sr->sr_lun);
-                       ncr5380_abort(sc);
-               }
-               if (sc->sc_state != NCR_IDLE) {
-                       panic("ncr5380_scsi_cmd: polled request, abort failed");
-               }
-       }
-
-       /*
-        * Find lowest empty slot in ring buffer.
-        * XXX: What about "fairness" and cmd order?
-        */
-       for (i = 0; i < SCI_OPENINGS; i++)
-               if (sc->sc_ring[i].sr_xs == NULL)
-                       goto new;
-
-       rv = TRY_AGAIN_LATER;
-       NCR_TRACE("scsi_cmd: no openings, rv=%d\n", rv);
-       goto out;
-
-new:
-       /* Create queue entry */
-       sr = &sc->sc_ring[i];
-       sr->sr_xs = xs;
-       sr->sr_target = xs->sc_link->target;
-       sr->sr_lun = xs->sc_link->lun;
-       sr->sr_dma_hand = NULL;
-       sr->sr_dataptr = xs->data;
-       sr->sr_datalen = xs->datalen;
-       sr->sr_flags = (flags & SCSI_POLL) ? SR_IMMED : 0;
-       sr->sr_status = -1;     /* no value */
-       sc->sc_ncmds++;
-       rv = SUCCESSFULLY_QUEUED;
-
-       NCR_TRACE("scsi_cmd: new sr=0x%x\n", (long)sr);
-
-       if (flags & SCSI_POLL) {
-               /* Force this new command to be next. */
-               sc->sc_rr = i;
-       }
-
-       /*
-        * If we were idle, run some commands...
-        */
-       if (sc->sc_state == NCR_IDLE) {
-               NCR_TRACE("scsi_cmd: call sched, cur=0x%x\n",
-                                 (long) sc->sc_current);
-               ncr5380_sched(sc);
-               NCR_TRACE("scsi_cmd: sched done, cur=0x%x\n",
-                                 (long) sc->sc_current);
-       }
-
-       if (flags & SCSI_POLL) {
-               /* Make sure ncr5380_sched() finished it. */
-               if ((xs->flags & ITSDONE) == 0)
-                       panic("ncr5380_scsi_cmd: poll didn't finish");
-               rv = COMPLETE;
-       }
-
-out:
-       splx(s);
-       return (rv);
-}
-
-
-/*
- * POST PROCESSING OF SCSI_CMD (usually current)
- * Called by ncr5380_sched(), ncr5380_machine()
- */
-static void
-ncr5380_done(sc)
-       struct ncr5380_softc *sc;
-{
-       struct  sci_req *sr;
-       struct  scsi_xfer *xs;
-
-#ifdef DIAGNOSTIC
-       if ((getsr() & PSL_IPL) < PSL_IPL2)
-               panic("ncr5380_done: bad spl");
-       if (sc->sc_state == NCR_IDLE)
-               panic("ncr5380_done: state=idle");
-       if (sc->sc_current == NULL)
-               panic("ncr5380_done: current=0");
-#endif
-
-       sr = sc->sc_current;
-       xs = sr->sr_xs;
-
-       NCR_TRACE("done: top, cur=0x%x\n", (long) sc->sc_current);
-
-       /*
-        * Clean up DMA resources for this command.
-        */
-       if (sr->sr_dma_hand) {
-               NCR_TRACE("done: dma_free, dh=0x%x\n",
-                                 (long) sr->sr_dma_hand);
-               (*sc->sc_dma_free)(sc);
-       }
-#ifdef DIAGNOSTIC
-       if (sr->sr_dma_hand)
-               panic("ncr5380_done: dma free did not");
-#endif
-
-       if (sc->sc_state & NCR_ABORTING) {
-               NCR_TRACE("done: aborting, error=%d\n", xs->error);
-               if (xs->error == XS_NOERROR)
-                       xs->error = XS_TIMEOUT;
-       }
-
-       NCR_TRACE("done: check error=%d\n", (long) xs->error);
-
-       /* If error is already set, ignore sr_status value. */
-       if (xs->error != XS_NOERROR)
-               goto finish;
-
-       NCR_TRACE("done: check status=%d\n", sr->sr_status);
-
-       switch (sr->sr_status) {
-       case SCSI_OK:   /* 0 */
-               if (sr->sr_flags & SR_SENSE) {
-                       if (ncr5380_debug & NCR_DBG_CMDS) {
-                               ncr5380_show_sense(xs);
-                       }
-                       xs->error = XS_SENSE;
-               }
-               break;
-
-       case SCSI_CHECK:
-               if (sr->sr_flags & SR_SENSE) {
-                       /* Sense command also asked for sense? */
-                       printf("ncr5380_done: sense asked for sense\n");
-                       NCR_BREAK();
-                       xs->error = XS_DRIVER_STUFFUP;
-                       break;
-               }
-               sr->sr_flags |= SR_SENSE;
-               NCR_TRACE("done: get sense, sr=0x%x\n", (long) sr);
-               /*
-                * Leave queued, but clear sc_current so we start over
-                * with selection.  Guaranteed to get the same request.
-                */
-               sc->sc_state = NCR_IDLE;
-               sc->sc_current = NULL;
-               sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
-               return;         /* XXX */
-
-       case SCSI_BUSY:
-               xs->error = XS_BUSY;
-               break;
-
-       case -1:
-               /* This is our "impossible" initial value. */
-               /* fallthrough */
-       default:
-               printf("%s: target %d, bad status=%d\n",
-                       sc->sc_dev.dv_xname, sr->sr_target, sr->sr_status);
-               xs->error = XS_DRIVER_STUFFUP;
-               break;
-       }
-
-finish:
-
-       NCR_TRACE("done: finish, error=%d\n", xs->error);
-
-       /*
-        * Dequeue the finished command, but don't clear sc_state until
-        * after the call to scsi_done(), because that may call back to
-        * ncr5380_scsi_cmd() - unwanted recursion!
-        *
-        * Keeping sc->sc_state != idle terminates the recursion.
-        */
-#ifdef DIAGNOSTIC
-       if ((sc->sc_state & NCR_WORKING) == 0)
-               panic("ncr5380_done: bad state");
-#endif
-
-       /* Clear our pointers to the request. */
-       sc->sc_current = NULL;
-       sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
-       untimeout(ncr5380_cmd_timeout, sr);
-
-       /* Make the request free. */
-       sr->sr_xs = NULL;
-       sc->sc_ncmds--;
-
-       /* Tell common SCSI code it is done. */
-       xs->flags |= ITSDONE;
-       scsi_done(xs);
-
-       sc->sc_state = NCR_IDLE;
-       /* Now ncr5380_sched() may be called again. */
-}
-
-
-/*
- * Schedule a SCSI operation.  This routine should return
- * only after it achieves one of the following conditions:
- *     Busy (sc->sc_state != NCR_IDLE)
- *     No more work can be started.
- */
-static void
-ncr5380_sched(sc)
-       struct  ncr5380_softc *sc;
-{
-       struct sci_req  *sr;
-       struct scsi_xfer *xs;
-       int     target, lun;
-       int     error, i;
-
-#ifdef DIAGNOSTIC
-       if ((getsr() & PSL_IPL) < PSL_IPL2)
-               panic("ncr5380_sched: bad spl");
-#endif
-
-       /* Another hack (Er.. hook!) for the sun3 si: */
-       if (sc->sc_intr_off) {
-               NCR_TRACE("sched: top, intr off\n", 0);
-           sc->sc_intr_off(sc);
-       }
-
-next_job:
-       /*
-        * Grab the next job from queue.  Must be idle.
-        */
-#ifdef DIAGNOSTIC
-       if (sc->sc_state != NCR_IDLE)
-               panic("ncr5380_sched: not idle");
-       if (sc->sc_current)
-               panic("ncr5380_sched: current set");
-#endif
-
-       /*
-        * Always start the search where we last looked.
-        * The REQUEST_SENSE logic depends on this to
-        * choose the same job as was last picked, so it
-        * can just clear sc_current and reschedule.
-        * (Avoids loss of "contingent allegiance".)
-        */
-       i = sc->sc_rr;
-       sr = NULL;
-       do {
-               if (sc->sc_ring[i].sr_xs) {
-                       target = sc->sc_ring[i].sr_target;
-                       lun = sc->sc_ring[i].sr_lun;
-                       if (sc->sc_matrix[target][lun] == NULL) {
-                           sc->sc_matrix[target][lun] =
-                                       sr = &sc->sc_ring[i];
-                           sc->sc_rr = i;
-                           break;
-                       }
-               }
-               i++;
-               if (i == SCI_OPENINGS)
-                       i = 0;
-       } while (i != sc->sc_rr);
-
-       if (sr == NULL) {
-               NCR_TRACE("sched: no work, cur=0x%x\n",
-                                 (long) sc->sc_current);
-
-               /* Another hack (Er.. hook!) for the sun3 si: */
-               if (sc->sc_intr_on) {
-                       NCR_TRACE("sched: ret, intr ON\n", 0);
-                   sc->sc_intr_on(sc);
-               }
-
-               return;         /* No more work to do. */
-       }
-
-       NCR_TRACE("sched: select for t/l=0x%02x\n",
-                         (sr->sr_target << 4) | sr->sr_lun);
-
-       sc->sc_state = NCR_WORKING;
-       error = ncr5380_select(sc, sr);
-       if (sc->sc_current) {
-               /* Lost the race!  reselected out from under us! */
-               /* Work with the reselected job. */
-               if (sr->sr_flags & SR_IMMED) {
-                       printf("%s: reselected while polling (abort)\n",
-                                  sc->sc_dev.dv_xname);
-                       /* Abort the reselected job. */
-                       sc->sc_state |= NCR_ABORTING;
-                       sc->sc_msgpriq |= SEND_ABORT;
-               }
-               sr = sc->sc_current;
-               xs = sr->sr_xs;
-               NCR_TRACE("sched: reselect, new sr=0x%x\n", (long)sr);
-               goto have_nexus;
-       }
-
-       /* Normal selection result */
-       sc->sc_current = sr;    /* connected */
-       xs = sr->sr_xs;
-
-       /*
-        * Initialize pointers, etc. for this job
-        */
-       sc->sc_dataptr  = sr->sr_dataptr;
-       sc->sc_datalen  = sr->sr_datalen;
-       sc->sc_prevphase = PHASE_INVALID;
-       sc->sc_msgpriq = SEND_IDENTIFY;
-       sc->sc_msgoutq = 0;
-       sc->sc_msgout  = 0;
-
-       NCR_TRACE("sched: select rv=%d\n", error);
-
-       switch (error) {
-       case XS_NOERROR:
-               break;
-
-       case XS_BUSY:
-               /* XXX - Reset and try again. */
-               printf("%s: SCSI bus busy, resetting...\n",
-                          sc->sc_dev.dv_xname);
-               ncr5380_reset_scsibus(sc);
-               /* fallthrough */
-       case XS_SELTIMEOUT:
-       default:
-               xs->error = error;      /* from select */
-               NCR_TRACE("sched: call done, sr=0x%x\n", (long)sr);
-               ncr5380_done(sc);
-
-               /* Paranoia: clear everything. */
-               sc->sc_dataptr = NULL;
-               sc->sc_datalen = 0;
-               sc->sc_prevphase = PHASE_INVALID;
-               sc->sc_msgpriq = 0;
-               sc->sc_msgoutq = 0;
-               sc->sc_msgout  = 0;
-
-               goto next_job;
-       }
-
-       /*
-        * Selection was successful.  Normally, this means
-        * we are starting a new command.  However, this
-        * might be the termination of an overdue job.
-        */
-       if (sr->sr_flags & SR_OVERDUE) {
-               NCR_TRACE("sched: overdue, sr=0x%x\n", (long)sr);
-               sc->sc_state |= NCR_ABORTING;
-               sc->sc_msgpriq |= SEND_ABORT;
-               goto have_nexus;
-       }
-
-       /*
-        * This may be the continuation of some job that
-        * completed with a "check condition" code.
-        */
-       if (sr->sr_flags & SR_SENSE) {
-               NCR_TRACE("sched: get sense, sr=0x%x\n", (long)sr);
-               /* Do not allocate DMA, nor set timeout. */
-               goto have_nexus;
-       }
-
-       /*
-        * OK, we are starting a new command.
-        * Initialize and allocate resources for the new command.
-        * Device reset is special (only uses MSG_OUT phase).
-        * Normal commands start in MSG_OUT phase where we will
-        * send and IDENDIFY message, and then expect CMD phase.
-        */
-       if (ncr5380_debug & NCR_DBG_CMDS) {
-               printf("ncr5380_sched: begin, target=%d, LUN=%d\n",
-                          xs->sc_link->target, xs->sc_link->lun);
-               ncr5380_show_scsi_cmd(xs);
-       }
-       if (xs->flags & SCSI_RESET) {
-               NCR_TRACE("sched: cmd=reset, sr=0x%x\n", (long)sr);
-               /* Not an error, so do not set NCR_ABORTING */
-               sc->sc_msgpriq |= SEND_DEV_RESET;
-               goto have_nexus;
-       }
-
-#ifdef DIAGNOSTIC
-       if ((xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) == 0) {
-               if (sc->sc_dataptr) {
-                       printf("%s: ptr but no data in/out flags?\n");
-                       NCR_BREAK();
-                       sc->sc_dataptr = NULL;
-               }
-       }
-#endif
-
-       /* Allocate DMA space (maybe) */
-       if (sc->sc_dataptr && sc->sc_dma_alloc &&
-               (sc->sc_datalen >= sc->sc_min_dma_len))
-       {
-               NCR_TRACE("sched: dma_alloc, len=%d\n", sc->sc_datalen);
-               (*sc->sc_dma_alloc)(sc);
-       }
-
-       /*
-        * Initialization hook called just after select,
-        * at the beginning of COMMAND phase.
-        * (but AFTER the DMA allocation is done)
-        *
-        * The evil Sun "si" adapter (OBIO variant) needs some
-        * setup done to the DMA engine BEFORE the target puts
-        * the SCSI bus into any DATA phase.
-        */
-       if (sr->sr_dma_hand && sc->sc_dma_setup) {
-               NCR_TRACE("sched: dma_setup, dh=0x%x\n",
-                                 (long) sr->sr_dma_hand);
-           sc->sc_dma_setup(sc);
-       }
-
-       /*
-        * Schedule a timeout for the job we are starting.
-        */
-       if ((sr->sr_flags & SR_IMMED) == 0) {
-               i = (xs->timeout * hz) / 1000;
-               NCR_TRACE("sched: set timeout=%d\n", i);
-               timeout(ncr5380_cmd_timeout, sr, i);
-       }
-
-have_nexus:
-       NCR_TRACE("sched: call machine, cur=0x%x\n",
-                         (long) sc->sc_current);
-       ncr5380_machine(sc);
-       NCR_TRACE("sched: machine done, cur=0x%x\n",
-                         (long) sc->sc_current);
-
-       /*
-        * What state did ncr5380_machine() leave us in?
-        * Hopefully it sometimes completes a job...
-        */
-       if (sc->sc_state == NCR_IDLE)
-               goto next_job;
-
-       return;         /* Have work in progress. */
-}
-
-
-/*
- *  Reselect handler: checks for reselection, and if we are being
- *     reselected, it sets up sc->sc_current.
- *
- *  We are reselected when:
- *     SEL is TRUE
- *     IO  is TRUE
- *     BSY is FALSE
- */
-void
-ncr5380_reselect(sc)
-       struct ncr5380_softc *sc;
-{
-       struct sci_req *sr;
-       int target, lun, phase, timo;
-       u_char bus, data, icmd, msg;
-
-#ifdef DIAGNOSTIC
-       /*
-        * Note: sc_state will be "idle" when ncr5380_intr()
-        * calls, or "working" when ncr5380_select() calls.
-        * (So don't test that in this DIAGNOSTIC)
-        */
-       if (sc->sc_current)
-               panic("ncr5380_reselect: current set");
-#endif
-
-       /*
-        * First, check the select line.
-        * (That has to be set first.)
-        */
-       bus = *(sc->sci_bus_csr);
-       if ((bus & SCI_BUS_SEL) == 0) {
-               /* Not a selection or reselection. */
-               return;
-       }
-
-       /*
-        * The target will assert BSY first (for bus arbitration),
-        * then raise SEL, and finally drop BSY.  Only then is the
-        * data bus required to have valid selection ID bits set.
-        * Wait for: SEL==1, BSY==0 before reading the data bus.
-        */
-       timo = ncr5380_wait_nrq_timo;
-       for (;;) {
-               if ((bus & SCI_BUS_BSY) == 0)
-                       break;
-               /* Probably never get here... */
-               if (--timo <= 0) {
-                       printf("%s: reselect, BSY stuck, bus=0x%x\n",
-                               sc->sc_dev.dv_xname, bus);
-                       /* Not much we can do. Reset the bus. */
-                       ncr5380_reset_scsibus(sc);
-                       return;
-               }
-               delay(10);
-               bus = *(sc->sci_bus_csr);
-               /* If SEL went away, forget it. */
-               if ((bus & SCI_BUS_SEL) == 0)
-                       return;
-               /* Still have SEL, check BSY. */
-       }
-       NCR_TRACE("reselect, valid data after %d loops\n",
-                         ncr5380_wait_nrq_timo - timo);
-
-       /*
-        * Good.  We have SEL=1 and BSY=0.  Now wait for a
-        * "bus settle delay" before we sample the data bus
-        */
-       delay(2);
-       data = *(sc->sci_data) & 0xFF;
-       /* XXX - Should check parity... */
-
-       /*
-        * Is this a reselect (I/O == 1) or have we been
-        * selected as a target? (I/O == 0)
-        */
-       if ((bus & SCI_BUS_IO) == 0) {
-               printf("%s: selected as target, data=0x%x\n",
-                       sc->sc_dev.dv_xname, data);
-               /* Not much we can do. Reset the bus. */
-               ncr5380_reset_scsibus(sc);
-               return;
-       }
-
-       /*
-        * OK, this is a reselection.
-        */
-       for (target = 0; target < 7; target++)
-               if (data & (1 << target))
-                       break;
-
-       if ((data & 0x7F) != (1 << target)) {
-               /* No selecting ID? or >2 IDs on bus? */
-               printf("%s: bad reselect, data=0x%x\n",
-                       sc->sc_dev.dv_xname, data);
-               return;
-       }
-
-       NCR_TRACE("reselect: target=0x%x\n", target);
-
-       /* Raise BSY to acknowledge target reselection. */
-       *(sc->sci_icmd) = SCI_ICMD_BSY;
-
-       /* Wait for target to drop SEL. */
-       timo = ncr5380_wait_nrq_timo;
-       for (;;) {
-               bus = *(sc->sci_bus_csr);
-               if ((bus & SCI_BUS_SEL) == 0)
-                       break;  /* success */
-               if (--timo <= 0) {
-                       printf("%s: reselect, SEL stuck, bus=0x%x\n",
-                               sc->sc_dev.dv_xname, bus);
-                       NCR_BREAK();
-                       /* assume connected (fail later if not) */
-                       break;
-               }
-               delay(2);
-       }
-
-       /* Now we drop BSY, and we are connected. */
-       *(sc->sci_icmd) = 0;
-       *sc->sci_sel_enb = 0;
-       SCI_CLR_INTR(sc);
-
-       /*
-        * At this point the target should send an IDENTIFY message,
-        * which will permit us to determine the reselecting LUN.
-        * If not, we assume LUN 0.
-        */
-       lun = 0;
-       /* Wait for REQ before reading bus phase. */
-       if (ncr5380_wait_req(sc)) {
-               printf("%s: reselect, no REQ\n",
-                          sc->sc_dev.dv_xname);
-               /* Try to send an ABORT message. */
-               goto abort;
-       }
-       phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
-       if (phase != PHASE_MSG_IN) {
-               printf("%s: reselect, phase=%d\n",
-                          sc->sc_dev.dv_xname, phase);
-               goto abort;
-       }
-
-       /* Ack. the change to PHASE_MSG_IN */
-       *(sc->sci_tcmd) = PHASE_MSG_IN;
-
-       /* Peek at the message byte without consuming it! */
-       msg = *(sc->sci_data);
-       if ((msg & 0x80) == 0) {
-               printf("%s: reselect, not identify, msg=%d\n",
-                          sc->sc_dev.dv_xname, msg);
-               goto abort;
-       }
-       lun = msg & 7;
-       
-       /* We now know target/LUN.  Do we have the request? */
-       sr = sc->sc_matrix[target][lun];
-       if (sr) {
-               /* We now have a nexus. */
-               sc->sc_state |= NCR_WORKING;
-               sc->sc_current = sr;
-               NCR_TRACE("reselect: resume sr=0x%x\n", (long)sr);
-
-               /* Implicit restore pointers message */
-               sc->sc_dataptr = sr->sr_dataptr;
-               sc->sc_datalen = sr->sr_datalen;
-
-               sc->sc_prevphase = PHASE_INVALID;
-               sc->sc_msgpriq = 0;
-               sc->sc_msgoutq = 0;
-               sc->sc_msgout  = 0;
-
-               /*
-                * Another hack for the Sun3 "si", which needs
-                * some setup done to its DMA engine before the
-                * target puts the SCSI bus into any DATA phase.
-                */
-               if (sr->sr_dma_hand && sc->sc_dma_setup) {
-                       NCR_TRACE("reselect: call DMA setup, dh=0x%x\n",
-                                         (long) sr->sr_dma_hand);
-                   sc->sc_dma_setup(sc);
-               }
-
-               /* Now consume the IDENTIFY message. */
-               ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
-               return;
-       }
-
-       printf("%s: phantom reselect: target=%d, LUN=%d\n",
-                  sc->sc_dev.dv_xname, target, lun);
-abort:
-       /*
-        * Try to send an ABORT message.  This makes us
-        * temporarily busy, but no current command...
-        */
-       sc->sc_state |= NCR_ABORTING;
-
-       /* Raise ATN, delay, raise ACK... */
-       icmd = SCI_ICMD_ATN;
-       *sc->sci_icmd = icmd;
-       delay(2);
-
-       /* Now consume the IDENTIFY message. */
-       ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
-
-       /* Finally try to send the ABORT. */
-       sc->sc_prevphase = PHASE_INVALID;
-       sc->sc_msgpriq = SEND_ABORT;
-       ncr5380_msg_out(sc);
-
-       *(sc->sci_tcmd) = PHASE_INVALID;
-       *sc->sci_sel_enb = 0;
-       SCI_CLR_INTR(sc);
-       *sc->sci_sel_enb = 0x80;
-
-       sc->sc_state &= ~NCR_ABORTING;
-}
-
-
-/*
- *  Select target: xs is the transfer that we are selecting for.
- *  sc->sc_current should be NULL.
- *
- *  Returns:
- *     sc->sc_current != NULL  ==> we were reselected (race!)
- *     XS_NOERROR              ==> selection worked
- *     XS_BUSY                 ==> lost arbitration
- *     XS_SELTIMEOUT           ==> no response to selection
- */
-static int
-ncr5380_select(sc, sr)
-       struct ncr5380_softc *sc;
-       struct sci_req *sr;
-{
-       int timo;
-       u_char bus, data, icmd;
-
-       /* Check for reselect */
-       ncr5380_reselect(sc);
-       if (sc->sc_current) {
-               NCR_TRACE("select: reselect, cur=0x%x\n",
-                                 (long) sc->sc_current);
-               return XS_BUSY; /* reselected */
-       }
-
-       /*
-        * Set phase bits to 0, otherwise the 5380 won't drive the bus during
-        * selection.
-        */
-       *sc->sci_tcmd = PHASE_DATA_OUT;
-       *sc->sci_icmd = icmd = 0;
-       *sc->sci_mode = 0;
-
-       /*
-        * Arbitrate for the bus.  The 5380 takes care of the
-        * time-critical bus interactions.  We set our ID bit
-        * in the output data register and set MODE_ARB.  The
-        * 5380 watches for the required "bus free" period.
-        * If and when the "bus free" period is detected, the
-        * 5380 then drives BSY, drives the data bus, and sets
-        * the "arbitration in progress" (AIP) bit to let us
-        * know arbitration has started.  We then wait for one
-        * arbitration delay (2.2uS) and check the ICMD_LST bit,
-        * which will be set if someone else drives SEL.
-        */
-       *(sc->sci_odata) = 0x80;        /* OUR_ID */
-       *(sc->sci_mode) = SCI_MODE_ARB;
-
-       /* Wait for ICMD_AIP. */
-       timo = ncr5380_wait_req_timo;
-       for (;;) {
-               if (*(sc->sci_icmd) & SCI_ICMD_AIP)
-                       break;
-               if (--timo <= 0) {
-                       /* Did not see any "bus free" period. */
-                       *sc->sci_mode = 0;
-                       NCR_TRACE("select: bus busy, rc=%d\n", XS_BUSY);
-                       return XS_BUSY;
-               }
-               delay(2);
-       }
-       NCR_TRACE("select: have AIP after %d loops\n",
-                         ncr5380_wait_req_timo - timo);
-
-       /* Got AIP.  Wait one arbitration delay (2.2 uS.) */
-       delay(3);
-
-       /* Check for ICMD_LST */
-       if (*(sc->sci_icmd) & SCI_ICMD_LST) {
-               /* Some other target asserted SEL. */
-               *sc->sci_mode = 0;
-               NCR_TRACE("select: lost one, rc=%d\n", XS_BUSY);
-               ncr5380_reselect(sc);   /* XXX */
-               return XS_BUSY;
-       }
-
-       /*
-        * No other device has declared itself the winner.
-        * The spec. says to check for higher IDs, but we
-        * are always the highest (ID=7) so don't bother.
-        * We can now declare victory by asserting SEL.
-        *
-        * Note that the 5380 is asserting BSY because we
-        * asked it to do arbitration.  We will now hold
-        * BSY directly so we can turn off ARB mode.
-        */
-       icmd = (SCI_ICMD_BSY | SCI_ICMD_SEL);
-       *sc->sci_icmd = icmd;
-
-       /*
-        * "The SCSI device that wins arbitration shall wait
-        *  at least a bus clear delay plus a bus settle delay
-        *  after asserting the SEL signal before changing
-        *  any [other] signal."  (1.2uS. total)
-        */
-       delay(2);
-
-#if 1
-       /*
-        * XXX: Check one last time to see if we really
-        * XXX: did win arbitration.  (too paranoid?)
-        */
-       if (*(sc->sci_icmd) & SCI_ICMD_LST) {
-               *sc->sci_icmd = 0;
-               *sc->sci_mode = 0;
-               NCR_TRACE("select: lost two, rc=%d\n", XS_BUSY);
-               return XS_BUSY;
-       }
-#endif
-       /* Leave ARB mode Now that we drive BSY+SEL */
-       *sc->sci_mode = 0;
-       *sc->sci_sel_enb = 0;
-
-       /*
-        * Arbitration is complete.  Now do selection:
-        * Drive the data bus with the ID bits for both
-        * the host and target.  Also set ATN now, to
-        * ask the target for a messgae out phase.
-        */
-       data = 0x80 | (1 << sr->sr_target);
-       *(sc->sci_odata) = data;
-       icmd |= (SCI_ICMD_DATA | SCI_ICMD_ATN);
-       *(sc->sci_icmd) = icmd;
-       delay(2);       /* two deskew delays. */
-
-       /* De-assert BSY (targets sample the data now). */
-       icmd &= ~SCI_ICMD_BSY;
-       *(sc->sci_icmd) = icmd;
-       delay(3);       /* Bus settle delay. */
-
-       /*
-        * Wait for the target to assert BSY.
-        * SCSI spec. says wait for 250 mS.
-        */
-       for (timo = 25000;;) {
-               if (*sc->sci_bus_csr & SCI_BUS_BSY)
-                       goto success;
-               if (--timo <= 0)
-                       break;
-               delay(10);
-       }
-
-       /*
-        * There is no reaction from the target.  Start the selection
-        * timeout procedure. We release the databus but keep SEL+ATN
-        * asserted. After that we wait a 'selection abort time' (200
-        * usecs) and 2 deskew delays (90 ns) and check BSY again.
-        * When BSY is asserted, we assume the selection succeeded,
-        * otherwise we release the bus.
-        */
-       icmd &= ~SCI_ICMD_DATA;
-       *(sc->sci_icmd) = icmd;
-       delay(201);
-       if ((*sc->sci_bus_csr & SCI_BUS_BSY) == 0) {
-               /* Really no device on bus */
-               *sc->sci_tcmd = PHASE_INVALID;
-               *sc->sci_icmd = 0;
-               *sc->sci_mode = 0;
-               *sc->sci_sel_enb = 0;
-               SCI_CLR_INTR(sc);
-               *sc->sci_sel_enb = 0x80;
-               NCR_TRACE("select: device down, rc=%d\n", XS_SELTIMEOUT);
-               return XS_SELTIMEOUT;
-       }
-
-success:
-       /*
-        * The target is now driving BSY, so we can stop
-        * driving SEL and the data bus (keep ATN true).
-        * Configure the ncr5380 to monitor BSY, parity.
-        */
-       icmd &= ~(SCI_ICMD_DATA | SCI_ICMD_SEL);
-       *sc->sci_icmd = icmd;
-
-       /* XXX - Make parity checking optional? */
-       *sc->sci_mode = (SCI_MODE_MONBSY | SCI_MODE_PAR_CHK);
-
-       return XS_NOERROR;
-}
-
-
-/*****************************************************************
- * Functions to handle each info. transfer phase:
- *****************************************************************/
-
-/*
- * The message system:
- *
- * This is a revamped message system that now should easier accomodate
- * new messages, if necessary.
- *
- * Currently we accept these messages:
- * IDENTIFY (when reselecting)
- * COMMAND COMPLETE # (expect bus free after messages marked #)
- * NOOP
- * MESSAGE REJECT
- * SYNCHRONOUS DATA TRANSFER REQUEST
- * SAVE DATA POINTER
- * RESTORE POINTERS
- * DISCONNECT #
- *
- * We may send these messages in prioritized order:
- * BUS DEVICE RESET #          if SCSI_RESET & xs->flags (or in weird sits.)
- * MESSAGE PARITY ERROR                par. err. during MSGI
- * MESSAGE REJECT              If we get a message we don't know how to handle
- * ABORT #                     send on errors
- * INITIATOR DETECTED ERROR    also on errors (SCSI2) (during info xfer)
- * IDENTIFY                    At the start of each transfer
- * SYNCHRONOUS DATA TRANSFER REQUEST   if appropriate
- * NOOP                                if nothing else fits the bill ...
- */
-
-#define IS1BYTEMSG(m) (((m) != 0x01 && (m) < 0x20) || (m) >= 0x80)
-#define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
-#define ISEXTMSG(m) ((m) == 0x01)
-
-/*
- * Precondition:
- * The SCSI bus is already in the MSGI phase and there is a message byte
- * on the bus, along with an asserted REQ signal.
- *
- * Our return value determines whether our caller, ncr5380_machine()
- * will expect to see another REQ (and possibly phase change).
- */
-static int
-ncr5380_msg_in(sc)
-       register struct ncr5380_softc *sc;
-{
-       struct sci_req *sr = sc->sc_current;
-       int n, phase, timo;
-       int act_flags;
-       register u_char icmd;
-
-       /* acknowledge phase change */
-       *sc->sci_tcmd = PHASE_MSG_IN;
-
-       act_flags = ACT_CONTINUE;
-       icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
-
-       if (sc->sc_prevphase == PHASE_MSG_IN) {
-               /* This is a continuation of the previous message. */
-               n = sc->sc_imp - sc->sc_imess;
-               NCR_TRACE("msg_in: continuation, n=%d\n", n);
-               goto nextbyte;
-       }
-
-       /* This is a new MESSAGE IN phase.  Clean up our state. */
-       sc->sc_state &= ~NCR_DROP_MSGIN;
-
-nextmsg:
-       n = 0;
-       sc->sc_imp = &sc->sc_imess[n];
-
-nextbyte:
-       /*
-        * Read a whole message, but don't ack the last byte.  If we reject the
-        * message, we have to assert ATN during the message transfer phase
-        * itself.
-        */
-       for (;;) {
-               /*
-                * Read a message byte.
-                * First, check BSY, REQ, phase...
-                */
-               if (!SCI_BUSY(sc)) {
-                       NCR_TRACE("msg_in: lost BSY, n=%d\n", n);
-                       /* XXX - Assume the command completed? */
-                       act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
-                       return (act_flags);
-               }
-               if (ncr5380_wait_req(sc)) {
-                       NCR_TRACE("msg_in: BSY but no REQ, n=%d\n", n);
-                       /* Just let ncr5380_machine() handle it... */
-                       return (act_flags);
-               }
-               phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
-               if (phase != PHASE_MSG_IN) {
-                       /*
-                        * Target left MESSAGE IN, probably because it
-                        * a) noticed our ATN signal, or
-                        * b) ran out of messages.
-                        */
-                       return (act_flags);
-               }
-               /* Still in MESSAGE IN phase, and REQ is asserted. */
-               if (*sc->sci_csr & SCI_CSR_PERR) {
-                       ncr_sched_msgout(sc, SEND_PARITY_ERROR);
-                       sc->sc_state |= NCR_DROP_MSGIN;
-               }
-
-               /* Gather incoming message bytes if needed. */
-               if ((sc->sc_state & NCR_DROP_MSGIN) == 0) {
-                       if (n >= NCR_MAX_MSG_LEN) {
-                               ncr_sched_msgout(sc, SEND_REJECT);
-                               sc->sc_state |= NCR_DROP_MSGIN;
-                       } else {
-                               *sc->sc_imp++ = *sc->sci_data;
-                               n++;
-                               /*
-                                * This testing is suboptimal, but most
-                                * messages will be of the one byte variety, so
-                                * it should not affect performance
-                                * significantly.
-                                */
-                               if (n == 1 && IS1BYTEMSG(sc->sc_imess[0]))
-                                       goto have_msg;
-                               if (n == 2 && IS2BYTEMSG(sc->sc_imess[0]))
-                                       goto have_msg;
-                               if (n >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
-                                       n == sc->sc_imess[1] + 2)
-                                       goto have_msg;
-                       }
-               }
-
-               /*
-                * If we reach this spot we're either:
-                * a) in the middle of a multi-byte message, or
-                * b) dropping bytes.
-                */
-
-               /* Ack the last byte read. */
-               icmd |= SCI_ICMD_ACK;
-               *sc->sci_icmd = icmd;
-
-               if (ncr5380_wait_not_req(sc)) {
-                       NCR_TRACE("msg_in: drop, stuck REQ, n=%d\n", n);
-                       act_flags |= ACT_RESET_BUS;
-               }
-
-               icmd &= ~SCI_ICMD_ACK;
-               *sc->sci_icmd = icmd;
-
-               if (act_flags != ACT_CONTINUE)
-                       return (act_flags);
-
-               /* back to nextbyte */
-       }
-
-have_msg:
-       /* We now have a complete message.  Parse it. */
-
-       switch (sc->sc_imess[0]) {
-       case MSG_CMDCOMPLETE:
-               NCR_TRACE("msg_in: CMDCOMPLETE\n", 0);
-               /* Target is about to disconnect. */
-               act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
-               break;
-
-       case MSG_DISCONNECT:
-               NCR_TRACE("msg_in: DISCONNECT\n", 0);
-               /* Target is about to disconnect. */
-               act_flags |= ACT_DISCONNECT;
-               break;
-
-       case MSG_PARITY_ERROR:
-               NCR_TRACE("msg_in: PARITY_ERROR\n", 0);
-               /* Resend the last message. */
-               ncr_sched_msgout(sc, sc->sc_msgout);
-               break;
-
-       case MSG_MESSAGE_REJECT:
-               /* The target rejects the last message we sent. */
-               NCR_TRACE("msg_in: got reject for 0x%x\n", sc->sc_msgout);
-               switch (sc->sc_msgout) {
-               case SEND_IDENTIFY:
-                       /* Really old target controller? */
-                       /* XXX ... */
-                       break;
-               case SEND_INIT_DET_ERR:
-                       goto abort;
-               }
-               break;
-
-       case MSG_NOOP:
-               NCR_TRACE("msg_in: NOOP\n", 0);
-               break;
-
-       case MSG_SAVEDATAPOINTER:
-               NCR_TRACE("msg_in: SAVE_PTRS\n", 0);
-               sr->sr_dataptr = sc->sc_dataptr;
-               sr->sr_datalen = sc->sc_datalen;
-               break;
-
-       case MSG_RESTOREPOINTERS:
-               NCR_TRACE("msg_in: RESTORE_PTRS\n", 0);
-               sc->sc_dataptr = sr->sr_dataptr;
-               sc->sc_datalen = sr->sr_datalen;
-               break;
-
-       case MSG_EXTENDED:
-               switch (sc->sc_imess[2]) {
-               case MSG_EXT_SDTR:
-               case MSG_EXT_WDTR:
-                       /* The ncr5380 can not do synchronous mode. */
-                       goto reject;
-               default:
-                       printf("%s: unrecognized MESSAGE EXTENDED; sending REJECT\n",
-                                  sc->sc_dev.dv_xname);
-                       NCR_BREAK();
-                       goto reject;
-               }
-               break;
-
-       default:
-               NCR_TRACE("msg_in: eh? imsg=0x%x\n", sc->sc_imess[0]);
-               printf("%s: unrecognized MESSAGE; sending REJECT\n",
-                          sc->sc_dev.dv_xname);
-               NCR_BREAK();
-               /* fallthrough */
-       reject:
-               ncr_sched_msgout(sc, SEND_REJECT);
-               break;
-
-       abort:
-               sc->sc_state |= NCR_ABORTING;
-               ncr_sched_msgout(sc, SEND_ABORT);
-               break;
-       }
-
-       /* Ack the last byte read. */
-       icmd |= SCI_ICMD_ACK;
-       *sc->sci_icmd = icmd;
-
-       if (ncr5380_wait_not_req(sc)) {
-               NCR_TRACE("msg_in: last, stuck REQ, n=%d\n", n);
-               act_flags |= ACT_RESET_BUS;
-       }
-
-       icmd &= ~SCI_ICMD_ACK;
-       *sc->sci_icmd = icmd;
-
-       /* Go get the next message, if any. */
-       if (act_flags == ACT_CONTINUE)
-               goto nextmsg;
-
-       return (act_flags);
-}
-
-
-/*
- * The message out (and in) stuff is a bit complicated:
- * If the target requests another message (sequence) without
- * having changed phase in between it really asks for a
- * retransmit, probably due to parity error(s).
- * The following messages can be sent:
- * IDENTIFY       @ These 4 stem from SCSI command activity
- * SDTR                   @
- * WDTR                   @
- * DEV_RESET      @
- * REJECT if MSGI doesn't make sense
- * PARITY_ERROR if parity error while in MSGI
- * INIT_DET_ERR if parity error while not in MSGI
- * ABORT if INIT_DET_ERR rejected
- * NOOP if asked for a message and there's nothing to send
- *
- * Note that we call this one with (sc_current == NULL)
- * when sending ABORT for unwanted reselections.
- */
-static int
-ncr5380_msg_out(sc)
-       register struct ncr5380_softc *sc;
-{
-       struct sci_req *sr = sc->sc_current;
-       int n, phase, resel;
-       int progress, act_flags;
-       register u_char icmd;
-
-       /* acknowledge phase change */
-       *sc->sci_tcmd = PHASE_MSG_OUT;
-
-       progress = 0;   /* did we send any messages? */
-       act_flags = ACT_CONTINUE;
-
-       /*
-        * Set ATN.  If we're just sending a trivial 1-byte message,
-        * we'll clear ATN later on anyway.  Also drive the data bus.
-        */
-       icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
-       icmd |= (SCI_ICMD_ATN | SCI_ICMD_DATA);
-       *sc->sci_icmd = icmd;
-
-       if (sc->sc_prevphase == PHASE_MSG_OUT) {
-               if (sc->sc_omp == sc->sc_omess) {
-                       /*
-                        * This is a retransmission.
-                        *
-                        * We get here if the target stayed in MESSAGE OUT
-                        * phase.  Section 5.1.9.2 of the SCSI 2 spec indicates
-                        * that all of the previously transmitted messages must
-                        * be sent again, in the same order.  Therefore, we
-                        * requeue all the previously transmitted messages, and
-                        * start again from the top.  Our simple priority
-                        * scheme keeps the messages in the right order.
-                        */
-                       sc->sc_msgpriq |= sc->sc_msgoutq;
-                       NCR_TRACE("msg_out: retrans priq=0x%x\n", sc->sc_msgpriq);
-               } else {
-                       /* This is a continuation of the previous message. */
-                       n = sc->sc_omp - sc->sc_omess;
-                       NCR_TRACE("msg_out: continuation, n=%d\n", n);
-                       goto nextbyte;
-               }
-       }
-
-       /* No messages transmitted so far. */
-       sc->sc_msgoutq = 0;
-
-nextmsg:
-       /* Pick up highest priority message. */
-       sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
-       sc->sc_msgpriq &= ~sc->sc_msgout;
-       sc->sc_msgoutq |= sc->sc_msgout;
-
-       /* Build the outgoing message data. */
-       switch (sc->sc_msgout) {
-       case SEND_IDENTIFY:
-               NCR_TRACE("msg_out: SEND_IDENTIFY\n", 0);
-               if (sr == NULL) {
-                       printf("%s: SEND_IDENTIFY while not connected; sending NOOP\n",
-                               sc->sc_dev.dv_xname);
-                       NCR_BREAK();
-                       goto noop;
-               }
-               resel = (sc->sc_flags & NCR5380_PERMIT_RESELECT) ? 1 : 0;
-               resel &= (sr->sr_flags & (SR_IMMED | SR_SENSE)) ? 0 : 1;
-               sc->sc_omess[0] = MSG_IDENTIFY(sr->sr_lun, resel);
-               n = 1;
-               break;
-
-       case SEND_DEV_RESET:
-               NCR_TRACE("msg_out: SEND_DEV_RESET\n", 0);
-               /* Expect disconnect after this! */
-               /* XXX: Kill jobs for this target? */
-               act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
-               sc->sc_omess[0] = MSG_BUS_DEV_RESET;
-               n = 1;
-               break;
-
-       case SEND_REJECT:
-               NCR_TRACE("msg_out: SEND_REJECT\n", 0);
-               sc->sc_omess[0] = MSG_MESSAGE_REJECT;
-               n = 1;
-               break;
-
-       case SEND_PARITY_ERROR:
-               NCR_TRACE("msg_out: SEND_PARITY_ERROR\n", 0);
-               sc->sc_omess[0] = MSG_PARITY_ERROR;
-               n = 1;
-               break;
-
-       case SEND_INIT_DET_ERR:
-               NCR_TRACE("msg_out: SEND_INIT_DET_ERR\n", 0);
-               sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
-               n = 1;
-               break;
-
-       case SEND_ABORT:
-               NCR_TRACE("msg_out: SEND_ABORT\n", 0);
-               /* Expect disconnect after this! */
-               /* XXX: Set error flag? */
-               act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
-               sc->sc_omess[0] = MSG_ABORT;
-               n = 1;
-               break;
-
-       case 0:
-               printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
-                       sc->sc_dev.dv_xname);
-               NCR_BREAK();
-       noop:
-               NCR_TRACE("msg_out: send NOOP\n", 0);
-               sc->sc_omess[0] = MSG_NOOP;
-               n = 1;
-               break;
-
-       default:
-               printf("%s: weird MESSAGE OUT; sending NOOP\n",
-                       sc->sc_dev.dv_xname);
-               NCR_BREAK();
-               goto noop;
-       }
-       sc->sc_omp = &sc->sc_omess[n];
-
-nextbyte:
-       /* Send message bytes. */
-       while (n > 0) {
-               /*
-                * Send a message byte.
-                * First check BSY, REQ, phase...
-                */
-               if (!SCI_BUSY(sc)) {
-                       NCR_TRACE("msg_out: lost BSY, n=%d\n", n);
-                       goto out;
-               }
-               if (ncr5380_wait_req(sc)) {
-                       NCR_TRACE("msg_out: no REQ, n=%d\n", n);
-                       goto out;
-               }
-               phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
-               if (phase != PHASE_MSG_OUT) {
-                       /*
-                        * Target left MESSAGE OUT, possibly to reject
-                        * our message.
-                        */
-                       NCR_TRACE("msg_out: new phase=%d\n", phase);
-                       goto out;
-               }
-
-               /* Yes, we can send this message byte. */
-               --n;
-
-               /* Clear ATN before last byte if this is the last message. */
-               if (n == 0 && sc->sc_msgpriq == 0) {
-                       icmd &= ~SCI_ICMD_ATN;
-                       *sc->sci_icmd = icmd;
-                       /* 2 deskew delays */
-                       delay(2);       /* XXX */
-               }
-
-               /* Put data on the bus. */
-               *sc->sci_odata = *--sc->sc_omp;
-
-               /* Raise ACK to tell target data is on the bus. */
-               icmd |= SCI_ICMD_ACK;
-               *sc->sci_icmd = icmd;
-
-               /* Wait for REQ to be negated. */
-               if (ncr5380_wait_not_req(sc)) {
-                       NCR_TRACE("msg_out: stuck REQ, n=%d\n", n);
-                       act_flags |= ACT_RESET_BUS;
-               }
-
-               /* Finally, drop ACK. */
-               icmd &= ~SCI_ICMD_ACK;
-               *sc->sci_icmd = icmd;
-
-               /* Stuck bus or something... */
-               if (act_flags & ACT_RESET_BUS)
-                       goto out;
-
-       }
-       progress++;
-
-       /* We get here only if the entire message has been transmitted. */
-       if (sc->sc_msgpriq != 0) {
-               /* There are more outgoing messages. */
-               goto nextmsg;
-       }
-
-       /*
-        * The last message has been transmitted.  We need to remember the last
-        * message transmitted (in case the target switches to MESSAGE IN phase
-        * and sends a MESSAGE REJECT), and the list of messages transmitted
-        * this time around (in case the target stays in MESSAGE OUT phase to
-        * request a retransmit).
-        */
-
-out:
-       /* Stop driving the data bus. */
-       icmd &= ~SCI_ICMD_DATA;
-       *sc->sci_icmd = icmd;
-
-       if (!progress)
-               act_flags |= ACT_RESET_BUS;
-
-       return (act_flags);
-}
-
-
-/*
- * Handle command phase.
- */
-static int
-ncr5380_command(sc)
-       struct ncr5380_softc *sc;
-{
-       struct sci_req *sr = sc->sc_current;
-       struct scsi_xfer *xs = sr->sr_xs;
-       struct scsi_sense rqs;
-       int len;
-
-       /* acknowledge phase change */
-       *sc->sci_tcmd = PHASE_COMMAND;
-
-       if (sr->sr_flags & SR_SENSE) {
-               rqs.opcode = REQUEST_SENSE;
-               rqs.byte2 = xs->sc_link->lun << 5;
-               rqs.length = sizeof(xs->sense);
-
-               rqs.unused[0] = rqs.unused[1] = rqs.control = 0;
-               len = ncr5380_pio_out(sc, PHASE_COMMAND, sizeof(rqs),
-                       (u_char *)&rqs);
-       }
-       else {
-               /* Assume command can be sent in one go. */
-               /* XXX: Do this using DMA, and get a phase change intr? */
-               len = ncr5380_pio_out(sc, PHASE_COMMAND, xs->cmdlen,
-                       (u_char *)xs->cmd);
-       }
-
-       if (len != xs->cmdlen) {
-#ifdef DEBUG
-               printf("ncr5380_command: short transfer: wanted %d got %d.\n",
-                          xs->cmdlen, len);
-               ncr5380_show_scsi_cmd(xs);
-               NCR_BREAK();
-#endif
-               if (len < 6) {
-                       xs->error = XS_DRIVER_STUFFUP;
-                       sc->sc_state |= NCR_ABORTING;
-                       ncr_sched_msgout(sc, SEND_ABORT);
-               }
-
-       }
-
-       return ACT_CONTINUE;
-}
-
-
-/*
- * Handle either data_in or data_out
- */
-static int
-ncr5380_data_xfer(sc, phase)
-       struct ncr5380_softc *sc;
-       int phase;
-{
-       struct sci_req *sr = sc->sc_current;
-       struct scsi_xfer *xs = sr->sr_xs;
-       int expected_phase;
-       int i, len;
-
-       if (sr->sr_flags & SR_SENSE) {
-               NCR_TRACE("data_xfer: get sense, sr=0x%x\n", (long)sr);
-               if (phase != PHASE_DATA_IN) {
-                       printf("%s: sense phase error\n", sc->sc_dev.dv_xname);
-                       goto abort;
-               }
-               /* acknowledge phase change */
-               *sc->sci_tcmd = PHASE_DATA_IN;
-               len = ncr5380_pio_in(sc, phase, sizeof(xs->sense),
-                               (u_char *)&xs->sense);
-               return ACT_CONTINUE;
-       }
-
-       /*
-        * When aborting a command, disallow any data phase.
-        */
-       if (sc->sc_state & NCR_ABORTING) {
-               printf("%s: aborting, but phase=%s (reset)\n",
-                      sc->sc_dev.dv_xname,
-                          phase_names[phase & 7]);
-               return ACT_RESET_BUS;   /* XXX */
-       }
-
-       /* Validate expected phase (data_in or data_out) */
-       expected_phase = (xs->flags & SCSI_DATA_OUT) ?
-               PHASE_DATA_OUT : PHASE_DATA_IN;
-       if (phase != expected_phase) {
-               printf("%s: data phase error\n",
-                          sc->sc_dev.dv_xname);
-               goto abort;
-       }
-
-       /* Make sure we have some data to move. */
-       if (sc->sc_datalen <= 0) {
-               printf("%s: can not transfer more data\n",
-                          sc->sc_dev.dv_xname);
-               goto abort;
-       }
-
-       /*
-        * Attempt DMA only if dma_alloc gave us a DMA handle AND
-        * there is enough left to transfer so DMA is worth while.
-        */
-       if (sr->sr_dma_hand &&
-               (sc->sc_datalen >= sc->sc_min_dma_len))
-       {
-               /*
-                * OK, really start DMA.  Note, the MI start function
-                * is responsible for setting the TCMD register, etc.
-                * (Acknowledge the phase change there, not here.)
-                */
-               NCR_TRACE("data_xfer: dma_start, dh=0x%x\n",
-                         (long) sr->sr_dma_hand);
-               (*sc->sc_dma_start)(sc);
-               return ACT_WAIT_DMA;
-       }
-
-       NCR_TRACE("data_xfer: doing PIO, len=%d\n", sc->sc_datalen);
-
-       /* acknowledge phase change */
-       *sc->sci_tcmd = phase;
-       if (phase == PHASE_DATA_OUT) {
-               len = ncr5380_pio_out(sc, phase, sc->sc_datalen, sc->sc_dataptr);
-       } else {
-               len = ncr5380_pio_in (sc, phase, sc->sc_datalen, sc->sc_dataptr);
-       }
-       sc->sc_dataptr += len;
-       sc->sc_datalen -= len;
-
-       NCR_TRACE("data_xfer: did PIO, resid=%d\n", sc->sc_datalen);
-       return (ACT_CONTINUE);
-
-abort:
-       sc->sc_state |= NCR_ABORTING;
-       ncr_sched_msgout(sc, SEND_ABORT);
-       return (ACT_CONTINUE);
-}
-
-
-static int
-ncr5380_status(sc)
-       struct ncr5380_softc *sc;
-{
-       int len;
-       u_char status;
-       struct sci_req *sr = sc->sc_current;
-       struct scsi_xfer *xs = sr->sr_xs;
-
-       /* acknowledge phase change */
-       *sc->sci_tcmd = PHASE_STATUS;
-
-       len = ncr5380_pio_in(sc, PHASE_STATUS, 1, &status);
-       if (len) {
-               sr->sr_status = status;
-       } else {
-               printf("ncr5380_status: none?\n");
-       }
-
-       return ACT_CONTINUE;
-}
-
-
-/*
- * This is the big state machine that follows SCSI phase changes.
- * This is somewhat like a co-routine.  It will do a SCSI command,
- * and exit if the command is complete, or if it must wait, i.e.
- * for DMA to complete or for reselect to resume the job.
- *
- * The bus must be selected, and we need to know which command is
- * being undertaken.
- */
-static void
-ncr5380_machine(sc)
-       struct ncr5380_softc *sc;
-{
-       struct sci_req *sr;
-       struct scsi_xfer *xs;
-       int act_flags, phase, timo;
-
-#ifdef DIAGNOSTIC
-       if ((getsr() & PSL_IPL) < PSL_IPL2)
-               panic("ncr5380_machine: bad spl");
-       if (sc->sc_state == NCR_IDLE)
-               panic("ncr5380_machine: state=idle");
-       if (sc->sc_current == NULL)
-               panic("ncr5380_machine: no current cmd");
-#endif
-
-       sr = sc->sc_current;
-       xs = sr->sr_xs;
-       act_flags = ACT_CONTINUE;
-
-       /*
-        * This will be called by ncr5380_intr() when DMA is
-        * complete.  Must stop DMA before touching the 5380 or
-        * there will be "register conflict" errors.
-        */
-       if (sc->sc_state & NCR_DOINGDMA) {
-               /* Pick-up where where we left off... */
-               goto dma_done;
-       }
-
-next_phase:
-
-       if (!SCI_BUSY(sc)) {
-               /* Unexpected disconnect */
-               printf("ncr5380_machine: unexpected disconnect.\n");
-               xs->error = XS_DRIVER_STUFFUP;
-               act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
-               goto do_actions;
-       }
-
-       /*
-        * Wait for REQ before reading the phase.
-        * Need to wait longer than usual here, because
-        * some devices are just plain slow...
-        */
-       timo = ncr5380_wait_phase_timo;
-       for (;;) {
-               if (*sc->sci_bus_csr & SCI_BUS_REQ)
-                       break;
-               if (--timo <= 0) {
-                       if (sc->sc_state & NCR_ABORTING) {
-                               printf("%s: no REQ while aborting, reset\n",
-                                      sc->sc_dev.dv_xname);
-                               act_flags |= ACT_RESET_BUS;
-                               goto do_actions;
-                       }
-                       printf("%s: no REQ for next phase, abort\n",
-                              sc->sc_dev.dv_xname);
-                       sc->sc_state |= NCR_ABORTING;
-                       ncr_sched_msgout(sc, SEND_ABORT);
-                       goto next_phase;
-               }
-               delay(100);
-       }
-
-       phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
-       NCR_TRACE("machine: phase=%s\n",
-                         (long) phase_names[phase & 7]);
-
-       /*
-        * We assume that the device knows what it's doing,
-        * so any phase is good.
-        */
-
-#if 0
-       /*
-        * XXX: Do not ACK the phase yet! do it later...
-        * XXX: ... each phase routine does that itself.
-        * In particular, DMA needs it done LATER.
-        */
-       *sc->sci_tcmd = phase;  /* acknowledge phase change */
-#endif
-
-       switch (phase) {
-
-       case PHASE_DATA_OUT:
-       case PHASE_DATA_IN:
-               act_flags = ncr5380_data_xfer(sc, phase);
-               break;
-
-       case PHASE_COMMAND:
-               act_flags = ncr5380_command(sc);
-               break;
-
-       case PHASE_STATUS:
-               act_flags = ncr5380_status(sc);
-               break;
-
-       case PHASE_MSG_OUT:
-               act_flags = ncr5380_msg_out(sc);
-               break;
-
-       case PHASE_MSG_IN:
-               act_flags = ncr5380_msg_in(sc);
-               break;
-
-       default:
-               printf("ncr5380_machine: Unexpected phase 0x%x\n", phase);
-               sc->sc_state |= NCR_ABORTING;
-               ncr_sched_msgout(sc, SEND_ABORT);
-               goto next_phase;
-
-       } /* switch */
-       sc->sc_prevphase = phase;
-
-do_actions:
-       __asm("_ncr5380_actions:");
-
-       if (act_flags & ACT_WAIT_DMA) {
-               act_flags &= ~ACT_WAIT_DMA;
-               /* Wait for DMA to complete (polling, or interrupt). */
-               if ((sr->sr_flags & SR_IMMED) == 0) {
-                       NCR_TRACE("machine: wait for DMA intr.\n", 0);
-                       return;         /* will resume at dma_done */
-               }
-               /* Busy-wait for it to finish. */
-               NCR_TRACE("machine: dma_poll, dh=0x%x\n",
-                                 (long) sr->sr_dma_hand);
-               (*sc->sc_dma_poll)(sc);
-       dma_done:
-               /* Return here after interrupt. */
-               if (sr->sr_flags & SR_OVERDUE)
-                       sc->sc_state |= NCR_ABORTING;
-               NCR_TRACE("machine: dma_stop, dh=0x%x\n",
-                                 (long) sr->sr_dma_hand);
-               (*sc->sc_dma_stop)(sc);
-               SCI_CLR_INTR(sc);       /* XXX */
-               /*
-                * While DMA is running we can not touch the SBC,
-                * so various places just set NCR_ABORTING and
-                * expect us the "kick it" when DMA is done.
-                */
-               if (sc->sc_state & NCR_ABORTING) {
-                       ncr_sched_msgout(sc, SEND_ABORT);
-               }
-       }
-
-       /*
-        * Check for parity error.
-        * XXX - better place to check?
-        */
-       if (*(sc->sci_csr) & SCI_CSR_PERR) {
-               printf("%s: parity error!\n",
-                          sc->sc_dev.dv_xname);
-               /* XXX: sc->sc_state |= NCR_ABORTING; */
-               ncr_sched_msgout(sc, SEND_PARITY_ERROR);
-       }
-
-       if (act_flags == ACT_CONTINUE)
-               goto next_phase;
-       /* All other actions "break" from the loop. */
-
-       NCR_TRACE("machine: act_flags=0x%x\n", act_flags);
-
-       if (act_flags & ACT_RESET_BUS) {
-               act_flags |= ACT_CMD_DONE;
-               /*
-                * Reset the SCSI bus, usually due to a timeout.
-                * The error code XS_TIMEOUT allows retries.
-                */
-               sc->sc_state |= NCR_ABORTING;
-               printf("%s: reset SCSI bus for TID=%d LUN=%d\n",
-                          sc->sc_dev.dv_xname,
-                          sr->sr_target, sr->sr_lun);
-               ncr5380_reset_scsibus(sc);
-       }
-
-       if (act_flags & ACT_CMD_DONE) {
-               act_flags |= ACT_DISCONNECT;
-               /* Need to call scsi_done() */
-               /* XXX: from the aic6360 driver, but why? */
-               if (sc->sc_datalen < 0) {
-                       printf("%s: %d extra bytes from %d:%d\n",
-                                  sc->sc_dev.dv_xname, -sc->sc_datalen,
-                                  sr->sr_target, sr->sr_lun);
-                       sc->sc_datalen = 0;
-               }
-               xs->resid = sc->sc_datalen;
-               /* Note: this will clear sc_current */
-               NCR_TRACE("machine: call done, cur=0x%x\n", (long)sr);
-               ncr5380_done(sc);
-       }
-
-       if (act_flags & ACT_DISCONNECT) {
-               /*
-                * The device has dropped BSY (or will soon).
-                * Return and let ncr5380_sched() do its thing.
-                */
-               *sc->sci_icmd = 0;
-               *sc->sci_mode = 0;
-               *sc->sci_tcmd = PHASE_INVALID;
-               *sc->sci_sel_enb = 0;
-               SCI_CLR_INTR(sc);
-               *sc->sci_sel_enb = 0x80;
-
-               if ((act_flags & ACT_CMD_DONE) == 0) {
-                       __asm("_ncr5380_disconnected:");
-                       NCR_TRACE("machine: discon, cur=0x%x\n", (long)sr);
-               }
-
-               /*
-                * We may be here due to a disconnect message,
-                * in which case we did NOT call ncr5380_done,
-                * and we need to clear sc_current.
-                */
-               sc->sc_state = NCR_IDLE;
-               sc->sc_current = NULL;
-
-               /* Paranoia: clear everything. */
-               sc->sc_dataptr = NULL;
-               sc->sc_datalen = 0;
-               sc->sc_prevphase = PHASE_INVALID;
-               sc->sc_msgpriq = 0;
-               sc->sc_msgoutq = 0;
-               sc->sc_msgout  = 0;
-
-               /* Our caller will re-enable interrupts. */
-       }
-}
-
-
-#ifdef DEBUG
-
-static void
-ncr5380_show_scsi_cmd(xs)
-       struct scsi_xfer *xs;
-{
-       u_char  *b = (u_char *) xs->cmd;
-       int     i  = 0;
-
-       if ( ! ( xs->flags & SCSI_RESET ) ) {
-               printf("si(%d:%d:%d)-",
-                          xs->sc_link->scsibus,
-                          xs->sc_link->target,
-                          xs->sc_link->lun);
-               while (i < xs->cmdlen) {
-                       if (i) printf(",");
-                       printf("%x",b[i++]);
-               }
-               printf("-\n");
-       } else {
-               printf("si(%d:%d:%d)-RESET-\n",
-                          xs->sc_link->scsibus,
-                          xs->sc_link->target,
-                          xs->sc_link->lun);
-       }
-}
-
-
-static void
-ncr5380_show_sense(xs)
-       struct scsi_xfer *xs;
-{
-       u_char  *b = (u_char *)&xs->sense;
-       int     i;
-
-       printf("sense:");
-       for (i = 0; i < sizeof(xs->sense); i++)
-               printf(" %02x", b[i]);
-       printf("\n");
-}
-
-int ncr5380_traceidx = 0;
-
-#define        TRACE_MAX       1024
-struct trace_ent {
-       char *msg;
-       long  val;
-} ncr5380_tracebuf[TRACE_MAX];
-
-void
-ncr5380_trace(msg, val)
-       char *msg;
-       long  val;
-{
-       register struct trace_ent *tr;
-       register int s;
-
-       s = splhigh();
-
-       tr = &ncr5380_tracebuf[ncr5380_traceidx];
-
-       ncr5380_traceidx++;
-       if (ncr5380_traceidx >= TRACE_MAX)
-               ncr5380_traceidx = 0;
-
-       tr->msg = msg;
-       tr->val = val;
-
-       splx(s);
-}
-
-#ifdef DDB
-void
-ncr5380_clear_trace()
-{
-       ncr5380_traceidx = 0;
-       bzero((char*) ncr5380_tracebuf, sizeof(ncr5380_tracebuf));
-}
-
-void
-ncr5380_show_trace()
-{
-       struct trace_ent *tr;
-       int idx;
-
-       idx = ncr5380_traceidx;
-       do {
-               tr = &ncr5380_tracebuf[idx];
-               idx++;
-               if (idx >= TRACE_MAX)
-                       idx = 0;
-               if (tr->msg)
-                       db_printf(tr->msg, tr->val);
-       } while (idx != ncr5380_traceidx);
-}
-
-void
-ncr5380_show_req(sr)
-       struct sci_req *sr;
-{
-       struct scsi_xfer *xs = sr->sr_xs;
-
-       db_printf("TID=%d ",    sr->sr_target);
-       db_printf("LUN=%d ",    sr->sr_lun);
-       db_printf("dh=0x%x ",   sr->sr_dma_hand);
-       db_printf("dptr=0x%x ", sr->sr_dataptr);
-       db_printf("dlen=0x%x ", sr->sr_datalen);
-       db_printf("flags=%d ",  sr->sr_flags);
-       db_printf("stat=%d ",   sr->sr_status);
-
-       if (xs == NULL) {
-               db_printf("(xs=NULL)\n");
-               return;
-       }
-       db_printf("\n");
-#ifdef SCSIDEBUG
-       show_scsi_xs(xs);
-#else
-       db_printf("xs=0x%x\n", xs);
-#endif
-}
-
-void
-ncr5380_show_state()
-{
-       struct ncr5380_softc *sc;
-       struct sci_req *sr;
-       int i, j, k;
-
-       sc = ncr5380_debug_sc;
-
-       if (sc == NULL) {
-               db_printf("ncr5380_debug_sc == NULL\n");
-               return;
-       }
-
-       db_printf("sc_ncmds=%d\n",      sc->sc_ncmds);
-       k = -1; /* which is current? */
-       for (i = 0; i < SCI_OPENINGS; i++) {
-               sr = &sc->sc_ring[i];
-               if (sr->sr_xs) {
-                       if (sr == sc->sc_current)
-                               k = i;
-                       db_printf("req %d: (sr=0x%x)", i, (long)sr);
-                       ncr5380_show_req(sr);
-               }
-       }
-       db_printf("sc_rr=%d, current=%d\n", sc->sc_rr, k);
-
-       db_printf("Active request matrix:\n");
-       for(i = 0; i < 8; i++) {                /* targets */
-               for (j = 0; j < 8; j++) {       /* LUN */
-                       sr = sc->sc_matrix[i][j];
-                       if (sr) {
-                               db_printf("TID=%d LUN=%d sr=0x%x\n", i, j, (long)sr);
-                       }
-               }
-       }
-
-       db_printf("sc_state=0x%x\n",    sc->sc_state);
-       db_printf("sc_current=0x%x\n",  sc->sc_current);
-       db_printf("sc_dataptr=0x%x\n",  sc->sc_dataptr);
-       db_printf("sc_datalen=0x%x\n",  sc->sc_datalen);
-
-       db_printf("sc_prevphase=%d\n",  sc->sc_prevphase);
-       db_printf("sc_msgpriq=0x%x\n",  sc->sc_msgpriq);
-}
-
-#endif /* DDB */
-#endif /* DEBUG */
index a481210..e69de29 100644 (file)
@@ -1,178 +0,0 @@
-/*     $NetBSD: ncr5380var.h,v 1.2 1995/11/17 23:27:49 gwr Exp $       */
-
-/*
- * Copyright (c) 1995 David Jones, Gordon W. Ross
- * Copyright (c) 1994 Jarle Greipsland
- * 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. 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
- *    must display the following acknowledgement:
- *      This product includes software developed by
- *      David Jones and Gordon Ross
- *
- * 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 file defines the interface between the machine-dependent
- * module and the machine-indepenedent ncr5380sbc.c module.
- */
-
-#define SCI_CLR_INTR(sc)       (*(sc)->sci_iack)
-#define        SCI_BUSY(sc)            (*sc->sci_bus_csr & SCI_BUS_BSY)
-
-/* These are NOT artibtrary, but map to bits in sci_tcmd */
-#define PHASE_DATA_OUT 0x0
-#define PHASE_DATA_IN  0x1
-#define PHASE_COMMAND  0x2
-#define PHASE_STATUS   0x3
-#define PHASE_UNSPEC1  0x4
-#define PHASE_UNSPEC2  0x5
-#define PHASE_MSG_OUT  0x6
-#define PHASE_MSG_IN   0x7
-
-/*
- * This illegal phase is used to prevent the 5380 from having
- * a phase-match condition when we don't want one, such as
- * when setting up the DMA engine or whatever...
- */
-#define PHASE_INVALID  PHASE_UNSPEC1
-
-
-/* Per-request state.  This is required in order to support reselection. */
-struct sci_req {
-       struct          scsi_xfer *sr_xs;       /* Pointer to xfer struct, NULL=unused */
-       int             sr_target, sr_lun;      /* For fast access */
-       void            *sr_dma_hand;           /* Current DMA hnadle */
-       u_char          *sr_dataptr;            /* Saved data pointer */
-       int             sr_datalen;
-       int             sr_flags;               /* Internal error code */
-#define        SR_IMMED                        1       /* Immediate command */
-#define        SR_SENSE                        2       /* We are getting sense */
-#define        SR_OVERDUE                      4       /* Timeout while not current */
-#define        SR_ERROR                        8       /* Error occurred */
-       int             sr_status;              /* Status code from last cmd */
-};
-#define        SCI_OPENINGS    16              /* How many commands we can enqueue. */
-
-
-struct ncr5380_softc {
-       struct device   sc_dev;
-       struct          scsi_link sc_link;
-
-       /* Pointers to 5380 registers.  See ncr5380reg.h */
-       volatile u_char *sci_r0;
-       volatile u_char *sci_r1;
-       volatile u_char *sci_r2;
-       volatile u_char *sci_r3;
-       volatile u_char *sci_r4;
-       volatile u_char *sci_r5;
-       volatile u_char *sci_r6;
-       volatile u_char *sci_r7;
-
-       /* Functions set from MD code */
-       int             (*sc_pio_out) __P((struct ncr5380_softc *,
-                                          int, int, u_char *));
-       int             (*sc_pio_in) __P((struct ncr5380_softc *,
-                                         int, int, u_char *));
-       void            (*sc_dma_alloc) __P((struct ncr5380_softc *));
-       void            (*sc_dma_free) __P((struct ncr5380_softc *));
-
-       void            (*sc_dma_setup) __P((struct ncr5380_softc *));
-       void            (*sc_dma_start) __P((struct ncr5380_softc *));
-       void            (*sc_dma_poll) __P((struct ncr5380_softc *));
-       void            (*sc_dma_eop) __P((struct ncr5380_softc *));
-       void            (*sc_dma_stop) __P((struct ncr5380_softc *));
-
-       void            (*sc_intr_on) __P((struct ncr5380_softc *));
-       void            (*sc_intr_off) __P((struct ncr5380_softc *));
-
-       int             sc_flags;       /* Misc. flags and capabilities */
-#define        NCR5380_PERMIT_RESELECT         1  /* Allow disconnect/reselect */
-#define        NCR5380_FORCE_POLLING           2  /* Do not use interrupts. */
-
-       int     sc_min_dma_len; /* Smaller than this is done with PIO */
-
-       /* Begin MI shared data */
-
-       int             sc_state;
-#define        NCR_IDLE                   0    /* Ready for new work. */
-#define NCR_WORKING    0x01    /* Some command is in progress. */
-#define        NCR_ABORTING    0x02    /* Bailing out */
-#define NCR_DOINGDMA   0x04    /* The FIFO data path is active! */
-#define NCR_DROP_MSGIN 0x10    /* Discard all msgs (parity err detected) */
-
-       /* The request that has the bus now. */
-       struct          sci_req *sc_current;
-
-       /* Active data pointer for current SCSI command. */
-       u_char          *sc_dataptr;
-       int             sc_datalen;
-
-       /* Begin MI private data */
-
-       /* The number of operations in progress on the bus */
-       volatile int    sc_ncmds;
-
-       /* Ring buffer of pending/active requests */
-       struct          sci_req sc_ring[SCI_OPENINGS];
-       int             sc_rr;          /* Round-robin scan pointer */
-
-       /* Active requests, by target/LUN */
-       struct          sci_req *sc_matrix[8][8];
-
-       /* Message stuff */
-       int     sc_prevphase;
-
-       u_int   sc_msgpriq;     /* Messages we want to send */
-       u_int   sc_msgoutq;     /* Messages sent during last MESSAGE OUT */
-       u_int   sc_msgout;      /* Message last transmitted */
-#define SEND_DEV_RESET         0x01
-#define SEND_PARITY_ERROR      0x02
-#define SEND_ABORT             0x04
-#define SEND_REJECT            0x08
-#define SEND_INIT_DET_ERR      0x10
-#define SEND_IDENTIFY                  0x20
-#define SEND_SDTR              0x40
-#define        SEND_WDTR               0x80
-#define NCR_MAX_MSG_LEN 8
-       u_char  sc_omess[NCR_MAX_MSG_LEN];
-       u_char  *sc_omp;                /* Outgoing message pointer */
-       u_char  sc_imess[NCR_MAX_MSG_LEN];
-       u_char  *sc_imp;                /* Incoming message pointer */
-
-};
-
-void   ncr5380_init __P((struct ncr5380_softc *));
-void   ncr5380_reset_scsibus __P((struct ncr5380_softc *));
-int    ncr5380_intr __P((struct ncr5380_softc *));
-int    ncr5380_scsi_cmd __P((struct scsi_xfer *));
-int    ncr5380_pio_in __P((struct ncr5380_softc *, int, int, u_char *));
-int    ncr5380_pio_out __P((struct ncr5380_softc *, int, int, u_char *));
-
-#ifdef DEBUG
-struct ncr5380_softc *ncr5380_debug_sc;
-void ncr5380_trace __P((char *msg, long val));
-#define        NCR_TRACE(msg, val) ncr5380_trace(msg, val)
-#else
-#define        NCR_TRACE(msg, val)     /* nada */
-#endif
index 658e886..e69de29 100644 (file)
-/*     $NetBSD: ncr_si.c,v 1.3 1996/01/01 22:51:26 thorpej Exp $       */
-
-/*
- * Copyright (c) 1995 David Jones, Gordon W. Ross
- * Copyright (c) 1994 Adam Glass
- * 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. 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
- *    must display the following acknowledgement:
- *      This product includes software developed by
- *      Adam Glass, David Jones, and Gordon Ross
- *
- * 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 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.
- *
- * 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.
- *
- * What wonderfully whacky hardware this is!
- *
- * 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.
- */
-
-#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/buf.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-
-#include <scsi/scsi_all.h>
-#include <scsi/scsi_debug.h>
-#include <scsi/scsiconf.h>
-
-#include <machine/autoconf.h>
-#include <machine/isr.h>
-#include <machine/obio.h>
-#include <machine/dvma.h>
-
-#define DEBUG XXX
-
-#include <dev/ic/ncr5380reg.h>
-#include <dev/ic/ncr5380var.h>
-
-#include "ncr_sireg.h"
-#include "am9516.h"
-
-/*
- * 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?)
- */
-#define        MAX_DMA_LEN 0xE000
-
-/*
- * How many uS. to delay after touching the am9516 UDC.
- */
-#define UDC_WAIT_USEC 5
-
-#ifdef DEBUG
-int si_debug = 0;
-static int si_link_flags = 0 /* | SDEV_DB2 */ ;
-#endif
-
-/*
- * This structure is used to keep track of mapped 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) */
-       u_char *        dh_addr;        /* KVA of start of buffer */
-       int             dh_maplen;      /* Length of KVA mapping. */
-       long            dh_dvma;        /* VA of buffer in DVMA space */
-       /* DMA command block for the OBIO controller. */
-       struct udc_table dh_cmd;
-};
-
-/*
- * 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;
-       int             sc_adapter_type;
-       int             sc_adapter_iv_am; /* int. vec + address modifier */
-       struct si_dma_handle *sc_dma;
-       int     sc_xlen;                /* length of current DMA segment. */
-};
-
-/* Options.  Interesting values are: 1,3,7 */
-int si_options = 0;
-#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 */
-
-/* How long to wait for DMA before declaring an error. */
-int si_dma_intr_timo = 500;    /* ticks (sec. X 100) */
-
-static char si_name[] = "si";
-static int     si_match();
-static void    si_attach();
-static int     si_intr(void *arg);
-static void    si_reset_adapter(struct ncr5380_softc *sc);
-static void    si_minphys(struct buf *bp);
-
-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_vme_dma_setup __P((struct ncr5380_softc *));
-void si_vme_dma_start __P((struct ncr5380_softc *));
-void si_vme_dma_eop __P((struct ncr5380_softc *));
-void si_vme_dma_stop __P((struct ncr5380_softc *));
-
-void si_vme_intr_on  __P((struct ncr5380_softc *));
-void si_vme_intr_off __P((struct ncr5380_softc *));
-
-void si_obio_dma_setup __P((struct ncr5380_softc *));
-void si_obio_dma_start __P((struct ncr5380_softc *));
-void si_obio_dma_eop __P((struct ncr5380_softc *));
-void si_obio_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()    */
-};
-
-/* 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 cfdriver ncr_sicd = {
-       NULL, si_name, si_match, si_attach,
-       DV_DULL, sizeof(struct si_softc), NULL, 0,
-};
-
-static int
-si_print(aux, name)
-       void *aux;
-       char *name;
-{
-       if (name != NULL)
-               printf("%s: scsibus ", name);
-       return UNCONF;
-}
-
-static int
-si_match(parent, vcf, args)
-       struct device   *parent;
-       void            *vcf, *args;
-{
-       struct cfdata   *cf = vcf;
-       struct confargs *ca = args;
-       int x, probe_addr;
-
-       /* Default interrupt priority always splbio==2 */
-       if (ca->ca_intpri == -1)
-               ca->ca_intpri = 2;
-
-       if ((cpu_machine_id == SUN3_MACH_50) ||
-           (cpu_machine_id == SUN3_MACH_60) )
-       {
-               /* Sun3/50 or Sun3/60 have only OBIO "si" */
-               if (ca->ca_bustype != BUS_OBIO)
-                       return(0);
-               if (ca->ca_paddr == -1)
-                       ca->ca_paddr = OBIO_NCR_SCSI;
-               /* OK... */
-       } else {
-               /* Other Sun3 models may have VME "si" or "sc" */
-               if (ca->ca_bustype != BUS_VME16)
-                       return (0);
-               if (ca->ca_paddr == -1)
-                       return (0);
-               /* OK... */
-       }
-
-       /* Make sure there is something there... */
-       x = bus_peek(ca->ca_bustype, ca->ca_paddr + 1, 1);
-       if (x == -1)
-               return (0);
-
-       /*
-        * If this is a VME SCSI board, we have to determine whether
-        * it is an "sc" (Sun2) or "si" (Sun3) SCSI board.  This can
-        * be determined using the fact that the "sc" board occupies
-        * 4K bytes in VME space but the "si" board occupies 2K bytes.
-        */
-       if (ca->ca_bustype == BUS_VME16) {
-               /* Note, the "si" board should NOT respond here. */
-               x = bus_peek(ca->ca_bustype, ca->ca_paddr + 0x801, 1);
-               if (x != -1)
-                       return(0);
-       }
-
-    return (1);
-}
-
-static void
-si_attach(parent, self, args)
-       struct device   *parent, *self;
-       void            *args;
-{
-       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 = args;
-       int i;
-
-       switch (ca->ca_bustype) {
-
-       case BUS_OBIO:
-               regs = (struct si_regs *)
-                       obio_alloc(ca->ca_paddr, sizeof(*regs));
-               break;
-
-       case BUS_VME16:
-               regs = (struct si_regs *)
-                       bus_mapin(ca->ca_bustype, ca->ca_paddr, sizeof(*regs));
-               break;
-
-       default:
-               printf("unknown\n");
-               return;
-       }
-       printf("\n");
-
-       /*
-        * Fill in the prototype scsi_link.
-        */
-       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 fields used by the MI code
-        */
-       ncr_sc->sci_r0 = &regs->sci.sci_r0;
-       ncr_sc->sci_r1 = &regs->sci.sci_r1;
-       ncr_sc->sci_r2 = &regs->sci.sci_r2;
-       ncr_sc->sci_r3 = &regs->sci.sci_r3;
-       ncr_sc->sci_r4 = &regs->sci.sci_r4;
-       ncr_sc->sci_r5 = &regs->sci.sci_r5;
-       ncr_sc->sci_r6 = &regs->sci.sci_r6;
-       ncr_sc->sci_r7 = &regs->sci.sci_r7;
-
-       /*
-        * MD function pointers used by the MI code.
-        */
-       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;
-       ncr_sc->sc_intr_on   = NULL;
-       ncr_sc->sc_intr_off  = NULL;
-       if (ca->ca_bustype == BUS_VME16) {
-               ncr_sc->sc_dma_setup = si_vme_dma_setup;
-               ncr_sc->sc_dma_start = si_vme_dma_start;
-               ncr_sc->sc_dma_eop   = si_vme_dma_stop;
-               ncr_sc->sc_dma_stop  = si_vme_dma_stop;
-               if (si_options & SI_DO_RESELECT) {
-                       /*
-                        * Need to enable interrupts (and DMA!)
-                        * on this H/W for reselect to work.
-                        */
-                       ncr_sc->sc_intr_on   = si_vme_intr_on;
-                       ncr_sc->sc_intr_off  = si_vme_intr_off;
-               }
-       } else {
-               ncr_sc->sc_dma_setup = si_obio_dma_setup;
-               ncr_sc->sc_dma_start = si_obio_dma_start;
-               ncr_sc->sc_dma_eop   = si_obio_dma_stop;
-               ncr_sc->sc_dma_stop  = si_obio_dma_stop;
-       }
-       ncr_sc->sc_flags = 0;
-       if (si_options & SI_DO_RESELECT)
-               ncr_sc->sc_flags |= NCR5380_PERMIT_RESELECT;
-       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.
-        */
-
-       /* Need DVMA-capable memory for the UDC command blocks. */
-       i = SCI_OPENINGS * sizeof(struct si_dma_handle);
-       sc->sc_dma = (struct si_dma_handle *) dvma_malloc(i);
-       if (sc->sc_dma == NULL)
-               panic("si: dvma_malloc failed\n");
-       for (i = 0; i < SCI_OPENINGS; i++)
-               sc->sc_dma[i].dh_flags = 0;
-
-       sc->sc_regs = regs;
-       sc->sc_adapter_type = ca->ca_bustype;
-
-       /* Now ready for interrupts. */
-       if (ca->ca_bustype == BUS_OBIO) {
-               isr_add_autovect(si_intr, (void *)sc,
-                                ca->ca_intpri);
-       } else {
-               isr_add_vectored(si_intr, (void *)sc,
-                                ca->ca_intpri, ca->ca_intvec);
-               sc->sc_adapter_iv_am =
-                       VME_SUPV_DATA_24 | (ca->ca_intvec & 0xFF);
-       }
-
-#ifdef DEBUG
-       if (si_debug)
-               printf("si: Set TheSoftC=%x TheRegs=%x\n", sc, regs);
-       ncr_sc->sc_link.flags |= si_link_flags;
-#endif
-
-       /*
-        *  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), si_print);
-}
-
-static void
-si_minphys(struct buf *bp)
-{
-       if (bp->b_bcount > MAX_DMA_LEN) {
-#ifdef DEBUG
-               if (si_debug) {
-                       printf("si_minphys len = 0x%x.\n", bp->b_bcount);
-                       Debugger();
-               }
-#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_intr(void *arg)
-{
-       struct si_softc *sc = arg;
-       volatile struct si_regs *si = sc->sc_regs;
-       int dma_error, claimed;
-       u_short csr;
-
-       claimed = 0;
-       dma_error = 0;
-
-       /* SBC interrupt? DMA interrupt? */
-       csr = si->si_csr;
-       NCR_TRACE("si_intr: csr=0x%x\n", csr);
-
-       if (csr & SI_CSR_DMA_CONFLICT) {
-               dma_error |= SI_CSR_DMA_CONFLICT;
-               printf("si_intr: DMA conflict\n");
-       }
-       if (csr & SI_CSR_DMA_BUS_ERR) {
-               dma_error |= SI_CSR_DMA_BUS_ERR;
-               printf("si_intr: DMA bus error\n");
-       }
-       if (dma_error) {
-               if (sc->ncr_sc.sc_state & NCR_DOINGDMA)
-                       sc->ncr_sc.sc_state |= NCR_ABORTING;
-               /* Make sure we will call the main isr. */
-               csr |= SI_CSR_DMA_IP;
-       }
-
-       if (csr & (SI_CSR_SBC_IP | SI_CSR_DMA_IP)) {
-               claimed = ncr5380_intr(&sc->ncr_sc);
-#ifdef DEBUG
-               if (!claimed) {
-                       printf("si_intr: spurious from SBC\n");
-                       if (si_debug & 4) {
-                               Debugger();     /* XXX */
-                       }
-               }
-#endif
-       }
-
-       return (claimed);
-}
-
-
-static void
-si_reset_adapter(struct ncr5380_softc *ncr_sc)
-{
-       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
-
-       /*
-        * The SCSI3 controller has an 8K FIFO to buffer data between the
-        * 5380 and the DMA.  Make sure it starts out empty.
-        *
-        * The reset bits in the CSR are active low.
-        */
-       si->si_csr = 0;
-       delay(10);
-       si->si_csr = SI_CSR_FIFO_RES | SI_CSR_SCSI_RES | SI_CSR_INTR_EN;
-       delay(10);
-       si->fifo_count = 0;
-
-       if (sc->sc_adapter_type == BUS_VME16) {
-               si->dma_addrh = 0;
-               si->dma_addrl = 0;
-               si->dma_counth = 0;
-               si->dma_countl = 0;
-               si->si_iv_am = sc->sc_adapter_iv_am;
-               si->fifo_cnt_hi = 0;
-       }
-
-       SCI_CLR_INTR(ncr_sc);
-}
-
-
-/*****************************************************************
- * 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;
-{
-       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 si_dma_handle *dh;
-       int i, xlen;
-       u_long addr;
-
-#ifdef DIAGNOSTIC
-       if (sr->sr_dma_hand != NULL)
-               panic("si_dma_alloc: already have DMA handle");
-#endif
-
-#if 1  /* XXX - Temporary */
-       /* XXX - In case we think DMA is completely broken... */
-       if ((si_options & SI_ENABLE_DMA) == 0)
-               return;
-#endif
-
-       addr = (u_long) ncr_sc->sc_dataptr;
-       xlen = ncr_sc->sc_datalen;
-
-       /* If the DMA start addr is misaligned then do PIO */
-       if ((addr & 1) || (xlen & 1)) {
-               printf("si_dma_alloc: misaligned.\n");
-               return;
-       }
-
-       /* Make sure our caller checked sc_min_dma_len. */
-       if (xlen < MIN_DMA_LEN)
-               panic("si_dma_alloc: xlen=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...
-        */
-       if (xlen > MAX_DMA_LEN) {
-               printf("si_dma_alloc: excessive xlen=0x%x\n", xlen);
-               Debugger();
-               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)
-                       goto found;
-       }
-       panic("si: no free DMA handles.");
-found:
-
-       dh = &sc->sc_dma[i];
-       dh->dh_flags = SIDH_BUSY;
-       dh->dh_addr = (u_char*) addr;
-       dh->dh_maplen  = xlen;
-       dh->dh_dvma = 0;
-
-       /* Copy the "write" flag for convenience. */
-       if (xs->flags & SCSI_DATA_OUT)
-               dh->dh_flags |= SIDH_OUT;
-
-#if 0
-       /*
-        * Some machines might not need to remap B_PHYS buffers.
-        * The sun3 does not map B_PHYS buffers into DVMA space,
-        * (they are mapped into normal KV space) so on the sun3
-        * we must always remap to a DVMA address here. Re-map is
-        * cheap anyway, because it's done by segments, not pages.
-        */
-       if (xs->bp && (xs->bp->b_flags & B_PHYS))
-               dh->dh_flags |= SIDH_PHYS;
-#endif
-
-       dh->dh_dvma = (u_long) dvma_mapin((char *)addr, xlen);
-       if (!dh->dh_dvma) {
-               /* Can't remap segment */
-               printf("si_dma_alloc: can't remap %x/%x\n",
-                       dh->dh_addr, dh->dh_maplen);
-               dh->dh_flags = 0;
-               return;
-       }
-
-       /* success */
-       sr->sr_dma_hand = dh;
-
-       return;
-}
-
-
-void
-si_dma_free(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
-{
-       struct sci_req *sr = ncr_sc->sc_current;
-       struct si_dma_handle *dh = sr->sr_dma_hand;
-
-#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) {
-               /* XXX - Should separate allocation and mapping. */
-               /* Give back the DVMA space. */
-               dvma_mapout((caddr_t)dh->dh_dvma, dh->dh_maplen);
-               dh->dh_dvma = 0;
-               dh->dh_flags = 0;
-       }
-       sr->sr_dma_hand = NULL;
-}
-
-
-/*
- * Poll (spin-wait) for DMA completion.
- * Called right after xx_dma_start(), and
- * xx_dma_stop() will be called next.
- * Same for either VME or OBIO.
- */
-void
-si_dma_poll(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 si_dma_handle *dh = sr->sr_dma_hand;
-       volatile struct si_regs *si = sc->sc_regs;
-       int tmo, csr_mask;
-
-       /* Make sure DMA started successfully. */
-       if (ncr_sc->sc_state & NCR_ABORTING)
-               return;
-
-       csr_mask = SI_CSR_SBC_IP | SI_CSR_DMA_IP |
-               SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR;
-
-       tmo = 50000;    /* X100 = 5 sec. */
-       for (;;) {
-               if (si->si_csr & csr_mask)
-                       break;
-               if (--tmo <= 0) {
-                       printf("si: DMA timeout (while polling)\n");
-                       /* Indicate timeout as MI code would. */
-                       sr->sr_flags |= SR_OVERDUE;
-                       break;
-               }
-               delay(100);
-       }
-
-#ifdef DEBUG
-       if (si_debug) {
-               printf("si_dma_poll: done, csr=0x%x\n", si->si_csr);
-       }
-#endif
-}
-
-
-/*****************************************************************
- * VME functions for DMA
- ****************************************************************/
-
-
-/*
- * 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_vme_intr_on(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
-{
-       struct si_softc *sc = (struct si_softc *)ncr_sc;
-       volatile struct si_regs *si = sc->sc_regs;
-
-       si_vme_dma_setup(ncr_sc);
-       si->si_csr |= SI_CSR_DMA_EN;
-}
-
-/*
- * This is called when the bus is idle and we are
- * about to start playing with the SBC chip.
- */
-void
-si_vme_intr_off(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
-{
-       struct si_softc *sc = (struct si_softc *)ncr_sc;
-       volatile struct si_regs *si = sc->sc_regs;
-
-       si->si_csr &= ~SI_CSR_DMA_EN;
-}
-
-/*
- * 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_vme_dma_setup(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
-{
-       struct si_softc *sc = (struct si_softc *)ncr_sc;
-       volatile struct si_regs *si = sc->sc_regs;
-
-       /* Reset the FIFO */
-       si->si_csr &= ~SI_CSR_FIFO_RES;         /* active low */
-       si->si_csr |= SI_CSR_FIFO_RES;
-
-       /* Set direction (assume recv here) */
-       si->si_csr &= ~SI_CSR_SEND;
-       /* Assume worst alignment */
-       si->si_csr |= SI_CSR_BPCON;
-
-       si->dma_addrh = 0;
-       si->dma_addrl = 0;
-
-       si->dma_counth = 0;
-       si->dma_countl = 0;
-
-       /* Clear FIFO counter. (also hits dma_count) */
-       si->fifo_cnt_hi = 0;
-       si->fifo_count = 0;             
-}
-
-
-void
-si_vme_dma_start(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 si_dma_handle *dh = sr->sr_dma_hand;
-       volatile struct si_regs *si = sc->sc_regs;
-       long data_pa;
-       int xlen;
-
-       /*
-        * Get the DVMA mapping for this segment.
-        * XXX - Should separate allocation and mapin.
-        */
-       data_pa = dvma_kvtopa(dh->dh_dvma, sc->sc_adapter_type);
-       data_pa += (ncr_sc->sc_dataptr - dh->dh_addr);
-       if (data_pa & 1)
-               panic("si_dma_start: bad pa=0x%x", data_pa);
-       xlen = ncr_sc->sc_datalen;
-       xlen &= ~1;
-       sc->sc_xlen = xlen;     /* XXX: or less... */
-
-#ifdef DEBUG
-       if (si_debug & 2) {
-               printf("si_dma_start: dh=0x%x, pa=0x%x, xlen=%d\n",
-                          dh, data_pa, xlen);
-       }
-#endif
-
-       /*
-        * Set up the DMA controller.
-        */
-       si->si_csr &= ~SI_CSR_FIFO_RES;         /* active low */
-       si->si_csr |= SI_CSR_FIFO_RES;
-
-       /* Set direction (send/recv) */
-       if (dh->dh_flags & SIDH_OUT) {
-               si->si_csr |= SI_CSR_SEND;
-       } else {
-               si->si_csr &= ~SI_CSR_SEND;
-       }
-
-       if (data_pa & 2) {
-               si->si_csr |= SI_CSR_BPCON;
-       } else {
-               si->si_csr &= ~SI_CSR_BPCON;
-       }
-
-       si->dma_addrh = (ushort)(data_pa >> 16);
-       si->dma_addrl = (ushort)(data_pa & 0xFFFF);
-
-       si->dma_counth = (ushort)(xlen >> 16);
-       si->dma_countl = (ushort)(xlen & 0xFFFF);
-
-#if 1
-       /* Set it anyway, even though dma_count hits it? */
-       si->fifo_cnt_hi = (ushort)(xlen >> 16);
-       si->fifo_count  = (ushort)(xlen & 0xFFFF);
-#endif
-
-#ifdef DEBUG
-       if (si->fifo_count != xlen) {
-               printf("si_dma_start: fifo_count=0x%x, xlen=0x%x\n",
-                          si->fifo_count, xlen);
-               Debugger();
-       }
-#endif
-
-       /*
-        * Acknowledge the phase change.  (After DMA setup!)
-        * Put the SBIC into DMA mode, and start the transfer.
-        */
-       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 */
-       } 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 */
-       }
-
-       /* Let'er rip! */
-       si->si_csr |= SI_CSR_DMA_EN;
-
-       ncr_sc->sc_state |= NCR_DOINGDMA;
-
-#ifdef DEBUG
-       if (si_debug & 2) {
-               printf("si_dma_start: started, flags=0x%x\n",
-                          ncr_sc->sc_state);
-       }
-#endif
-}
-
-
-void
-si_vme_dma_eop(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
-{
-
-       /* Not needed - DMA was stopped prior to examining sci_csr */
-}
-
-
-void
-si_vme_dma_stop(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 si_dma_handle *dh = sr->sr_dma_hand;
-       volatile struct si_regs *si = sc->sc_regs;
-       int resid, ntrans;
-
-       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;
-
-       /* First, halt the DMA engine. */
-       si->si_csr &= ~SI_CSR_DMA_EN;   /* VME only */
-
-       if (si->si_csr & (SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR)) {
-               printf("si: DMA error, csr=0x%x, reset\n", si->si_csr);
-               sr->sr_xs->error = XS_DRIVER_STUFFUP;
-               ncr_sc->sc_state |= NCR_ABORTING;
-               si_reset_adapter(ncr_sc);
-       }
-
-       /* Note that timeout may have set the error flag. */
-       if (ncr_sc->sc_state & NCR_ABORTING)
-               goto out;
-
-       /*
-        * Now try to figure out how much actually transferred
-        *
-        * The fifo_count does not reflect how many bytes were
-        * actually transferred for VME.
-        *
-        * SCSI-3 VME interface is a little funny on writes:
-        * if we have a disconnect, the dma has overshot by
-        * one byte and needs to be incremented.  This is
-        * true if we have not transferred either all data
-        * or no data.  XXX - from Matt Jacob
-        */
-
-       resid = si->fifo_count & 0xFFFF;
-       ntrans = sc->sc_xlen - resid;
-
-#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;
-       }
-       if (ntrans > ncr_sc->sc_datalen)
-               panic("si_dma_stop: excess transfer");
-
-       /* Adjust data pointer */
-       ncr_sc->sc_dataptr += ntrans;
-       ncr_sc->sc_datalen -= ntrans;
-
-       /*
-        * After a read, we may need to clean-up
-        * "Left-over bytes" (yuck!)
-        */
-       if (((dh->dh_flags & SIDH_OUT) == 0) &&
-               ((si->si_csr & SI_CSR_LOB) != 0))
-       {
-               char *cp = ncr_sc->sc_dataptr;
-#ifdef DEBUG
-               printf("si: Got Left-over bytes!\n");
-#endif
-               if (si->si_csr & SI_CSR_BPCON) {
-                       /* have SI_CSR_BPCON */
-                       cp[-1] = (si->si_bprl & 0xff00) >> 8;
-               } else {
-                       switch (si->si_csr & SI_CSR_LOB) {
-                       case SI_CSR_LOB_THREE:
-                               cp[-3] = (si->si_bprh & 0xff00) >> 8;
-                               cp[-2] = (si->si_bprh & 0x00ff);
-                               cp[-1] = (si->si_bprl & 0xff00) >> 8;
-                               break;
-                       case SI_CSR_LOB_TWO:
-                               cp[-2] = (si->si_bprh & 0xff00) >> 8;
-                               cp[-1] = (si->si_bprh & 0x00ff);
-                               break;
-                       case SI_CSR_LOB_ONE:
-                               cp[-1] = (si->si_bprh & 0xff00) >> 8;
-                               break;
-                       }
-               }
-       }
-
-out:
-       si->dma_addrh = 0;
-       si->dma_addrl = 0;
-
-       si->dma_counth = 0;
-       si->dma_countl = 0;
-
-       si->fifo_cnt_hi = 0;
-       si->fifo_count  = 0;
-
-       /* Put SBIC back in PIO mode. */
-       *ncr_sc->sci_mode &= ~(SCI_MODE_DMA | SCI_MODE_DMA_IE);
-       *ncr_sc->sci_icmd = 0;
-}
-
-
-/*****************************************************************
- * OBIO functions for DMA
- ****************************************************************/
-
-
-static __inline__ void
-si_obio_udc_write(si, regnum, value)
-       volatile struct si_regs *si;
-       int regnum, value;
-{
-       delay(UDC_WAIT_USEC);
-       si->udc_addr = regnum;
-       delay(UDC_WAIT_USEC);
-       si->udc_data = value;
-}
-
-static __inline__ int
-si_obio_udc_read(si, regnum)
-       volatile struct si_regs *si;
-       int regnum;
-{
-       delay(UDC_WAIT_USEC);
-       si->udc_addr = regnum;
-       delay(UDC_WAIT_USEC);
-       return (si->udc_data);
-}
-
-
-/*
- * 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.
- *
- * The OBIO "si" IGNORES any attempt to set the FIFO count
- * register after the SCSI bus goes into any DATA phase, so
- * this function has to setup the evil FIFO logic.
- */
-void
-si_obio_dma_setup(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
-{
-       struct si_softc *sc = (struct si_softc *)ncr_sc;
-       volatile struct si_regs *si = sc->sc_regs;
-       struct sci_req *sr;
-       struct si_dma_handle *dh;
-       int send = 0;
-       int xlen = 0;
-
-       /* Let this work even without a dma hand, for testing... */
-       if ((sr = ncr_sc->sc_current) != NULL) {
-               if ((dh = sr->sr_dma_hand) != NULL) {
-                       send = dh->dh_flags & SIDH_OUT;
-                       xlen = ncr_sc->sc_datalen;
-                       xlen &= ~1;
-               }
-       }
-
-#ifdef DEBUG
-       if (si_debug) {
-               printf("si_dma_setup: send=%d xlen=%d\n", send, xlen);
-       }
-#endif
-
-       /* Reset the FIFO */
-       si->si_csr &= ~SI_CSR_FIFO_RES;         /* active low */
-       si->si_csr |= SI_CSR_FIFO_RES;
-
-       /* Set direction (send/recv) */
-       if (send) {
-               si->si_csr |= SI_CSR_SEND;
-       } else {
-               si->si_csr &= ~SI_CSR_SEND;
-       }
-
-       /* Set the FIFO counter. */
-       si->fifo_count = xlen;
-
-#ifdef DEBUG
-       if ((si->fifo_count > xlen) || (si->fifo_count < (xlen - 1))) {
-               printf("si_dma_setup: fifo_count=0x%x, xlen=0x%x\n",
-                          si->fifo_count, xlen);
-               Debugger();
-       }
-#endif
-}
-
-
-void
-si_obio_dma_start(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 si_dma_handle *dh = sr->sr_dma_hand;
-       volatile struct si_regs *si = sc->sc_regs;
-       struct udc_table *cmd;
-       long data_pa, cmd_pa;
-       int xlen;
-
-       /*
-        * Get the DVMA mapping for this segment.
-        * XXX - Should separate allocation and mapin.
-        */
-       data_pa = dvma_kvtopa(dh->dh_dvma, sc->sc_adapter_type);
-       data_pa += (ncr_sc->sc_dataptr - dh->dh_addr);
-       if (data_pa & 1)
-               panic("si_dma_start: bad pa=0x%x", data_pa);
-       xlen = ncr_sc->sc_datalen;
-       xlen &= ~1;
-       sc->sc_xlen = xlen;     /* XXX: or less... */
-
-#ifdef DEBUG
-       if (si_debug & 2) {
-               printf("si_dma_start: dh=0x%x, pa=0x%x, xlen=%d\n",
-                          dh, data_pa, xlen);
-       }
-#endif
-
-       /*
-        * Set up the DMA controller.
-        * Already set FIFO count in dma_setup.
-        */
-
-#ifdef DEBUG
-       if ((si->fifo_count > xlen) ||
-               (si->fifo_count < (xlen - 1)))
-       {
-               printf("si_dma_start: fifo_count=0x%x, xlen=0x%x\n",
-                          si->fifo_count, xlen);
-               Debugger();
-       }
-#endif
-
-       /*
-        * The OBIO controller needs a command block.
-        */
-       cmd = &dh->dh_cmd;
-       cmd->addrh = ((data_pa & 0xFF0000) >> 8) | UDC_ADDR_INFO;
-       cmd->addrl = data_pa & 0xFFFF;
-       cmd->count = xlen / 2;  /* bytes -> words */
-       cmd->cmrh = UDC_CMR_HIGH;
-       if (dh->dh_flags & SIDH_OUT) {
-               cmd->cmrl = UDC_CMR_LSEND;
-               cmd->rsel = UDC_RSEL_SEND;
-       } else {
-               cmd->cmrl = UDC_CMR_LRECV;
-               cmd->rsel = UDC_RSEL_RECV;
-       }
-
-       /* Tell the DMA chip where the control block is. */
-       cmd_pa = dvma_kvtopa((long)cmd, BUS_OBIO);
-       si_obio_udc_write(si, UDC_ADR_CAR_HIGH,
-                                         (cmd_pa & 0xff0000) >> 8);
-       si_obio_udc_write(si, UDC_ADR_CAR_LOW,
-                                         (cmd_pa & 0xffff));
-
-       /* Tell the chip to be a DMA master. */
-       si_obio_udc_write(si, UDC_ADR_MODE, UDC_MODE);
-
-       /* Tell the chip to interrupt on error. */
-       si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_CIE);
-
-       /* Finally, give the UDC a "start chain" command. */
-       si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_STRT_CHN);
-
-       /*
-        * Acknowledge the phase change.  (After DMA setup!)
-        * Put the SBIC into DMA mode, and start the transfer.
-        */
-       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 */
-       } 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 */
-       }
-
-       ncr_sc->sc_state |= NCR_DOINGDMA;
-
-#ifdef DEBUG
-       if (si_debug & 2) {
-               printf("si_dma_start: started, flags=0x%x\n",
-                          ncr_sc->sc_state);
-       }
-#endif
-}
-
-
-void
-si_obio_dma_eop(ncr_sc)
-       struct ncr5380_softc *ncr_sc;
-{
-
-       /* Not needed - DMA was stopped prior to examining sci_csr */
-}
-
-
-void
-si_obio_dma_stop(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 si_dma_handle *dh = sr->sr_dma_hand;
-       volatile struct si_regs *si = sc->sc_regs;
-       int resid, ntrans, tmo, udc_cnt;
-
-       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;
-
-       if (si->si_csr & (SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR)) {
-               printf("si: DMA error, csr=0x%x, reset\n", si->si_csr);
-               sr->sr_xs->error = XS_DRIVER_STUFFUP;
-               ncr_sc->sc_state |= NCR_ABORTING;
-               si_reset_adapter(ncr_sc);
-       }
-
-       /* Note that timeout may have set the error flag. */
-       if (ncr_sc->sc_state & NCR_ABORTING)
-               goto out;
-
-       /*
-        * After a read, wait for the FIFO to empty.
-        * Note: this only works on the OBIO version.
-        */
-       if ((dh->dh_flags & SIDH_OUT) == 0) {
-               tmo = 200000;   /* X10 = 2 sec. */
-               for (;;) {
-                       if (si->si_csr & SI_CSR_FIFO_EMPTY)
-                               break;
-                       if (--tmo <= 0) {
-                               printf("si: dma fifo did not empty, reset\n");
-                               ncr_sc->sc_state |= NCR_ABORTING;
-                               /* si_reset_adapter(ncr_sc); */
-                               goto out;
-                       }
-                       delay(10);
-               }
-       }
-
-       /*
-        * Now try to figure out how much actually transferred
-        *
-        * The fifo_count might not reflect how many bytes were
-        * actually transferred for VME.
-        */
-
-       resid = si->fifo_count & 0xFFFF;
-       ntrans = sc->sc_xlen - resid;
-
-#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;
-       }
-       if (ntrans > ncr_sc->sc_datalen)
-               panic("si_dma_stop: excess transfer");
-
-       /* Adjust data pointer */
-       ncr_sc->sc_dataptr += ntrans;
-       ncr_sc->sc_datalen -= ntrans;
-
-       /*
-        * After a read, we may need to clean-up
-        * "Left-over bytes" (yuck!)
-        */
-       if ((dh->dh_flags & SIDH_OUT) == 0) {
-               /* If odd transfer count, grab last byte by hand. */
-               if (ntrans & 1) {
-                       ncr_sc->sc_dataptr[-1] =
-                               (si->fifo_data & 0xff00) >> 8;
-                       goto out;
-               }
-               /* UDC might not have transfered the last word. */
-               udc_cnt = si_obio_udc_read(si, UDC_ADR_COUNT);
-               if (((udc_cnt * 2) - resid) == 2) {
-                       ncr_sc->sc_dataptr[-2] =
-                               (si->fifo_data & 0xff00) >> 8;
-                       ncr_sc->sc_dataptr[-1] =
-                               (si->fifo_data & 0x00ff);
-               }
-       }
-
-out:
-       /* Reset the UDC. */
-       si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_RESET);
-       si->fifo_count = 0;
-
-       /* Put SBIC back in PIO mode. */
-       *ncr_sc->sci_mode &= ~(SCI_MODE_DMA | SCI_MODE_DMA_IE);
-       *ncr_sc->sci_icmd = 0;
-}
-
index 2d75eb6..e69de29 100644 (file)
@@ -1,103 +0,0 @@
-/*     $NetBSD: ncr_sireg.h,v 1.2 1995/11/17 23:27:55 gwr Exp $        */
-
-/*
- * Register map for the Sun3 SCSI Interface (si)
- * The first part of this register map is an NCR5380
- * SCSI Bus Interface Controller (SBIC).  The rest is a
- * DMA controller and custom logic in one of two flavors,
- * one for the OBIO interface (3/50,3/60) and one for the
- * VME interface (3/160,3/260,etc.), where some registers
- * are implemented only on one or the other, some on both.
- */
-
-/*
- * Some of these registers apply to only one interface and some
- * apply to both. The registers which apply to the Sun3/50 onboard 
- * version only are udc_rdata and udc_raddr. The registers which
- * apply to the Sun3 vme version only are dma_addr, dma_count, bpr,
- * iv_am, and bcrh. Thus, the sbc registers, fifo_data, bcr, and csr 
- * apply to both interfaces.
- * One other feature of the vme interface: a write to the dma count 
- * register also causes a write to the fifo byte count register and
- * vis versa.
- */
-
-/*
- * Am5380 Register map (no padding)
- */
-struct ncr5380regs {
-       volatile u_char sci_r0;
-       volatile u_char sci_r1;
-       volatile u_char sci_r2;
-       volatile u_char sci_r3;
-       volatile u_char sci_r4;
-       volatile u_char sci_r5;
-       volatile u_char sci_r6;
-       volatile u_char sci_r7;
-};
-
-struct si_regs {
-       struct ncr5380regs sci;
-
-       /* DMA controller registers */
-       u_short                 dma_addrh;      /* dma address (VME only) */
-       u_short                 dma_addrl;      /* (high word, low word)  */
-       u_short                 dma_counth;     /* dma count   (VME only) */
-       u_short                 dma_countl;     /* (high word, low word)  */
-
-       /* AMD 9516 regs (OBIO only) see am9516.h */
-       u_short                 udc_data;       /* Am9516, reg data (OBIO only) */
-       u_short                 udc_addr;       /* Am9516, reg addr (OBIO only) */
-
-       /* These three registers are on both OBIO and VME versions. */
-       u_short                 fifo_data;      /* fifo data register */
-                                               /* holds extra byte on odd */
-                                               /* byte dma read */
-       u_short                 fifo_count;             /* fifo byte count */
-       u_short                 si_csr;         /* control/status register */
-
-       /* The rest of these are on the VME interface only: */
-       u_short                 si_bprh;                /* byte pack, high (VME only) */
-       u_short                 si_bprl;                /* byte pack, low  (VME only) */
-       u_short                 si_iv_am;               /* bits 0-7: intr vector */
-                                               /* bits 8-13: addr modifier (VME only) */
-                                               /* bits 14-15: unused */
-       u_short                 fifo_cnt_hi;    /* high part of fifo_count (VME only) */
-
-       /* Whole thing repeats after 32 bytes. */
-       u_short                 _space[3];
-};
-
-/* possible values for the address modifier, sun3 vme version only */
-#define VME_SUPV_DATA_24       0x3d00
-
-/*
- * Status Register.
- * Note:
- *     (r)     indicates bit is read only.
- *     (rw)    indicates bit is read or write.
- *     (v)     vme host adaptor interface only.
- *     (o)     sun3/50 onboard host adaptor interface only.
- *     (b)     both vme and sun3/50 host adaptor interfaces.
- */
-#define SI_CSR_DMA_ACTIVE      0x8000  /* (r,o) dma transfer active */
-#define SI_CSR_DMA_CONFLICT    0x4000  /* (r,b) reg accessed while dmaing */
-#define SI_CSR_DMA_BUS_ERR     0x2000  /* (r,b) bus error during dma */
-#define SI_CSR_ID              0x1000  /* (r,b) 0 for 3/50, 1 for SCSI-3, */
-                                       /* 0 if SCSI-3 unmodified */
-#define SI_CSR_FIFO_FULL       0x0800  /* (r,b) fifo full */
-#define SI_CSR_FIFO_EMPTY      0x0400  /* (r,b) fifo empty */
-#define SI_CSR_SBC_IP          0x0200  /* (r,b) sbc interrupt pending */
-#define SI_CSR_DMA_IP          0x0100  /* (r,b) dma interrupt pending */
-#define SI_CSR_LOB             0x00c0  /* (r,v) number of leftover bytes */
-#define SI_CSR_LOB_THREE       0x00c0  /* (r,v) three leftover bytes */
-#define SI_CSR_LOB_TWO         0x0080  /* (r,v) two leftover bytes */
-#define SI_CSR_LOB_ONE         0x0040  /* (r,v) one leftover byte */
-#define SI_CSR_BPCON           0x0020  /* (rw,v) byte packing control */
-                                       /* dma is in 0=longwords, 1=words */
-#define SI_CSR_DMA_EN          0x0010  /* (rw,v) dma/interrupt enable */
-#define SI_CSR_SEND            0x0008  /* (rw,b) dma dir, 1=to device */
-#define SI_CSR_INTR_EN         0x0004  /* (rw,b) interrupts enable */
-#define SI_CSR_FIFO_RES                0x0002  /* (rw,b) inits fifo, 0=reset */
-#define SI_CSR_SCSI_RES                0x0001  /* (rw,b) reset sbc and udc, 0=reset */
-
index 9178004..9eb21c0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: obctl.c,v 1.6 1994/12/12 18:59:21 gwr Exp $    */
+/*     $NetBSD: obctl.c,v 1.8 1996/03/26 15:16:12 gwr Exp $    */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
  *    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 Adam Glass.
- * 4. The name of the Author may not be used to endorse or promote products
+ *     This product includes software developed by Adam Glass and Gordon Ross.
+ * 4. The name of the authors may not be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY Adam Glass ``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 Adam Glass 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 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.
+ */
+
+/*
+ * On-board control space (OBCTL)
+ * Used by the idprom...
  */
 
 #include <sys/param.h>
 #include <machine/autoconf.h>
 #include <machine/obctl.h>
 
+static int  obctl_match __P((struct device *, void *, void *));
 static void obctl_attach __P((struct device *, struct device *, void *));
-static void obctl_scan __P((struct device *, void *));
 
-struct cfdriver obctlcd = {
-       NULL, "obctl", always_match, obctl_attach, DV_DULL,
-       sizeof(struct device), 0 };
+struct cfattach obctl_ca = {
+       sizeof(struct device), obctl_match, obctl_attach
+};
+
+struct cfdriver obctl_cd = {
+       NULL, "obctl", DV_DULL
+};
+
+static int
+obctl_match(parent, vcf, aux)
+       struct device *parent;
+       void *vcf, *aux;
+{
+       struct confargs *ca = aux;
+
+       if (ca->ca_bustype != BUS_OBCTL)
+               return (0);
+       return(1);
+}
 
 static void
 obctl_attach(parent, self, args)
@@ -53,13 +73,7 @@ obctl_attach(parent, self, args)
        void *args;
 {
        printf("\n");
-       config_scan(obctl_scan, self);
-}
 
-static void
-obctl_scan(parent, child)
-       struct device *parent;
-       void *child;
-{
-       bus_scan(parent, child, BUS_OBCTL);
+       /* We know ca_bustype == BUS_OBCTL */
+       (void) config_search(bus_scan, self, args);
 }
index b15a67d..8573ec2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: obio.c,v 1.16 1995/02/13 22:23:57 gwr Exp $    */
+/*     $NetBSD: obio.c,v 1.18 1996/03/26 15:16:14 gwr Exp $    */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
 #include <machine/isr.h>
 #include <machine/obio.h>
 
+static int  obio_match __P((struct device *, void *, void *));
 static void obio_attach __P((struct device *, struct device *, void *));
-static void obio_scan __P((struct device *, void *));
+static int  obio_print __P((void *, char *parentname));
 
-struct cfdriver obiocd = {
-       NULL, "obio", always_match, obio_attach, DV_DULL,
-       sizeof(struct device), 0 };
+struct cfattach obio_ca = {
+       sizeof(struct device), obio_match, obio_attach
+};
+
+struct cfdriver obio_cd = {
+       NULL, "obio", DV_DULL
+};
+
+static int
+obio_match(parent, vcf, aux)
+       struct device *parent;
+       void *vcf, *aux;
+{
+       struct confargs *ca = aux;
+
+       if (ca->ca_bustype != BUS_OBIO)
+               return (0);
+       return(1);
+}
+
+#define        OBIO_INCR       0x020000
+#define OBIO_END       0x200000
 
 static void
-obio_attach(parent, self, args)
+obio_attach(parent, self, aux)
        struct device *parent;
        struct device *self;
-       void *args;
+       void *aux;
 {
+       struct confargs *ca = aux;
+       int     addr;
+
        printf("\n");
-       config_scan(obio_scan, self);
+
+       /* Configure these in order of address. */
+       for (addr = 0; addr < OBIO_END; addr += OBIO_INCR) {
+
+               /* We know ca_bustype == BUS_OBIO */
+               ca->ca_paddr = addr;
+               ca->ca_intpri = -1;
+               ca->ca_intvec = -1;
+
+               (void) config_found(self, ca, obio_print);
+       }
 }
 
-static void
-obio_scan(parent, child)
-       struct device *parent;
-       void *child;
+/*
+ * Print out the confargs.  The (parent) name is non-NULL
+ * when there was no match found by config_found().
+ */
+static int
+obio_print(args, name)
+       void *args;
+       char *name;
 {
-       bus_scan(parent, child, BUS_OBIO);
+       struct confargs *ca = args;
+
+       /* Be quiet about empty OBIO locations. */
+       if (name)
+               return(QUIET);
+
+       printf(" addr 0x%x", ca->ca_paddr);
+
+       return(UNCONF);
 }
 
+/*****************************************************************/
+
 /*
  * Spacing of "interesting" OBIO mappings.  We will
  * record only those with an OBIO address that is a
index 6a9f557..37cce83 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: obmem.c,v 1.6 1994/12/12 18:59:23 gwr Exp $    */
+/*     $NetBSD: obmem.c,v 1.8 1996/03/26 15:16:17 gwr Exp $    */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
  *    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 Adam Glass.
- * 4. The name of the Author may not be used to endorse or promote products
+ *     This product includes software developed by Adam Glass and Gordon Ross.
+ * 4. The name of the authors may not be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY Adam Glass ``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 Adam Glass 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 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.
  */
 
 /*
 #include <machine/autoconf.h>
 #include <machine/obmem.h>
 
+static int  obmem_match __P((struct device *, void *, void *));
 static void obmem_attach __P((struct device *, struct device *, void *));
-static void obmem_scan __P((struct device *, void *));
 
-struct cfdriver obmemcd = {
-       NULL, "obmem", always_match, obmem_attach, DV_DULL,
-       sizeof(struct device), 0 };
+struct cfattach obmem_ca = {
+       sizeof(struct device), obmem_match, obmem_attach
+};
+
+struct cfdriver obmem_cd = {
+       NULL, "obmem", DV_DULL
+};
+
+static int
+obmem_match(parent, vcf, aux)
+       struct device *parent;
+       void *vcf, *aux;
+{
+       struct confargs *ca = aux;
+
+       if (ca->ca_bustype != BUS_OBMEM)
+               return (0);
+       return(1);
+}
 
 static void
 obmem_attach(parent, self, args)
@@ -58,13 +73,7 @@ obmem_attach(parent, self, args)
        void *args;
 {
        printf("\n");
-       config_scan(obmem_scan, self);
-}
 
-static void
-obmem_scan(parent, child)
-       struct device *parent;
-       void *child;
-{
-       bus_scan(parent, child, BUS_OBMEM);
+       /* We know ca_bustype == BUS_OBMEM */
+       (void) config_search(bus_scan, self, args);
 }
index 14033fe..e69de29 100644 (file)
@@ -1,342 +0,0 @@
-/*     $NetBSD: prom.c,v 1.15 1995/04/10 06:14:57 mycroft Exp $        */
-
-/*
- * Copyright (c) 1993 Adam Glass
- * 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 Adam Glass.
- * 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 Adam Glass ``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 Adam Glass 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 "prom.h"
-
-#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/buf.h>
-#include <sys/ioctl.h>
-#include <sys/tty.h>
-#include <sys/file.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/device.h>
-
-#include <machine/autoconf.h>
-#include <machine/mon.h>
-
-#include <dev/cons.h>
-#include "../sun3/interreg.h"
-
-/*
- * cleanup:
- * get autoconfiguration right, right style
- * not a true serial driver but a tty driver, i.e no carrier
- * make sure start is non-blocking
- * add read support via timeouts
- */
-
-void promattach __P((struct device *, struct device *, void *));
-
-struct prom_softc {
-       struct device sc_dev;
-       int sc_flags;
-       int sc_nopen;
-};
-struct tty *prom_tty[NPROM];
-
-struct cfdriver promcd = {
-       NULL, "prom", always_match, promattach, DV_TTY, sizeof(struct prom_softc)
-};
-
-#define UNIT_TO_PROM_SC(unit) promcd.cd_devs[unit]
-#ifndef PROM_RECEIVE_FREQ
-#define PROM_RECEIVE_FREQ 10
-#endif    
-
-int promopen __P((dev_t, int, int, struct proc *));
-int promclose __P((dev_t, int, int, struct proc *));
-int promread __P((dev_t, struct uio *, int));
-int promwrite __P((dev_t, struct uio *, int));
-int promioctl __P((dev_t, int, caddr_t, int, struct proc *));
-int promstop __P((struct tty *, int));
-
-static int promparam __P((struct tty *, struct termios *));
-static void promstart __P((struct tty *));
-static void promreceive __P((void *));
-
-void
-promattach(parent, self, aux)
-       struct device *parent, *self;
-       void *aux;
-{
-
-       printf("\n");           
-}
-
-int
-promopen(dev, flag, mode, p)
-       dev_t dev;
-       int flag, mode;
-       struct proc *p;
-{
-       struct tty *tp;
-       struct prom_softc *sc;
-       int unit, result;
-
-       unit = minor(dev);
-       if (unit >= promcd.cd_ndevs)
-               return ENXIO;
-       sc = UNIT_TO_PROM_SC(unit);
-       if (sc == NULL)
-               return ENXIO;
-
-       if (prom_tty[unit] == NULL)
-               tp = prom_tty[unit] = ttymalloc();
-       else
-               tp = prom_tty[unit];
-
-       tp->t_oproc = promstart;
-       tp->t_param = promparam;
-       tp->t_dev = dev;
-       if ((tp->t_state & TS_ISOPEN) == 0) {
-               tp->t_state |= TS_WOPEN;
-               ttychars(tp);
-               if (tp->t_ispeed == 0) {
-                       tp->t_iflag = TTYDEF_IFLAG;
-                       tp->t_oflag = TTYDEF_OFLAG;
-                       tp->t_cflag = TTYDEF_CFLAG;
-                       tp->t_lflag = TTYDEF_LFLAG;
-                       tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
-               }
-               promparam(tp, &tp->t_termios);
-               ttsetwater(tp);
-       } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
-               return EBUSY;
-       }
-
-       tp->t_state |= TS_CARR_ON;
-       result = (*linesw[tp->t_line].l_open)(dev, tp);
-       if (result)
-               return result;
-       timeout(promreceive, tp, hz/PROM_RECEIVE_FREQ);
-       return 0;
-}
-
-int
-promclose(dev, flag, mode, p)
-       dev_t dev;
-       int flag, mode;
-       struct proc *p;
-{
-       struct tty *tp;
-       int unit;
-       struct prom_softc *sc;
-
-       unit = minor(dev);
-       sc = UNIT_TO_PROM_SC(unit);
-       tp = prom_tty[unit];
-
-       (*linesw[tp->t_line].l_close)(tp, flag);
-       return ttyclose(tp);
-}
-
-int
-promread(dev, uio, flag)
-       dev_t dev;
-       struct uio *uio;
-       int flag;
-{
-       register struct tty *tp;
-
-       tp = prom_tty[minor(dev)];
-       return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
-}
-
-int
-promwrite(dev, uio, flag)
-       dev_t dev;
-       struct uio *uio;
-       int flag;
-{
-       register struct tty *tp;
-
-       tp = prom_tty[minor(dev)];
-       return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
-}
-
-int
-promioctl(dev, cmd, data, flag, p)
-       dev_t dev;
-       u_long cmd;
-       caddr_t data;
-       int flag;
-       struct proc *p;
-{
-       register struct tty *tp;
-       int error;
-
-       tp = prom_tty[minor(dev)];
-
-       error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
-       if (error >= 0)
-               return error;
-       error = ttioctl(tp, cmd, data, flag, p);
-       if (error >= 0)
-               return error;
-
-       return ENOTTY;
-}
-
-void
-promstart(tp)
-       struct tty *tp;
-{
-       int s, c, count;
-       u_char outbuf[50];
-       u_char *bufp;
-
-       s = spltty();
-       if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT))
-               goto out;
-       tp->t_state |= TS_BUSY;
-       if (tp->t_outq.c_cc <= tp->t_lowat) {
-               if (tp->t_state & TS_ASLEEP) {
-                   tp->t_state &=~ TS_ASLEEP;
-                   wakeup((caddr_t)&tp->t_outq);
-               }
-               selwakeup(&tp->t_wsel);
-       }
-       count = q_to_b(&tp->t_outq, outbuf, 49);
-       if (count) {
-               outbuf[count] = '\0';
-               (void) splhigh();
-               mon_printf("%s", outbuf);
-               (void) spltty();
-       }
-       tp->t_state &= ~TS_BUSY;
-out:
-       splx(s);
-}
-
-void
-promstop(tp, flag)
-       struct tty *tp;
-       int flag;
-{
-
-}
-
-static int
-promparam(tp, t)
-       struct tty *tp;
-       struct termios *t;
-{
-       struct prom_softc *sc;
-
-       if (t->c_ispeed == 0 || (t->c_ispeed != t->c_ospeed))
-               return EINVAL;
-       tp->t_ispeed = t->c_ispeed;
-       tp->t_ospeed = t->c_ospeed;
-       tp->t_cflag = t->c_cflag;
-       return 0;
-}
-
-static void
-promreceive(arg)
-       void *arg;
-{
-       struct tty *tp = arg;
-       int c, s;
-       extern unsigned int orig_nmi_vector;
-       extern int nmi_intr();
-
-       s = spltty();
-       if (tp->t_state & TS_ISOPEN) {
-               if ((tp->t_state & TS_BUSY) == 0) {
-                       set_clk_mode(0, IREG_CLOCK_ENAB_7|IREG_CLOCK_ENAB_5, 0);
-                       isr_add_custom(7, orig_nmi_vector);
-                       set_clk_mode(IREG_CLOCK_ENAB_7, 0, 1);
-                       c = mon_may_getchar();
-                       set_clk_mode(0, IREG_CLOCK_ENAB_7|IREG_CLOCK_ENAB_5, 0);
-                       isr_add_custom(7, nmi_intr);
-                       set_clk_mode(IREG_CLOCK_ENAB_5, 0, 1);
-                       if (c != -1)
-                               (*linesw[tp->t_line].l_rint)(c, tp);
-               }
-               timeout(promreceive, tp, hz/PROM_RECEIVE_FREQ);
-       }
-       splx(s);
-}
-
-void
-promcnprobe(cp)
-       struct consdev *cp;
-{
-       int prommajor;
-
-       /* locate the major number */
-       for (prommajor = 0; prommajor < nchrdev; prommajor++)
-               if (cdevsw[prommajor].d_open == promopen)
-                       break;
-
-       cp->cn_dev = makedev(prommajor, 0);
-       cp->cn_pri = CN_INTERNAL;       /* will always exist but you don't
-                                        * want to use it unless you have to
-                                        */
-}
-
-void
-promcninit(cp)
-       struct consdev *cp;
-{
-
-       mon_printf("console on prom0\n");
-}
-
-int
-promcngetc(dev)
-       dev_t dev;
-{
-
-       mon_printf("not sure how to do promcngetc() yet\n");
-}
-
-/*
- * Console kernel output character routine.
- */
-void
-promcnputc(dev, c)
-       dev_t dev;
-       int c;
-{
-       int s;
-
-       s = splhigh();
-       if (minor(dev) != 0)
-               mon_printf("non unit 0 prom console???\n");
-       mon_putchar(c);
-       splx(s);
-}
index 10b3416..72b7328 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: rd_root.c,v 1.2 1995/11/17 23:24:56 gwr Exp $  */
+/*     $NetBSD: rd_root.c,v 1.4 1996/03/26 14:58:47 gwr Exp $  */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
index ff27756..e69de29 100644 (file)
@@ -1,142 +0,0 @@
-/*     $NetBSD: scsi_5380.h,v 1.4 1994/11/21 21:31:18 gwr Exp $        */
-
-/* 
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- * 
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- * 
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 
- * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- * 
- * Carnegie Mellon requests users of this software to return to
- * 
- *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
- *  School of Computer Science
- *  Carnegie Mellon University
- *  Pittsburgh PA 15213-3890
- * 
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * HISTORY (mach3)
- * Revision 2.3  91/08/24  12:25:10  af
- *     Moved padding of regmap in impl file.
- *     [91/08/02  04:22:39  af]
- * 
- * Revision 2.2  91/06/19  16:28:35  rvb
- *     From the NCR data sheets
- *     "NCR 5380 Family, SCSI Protocol Controller Data Manual"
- *     NCR Microelectronics Division, Colorado Spring, 6/98 T01891L
- *     [91/04/21            af]
- * 
- */
-
-/*
- *     File: scsi_5380.h
- *     Author: Alessandro Forin, Carnegie Mellon University
- *     Date:   5/91
- *
- *     Defines for the NCR 5380 (SCSI chip), aka Am5380
- */
-
-/*
- * Register map
- */
-
-typedef struct {
-       volatile unsigned char  sci_data;       /* r:  Current data */
-#define                        sci_odata sci_data      /* w:  Out data */
-       volatile unsigned char  sci_icmd;       /* rw: Initiator command */
-       volatile unsigned char  sci_mode;       /* rw: Mode */
-       volatile unsigned char  sci_tcmd;       /* rw: Target command */
-       volatile unsigned char  sci_bus_csr;    /* r:  Bus Status */
-#define                        sci_sel_enb sci_bus_csr /* w:  Select enable */
-       volatile unsigned char  sci_csr;        /* r:  Status */
-#define                        sci_dma_send sci_csr    /* w:  Start dma send data */
-       volatile unsigned char  sci_idata;      /* r:  Input data */
-#define                        sci_trecv sci_idata     /* w:  Start dma receive, target */
-       volatile unsigned char  sci_iack;       /* r:  Interrupt Acknowledge  */
-#define                        sci_irecv sci_iack      /* w:  Start dma receive, initiator */
-} sci_regmap_t;
-
-
-/*
- * Initiator command register
- */
-
-#define SCI_ICMD_DATA          0x01            /* rw: Assert data bus   */
-#define SCI_ICMD_ATN           0x02            /* rw: Assert ATN signal */
-#define SCI_ICMD_SEL           0x04            /* rw: Assert SEL signal */
-#define SCI_ICMD_BSY           0x08            /* rw: Assert BSY signal */
-#define SCI_ICMD_ACK           0x10            /* rw: Assert ACK signal */
-#define SCI_ICMD_LST           0x20            /* r:  Lost arbitration */
-#define SCI_ICMD_DIFF  SCI_ICMD_LST            /* w:  Differential cable */
-#define SCI_ICMD_AIP           0x40            /* r:  Arbitration in progress */
-#define SCI_ICMD_TEST  SCI_ICMD_AIP            /* w:  Test mode */
-#define SCI_ICMD_RST           0x80            /* rw: Assert RST signal */
-
-
-/*
- * Mode register
- */
-
-#define SCI_MODE_ARB           0x01            /* rw: Start arbitration */
-#define SCI_MODE_DMA           0x02            /* rw: Enable DMA xfers */
-#define SCI_MODE_MONBSY                0x04            /* rw: Monitor BSY signal */
-#define SCI_MODE_DMA_IE                0x08            /* rw: Enable DMA complete interrupt */
-#define SCI_MODE_PERR_IE       0x10            /* rw: Interrupt on parity errors */
-#define SCI_MODE_PAR_CHK       0x20            /* rw: Check parity */
-#define SCI_MODE_TARGET                0x40            /* rw: Target mode (Initiator if 0) */
-#define SCI_MODE_BLOCKDMA      0x80            /* rw: Block-mode DMA handshake (MBZ) */
-
-
-/*
- * Target command register
- */
-
-#define SCI_TCMD_IO            0x01            /* rw: Assert I/O signal */
-#define SCI_TCMD_CD            0x02            /* rw: Assert C/D signal */
-#define SCI_TCMD_MSG           0x04            /* rw: Assert MSG signal */
-#define SCI_TCMD_PHASE_MASK    0x07            /* r:  Mask for current bus phase */
-#define SCI_TCMD_REQ           0x08            /* rw: Assert REQ signal */
-#define        SCI_TCMD_LAST_SENT      0x80            /* ro: Last byte was xferred
-                                                *     (not on 5380/1) */
-
-#define        SCI_PHASE(x)            SCSI_PHASE(x)
-
-/*
- * Current (SCSI) Bus status
- */
-
-#define SCI_BUS_DBP            0x01            /* r:  Data Bus parity */
-#define SCI_BUS_SEL            0x02            /* r:  SEL signal */
-#define SCI_BUS_IO             0x04            /* r:  I/O signal */
-#define SCI_BUS_CD             0x08            /* r:  C/D signal */
-#define SCI_BUS_MSG            0x10            /* r:  MSG signal */
-#define SCI_BUS_REQ            0x20            /* r:  REQ signal */
-#define SCI_BUS_BSY            0x40            /* r:  BSY signal */
-#define SCI_BUS_RST            0x80            /* r:  RST signal */
-
-#define        SCI_CUR_PHASE(x)        SCSI_PHASE((x)>>2)
-
-/*
- * Bus and Status register
- */
-
-#define SCI_CSR_ACK            0x01            /* r:  ACK signal */
-#define SCI_CSR_ATN            0x02            /* r:  ATN signal */
-#define SCI_CSR_DISC           0x04            /* r:  Disconnected (BSY==0) */
-#define SCI_CSR_PHASE_MATCH    0x08            /* r:  Bus and SCI_TCMD match */
-#define SCI_CSR_INT            0x10            /* r:  Interrupt request */
-#define SCI_CSR_PERR           0x20            /* r:  Parity error */
-#define SCI_CSR_DREQ           0x40            /* r:  DMA request */
-#define SCI_CSR_DONE           0x80            /* r:  DMA count is zero */
-
index c2916d3..e69de29 100644 (file)
@@ -1,58 +0,0 @@
-/*     $NetBSD: scsi_defs.h,v 1.4 1995/06/01 20:22:17 gwr Exp $        */
-
-/*-
- * Copyright (C) 1993  Allen K. Briggs, Chris P. Caputo,
- *                     Michael L. Finch, Bradley A. Grantham, and
- *                     Lawrence A. Kesteloot
- * 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 the Alice Group.
- * 4. The names of the Alice Group or any of its members may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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.
- */
-
-#ifndef _SCSI_DEFS_H
-#define _SCSI_DEFS_H
-
-#define SCSI_PHASE_DATA_OUT    0x0
-#define SCSI_PHASE_DATA_IN     0x1
-#define SCSI_PHASE_CMD         0x2
-#define SCSI_PHASE_STATUS      0x3
-#define SCSI_PHASE_UNSPEC1     0x4
-#define SCSI_PHASE_UNSPEC2     0x5
-#define SCSI_PHASE_MESSAGE_OUT 0x6
-#define SCSI_PHASE_MESSAGE_IN  0x7
-
-#define SCSI_PHASE(x)  ((x)&0x7)
-
-/* These should be fixed up. */
-
-#define SCSI_RET_SUCCESS       0
-#define SCSI_RET_RETRY         1
-#define SCSI_RET_DEVICE_DOWN   2
-#define SCSI_RET_COMMAND_FAIL  3
-#define SCSI_RET_NEED_RESET    4
-
-#endif
index 6068ec3..e69de29 100644 (file)
@@ -1,88 +0,0 @@
-/*     $NetBSD: scsi_sunsi.h,v 1.2 1995/06/01 20:22:27 gwr Exp $       */
-
-/*
- * Register map for the Sun3 SCSI Interface (si)
- * The first part of this register map is an NCR5380
- * SCSI Bus Interface Controller (SBIC).  The rest is a
- * DMA controller and custom logic in one of two flavors,
- * one for the OBIO interface (3/50,3/60) and one for the
- * VME interface (3/160,3/260,etc.), where some registers
- * are implemented only on one or the other, some on both.
- */
-
-/*
- * Some of these registers apply to only one interface and some
- * apply to both. The registers which apply to the Sun3/50 onboard 
- * version only are udc_rdata and udc_raddr. The registers which
- * apply to the Sun3 vme version only are dma_addr, dma_count, bpr,
- * iv_am, and bcrh. Thus, the sbc registers, fifo_data, bcr, and csr 
- * apply to both interfaces.
- * One other feature of the vme interface: a write to the dma count 
- * register also causes a write to the fifo byte count register and
- * vis versa.
- */
-
-struct si_regs {
-       sci_regmap_t sci;       /* See scsi_5380.h */
-       /* DMA controller registers */
-       u_short                 dma_addrh;      /* dma address (VME only) */
-       u_short                 dma_addrl;      /* (high word, low word)  */
-       u_short                 dma_counth;     /* dma count   (VME only) */
-       u_short                 dma_countl;     /* (high word, low word)  */
-
-       /* AMD 9516 regs (OBIO only) see am9516.h */
-       u_short                 udc_data;       /* Am9516, reg data (OBIO only) */
-       u_short                 udc_addr;       /* Am9516, reg addr (OBIO only) */
-
-       /* These three registers are on both OBIO and VME versions. */
-       u_short                 fifo_data;      /* fifo data register */
-                                               /* holds extra byte on odd */
-                                               /* byte dma read */
-       u_short                 fifo_count;             /* fifo byte count */
-       u_short                 si_csr;         /* control/status register */
-
-       /* The rest of these are on the VME interface only: */
-       u_short                 bprh;           /* byte pack, high (VME only) */
-       u_short                 bprl;           /* byte pack, low  (VME only) */
-       u_short                 iv_am;          /* bits 0-7: intr vector */
-                                               /* bits 8-13: addr modifier (VME only) */
-                                               /* bits 14-15: unused */
-       u_short                 bcrh;           /* high portion of bcr (VME only) */
-};
-
-/* possible values for the address modifier, sun3 vme version only */
-#define VME_SUPV_DATA_24       0x3d00
-
-/* XXX - must massage dvma addresses for Sun3/50 hardware (?) */
-#define DVMA_OFFSET            (int)(DVMA - (char *)KERNELBASE)
-
-/*
- * Status Register.
- * Note:
- *     (r)     indicates bit is read only.
- *     (rw)    indicates bit is read or write.
- *     (v)     vme host adaptor interface only.
- *     (o)     sun3/50 onboard host adaptor interface only.
- *     (b)     both vme and sun3/50 host adaptor interfaces.
- */
-#define SI_CSR_DMA_ACTIVE      0x8000  /* (r,o) dma transfer active */
-#define SI_CSR_DMA_CONFLICT    0x4000  /* (r,b) reg accessed while dmaing */
-#define SI_CSR_DMA_BUS_ERR     0x2000  /* (r,b) bus error during dma */
-#define SI_CSR_ID              0x1000  /* (r,b) 0 for 3/50, 1 for SCSI-3, */
-                                       /* 0 if SCSI-3 unmodified */
-#define SI_CSR_FIFO_FULL       0x0800  /* (r,b) fifo full */
-#define SI_CSR_FIFO_EMPTY      0x0400  /* (r,b) fifo empty */
-#define SI_CSR_SBC_IP          0x0200  /* (r,b) sbc interrupt pending */
-#define SI_CSR_DMA_IP          0x0100  /* (r,b) dma interrupt pending */
-#define SI_CSR_LOB             0x00c0  /* (r,v) number of leftover bytes */
-#define SI_CSR_LOB_THREE       0x00c0  /* (r,v) three leftover bytes */
-#define SI_CSR_LOB_TWO         0x0080  /* (r,v) two leftover bytes */
-#define SI_CSR_LOB_ONE         0x0040  /* (r,v) one leftover byte */
-#define SI_CSR_BPCON           0x0020  /* (rw,v) byte packing control */
-                                       /* dma is in 0=longwords, 1=words */
-#define SI_CSR_DMA_EN          0x0010  /* (rw,v) dma enable */
-#define SI_CSR_SEND            0x0008  /* (rw,b) dma dir, 1=to device */
-#define SI_CSR_INTR_EN         0x0004  /* (rw,b) interrupts enable */
-#define SI_CSR_FIFO_RES                0x0002  /* (rw,b) inits fifo, 0=reset */
-#define SI_CSR_SCSI_RES                0x0001  /* (rw,b) reset sbc and udc, 0=reset */
-
index b803393..893c536 100644 (file)
@@ -1,10 +1,8 @@
-/*     $NetBSD: si.c,v 1.22 1995/10/08 23:42:58 gwr Exp $      */
+/*     $NetBSD: si.c,v 1.24 1996/03/26 15:01:10 gwr Exp $      */
 
 /*
- * Copyright (C) 1994 Adam Glass, Gordon W. Ross
- * Copyright (C) 1993  Allen K. Briggs, Chris P. Caputo,
- *                     Michael L. Finch, Bradley A. Grantham, and
- *                     Lawrence A. Kesteloot
+ * Copyright (c) 1995 David Jones, Gordon W. Ross
+ * Copyright (c) 1994 Adam Glass
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * 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
+ * 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
  *    must display the following acknowledgement:
- *     This product includes software developed by the Alice Group.
- * 4. The names of the Alice Group or any of its members may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
+ *      This product includes software developed by
+ *      Adam Glass, David Jones, and Gordon Ross
  *
- * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
+ * 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 ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * 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.
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#define DEBUG 1
-
-/* XXX - Need to add support for real DMA. -gwr */
-/* #define PSEUDO_DMA 1 (broken) */
+/*
+ * 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.
+ *
+ * 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.
+ *
+ * What wonderfully whacky hardware this is!
+ *
+ * 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.
+ */
 
-#include <sys/types.h>
-#include <sys/malloc.h>
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
 #include <sys/buf.h>
 #include <sys/proc.h>
 #include <sys/user.h>
-#include <sys/device.h>
-
-#include <machine/autoconf.h>
-#include <machine/isr.h>
-#include <machine/obio.h>
 
 #include <scsi/scsi_all.h>
 #include <scsi/scsi_debug.h>
 #include <scsi/scsiconf.h>
 
-#include "scsi_defs.h"
-#include "scsi_5380.h"
-#include "scsi_sunsi.h"
-
-#ifdef DEBUG
-static int si_debug = 0;
-static int si_flags = 0 /* | SDEV_DB2 */ ;
-#endif
-
-#define SCI_PHASE_DISC         0       /* sort of ... */
-#define SCI_CLR_INTR(regs)     ((volatile)(regs->sci_iack))
-#define SCI_ACK(ptr,phase)     (ptr)->sci_tcmd = (phase)
-#define SCSI_TIMEOUT_VAL       1000000
-#define WAIT_FOR_NOT_REQ(ptr) {        \
-       int scsi_timeout = SCSI_TIMEOUT_VAL; \
-       while ( ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
-                ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
-                ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
-                (--scsi_timeout) ); \
-       if (!scsi_timeout) { \
-               printf("scsi timeout--WAIT_FOR_NOT_REQ---%s, line %d.\n", \
-                       __FILE__, __LINE__); \
-               goto scsi_timeout_error; \
-       } \
-       }
-#define WAIT_FOR_REQ(ptr) {    \
-       int scsi_timeout = SCSI_TIMEOUT_VAL; \
-       while ( (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
-               (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
-               (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
-                (--scsi_timeout) ); \
-       if (!scsi_timeout) { \
-               printf("scsi timeout--WAIT_FOR_REQ---%s, line %d.\n", \
-                       __FILE__, __LINE__); \
-               goto scsi_timeout_error; \
-       } \
-       }
-#define WAIT_FOR_BSY(ptr) {    \
-       int scsi_timeout = SCSI_TIMEOUT_VAL; \
-       while ( (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
-               (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
-               (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
-                (--scsi_timeout) ); \
-       if (!scsi_timeout) { \
-               printf("scsi timeout--WAIT_FOR_BSY---%s, line %d.\n", \
-                       __FILE__, __LINE__); \
-               goto scsi_timeout_error; \
-       } \
-       }
-
-#define ARBITRATION_RETRIES 1000
+#include <machine/autoconf.h>
+#include <machine/isr.h>
+#include <machine/obio.h>
+#include <machine/dvma.h>
 
-/* XXX - Always available, but might do nothing. */
-int Debugger();
+#define DEBUG XXX
 
-struct ncr5380_softc {
-    struct device sc_dev;
-    volatile void *sc_regs;
-    int sc_adapter_type;
-    int sc_adapter_iv_am;      /* int. vec + address modifier */
-    struct scsi_link sc_link;
-};
+#include <dev/ic/ncr5380reg.h>
+#include <dev/ic/ncr5380var.h>
 
-static void            ncr5380_minphys(struct buf *bp);
-static int             ncr5380_scsi_cmd(struct scsi_xfer *xs);
-static int             ncr5380_reset_adapter(struct ncr5380_softc *);
-static int             ncr5380_reset_scsibus(struct ncr5380_softc *);
-static int             ncr5380_poll(int adapter, int timeout);
-static int             ncr5380_send_cmd(struct scsi_xfer *xs);
+#include "sireg.h"
+#include "sivar.h"
 
-static int             ncr_intr(void *);
+int si_debug = 0;
+#ifdef DEBUG
+static int si_link_flags = 0 /* | SDEV_DB2 */ ;
+#endif
 
-static int     si_generic(int adapter, int id, int lun,
-                        struct scsi_generic *cmd, int cmdlen,
-                        void *databuf, int datalen);
-static int     si_group0(int adapter, int id, int lun,
-                           int opcode, int addr, int len,
-                           int flags, caddr_t databuf, int datalen);
+/* How long to wait for DMA before declaring an error. */
+int si_dma_intr_timo = 500;    /* ticks (sec. X 100) */
 
-static char scsi_name[] = "si";
+static void    si_minphys __P((struct buf *));
+static int     si_print __P((void *, char *));
 
-struct scsi_adapter    ncr5380_switch = {
+static struct scsi_adapter     si_ops = {
        ncr5380_scsi_cmd,               /* scsi_cmd()           */
-       ncr5380_minphys,                /* scsi_minphys()       */
+       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." */
-struct scsi_device ncr_dev = {
+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.      */
 };
 
-static int     si_match();
-static void    si_attach();
+/*
+ * New-style autoconfig attachment. The cfattach
+ * structures are in si_obio.c and si_vme.c
+ */
 
-struct cfdriver sicd = {
-       NULL, "si", si_match, si_attach, DV_DULL,
-       sizeof(struct ncr5380_softc), NULL, 0,
+struct cfdriver si_cd = {
+       NULL, "si", DV_DULL
 };
 
-static int
-si_print(aux, name)
-       void *aux;
-       char *name;
-{
-       if (name != NULL)
-               printf("%s: scsibus ", name);
-       return UNCONF;
-}
 
-static int
-si_match(parent, vcf, args)
-       struct device   *parent;
-       void            *vcf, *args;
+void
+si_attach(sc)
+       struct si_softc *sc;
 {
-       struct cfdata   *cf = vcf;
-       struct confargs *ca = args;
-       int x, probe_addr;
-
-       /* Default interrupt priority always splbio==2 */
-       if (ca->ca_intpri == -1)
-               ca->ca_intpri = 2;
-
-       if ((cpu_machine_id == SUN3_MACH_50) ||
-           (cpu_machine_id == SUN3_MACH_60) )
-       {
-               /* Sun3/50 or Sun3/60 have only OBIO "si" */
-               if (ca->ca_bustype != BUS_OBIO)
-                       return(0);
-               if (ca->ca_paddr == -1)
-                       ca->ca_paddr = OBIO_NCR_SCSI;
-               /* OK... */
-       } else {
-               /* Other Sun3 models may have VME "si" or "sc" */
-               if (ca->ca_bustype != BUS_VME16)
-                       return (0);
-               if (ca->ca_paddr == -1)
-                       return (0);
-               /* OK... */
-       }
-
-       /* Make sure there is something there... */
-       x = bus_peek(ca->ca_bustype, ca->ca_paddr + 1, 1);
-       if (x == -1)
-               return (0);
+       struct ncr5380_softc *ncr_sc = (void *)sc;
+       volatile struct si_regs *regs = sc->sc_regs;
+       int i;
 
        /*
-        * If this is a VME SCSI board, we have to determine whether
-        * it is an "sc" (Sun2) or "si" (Sun3) SCSI board.  This can
-        * be determined using the fact that the "sc" board occupies
-        * 4K bytes in VME space but the "si" board occupies 2K bytes.
+        * Fill in the prototype scsi_link.
         */
-       if (ca->ca_bustype == BUS_VME16) {
-               /* Note, the "si" board should NOT respond here. */
-               x = bus_peek(ca->ca_bustype, ca->ca_paddr + 0x801, 1);
-               if (x != -1)
-                       return(0);
-       }
+       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;
 
-    return (1);
-}
+#ifdef DEBUG
+       if (si_debug)
+               printf("si: Set TheSoftC=%x TheRegs=%x\n", sc, regs);
+       ncr_sc->sc_link.flags |= si_link_flags;
+#endif
 
-static void
-si_attach(parent, self, args)
-       struct device   *parent, *self;
-       void            *args;
-{
-       struct ncr5380_softc *ncr5380 = (struct ncr5380_softc *) self;
-       volatile struct si_regs *regs;
-       struct confargs *ca = args;
-
-       switch (ca->ca_bustype) {
-
-       case BUS_OBIO:
-               regs = (struct si_regs *)
-                       obio_alloc(ca->ca_paddr, sizeof(*regs));
-               isr_add_autovect(ncr_intr, (void *)ncr5380,
-                                                ca->ca_intpri);
-               break;
-
-       case BUS_VME16:
-               regs = (struct si_regs *)
-                       bus_mapin(ca->ca_bustype, ca->ca_paddr, sizeof(*regs));
-               isr_add_vectored(ncr_intr, (void *)ncr5380,
-                                                ca->ca_intpri, ca->ca_intvec);
-               break;
-
-       default:
-               printf("unknown\n");
-               return;
-       }
+       /*
+        * Initialize fields used by the MI code
+        */
+       ncr_sc->sci_r0 = &regs->sci.sci_r0;
+       ncr_sc->sci_r1 = &regs->sci.sci_r1;
+       ncr_sc->sci_r2 = &regs->sci.sci_r2;
+       ncr_sc->sci_r3 = &regs->sci.sci_r3;
+       ncr_sc->sci_r4 = &regs->sci.sci_r4;
+       ncr_sc->sci_r5 = &regs->sci.sci_r5;
+       ncr_sc->sci_r6 = &regs->sci.sci_r6;
+       ncr_sc->sci_r7 = &regs->sci.sci_r7;
 
-       ncr5380->sc_adapter_type = ca->ca_bustype;
-       ncr5380->sc_adapter_iv_am =
-               VME_SUPV_DATA_24 | (ca->ca_intvec & 0xFF);
-       ncr5380->sc_regs = regs;
+       /*
+        * Allocate DMA handles.
+        */
+       i = SCI_OPENINGS * sizeof(struct si_dma_handle);
+       sc->sc_dma = (struct si_dma_handle *)
+               malloc(i, M_DEVBUF, M_WAITOK);
+       if (sc->sc_dma == NULL)
+               panic("si: dvma_malloc failed\n");
+       for (i = 0; i < SCI_OPENINGS; i++)
+               sc->sc_dma[i].dh_flags = 0;
 
        /*
-        * fill in the prototype scsi_link.
+        *  Initialize si board itself.
         */
-    ncr5380->sc_link.adapter_softc = ncr5380;
-    ncr5380->sc_link.adapter_target = 7;
-    ncr5380->sc_link.adapter = &ncr5380_switch;
-    ncr5380->sc_link.device = &ncr_dev;
-    ncr5380->sc_link.openings = 2;
-#ifdef DEBUG
-    ncr5380->sc_link.flags |= si_flags;
-#endif
+       si_reset_adapter(ncr_sc);
+       ncr5380_init(ncr_sc);
+       ncr5380_reset_scsibus(ncr_sc);
+       config_found(&(ncr_sc->sc_dev), &(ncr_sc->sc_link), si_print);
+}
 
-    printf("\n");
-       ncr5380_reset_adapter(ncr5380);
-       ncr5380_reset_scsibus(ncr5380);
-       config_found(self, &(ncr5380->sc_link), si_print);
+static int
+si_print(aux, name)
+       void *aux;
+       char *name;
+{
+       if (name != NULL)
+               printf("%s: scsibus ", name);
+       return UNCONF;
 }
 
-#define MIN_PHYS       65536   /*BARF!!!!*/
 static void
-ncr5380_minphys(struct buf *bp)
+si_minphys(struct buf *bp)
 {
-       if (bp->b_bcount > MIN_PHYS) {
-               printf("Uh-oh...  ncr5380_minphys setting bp->b_bcount = %x.\n", MIN_PHYS);
-               bp->b_bcount = MIN_PHYS;
+       if (bp->b_bcount > MAX_DMA_LEN) {
+#ifdef DEBUG
+               if (si_debug) {
+                       printf("si_minphys len = 0x%x.\n", bp->b_bcount);
+                       Debugger();
+               }
+#endif
+               bp->b_bcount = MAX_DMA_LEN;
        }
-       minphys(bp);
+       return (minphys(bp));
 }
-#undef MIN_PHYS
 
-static int
-ncr5380_scsi_cmd(struct scsi_xfer *xs)
+
+#define CSR_WANT (SI_CSR_SBC_IP | SI_CSR_DMA_IP | \
+       SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR )
+
+int
+si_intr(void *arg)
 {
-       int flags, s, r;
+       struct si_softc *sc = arg;
+       volatile struct si_regs *si = sc->sc_regs;
+       int dma_error, claimed;
+       u_short csr;
 
-       flags = xs->flags;
-       if (xs->bp) flags |= (SCSI_NOSLEEP);
-       if ( flags & ITSDONE ) {
-               printf("Already done?");
-               xs->flags &= ~ITSDONE;
-       }
-       if ( ! ( flags & INUSE ) ) {
-               printf("Not in use?");
-               xs->flags |= INUSE;
-       }
+       claimed = 0;
+       dma_error = 0;
 
-       s = splbio();
+       /* SBC interrupt? DMA interrupt? */
+       csr = si->si_csr;
+       NCR_TRACE("si_intr: csr=0x%x\n", csr);
 
-       if ( flags & SCSI_RESET ) {
-               printf("flags & SCSIRESET.\n");
-               ncr5380_reset_scsibus(xs->sc_link->adapter_softc);
-               r = COMPLETE;
-       } else {
-               r = ncr5380_send_cmd(xs);
-               xs->flags |= ITSDONE;
-               scsi_done(xs);
+       if (csr & SI_CSR_DMA_CONFLICT) {
+               dma_error |= SI_CSR_DMA_CONFLICT;
+               printf("si_intr: DMA conflict\n");
        }
-
-       splx(s);
-
-       switch(r) {
-       case COMPLETE:
-       case SUCCESSFULLY_QUEUED:
-               r = SUCCESSFULLY_QUEUED;
-               if (xs->flags & SCSI_POLL)
-                       r = COMPLETE;
-               break;
-       default:
-               break;
+       if (csr & SI_CSR_DMA_BUS_ERR) {
+               dma_error |= SI_CSR_DMA_BUS_ERR;
+               printf("si_intr: DMA bus error\n");
        }
-       return r;
-}
-
-#ifdef DEBUG
-static int
-ncr5380_show_scsi_cmd(struct scsi_xfer *xs)
-{
-       u_char  *b = (u_char *) xs->cmd;
-       int     i  = 0;
-
-       if ( ! ( xs->flags & SCSI_RESET ) ) {
-               printf("si(%d:%d:%d)-",
-                          xs->sc_link->scsibus,
-                          xs->sc_link->target,
-                          xs->sc_link->lun);
-               while (i < xs->cmdlen) {
-                       if (i) printf(",");
-                       printf("%x",b[i++]);
-               }
-               printf("-\n");
-       } else {
-               printf("si(%d:%d:%d)-RESET-\n",
-                          xs->sc_link->scsibus,
-                          xs->sc_link->target,
-                          xs->sc_link->lun);
+       if (dma_error) {
+               if (sc->ncr_sc.sc_state & NCR_DOINGDMA)
+                       sc->ncr_sc.sc_state |= NCR_ABORTING;
+               /* Make sure we will call the main isr. */
+               csr |= SI_CSR_DMA_IP;
        }
-}
-#endif
-
-/*
- * Actual chip control.
- */
 
-static void
-ncr_sbc_intr(struct ncr5380_softc *ncr5380)
-{
-       volatile sci_regmap_t *regs = ncr5380->sc_regs;
-
-       if ((regs->sci_csr & SCI_CSR_INT) == 0) {
+       if (csr & (SI_CSR_SBC_IP | SI_CSR_DMA_IP)) {
+               claimed = ncr5380_intr(&sc->ncr_sc);
 #ifdef DEBUG
-               printf (" ncr_sbc_intr: spurrious\n");
+               if (!claimed) {
+                       printf("si_intr: spurious from SBC\n");
+                       if (si_debug & 4) {
+                               Debugger();     /* XXX */
+                       }
+               }
 #endif
-               return;
        }
 
-       SCI_CLR_INTR(regs);
-#ifdef DEBUG
-       printf (" ncr_sbc_intr\n");
-#endif
-}
-
-static void
-ncr_dma_intr(struct ncr5380_softc *ncr5380)
-{
-       volatile struct si_regs *regs = ncr5380->sc_regs;
-
-#ifdef DEBUG
-       printf (" ncr_dma_intr\n");
-#endif
+       return (claimed);
 }
 
-static int
-ncr_intr(void *arg)
-{
-       struct ncr5380_softc *ncr5380 = arg;
-       volatile struct si_regs *si = ncr5380->sc_regs;
-       int rv = 0;
-
-       /* Interrupts not enabled?  Can not be for us. */
-       if ((si->si_csr & SI_CSR_INTR_EN) == 0)
-               return rv;
-
-       if (si->si_csr & SI_CSR_DMA_IP) {
-               ncr_dma_intr(ncr5380);
-               rv++;
-       }
-       if (si->si_csr & SI_CSR_SBC_IP) {
-               ncr_sbc_intr(ncr5380);
-               rv++;
-       }
-       return rv;
-}
 
-static int
-ncr5380_reset_adapter(struct ncr5380_softc *sc)
+void
+si_reset_adapter(struct ncr5380_softc *ncr_sc)
 {
+       struct si_softc *sc = (struct si_softc *)ncr_sc;
        volatile struct si_regs *si = sc->sc_regs;
 
 #ifdef DEBUG
@@ -423,585 +277,194 @@ ncr5380_reset_adapter(struct ncr5380_softc *sc)
        }
 #endif
 
-       /* The reset bits in the CSR are active low. */
+       /*
+        * The SCSI3 controller has an 8K FIFO to buffer data between the
+        * 5380 and the DMA.  Make sure it starts out empty.
+        *
+        * The reset bits in the CSR are active low.
+        */
        si->si_csr = 0;
-       delay(20);
-       si->si_csr = SI_CSR_FIFO_RES | SI_CSR_SCSI_RES;
+       delay(10);
+       si->si_csr = SI_CSR_FIFO_RES | SI_CSR_SCSI_RES | SI_CSR_INTR_EN;
+       delay(10);
        si->fifo_count = 0;
+
        if (sc->sc_adapter_type == BUS_VME16) {
                si->dma_addrh = 0;
                si->dma_addrl = 0;
                si->dma_counth = 0;
                si->dma_countl = 0;
-               si->iv_am = sc->sc_adapter_iv_am;
+               si->si_iv_am = sc->sc_adapter_iv_am;
+               si->fifo_cnt_hi = 0;
        }
-}
-
-static int
-ncr5380_reset_scsibus(struct ncr5380_softc *ncr5380)
-{
-       volatile sci_regmap_t *regs = ncr5380->sc_regs;
 
-#ifdef DEBUG
-       if (si_debug) {
-               printf("si_reset_scsibus\n");
-       }
-#endif
-
-       regs->sci_icmd = SCI_ICMD_RST;
-       delay(100);
-       regs->sci_icmd = 0;
-
-       regs->sci_mode = 0;
-       regs->sci_tcmd = SCI_PHASE_DISC;
-       regs->sci_sel_enb = 0;
-
-       SCI_CLR_INTR(regs);
-       /* XXX - Need long delay here! */
+       SCI_CLR_INTR(ncr_sc);
 }
 
-static int
-ncr5380_poll(int adapter, int timeout)
-{
-}
-
-static int
-ncr5380_send_cmd(struct scsi_xfer *xs)
-{
-       int     sense;
 
-#ifdef DIAGNOSTIC
-       if ((getsr() & PSL_IPL) < PSL_IPL2)
-               panic("ncr_send_cmd: bad spl");
-#endif
+/*****************************************************************
+ * Common functions for DMA
+ ****************************************************************/
 
-#ifdef DEBUG
-       if (si_debug & 2)
-               ncr5380_show_scsi_cmd(xs);
-#endif
-
-       sense = si_generic( xs->sc_link->scsibus, xs->sc_link->target,
-                         xs->sc_link->lun, xs->cmd, xs->cmdlen,
-                         xs->data, xs->datalen );
-
-       switch (sense) {
-       case 0: /* success */
-               xs->resid = 0;
-               xs->error = XS_NOERROR;
-               break;
-
-       case 0x02:      /* Check condition */
-#ifdef DEBUG
-               if (si_debug)
-                       printf("check cond. target %d.\n",
-                                  xs->sc_link->target);
-#endif
-               delay(10);      /* Phil's fix for slow devices. */
-               si_group0(xs->sc_link->scsibus,
-                                 xs->sc_link->target,
-                                 xs->sc_link->lun,
-                                 0x3, 0x0,
-                                 sizeof(struct scsi_sense_data),
-                                 0, (caddr_t) &(xs->sense),
-                                 sizeof(struct scsi_sense_data));
-               xs->error = XS_SENSE;
-               break;
-       case 0x08:      /* Busy - common code will delay, retry. */
-               xs->error = XS_BUSY;
-               break;
-       default:        /* Dead - tell common code to give up. */
-               xs->error = XS_DRIVER_STUFFUP;
-               break;
-
-       }
-       return (COMPLETE);
-}
-
-static int
-si_select_target(register volatile sci_regmap_t *regs,
-             u_char myid, u_char tid, int with_atn)
+/*
+ * 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;
 {
-       register u_char bid, icmd;
-       int             ret = SCSI_RET_RETRY;
-       int     arb_retries, arb_wait;
-
-       /* for our purposes.. */
-       myid = 1 << myid;
-       tid = 1 << tid;
-
-       regs->sci_sel_enb = 0; /* we don't want any interrupts. */
-       regs->sci_tcmd = 0;     /* get into a harmless state */
+       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 si_dma_handle *dh;
+       int i, xlen;
+       u_long addr;
 
-       arb_retries = ARBITRATION_RETRIES;
-
-retry_arbitration:
-       regs->sci_mode = 0;     /* get into a harmless state */
-wait_for_bus_free:
-       if (--arb_retries <= 0) {
-#ifdef DEBUG
-               if (si_debug) {
-                       printf("si_select: arb_retries expended; resetting...\n");
-               }
+#ifdef DIAGNOSTIC
+       if (sr->sr_dma_hand != NULL)
+               panic("si_dma_alloc: already have DMA handle");
 #endif
-               ret = SCSI_RET_NEED_RESET;
-               goto nosel;
-       }
 
-       icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
+       addr = (u_long) ncr_sc->sc_dataptr;
+       xlen = ncr_sc->sc_datalen;
 
-       if (regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) {
-               /* Something is sitting on the SCSI bus... */
-#ifdef DEBUG
-               /* Only complain once (the last time through). */
-               if (si_debug && (arb_retries <= 1)) {
-                       printf("si_select_target: still BSY+SEL\n");
-               }
-#endif
-               /* Give it a little time, then try again. */
-               delay(10);
-               goto wait_for_bus_free;
+       /* If the DMA start addr is misaligned then do PIO */
+       if ((addr & 1) || (xlen & 1)) {
+               printf("si_dma_alloc: misaligned.\n");
+               return;
        }
 
-       regs->sci_odata = myid;
-       regs->sci_mode = SCI_MODE_ARB;
-/*     regs->sci_mode |= SCI_MODE_ARB; XXX? */
-
-       /* AIP might not set if BSY went true after we checked */
-       /* Wait up to about 100 usec. for it to appear. */
-       arb_wait = 50;  /* X2 */
-       do {
-               if (regs->sci_icmd & SCI_ICMD_AIP)
-                       goto got_aip;
-               delay2us();
-       } while (--arb_wait > 0);
-       /* XXX - Could have missed it? */
-#ifdef DEBUG
-       if (si_debug)
-               printf("si_select_target: API did not appear\n");
-#endif
-       goto retry_arbitration;
+       /* Make sure our caller checked sc_min_dma_len. */
+       if (xlen < MIN_DMA_LEN)
+               panic("si_dma_alloc: xlen=0x%x\n", xlen);
 
-       got_aip:
-#ifdef DEBUG
-       if (si_debug & 4) {
-               printf("si_select_target: API after %d tries (last wait %d)\n",
-                          ARBITRATION_RETRIES - arb_retries,
-                          (50 - arb_wait));
+       /*
+        * 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...
+        */
+       if (xlen > MAX_DMA_LEN) {
+               printf("si_dma_alloc: excessive xlen=0x%x\n", xlen);
+               Debugger();
+               ncr_sc->sc_datalen = xlen = MAX_DMA_LEN;
        }
-#endif
 
-       delay(3);       /* 2.2 uSec. arbitration delay */
-
-       if (regs->sci_icmd & SCI_ICMD_LST) {
-#ifdef DEBUG
-               if (si_debug)
-                       printf ("lost 1\n");
-#endif
-               goto retry_arbitration; /* XXX */
+       /* 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)
+                       goto found;
        }
+       panic("si: no free DMA handles.");
+found:
 
-       regs->sci_mode &= ~SCI_MODE_PAR_CHK;
-       bid = regs->sci_data;
-
-       if ((bid & ~myid) > myid) {
-#ifdef DEBUG
-               if (si_debug)
-                       printf ("lost 2\n");
-#endif
-               /* Trying again will not help. */
-               goto lost;
-       }
-       if (regs->sci_icmd & SCI_ICMD_LST) {
-#ifdef DEBUG
-               if (si_debug)
-                       printf ("lost 3\n");
-#endif
-               goto lost;
-       }
+       dh = &sc->sc_dma[i];
+       dh->dh_flags = SIDH_BUSY;
+       dh->dh_addr = (u_char*) addr;
+       dh->dh_maplen  = xlen;
+       dh->dh_dvma = 0;
 
-       /* Won arbitration, enter selection phase now */
-       icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
-       icmd |= (with_atn ? (SCI_ICMD_SEL|SCI_ICMD_ATN) : SCI_ICMD_SEL);
-       regs->sci_icmd = icmd;
+       /* Copy the "write" flag for convenience. */
+       if (xs->flags & SCSI_DATA_OUT)
+               dh->dh_flags |= SIDH_OUT;
 
-       if (regs->sci_icmd & SCI_ICMD_LST) {
-#ifdef DEBUG
-               if (si_debug)
-                       printf ("nosel\n");
+#if 0
+       /*
+        * Some machines might not need to remap B_PHYS buffers.
+        * The sun3 does not map B_PHYS buffers into DVMA space,
+        * (they are mapped into normal KV space) so on the sun3
+        * we must always remap to a DVMA address here. Re-map is
+        * cheap anyway, because it's done by segments, not pages.
+        */
+       if (xs->bp && (xs->bp->b_flags & B_PHYS))
+               dh->dh_flags |= SIDH_PHYS;
 #endif
-               goto nosel;
-       }
-
-       /* XXX a target that violates specs might still drive the bus XXX */
-       /* XXX should put our id out, and after the delay check nothi XXX */
-       /* XXX ng else is out there.                                  XXX */
-
-       delay2us();
-
-       regs->sci_sel_enb = 0;
-
-       regs->sci_odata = myid | tid;
-
-       icmd |= SCI_ICMD_BSY|SCI_ICMD_DATA;
-       regs->sci_icmd = icmd;
-
-/*     regs->sci_mode &= ~SCI_MODE_ARB;         2 deskew delays, too */
-       regs->sci_mode = 0;                     /* 2 deskew delays, too */
-
-       icmd &= ~SCI_ICMD_BSY;
-       regs->sci_icmd = icmd;
-
-       /* bus settle delay, 400ns */
-       delay2us(); /* too much (was 2) ? */
 
-       regs->sci_mode |= SCI_MODE_PAR_CHK;
-
-       {
-               register int timeo  = 2500;/* 250 msecs in 100 usecs chunks */
-               while ((regs->sci_bus_csr & SCI_BUS_BSY) == 0) {
-                       if (--timeo > 0) {
-                               delay(100);
-                       } else {
-                               /* This is the "normal" no-such-device select error. */
-#ifdef DEBUG
-                               if (si_debug)
-                                       printf("si_select: not BSY (nothing there)\n");
-#endif
-                               goto nodev;
-                       }
-               }
+       dh->dh_dvma = (u_long) dvma_mapin((char *)addr, xlen);
+       if (!dh->dh_dvma) {
+               /* Can't remap segment */
+               printf("si_dma_alloc: can't remap %x/%x\n",
+                       dh->dh_addr, dh->dh_maplen);
+               dh->dh_flags = 0;
+               return;
        }
 
-       icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL);
-       regs->sci_icmd = icmd;
-/*     regs->sci_sel_enb = myid;*/     /* looks like we should NOT have it */
-       /* XXX - SCI_MODE_PAR_CHK ? */
-       return SCSI_RET_SUCCESS;
-
-nodev:
-       ret = SCSI_RET_DEVICE_DOWN;
-       regs->sci_sel_enb = myid;
-nosel:
-       regs->sci_icmd = 0;
-       regs->sci_mode = 0;
-       return ret;
-
-lost:
-       regs->sci_icmd = 0;
-       regs->sci_mode = 0;
-#ifdef DEBUG
-       if (si_debug) {
-               printf("si_select: lost arbitration\n");
-       }
-#endif
-       return ret;
-}
+       /* success */
+       sr->sr_dma_hand = dh;
 
-sci_data_out(regs, phase, count, data)
-       register volatile sci_regmap_t  *regs;
-       unsigned char           *data;
-{
-       register unsigned char  icmd;
-       register int            cnt=0;
-
-       /* ..checks.. */
-
-       icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
-loop:
-       /* SCSI bus phase not valid until REQ is true. */
-       WAIT_FOR_REQ(regs);
-       if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
-               return cnt;
-
-       icmd |= SCI_ICMD_DATA;
-       regs->sci_icmd = icmd;
-       regs->sci_odata = *data++;
-       icmd |= SCI_ICMD_ACK;
-       regs->sci_icmd = icmd;
-
-       icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_ACK);
-       WAIT_FOR_NOT_REQ(regs);
-       regs->sci_icmd = icmd;
-       ++cnt;
-       if (--count > 0)
-               goto loop;
-scsi_timeout_error:
-       return cnt;
+       return;
 }
 
-sci_data_in(regs, phase, count, data)
-       register volatile sci_regmap_t  *regs;
-       unsigned char           *data;
-{
-       register unsigned char  icmd;
-       register int            cnt=0;
-
-       /* ..checks.. */
-
-       icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
-
-loop:
-       /* SCSI bus phase not valid until REQ is true. */
-       WAIT_FOR_REQ(regs);
-       if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
-               return cnt;
-
-       *data++ = regs->sci_data;
-       icmd |= SCI_ICMD_ACK;
-       regs->sci_icmd = icmd;
 
-       icmd &= ~SCI_ICMD_ACK;
-       WAIT_FOR_NOT_REQ(regs);
-       regs->sci_icmd = icmd;
-       ++cnt;
-       if (--count > 0)
-               goto loop;
-
-scsi_timeout_error:
-       return cnt;
-}
-
-/* Return -1 (error) or number of bytes sent (>=0). */
-static int
-si_command_transfer(register volatile sci_regmap_t *regs,
-                int maxlen, u_char *data, u_char *status, u_char *msg)
+void
+si_dma_free(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
 {
-       int     xfer, phase;
-
-       xfer = 0;
-       regs->sci_icmd = 0;
-
-       while (1) {
-
-               WAIT_FOR_REQ(regs);
-
-               phase = SCI_CUR_PHASE(regs->sci_bus_csr);
-
-               switch (phase) {
-                       case SCSI_PHASE_CMD:
-                               SCI_ACK(regs,SCSI_PHASE_CMD);
-                               xfer += sci_data_out(regs, SCSI_PHASE_CMD,
-                                                       maxlen, data);
-                               goto out;
+       struct sci_req *sr = ncr_sc->sc_current;
+       struct si_dma_handle *dh = sr->sr_dma_hand;
 
-                       case SCSI_PHASE_DATA_IN:
-                               printf("command_transfer: Data in phase?\n");
-                               goto err;
-
-                       case SCSI_PHASE_DATA_OUT:
-                               printf("command_transfer: Data out phase?\n");
-                               goto err;
-
-                       case SCSI_PHASE_STATUS:
-                               SCI_ACK(regs,SCSI_PHASE_STATUS);
-                               printf("command_transfer: status in...\n");
-                               sci_data_in(regs, SCSI_PHASE_STATUS,
-                                               1, status);
-                               printf("command_transfer: status=0x%x\n", *status);
-                               goto err;
-
-                       case SCSI_PHASE_MESSAGE_IN:
-                               SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
-                               printf("command_transfer: msg in?\n");
-                               sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
-                                               1, msg);
-                               break;
+#ifdef DIAGNOSTIC
+       if (dh == NULL)
+               panic("si_dma_free: no DMA handle");
+#endif
 
-                       case SCSI_PHASE_MESSAGE_OUT:
-                               SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
-                               sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
-                                               1, msg);
-                               break;
+       if (ncr_sc->sc_state & NCR_DOINGDMA)
+               panic("si_dma_free: free while in progress");
 
-                       default:
-                               printf("command_transfer: Unexpected phase 0x%x\n", phase);
-                               goto err;
-               }
+       if (dh->dh_flags & SIDH_BUSY) {
+               /* XXX - Should separate allocation and mapping. */
+               /* Give back the DVMA space. */
+               dvma_mapout((caddr_t)dh->dh_dvma, dh->dh_maplen);
+               dh->dh_dvma = 0;
+               dh->dh_flags = 0;
        }
-scsi_timeout_error:
- err:
-       xfer = -1;
- out:
-       return xfer;
+       sr->sr_dma_hand = NULL;
 }
 
-static int
-si_data_transfer(register volatile sci_regmap_t *regs,
-             int maxlen, u_char *data, u_char *status, u_char *msg)
-{
-       int     retlen = 0, xfer, phase;
-
-       regs->sci_icmd = 0;
-
-       *status = 0;
-
-       while (1) {
-
-               WAIT_FOR_REQ(regs);
-
-               phase = SCI_CUR_PHASE(regs->sci_bus_csr);
-
-               switch (phase) {
-                       case SCSI_PHASE_CMD:
-                               printf("Command phase in data_transfer().\n");
-                               return retlen;
-                       case SCSI_PHASE_DATA_IN:
-                               SCI_ACK(regs,SCSI_PHASE_DATA_IN);
-#if PSEUDO_DMA
-                               xfer = sci_pdma_in(regs, SCSI_PHASE_DATA_IN,
-                                                       maxlen, data);
-#else
-                               xfer = sci_data_in(regs, SCSI_PHASE_DATA_IN,
-                                                       maxlen, data);
-#endif
-                               retlen += xfer;
-                               maxlen -= xfer;
-                               break;
-                       case SCSI_PHASE_DATA_OUT:
-                               SCI_ACK(regs,SCSI_PHASE_DATA_OUT);
-#if PSEUDO_DMA
-                               xfer = sci_pdma_out(regs, SCSI_PHASE_DATA_OUT,
-                                                       maxlen, data);
-#else
-                               xfer = sci_data_out(regs, SCSI_PHASE_DATA_OUT,
-                                                       maxlen, data);
-#endif
-                               retlen += xfer;
-                               maxlen -= xfer;
-                               break;
-                       case SCSI_PHASE_STATUS:
-                               SCI_ACK(regs,SCSI_PHASE_STATUS);
-                               sci_data_in(regs, SCSI_PHASE_STATUS,
-                                               1, status);
-                               break;
-                       case SCSI_PHASE_MESSAGE_IN:
-                               SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
-                               sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
-                                               1, msg);
-                               if (*msg == 0) {
-                                       return retlen;
-                               } else {
-                                       printf( "message 0x%x in "
-                                               "data_transfer.\n", *msg);
-                               }
-                               break;
-                       case SCSI_PHASE_MESSAGE_OUT:
-                               SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
-                               sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
-                                               1, msg);
-                               break;
-                       default:
-                               printf( "Unexpected phase 0x%x in "
-                                       "data_transfer().\n", phase);
-scsi_timeout_error:
-                               return retlen;
-                               break;
-               }
-       }
-}
 
-static int
-si_dorequest(struct ncr5380_softc *sc,
-       int target, int lun, u_char *cmd, int cmdlen,
-       char *databuf, int datalen, int *sent)
-       /* Returns 0 on success, -1 on internal error, or the status byte */
+/*
+ * Poll (spin-wait) for DMA completion.
+ * Called right after xx_dma_start(), and
+ * xx_dma_stop() will be called next.
+ * Same for either VME or OBIO.
+ */
+void
+si_dma_poll(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
 {
-       register volatile sci_regmap_t *regs = sc->sc_regs;
-       int     cmd_bytes_sent, r;
-       u_char  stat, msg, c;
-
-#ifdef DEBUG
-       if (si_debug) {
-               printf("si_dorequest: target=%d, lun=%d\n", target, lun);
-       }
-#endif
-
-       *sent = 0;
+       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 tmo, csr_mask;
 
-       if ( ( r = si_select_target(regs, 7, target, 1) ) != SCSI_RET_SUCCESS) {
-#ifdef DEBUG
-               if (si_debug) {
-                       printf("si_dorequest: select returned %d\n", r);
-               }
-#endif
+       /* Make sure DMA started successfully. */
+       if (ncr_sc->sc_state & NCR_ABORTING)
+               return;
 
-               SCI_CLR_INTR(regs);
-               switch (r) {
-
-               case SCSI_RET_NEED_RESET:
-                       printf("si_dorequest: target=%d, lun=%d, resetting...\n",
-                                  target, lun, r);
-                       ncr5380_reset_adapter(sc);
-                       ncr5380_reset_scsibus(sc);
-                       /* fall through */
-               case SCSI_RET_RETRY:
-                       return 0x08;    /* Busy - tell common code to retry. */
-
-               default:
-                       printf("si_dorequest: target=%d, lun=%d, error=%d.\n",
-                               target, lun, r);
-                       /* fall through */
-               case SCSI_RET_DEVICE_DOWN:
-                       return -1;      /* Dead - tell common code to give up. */
-               }
+       csr_mask = SI_CSR_SBC_IP | SI_CSR_DMA_IP |
+               SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR;
+
+       tmo = 50000;    /* X100 = 5 sec. */
+       for (;;) {
+               if (si->si_csr & csr_mask)
+                       break;
+               if (--tmo <= 0) {
+                       printf("si: DMA timeout (while polling)\n");
+                       /* Indicate timeout as MI code would. */
+                       sr->sr_flags |= SR_OVERDUE;
+                               break;
        }
-
-       c = 0x80 | lun;
-
-       if ((cmd_bytes_sent = si_command_transfer(regs, cmdlen,
-                               (u_char *) cmd, &stat, &c)) != cmdlen)
-       {
-               SCI_CLR_INTR(regs);
-               if (cmd_bytes_sent >= 0) {
-                       printf("Data underrun sending CCB (%d bytes of %d, sent).\n",
-                                  cmd_bytes_sent, cmdlen);
-               }
-               return -1;
+               delay(100);
        }
 
-       *sent = si_data_transfer(regs, datalen, (u_char *)databuf,
-                                 &stat, &msg);
 #ifdef DEBUG
        if (si_debug) {
-               printf("si_dorequest: data transfered = %d\n", *sent);
+               printf("si_dma_poll: done, csr=0x%x\n", si->si_csr);
        }
 #endif
-
-       return stat;
 }
 
-static int
-si_generic(int adapter, int id, int lun, struct scsi_generic *cmd,
-        int cmdlen, void *databuf, int datalen)
-{
-       register struct ncr5380_softc *sc = sicd.cd_devs[adapter];
-       int i, j, sent;
-
-       if (cmd->opcode == TEST_UNIT_READY)     /* XXX */
-               cmd->bytes[0] = ((u_char) lun << 5);
-
-       i = si_dorequest(sc, id, lun, (u_char *) cmd, cmdlen,
-                                        databuf, datalen, &sent);
-
-       return i;
-}
-
-static int
-si_group0(int adapter, int id, int lun, int opcode, int addr, int len,
-               int flags, caddr_t databuf, int datalen)
-{
-       register struct ncr5380_softc *sc = sicd.cd_devs[adapter];
-       unsigned char cmd[6];
-       int i, j, sent;
-
-       cmd[0] = opcode;                /* Operation code                       */
-       cmd[1] = (lun << 5) | ((addr >> 16) & 0x1F);    /* Lun & MSB of addr    */
-       cmd[2] = (addr >> 8) & 0xFF;    /* addr                                 */
-       cmd[3] = addr & 0xFF;           /* LSB of addr                          */
-       cmd[4] = len;                   /* Allocation length                    */
-       cmd[5] = flags;         /* Link/Flag                            */
-
-       i = si_dorequest(sc, id, lun, cmd, 6, databuf, datalen, &sent);
-
-       return i;
-}
diff --git a/sys/arch/sun3/dev/si_obio.c b/sys/arch/sun3/dev/si_obio.c
new file mode 100644 (file)
index 0000000..b808b03
--- /dev/null
@@ -0,0 +1,580 @@
+/*     $NetBSD: si_obio.c,v 1.1 1996/03/26 15:01:12 gwr Exp $  */
+
+/*
+ * Copyright (c) 1995 David Jones, Gordon W. Ross
+ * Copyright (c) 1994 Adam Glass
+ * 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. 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
+ *    must display the following acknowledgement:
+ *      This product includes software developed by
+ *      Adam Glass, David Jones, and Gordon Ross
+ *
+ * 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 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.
+ *
+ * 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.
+ *
+ * What wonderfully whacky hardware this is!
+ *
+ * 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.
+ */
+
+/*****************************************************************
+ * OBIO functions for DMA
+ ****************************************************************/
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsi_debug.h>
+#include <scsi/scsiconf.h>
+
+#include <machine/autoconf.h>
+#include <machine/isr.h>
+#include <machine/obio.h>
+#include <machine/dvma.h>
+
+#define DEBUG XXX
+
+#include <dev/ic/ncr5380reg.h>
+#include <dev/ic/ncr5380var.h>
+
+#include "sireg.h"
+#include "sivar.h"
+#include "am9516.h"
+
+/*
+ * How many uS. to delay after touching the am9516 UDC.
+ */
+#define UDC_WAIT_USEC 5
+
+void si_obio_dma_setup __P((struct ncr5380_softc *));
+void si_obio_dma_start __P((struct ncr5380_softc *));
+void si_obio_dma_eop __P((struct ncr5380_softc *));
+void si_obio_dma_stop __P((struct ncr5380_softc *));
+
+/*
+ * New-style autoconfig attachment
+ */
+
+static int     si_obio_match __P((struct device *, void *, void *));
+static void    si_obio_attach __P((struct device *, struct device *, void *));
+
+struct cfattach si_obio_ca = {
+       sizeof(struct si_softc), si_obio_match, si_obio_attach
+};
+
+/* Options.  Interesting values are: 1,3,7 */
+int si_obio_options = 3;
+#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 */
+
+
+static int
+si_obio_match(parent, vcf, args)
+       struct device   *parent;
+       void            *vcf, *args;
+{
+       struct cfdata   *cf = vcf;
+       struct confargs *ca = args;
+       int pa, x;
+
+#ifdef DIAGNOSTIC
+       if (ca->ca_bustype != BUS_OBIO) {
+               printf("si_obio_match: bustype %d?\n", ca->ca_bustype);
+               return (0);
+       }
+#endif
+
+       /*
+        * OBIO match functions may be called for every possible
+        * physical address, so match only our physical address.
+        */
+       if ((pa = cf->cf_paddr) == -1) {
+               /* Use our default PA. */
+               pa = OBIO_NCR_SCSI;
+       }
+       if (pa != ca->ca_paddr)
+               return (0);
+
+#if 0
+       if ((cpu_machine_id != SUN3_MACH_50) &&
+           (cpu_machine_id != SUN3_MACH_60) )
+       {
+               /* Only 3/50 and 3/60 have the obio si. */
+               return (0);
+       }
+#endif
+
+       /* Make sure there is something there... */
+       x = bus_peek(ca->ca_bustype, ca->ca_paddr + 1, 1);
+       return (x != -1);
+}
+
+static void
+si_obio_attach(parent, self, args)
+       struct device   *parent, *self;
+       void            *args;
+{
+       struct si_softc *sc = (struct si_softc *) self;
+       struct ncr5380_softc *ncr_sc = &sc->ncr_sc;
+       struct cfdata *cf = self->dv_cfdata;
+       struct confargs *ca = args;
+       int intpri;
+
+       /* Default interrupt level. */
+       if ((intpri = cf->cf_intpri) == -1)
+               intpri = 2;
+       printf(" level %d", intpri);
+
+       /* XXX: Get options from flags... */
+       printf(" : options=%d\n", si_obio_options);
+
+       ncr_sc->sc_flags = 0;
+       if (si_obio_options & SI_DO_RESELECT)
+               ncr_sc->sc_flags |= NCR5380_PERMIT_RESELECT;
+       if ((si_obio_options & SI_DMA_INTR) == 0)
+               ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
+
+       sc->sc_adapter_type = ca->ca_bustype;
+       sc->sc_regs = (struct si_regs *)
+               obio_alloc(ca->ca_paddr, sizeof(struct si_regs));
+
+       /*
+        * MD function pointers used by the MI code.
+        */
+       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;
+
+       ncr_sc->sc_dma_setup = si_obio_dma_setup;
+       ncr_sc->sc_dma_start = si_obio_dma_start;
+       ncr_sc->sc_dma_eop   = si_obio_dma_stop;
+       ncr_sc->sc_dma_stop  = si_obio_dma_stop;
+       ncr_sc->sc_intr_on   = NULL;
+       ncr_sc->sc_intr_off  = NULL;
+
+       ncr_sc->sc_min_dma_len = MIN_DMA_LEN;
+
+#if 1  /* XXX - Temporary */
+       /* XXX - In case we think DMA is completely broken... */
+       if ((si_obio_options & SI_ENABLE_DMA) == 0) {
+               /* Override this function pointer. */
+               ncr_sc->sc_dma_alloc = NULL;
+       }
+#endif
+
+       /* Need DVMA-capable memory for the UDC command block. */
+       sc->sc_dmacmd = dvma_malloc(sizeof (struct udc_table));
+
+       /* Attach interrupt handler. */
+       isr_add_autovect(si_intr, (void *)sc, intpri);
+
+       /* Do the common attach stuff. */
+       si_attach(sc);
+}
+
+
+static __inline__ void
+si_obio_udc_write(si, regnum, value)
+       volatile struct si_regs *si;
+       int regnum, value;
+{
+       si->udc_addr = regnum;
+       delay(UDC_WAIT_USEC);
+       si->udc_data = value;
+       delay(UDC_WAIT_USEC);
+}
+
+static __inline__ int
+si_obio_udc_read(si, regnum)
+       volatile struct si_regs *si;
+       int regnum;
+{
+       int value;
+
+       si->udc_addr = regnum;
+       delay(UDC_WAIT_USEC);
+       value = si->udc_data;
+       delay(UDC_WAIT_USEC);
+
+       return (value);
+}
+
+
+/*
+ * 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.
+ *
+ * The OBIO "si" IGNORES any attempt to set the FIFO count
+ * register after the SCSI bus goes into any DATA phase, so
+ * this function has to setup the evil FIFO logic.
+ */
+void
+si_obio_dma_setup(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       struct si_softc *sc = (struct si_softc *)ncr_sc;
+       volatile struct si_regs *si = sc->sc_regs;
+       struct sci_req *sr;
+       struct si_dma_handle *dh;
+       int send = 0;
+       int xlen = 0;
+
+       /* Let this work even without a dma hand, for testing... */
+       if ((sr = ncr_sc->sc_current) != NULL) {
+               if ((dh = sr->sr_dma_hand) != NULL) {
+                       send = dh->dh_flags & SIDH_OUT;
+                       xlen = ncr_sc->sc_datalen;
+                       xlen &= ~1;
+               }
+       }
+
+#ifdef DEBUG
+       if (si_debug) {
+               printf("si_dma_setup: send=%d xlen=%d\n", send, xlen);
+       }
+#endif
+
+       /* Reset the UDC. (In case not already reset?) */
+       si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_RESET);
+
+       /* Reset the FIFO */
+       si->si_csr &= ~SI_CSR_FIFO_RES;         /* active low */
+       si->si_csr |= SI_CSR_FIFO_RES;
+
+       /* Set direction (send/recv) */
+       if (send) {
+               si->si_csr |= SI_CSR_SEND;
+       } else {
+               si->si_csr &= ~SI_CSR_SEND;
+       }
+
+       /* Set the FIFO counter. */
+       si->fifo_count = xlen;
+
+       /*
+        * XXX: Reset DMA engine again!  Comment from Sprite:
+        * Go through reset again becuase of the bug on the 3/50
+        * where bytes occasionally linger in the DMA fifo.
+        */
+
+       /* Reset the UDC. */
+       si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_RESET);
+
+       /* Reset the FIFO */
+       si->si_csr &= ~SI_CSR_FIFO_RES;         /* active low */
+       si->si_csr |= SI_CSR_FIFO_RES;
+
+#ifdef DEBUG
+       if ((si->fifo_count > xlen) || (si->fifo_count < (xlen - 1))) {
+               printf("si_dma_setup: fifo_count=0x%x, xlen=0x%x\n",
+                          si->fifo_count, xlen);
+               Debugger();
+       }
+#endif
+}
+
+
+void
+si_obio_dma_start(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 si_dma_handle *dh = sr->sr_dma_hand;
+       volatile struct si_regs *si = sc->sc_regs;
+       struct udc_table *cmd;
+       long data_pa, cmd_pa;
+       int xlen;
+
+       /*
+        * Get the DVMA mapping for this segment.
+        * XXX - Should separate allocation and mapin.
+        */
+       data_pa = dvma_kvtopa(dh->dh_dvma, sc->sc_adapter_type);
+       data_pa += (ncr_sc->sc_dataptr - dh->dh_addr);
+       if (data_pa & 1)
+               panic("si_dma_start: bad pa=0x%x", data_pa);
+       xlen = ncr_sc->sc_datalen;
+       xlen &= ~1;
+       sc->sc_reqlen = xlen;   /* XXX: or less... */
+
+#ifdef DEBUG
+       if (si_debug & 2) {
+               printf("si_dma_start: dh=0x%x, pa=0x%x, xlen=%d\n",
+                          dh, data_pa, xlen);
+       }
+#endif
+
+       /*
+        * Set up the DMA controller.
+        * Already set FIFO count in dma_setup.
+        */
+
+#ifdef DEBUG
+       if ((si->fifo_count > xlen) ||
+               (si->fifo_count < (xlen - 1)))
+       {
+               printf("si_dma_start: fifo_count=0x%x, xlen=0x%x\n",
+                          si->fifo_count, xlen);
+               Debugger();
+       }
+#endif
+
+       /*
+        * The OBIO controller needs a command block.
+        */
+       cmd = sc->sc_dmacmd;
+       cmd->addrh = ((data_pa & 0xFF0000) >> 8) | UDC_ADDR_INFO;
+       cmd->addrl = data_pa & 0xFFFF;
+       cmd->count = xlen / 2;  /* bytes -> words */
+       cmd->cmrh = UDC_CMR_HIGH;
+       if (dh->dh_flags & SIDH_OUT) {
+               cmd->cmrl = UDC_CMR_LSEND;
+               cmd->rsel = UDC_RSEL_SEND;
+       } else {
+               cmd->cmrl = UDC_CMR_LRECV;
+               cmd->rsel = UDC_RSEL_RECV;
+       }
+
+       /* Tell the DMA chip where the control block is. */
+       cmd_pa = dvma_kvtopa((long)cmd, BUS_OBIO);
+       si_obio_udc_write(si, UDC_ADR_CAR_HIGH,
+                                         (cmd_pa & 0xff0000) >> 8);
+       si_obio_udc_write(si, UDC_ADR_CAR_LOW,
+                                         (cmd_pa & 0xffff));
+
+       /* Tell the chip to be a DMA master. */
+       si_obio_udc_write(si, UDC_ADR_MODE, UDC_MODE);
+
+       /* Tell the chip to interrupt on error. */
+       si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_CIE);
+
+       /* XXX: Move all of the above to _setup? */
+
+       /* Finally, give the UDC a "start chain" command. */
+       si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_STRT_CHN);
+
+       /*
+        * Acknowledge the phase change.  (After DMA setup!)
+        * Put the SBIC into DMA mode, and start the transfer.
+        */
+       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 */
+       } 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 */
+       }
+
+       ncr_sc->sc_state |= NCR_DOINGDMA;
+
+#ifdef DEBUG
+       if (si_debug & 2) {
+               printf("si_dma_start: started, flags=0x%x\n",
+                          ncr_sc->sc_state);
+       }
+#endif
+}
+
+
+void
+si_obio_dma_eop(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+
+       /* Not needed - DMA was stopped prior to examining sci_csr */
+}
+
+
+void
+si_obio_dma_stop(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 si_dma_handle *dh = sr->sr_dma_hand;
+       volatile struct si_regs *si = sc->sc_regs;
+       int resid, ntrans, tmo, udc_cnt;
+
+       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;
+
+       if (si->si_csr & (SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR)) {
+               printf("si: DMA error, csr=0x%x, reset\n", si->si_csr);
+               sr->sr_xs->error = XS_DRIVER_STUFFUP;
+               ncr_sc->sc_state |= NCR_ABORTING;
+               si_reset_adapter(ncr_sc);
+       }
+
+       /* Note that timeout may have set the error flag. */
+       if (ncr_sc->sc_state & NCR_ABORTING)
+               goto out;
+
+       /*
+        * After a read, wait for the FIFO to empty.
+        * Note: this only works on the OBIO version.
+        */
+       if ((dh->dh_flags & SIDH_OUT) == 0) {
+               tmo = 200000;   /* X10 = 2 sec. */
+               for (;;) {
+                       if (si->si_csr & SI_CSR_FIFO_EMPTY)
+                               break;
+                       if (--tmo <= 0) {
+                               printf("si: dma fifo did not empty, reset\n");
+                               ncr_sc->sc_state |= NCR_ABORTING;
+                               /* si_reset_adapter(ncr_sc); */
+                               goto out;
+                       }
+                       delay(10);
+               }
+       }
+
+       /*
+        * Now try to figure out how much actually transferred
+        *
+        * The fifo_count might not reflect how many bytes were
+        * actually transferred for VME.
+        */
+
+       resid = si->fifo_count & 0xFFFF;
+       ntrans = sc->sc_reqlen - resid;
+
+#ifdef DEBUG
+       if (si_debug & 2) {
+               printf("si_dma_stop: resid=0x%x ntrans=0x%x\n",
+                      resid, ntrans);
+       }
+#endif
+
+       /* XXX: Treat (ntrans==0) as a special, non-error case? */
+       if (ntrans < MIN_DMA_LEN) {
+               printf("si: fifo count: 0x%x\n", resid);
+               ncr_sc->sc_state |= NCR_ABORTING;
+               goto out;
+       }
+       if (ntrans > ncr_sc->sc_datalen)
+               panic("si_dma_stop: excess transfer");
+
+       /* Adjust data pointer */
+       ncr_sc->sc_dataptr += ntrans;
+       ncr_sc->sc_datalen -= ntrans;
+
+       /*
+        * After a read, we may need to clean-up
+        * "Left-over bytes" (yuck!)
+        */
+       if ((dh->dh_flags & SIDH_OUT) == 0) {
+               /* If odd transfer count, grab last byte by hand. */
+               if (ntrans & 1) {
+                       NCR_TRACE("si_dma_stop: leftover 1 at 0x%x\n",
+                               (int) ncr_sc->sc_dataptr - 1);
+                       ncr_sc->sc_dataptr[-1] =
+                               (si->fifo_data & 0xff00) >> 8;
+                       goto out;
+               }
+               /* UDC might not have transfered the last word. */
+               udc_cnt = si_obio_udc_read(si, UDC_ADR_COUNT);
+               if (((udc_cnt * 2) - resid) == 2) {
+                       NCR_TRACE("si_dma_stop: leftover 2 at 0x%x\n",
+                               (int) ncr_sc->sc_dataptr - 2);
+                       ncr_sc->sc_dataptr[-2] =
+                               (si->fifo_data & 0xff00) >> 8;
+                       ncr_sc->sc_dataptr[-1] =
+                               (si->fifo_data & 0x00ff);
+               }
+       }
+
+out:
+       /* Reset the UDC. */
+       si_obio_udc_write(si, UDC_ADR_COMMAND, UDC_CMD_RESET);
+       si->fifo_count = 0;
+       si->si_csr &= ~SI_CSR_SEND;
+
+    /* Reset the FIFO */
+    si->si_csr &= ~SI_CSR_FIFO_RES;     /* active low */
+    si->si_csr |= SI_CSR_FIFO_RES;
+
+       /* Put SBIC back in PIO mode. */
+       *ncr_sc->sci_mode &= ~(SCI_MODE_DMA | SCI_MODE_DMA_IE);
+       *ncr_sc->sci_icmd = 0;
+}
+
diff --git a/sys/arch/sun3/dev/si_vme.c b/sys/arch/sun3/dev/si_vme.c
new file mode 100644 (file)
index 0000000..637f893
--- /dev/null
@@ -0,0 +1,558 @@
+/*     $NetBSD: si_vme.c,v 1.1 1996/03/26 15:01:13 gwr Exp $   */
+
+/*
+ * Copyright (c) 1995 David Jones, Gordon W. Ross
+ * Copyright (c) 1994 Adam Glass
+ * 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. 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
+ *    must display the following acknowledgement:
+ *      This product includes software developed by
+ *      Adam Glass, David Jones, and Gordon Ross
+ *
+ * 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 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.
+ *
+ * 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.
+ *
+ * What wonderfully whacky hardware this is!
+ *
+ * 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.
+ */
+
+/*****************************************************************
+ * VME functions for DMA
+ ****************************************************************/
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+
+#include <scsi/scsi_all.h>
+#include <scsi/scsi_debug.h>
+#include <scsi/scsiconf.h>
+
+#include <machine/autoconf.h>
+#include <machine/isr.h>
+#include <machine/obio.h>
+#include <machine/dvma.h>
+
+#define DEBUG XXX
+
+#include <dev/ic/ncr5380reg.h>
+#include <dev/ic/ncr5380var.h>
+
+#include "sireg.h"
+#include "sivar.h"
+
+/*
+ * Transfers smaller than this are done using PIO
+ * (on assumption they're not worth DMA overhead)
+ */
+#define        MIN_DMA_LEN 128
+
+void si_vme_dma_setup __P((struct ncr5380_softc *));
+void si_vme_dma_start __P((struct ncr5380_softc *));
+void si_vme_dma_eop __P((struct ncr5380_softc *));
+void si_vme_dma_stop __P((struct ncr5380_softc *));
+
+void si_vme_intr_on  __P((struct ncr5380_softc *));
+void si_vme_intr_off __P((struct ncr5380_softc *));
+
+/*
+ * New-style autoconfig attachment
+ */
+
+static int     si_vmes_match __P((struct device *, void *, void *));
+static void    si_vmes_attach __P((struct device *, struct device *, void *));
+
+struct cfattach si_vmes_ca = {
+       sizeof(struct si_softc), si_vmes_match, si_vmes_attach
+};
+
+/* Options.  Interesting values are: 1,3,7 */
+int si_vme_options = 3;
+#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 */
+
+
+static int
+si_vmes_match(parent, vcf, args)
+       struct device   *parent;
+       void            *vcf, *args;
+{
+       struct cfdata   *cf = vcf;
+       struct confargs *ca = args;
+       int x, probe_addr;
+
+#ifdef DIAGNOSTIC
+       if (ca->ca_bustype != BUS_VME16) {
+               printf("si_vmes_match: bustype %d?\n", ca->ca_bustype);
+               return (0);
+       }
+#endif
+
+       if ((cpu_machine_id == SUN3_MACH_50) ||
+           (cpu_machine_id == SUN3_MACH_60) )
+       {
+               /* Sun3/50 or Sun3/60 do not have VME. */
+               return(0);
+       }
+
+       /*
+        * Other Sun3 models may have VME "si" or "sc".
+        * This driver has no default address.
+        */
+       if (ca->ca_paddr == -1)
+               return (0);
+
+       /* Default interrupt priority always splbio==2 */
+       if (ca->ca_intpri == -1)
+               ca->ca_intpri = 2;
+
+       /* Make sure there is something there... */
+       x = bus_peek(ca->ca_bustype, ca->ca_paddr + 1, 1);
+       if (x == -1)
+               return (0);
+
+       /*
+        * If this is a VME SCSI board, we have to determine whether
+        * it is an "sc" (Sun2) or "si" (Sun3) SCSI board.  This can
+        * be determined using the fact that the "sc" board occupies
+        * 4K bytes in VME space but the "si" board occupies 2K bytes.
+        */
+       /* Note: the "si" board should NOT respond here. */
+       x = bus_peek(ca->ca_bustype, ca->ca_paddr + 0x801, 1);
+       if (x != -1) {
+               /* Something responded at 2K+1.  Maybe an "sc" board? */
+#ifdef DEBUG
+               printf("si_vmes_match: May be an `sc' board at pa=0x%x\n",
+                          ca->ca_paddr);
+#endif
+               return(0);
+       }
+
+    return (1);
+}
+
+
+static void
+si_vmes_attach(parent, self, args)
+       struct device   *parent, *self;
+       void            *args;
+{
+       struct si_softc *sc = (struct si_softc *) self;
+       struct ncr5380_softc *ncr_sc = (struct ncr5380_softc *)sc;
+       struct confargs *ca = args;
+       int s;
+
+       /* XXX: Get options from flags... */
+       printf(" : options=%d\n", si_vme_options);
+
+       ncr_sc->sc_flags = 0;
+       if (si_vme_options & SI_DO_RESELECT)
+               ncr_sc->sc_flags |= NCR5380_PERMIT_RESELECT;
+       if ((si_vme_options & SI_DMA_INTR) == 0)
+               ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
+
+       sc->sc_adapter_type = ca->ca_bustype;
+       sc->sc_adapter_iv_am =
+               VME_SUPV_DATA_24 | (ca->ca_intvec & 0xFF);
+
+       sc->sc_regs = (struct si_regs *)
+               bus_mapin(ca->ca_bustype, ca->ca_paddr,
+                               sizeof(struct si_regs));
+
+       /*
+        * MD function pointers used by the MI code.
+        */
+       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;
+
+       ncr_sc->sc_dma_setup = si_vme_dma_setup;
+       ncr_sc->sc_dma_start = si_vme_dma_start;
+       ncr_sc->sc_dma_eop   = si_vme_dma_stop;
+       ncr_sc->sc_dma_stop  = si_vme_dma_stop;
+       ncr_sc->sc_intr_on   = si_vme_intr_on;
+       ncr_sc->sc_intr_off  = si_vme_intr_off;
+
+       ncr_sc->sc_min_dma_len = MIN_DMA_LEN;
+
+#if 1  /* XXX - Temporary */
+       /* XXX - In case we think DMA is completely broken... */
+       if ((si_vme_options & SI_ENABLE_DMA) == 0) {
+               /* Override this function pointer. */
+               ncr_sc->sc_dma_alloc = NULL;
+       }
+#endif
+
+       /* Attach interrupt handler. */
+       isr_add_vectored(si_intr, (void *)sc,
+               ca->ca_intpri, ca->ca_intvec);
+
+       /* Do the common attach stuff. */
+       si_attach(sc);
+}
+
+
+/*
+ * 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_vme_intr_on(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       struct si_softc *sc = (struct si_softc *)ncr_sc;
+       volatile struct si_regs *si = sc->sc_regs;
+
+       si_vme_dma_setup(ncr_sc);
+       si->si_csr |= SI_CSR_DMA_EN;
+}
+
+/*
+ * This is called when the bus is idle and we are
+ * about to start playing with the SBC chip.
+ */
+void
+si_vme_intr_off(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       struct si_softc *sc = (struct si_softc *)ncr_sc;
+       volatile struct si_regs *si = sc->sc_regs;
+
+       si->si_csr &= ~SI_CSR_DMA_EN;
+}
+
+/*
+ * 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_vme_dma_setup(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+       struct si_softc *sc = (struct si_softc *)ncr_sc;
+       volatile struct si_regs *si = sc->sc_regs;
+
+       /* Reset the FIFO */
+       si->si_csr &= ~SI_CSR_FIFO_RES;         /* active low */
+       si->si_csr |= SI_CSR_FIFO_RES;
+
+       /* Set direction (assume recv here) */
+       si->si_csr &= ~SI_CSR_SEND;
+       /* Assume worst alignment */
+       si->si_csr |= SI_CSR_BPCON;
+
+       si->dma_addrh = 0;
+       si->dma_addrl = 0;
+
+       si->dma_counth = 0;
+       si->dma_countl = 0;
+
+       /* Clear FIFO counter. (also hits dma_count) */
+       si->fifo_cnt_hi = 0;
+       si->fifo_count = 0;             
+}
+
+
+void
+si_vme_dma_start(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 si_dma_handle *dh = sr->sr_dma_hand;
+       volatile struct si_regs *si = sc->sc_regs;
+       long data_pa;
+       int xlen;
+
+       /*
+        * Get the DVMA mapping for this segment.
+        * XXX - Should separate allocation and mapin.
+        */
+       data_pa = dvma_kvtopa(dh->dh_dvma, sc->sc_adapter_type);
+       data_pa += (ncr_sc->sc_dataptr - dh->dh_addr);
+       if (data_pa & 1)
+               panic("si_dma_start: bad pa=0x%x", data_pa);
+       xlen = ncr_sc->sc_datalen;
+       xlen &= ~1;
+       sc->sc_reqlen = xlen;   /* XXX: or less... */
+
+#ifdef DEBUG
+       if (si_debug & 2) {
+               printf("si_dma_start: dh=0x%x, pa=0x%x, xlen=%d\n",
+                          dh, data_pa, xlen);
+       }
+#endif
+
+       /*
+        * Set up the DMA controller.
+        */
+       si->si_csr &= ~SI_CSR_FIFO_RES;         /* active low */
+       si->si_csr |= SI_CSR_FIFO_RES;
+
+       /* Set direction (send/recv) */
+       if (dh->dh_flags & SIDH_OUT) {
+               si->si_csr |= SI_CSR_SEND;
+       } else {
+               si->si_csr &= ~SI_CSR_SEND;
+       }
+
+       if (data_pa & 2) {
+               si->si_csr |= SI_CSR_BPCON;
+       } else {
+               si->si_csr &= ~SI_CSR_BPCON;
+       }
+
+       si->dma_addrh = (ushort)(data_pa >> 16);
+       si->dma_addrl = (ushort)(data_pa & 0xFFFF);
+
+       si->dma_counth = (ushort)(xlen >> 16);
+       si->dma_countl = (ushort)(xlen & 0xFFFF);
+
+#if 1
+       /* Set it anyway, even though dma_count hits it? */
+       si->fifo_cnt_hi = (ushort)(xlen >> 16);
+       si->fifo_count  = (ushort)(xlen & 0xFFFF);
+#endif
+
+#ifdef DEBUG
+       if (si->fifo_count != xlen) {
+               printf("si_dma_start: fifo_count=0x%x, xlen=0x%x\n",
+                          si->fifo_count, xlen);
+               Debugger();
+       }
+#endif
+
+       /*
+        * Acknowledge the phase change.  (After DMA setup!)
+        * Put the SBIC into DMA mode, and start the transfer.
+        */
+       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 */
+       } 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 */
+       }
+
+       /* Let'er rip! */
+       si->si_csr |= SI_CSR_DMA_EN;
+
+       ncr_sc->sc_state |= NCR_DOINGDMA;
+
+#ifdef DEBUG
+       if (si_debug & 2) {
+               printf("si_dma_start: started, flags=0x%x\n",
+                          ncr_sc->sc_state);
+       }
+#endif
+}
+
+
+void
+si_vme_dma_eop(ncr_sc)
+       struct ncr5380_softc *ncr_sc;
+{
+
+       /* Not needed - DMA was stopped prior to examining sci_csr */
+}
+
+
+void
+si_vme_dma_stop(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 si_dma_handle *dh = sr->sr_dma_hand;
+       volatile struct si_regs *si = sc->sc_regs;
+       int resid, ntrans;
+
+       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;
+
+       /* First, halt the DMA engine. */
+       si->si_csr &= ~SI_CSR_DMA_EN;   /* VME only */
+
+       if (si->si_csr & (SI_CSR_DMA_CONFLICT | SI_CSR_DMA_BUS_ERR)) {
+               printf("si: DMA error, csr=0x%x, reset\n", si->si_csr);
+               sr->sr_xs->error = XS_DRIVER_STUFFUP;
+               ncr_sc->sc_state |= NCR_ABORTING;
+               si_reset_adapter(ncr_sc);
+       }
+
+       /* Note that timeout may have set the error flag. */
+       if (ncr_sc->sc_state & NCR_ABORTING)
+               goto out;
+
+       /*
+        * Now try to figure out how much actually transferred
+        *
+        * The fifo_count does not reflect how many bytes were
+        * actually transferred for VME.
+        *
+        * SCSI-3 VME interface is a little funny on writes:
+        * if we have a disconnect, the dma has overshot by
+        * one byte and the resid needs to be incremented.
+        * Only happens for partial transfers.
+        * (Thanks to Matt Jacob)
+        */
+
+       resid = si->fifo_count & 0xFFFF;
+       if (dh->dh_flags & SIDH_OUT)
+               if ((resid > 0) && (resid < sc->sc_reqlen))
+                       resid++;
+       ntrans = sc->sc_reqlen - resid;
+
+#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;
+       }
+       if (ntrans > ncr_sc->sc_datalen)
+               panic("si_dma_stop: excess transfer");
+
+       /* Adjust data pointer */
+       ncr_sc->sc_dataptr += ntrans;
+       ncr_sc->sc_datalen -= ntrans;
+
+       /*
+        * After a read, we may need to clean-up
+        * "Left-over bytes" (yuck!)
+        */
+       if (((dh->dh_flags & SIDH_OUT) == 0) &&
+               ((si->si_csr & SI_CSR_LOB) != 0))
+       {
+               char *cp = ncr_sc->sc_dataptr;
+#ifdef DEBUG
+               printf("si: Got Left-over bytes!\n");
+#endif
+               if (si->si_csr & SI_CSR_BPCON) {
+                       /* have SI_CSR_BPCON */
+                       cp[-1] = (si->si_bprl & 0xff00) >> 8;
+               } else {
+                       switch (si->si_csr & SI_CSR_LOB) {
+                       case SI_CSR_LOB_THREE:
+                               cp[-3] = (si->si_bprh & 0xff00) >> 8;
+                               cp[-2] = (si->si_bprh & 0x00ff);
+                               cp[-1] = (si->si_bprl & 0xff00) >> 8;
+                               break;
+                       case SI_CSR_LOB_TWO:
+                               cp[-2] = (si->si_bprh & 0xff00) >> 8;
+                               cp[-1] = (si->si_bprh & 0x00ff);
+                               break;
+                       case SI_CSR_LOB_ONE:
+                               cp[-1] = (si->si_bprh & 0xff00) >> 8;
+                               break;
+                       }
+               }
+       }
+
+out:
+       si->dma_addrh = 0;
+       si->dma_addrl = 0;
+
+       si->dma_counth = 0;
+       si->dma_countl = 0;
+
+       si->fifo_cnt_hi = 0;
+       si->fifo_count  = 0;
+
+       /* Put SBIC back in PIO mode. */
+       *ncr_sc->sci_mode &= ~(SCI_MODE_DMA | SCI_MODE_DMA_IE);
+       *ncr_sc->sci_icmd = 0;
+}
diff --git a/sys/arch/sun3/dev/sireg.h b/sys/arch/sun3/dev/sireg.h
new file mode 100644 (file)
index 0000000..2cf847f
--- /dev/null
@@ -0,0 +1,103 @@
+/*     $NetBSD: sireg.h,v 1.1 1996/03/26 15:01:14 gwr Exp $    */
+
+/*
+ * Register map for the Sun3 SCSI Interface (si)
+ * The first part of this register map is an NCR5380
+ * SCSI Bus Interface Controller (SBIC).  The rest is a
+ * DMA controller and custom logic in one of two flavors,
+ * one for the OBIO interface (3/50,3/60) and one for the
+ * VME interface (3/160,3/260,etc.), where some registers
+ * are implemented only on one or the other, some on both.
+ */
+
+/*
+ * Some of these registers apply to only one interface and some
+ * apply to both. The registers which apply to the Sun3/50 onboard 
+ * version only are udc_rdata and udc_raddr. The registers which
+ * apply to the Sun3 vme version only are dma_addr, dma_count, bpr,
+ * iv_am, and bcrh. Thus, the sbc registers, fifo_data, bcr, and csr 
+ * apply to both interfaces.
+ * One other feature of the vme interface: a write to the dma count 
+ * register also causes a write to the fifo byte count register and
+ * vis versa.
+ */
+
+/*
+ * Am5380 Register map (no padding)
+ */
+struct ncr5380regs {
+       volatile u_char sci_r0;
+       volatile u_char sci_r1;
+       volatile u_char sci_r2;
+       volatile u_char sci_r3;
+       volatile u_char sci_r4;
+       volatile u_char sci_r5;
+       volatile u_char sci_r6;
+       volatile u_char sci_r7;
+};
+
+struct si_regs {
+       struct ncr5380regs sci;
+
+       /* DMA controller registers */
+       u_short                 dma_addrh;      /* dma address (VME only) */
+       u_short                 dma_addrl;      /* (high word, low word)  */
+       u_short                 dma_counth;     /* dma count   (VME only) */
+       u_short                 dma_countl;     /* (high word, low word)  */
+
+       /* AMD 9516 regs (OBIO only) see am9516.h */
+       u_short                 udc_data;       /* Am9516, reg data (OBIO only) */
+       u_short                 udc_addr;       /* Am9516, reg addr (OBIO only) */
+
+       /* These three registers are on both OBIO and VME versions. */
+       u_short                 fifo_data;      /* fifo data register */
+                                               /* holds extra byte on odd */
+                                               /* byte dma read */
+       u_short                 fifo_count;             /* fifo byte count */
+       u_short                 si_csr;         /* control/status register */
+
+       /* The rest of these are on the VME interface only: */
+       u_short                 si_bprh;                /* byte pack, high (VME only) */
+       u_short                 si_bprl;                /* byte pack, low  (VME only) */
+       u_short                 si_iv_am;               /* bits 0-7: intr vector */
+                                               /* bits 8-13: addr modifier (VME only) */
+                                               /* bits 14-15: unused */
+       u_short                 fifo_cnt_hi;    /* high part of fifo_count (VME only) */
+
+       /* Whole thing repeats after 32 bytes. */
+       u_short                 _space[3];
+};
+
+/* possible values for the address modifier, sun3 vme version only */
+#define VME_SUPV_DATA_24       0x3d00
+
+/*
+ * Status Register.
+ * Note:
+ *     (r)     indicates bit is read only.
+ *     (rw)    indicates bit is read or write.
+ *     (v)     vme host adaptor interface only.
+ *     (o)     sun3/50 onboard host adaptor interface only.
+ *     (b)     both vme and sun3/50 host adaptor interfaces.
+ */
+#define SI_CSR_DMA_ACTIVE      0x8000  /* (r,o) dma transfer active */
+#define SI_CSR_DMA_CONFLICT    0x4000  /* (r,b) reg accessed while dmaing */
+#define SI_CSR_DMA_BUS_ERR     0x2000  /* (r,b) bus error during dma */
+#define SI_CSR_ID              0x1000  /* (r,b) 0 for 3/50, 1 for SCSI-3, */
+                                       /* 0 if SCSI-3 unmodified */
+#define SI_CSR_FIFO_FULL       0x0800  /* (r,b) fifo full */
+#define SI_CSR_FIFO_EMPTY      0x0400  /* (r,b) fifo empty */
+#define SI_CSR_SBC_IP          0x0200  /* (r,b) sbc interrupt pending */
+#define SI_CSR_DMA_IP          0x0100  /* (r,b) dma interrupt pending */
+#define SI_CSR_LOB             0x00c0  /* (r,v) number of leftover bytes */
+#define SI_CSR_LOB_THREE       0x00c0  /* (r,v) three leftover bytes */
+#define SI_CSR_LOB_TWO         0x0080  /* (r,v) two leftover bytes */
+#define SI_CSR_LOB_ONE         0x0040  /* (r,v) one leftover byte */
+#define SI_CSR_BPCON           0x0020  /* (rw,v) byte packing control */
+                                       /* dma is in 0=longwords, 1=words */
+#define SI_CSR_DMA_EN          0x0010  /* (rw,v) dma/interrupt enable */
+#define SI_CSR_SEND            0x0008  /* (rw,b) dma dir, 1=to device */
+#define SI_CSR_INTR_EN         0x0004  /* (rw,b) interrupts enable */
+#define SI_CSR_FIFO_RES                0x0002  /* (rw,b) inits fifo, 0=reset */
+#define SI_CSR_SCSI_RES                0x0001  /* (rw,b) reset sbc and udc, 0=reset */
+
diff --git a/sys/arch/sun3/dev/sivar.h b/sys/arch/sun3/dev/sivar.h
new file mode 100644 (file)
index 0000000..1bbaee4
--- /dev/null
@@ -0,0 +1,89 @@
+/*     $NetBSD: sivar.h,v 1.1 1996/03/26 15:01:15 gwr Exp $    */
+
+/*
+ * Copyright (c) 1995 David Jones, Gordon W. Ross
+ * 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. 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
+ *    must display the following acknowledgement:
+ *      This product includes software developed by
+ *      David Jones and Gordon Ross
+ *
+ * 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 file defines the interface between si.c and
+ * the bus-specific files: si_obio.c, si_vme.c
+ */
+
+/*
+ * 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?)
+ */
+#define        MAX_DMA_LEN 0xE000
+
+/*
+ * This structure is used to keep track of mapped DMA requests.
+ */
+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) */
+       u_char *        dh_addr;        /* KVA of start of buffer */
+       int             dh_maplen;      /* Length of KVA mapping. */
+       long            dh_dvma;        /* VA of buffer in DVMA space */
+};
+
+/*
+ * 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;
+       int             sc_adapter_type;
+       int             sc_adapter_iv_am;       /* int. vec + address modifier */
+       int     sc_reqlen;              /* requested transfer length */
+       struct si_dma_handle *sc_dma;
+       /* DMA command block for the OBIO controller. */
+       void *sc_dmacmd;
+};
+
+extern int si_debug;
+
+void si_attach __P((struct si_softc *));
+int  si_intr __P((void *));
+
+void si_reset_adapter __P((struct ncr5380_softc *));
+
+void si_dma_alloc __P((struct ncr5380_softc *));
+void si_dma_free __P((struct ncr5380_softc *));
+void si_dma_poll __P((struct ncr5380_softc *));
index 20e9cc2..086c8b7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: vme.c,v 1.1 1994/12/12 18:59:26 gwr Exp $      */
+/*     $NetBSD: vme.c,v 1.3 1996/03/26 15:16:19 gwr Exp $      */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
 #include <machine/autoconf.h>
 /* #include <machine/vme.h> */
 
-static int  vme_match __P((struct device *, void *, void *));
-static void vme16attach __P((struct device *, struct device *, void *));
-static void vme32attach __P((struct device *, struct device *, void *));
-static void vme16scan __P((struct device *, void *));
-static void vme32scan __P((struct device *, void *));
+static int  vmes_match __P((struct device *, void *, void *));
+static int  vmel_match __P((struct device *, void *, void *));
 
-struct cfdriver vmescd = {
-       NULL, "vmes", vme_match, vme16attach, DV_DULL,
-       sizeof(struct device), 0 };
+static void vme_attach __P((struct device *, struct device *, void *));
 
-struct cfdriver vmelcd = {
-       NULL, "vmel", vme_match, vme32attach, DV_DULL,
-       sizeof(struct device), 0 };
+struct cfattach vmes_ca = {
+       sizeof(struct device), vmes_match, vme_attach
+};
 
-int vme_match(parent, vcf, aux)
+struct cfdriver vmes_cd = {
+       NULL, "vmes", DV_DULL
+};
+
+struct cfattach vmel_ca = {
+       sizeof(struct device), vmel_match, vme_attach
+};
+
+struct cfdriver vmel_cd = {
+       NULL, "vmel", DV_DULL
+};
+
+
+/* Does this machine have a VME bus? */
+extern int cpu_has_vme;
+
+static int
+vmes_match(parent, vcf, aux)
        struct device *parent;
        void *vcf, *aux;
 {
-       /* Does this machine have a VME bus? */
-       extern int cpu_has_vme;
+       struct confargs *ca = aux;
 
+       if (ca->ca_bustype != BUS_VME16)
+               return (0);
        return (cpu_has_vme);
 }
 
-static void
-vme16attach(parent, self, args)
+static int
+vmel_match(parent, vcf, aux)
        struct device *parent;
-       struct device *self;
-       void *args;
+       void *vcf, *aux;
 {
-       printf("\n");
-       config_scan(vme16scan, self);
-}
+       struct confargs *ca = aux;
 
-static void
-vme16scan(parent, child)
-       struct device *parent;
-       void *child;
-{
-       bus_scan(parent, child, BUS_VME16);
+       if (ca->ca_bustype != BUS_VME32)
+               return (0);
+       return (cpu_has_vme);
 }
 
 static void
-vme32attach(parent, self, args)
+vme_attach(parent, self, args)
        struct device *parent;
        struct device *self;
        void *args;
 {
        printf("\n");
-       config_scan(vme32scan, self);
-}
 
-static void
-vme32scan(parent, child)
-       struct device *parent;
-       void *child;
-{
-       bus_scan(parent, child, BUS_VME32);
+       /* We know ca_bustype == BUS_VMExx */
+       (void) config_search(bus_scan, self, args);
 }
index a4ae623..8c1e42f 100644 (file)
@@ -1,4 +1,4 @@
-/* $NetBSD: xd.c,v 1.2 1996/01/07 22:03:17 thorpej Exp $ */
+/*     $NetBSD: xd.c,v 1.7 1996/03/17 02:04:07 thorpej Exp $   */
 
 /*
  *
@@ -36,7 +36,7 @@
  * x d . c   x y l o g i c s   7 5 3 / 7 0 5 3   v m e / s m d   d r i v e r
  *
  * author: Chuck Cranor <chuck@ccrc.wustl.edu>
- * id: $Id: xd.c,v 1.5 1996/03/04 20:35:27 chuck Exp $
+ * id: $NetBSD: xd.c,v 1.7 1996/03/17 02:04:07 thorpej Exp $
  * started: 27-Feb-95
  * references: [1] Xylogics Model 753 User's Manual
  *                 part number: 166-753-001, Revision B, May 21, 1988.
@@ -245,12 +245,20 @@ int       xdgetdisklabel __P((struct xd_softc *, void *));
  * cfdrivers: device driver interface to autoconfig
  */
 
-struct cfdriver xdccd = {
-       NULL, "xdc", xdcmatch, xdcattach, DV_DULL, sizeof(struct xdc_softc)
+struct cfattach xdc_ca = {
+       sizeof(struct xdc_softc), xdcmatch, xdcattach
 };
 
-struct cfdriver xdcd = {
-       NULL, "xd", xdmatch, xdattach, DV_DISK, sizeof(struct xd_softc)
+struct cfdriver xdc_cd = {
+       NULL, "xdc", DV_DULL
+};
+
+struct cfattach xd_ca = {
+       sizeof(struct xd_softc), xdmatch, xdattach
+};
+
+struct cfdriver xd_cd = {
+       NULL, "xd", DV_DISK
 };
 
 struct xdc_attach_args {       /* this is the "aux" args to xdattach */
@@ -722,7 +730,7 @@ xdclose(dev, flag, fmt)
        int     flag, fmt;
 
 {
-       struct xd_softc *xd = xdcd.cd_devs[DISKUNIT(dev)];
+       struct xd_softc *xd = xd_cd.cd_devs[DISKUNIT(dev)];
        int     part = DISKPART(dev);
 
        /* clear mask bits */
@@ -752,11 +760,11 @@ xddump(dev)
        struct xd_softc *xd;
 
        unit = DISKUNIT(dev);
-       if (unit >= xdcd.cd_ndevs)
+       if (unit >= xd_cd.cd_ndevs)
                return ENXIO;
        part = DISKPART(dev);
 
-       xd = xdcd.cd_devs[unit];
+       xd = xd_cd.cd_devs[unit];
 
        printf("%s%c: crash dump not supported (yet)\n",
                   xd->sc_dev.dv_xname, 'a' + part);
@@ -795,7 +803,7 @@ xdioctl(dev, command, addr, flag, p)
 
        unit = DISKUNIT(dev);
 
-       if (unit >= xdcd.cd_ndevs || (xd = xdcd.cd_devs[unit]) == NULL)
+       if (unit >= xd_cd.cd_ndevs || (xd = xd_cd.cd_devs[unit]) == NULL)
                return (ENXIO);
 
        /* switch on ioctl type */
@@ -887,7 +895,7 @@ xdopen(dev, flag, fmt)
        /* first, could it be a valid target? */
 
        unit = DISKUNIT(dev);
-       if (unit >= xdcd.cd_ndevs || (xd = xdcd.cd_devs[unit]) == NULL)
+       if (unit >= xd_cd.cd_ndevs || (xd = xd_cd.cd_devs[unit]) == NULL)
                return (ENXIO);
        part = DISKPART(dev);
 
@@ -964,7 +972,7 @@ xdsize(dev)
 
        /* do it */
 
-       xdsc = xdcd.cd_devs[DISKUNIT(dev)];
+       xdsc = xd_cd.cd_devs[DISKUNIT(dev)];
        part = DISKPART(dev);
        if (xdsc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
                size = -1;      /* only give valid size for swap partitions */
@@ -993,7 +1001,7 @@ xdstrategy(bp)
 
        /* check for live device */
 
-       if (unit >= xdcd.cd_ndevs || (xd = xdcd.cd_devs[unit]) == 0 ||
+       if (unit >= xd_cd.cd_ndevs || (xd = xd_cd.cd_devs[unit]) == 0 ||
            bp->b_blkno < 0 ||
            (bp->b_bcount % xd->sc_dk.dk_label->d_secsize) != 0) {
                bp->b_error = EINVAL;
@@ -1425,6 +1433,9 @@ xdc_startbuf(xdcsc, xdsc, bp)
        /* Instrumentation. */
        disk_busy(&xdsc->sc_dk);
 
+       /* Instrumentation. */
+       disk_busy(&xdsc->sc_dk);
+
        /* now submit [note that xdc_submit_iorq can never fail on NORM reqs] */
 
        xdc_submit_iorq(xdcsc, rqno, XD_SUB_NORM);
index 2239799..6272098 100644 (file)
@@ -1,4 +1,4 @@
-/* $NetBSD: xdreg.h,v 1.1 1995/10/30 20:58:18 gwr Exp $ */
+/*     $NetBSD: xdreg.h,v 1.2 1996/02/22 06:55:32 thorpej Exp $        */
 
 /*
  *
index 096d01e..3550980 100644 (file)
@@ -1,4 +1,4 @@
-/* $NetBSD: xdvar.h,v 1.2 1996/01/07 22:03:18 thorpej Exp $ */
+/*     $NetBSD: xdvar.h,v 1.3 1996/02/22 06:55:33 thorpej Exp $        */
 
 /*
  *
index e66d57b..8bea7ab 100644 (file)
@@ -1,4 +1,4 @@
-/* $NetBSD: xy.c,v 1.2 1996/01/07 22:03:20 thorpej Exp $ */
+/* $NetBSD: xy.c,v 1.9 1996/03/17 02:04:10 thorpej Exp $ */
 
 /*
  *
@@ -36,7 +36,7 @@
  * x y . c   x y l o g i c s   4 5 0 / 4 5 1   s m d   d r i v e r
  *
  * author: Chuck Cranor <chuck@ccrc.wustl.edu>
- * id: $Id: xy.c,v 1.5 1996/03/04 20:35:29 chuck Exp $
+ * id: $NetBSD: xy.c,v 1.5 1996/03/04 20:35:29 chuck Exp $
  * started: 14-Sep-95
  * references: [1] Xylogics Model 753 User's Manual
  *                 part number: 166-753-001, Revision B, May 21, 1988.
@@ -188,12 +188,20 @@ int       xygetdisklabel __P((struct xy_softc *, void *));
  * cfdrivers: device driver interface to autoconfig
  */
 
-struct cfdriver xyccd = {
-       NULL, "xyc", xycmatch, xycattach, DV_DULL, sizeof(struct xyc_softc)
+struct cfattach xyc_ca = {
+       sizeof(struct xyc_softc), xycmatch, xycattach
 };
 
-struct cfdriver xycd = {
-       NULL, "xy", xymatch, xyattach, DV_DISK, sizeof(struct xy_softc)
+struct cfdriver xyc_cd = {
+       NULL, "xyc", DV_DULL
+};
+
+struct cfattach xy_ca = {
+       sizeof(struct xy_softc), xymatch, xyattach
+};
+
+struct cfdriver xy_cd = {
+       NULL, "xy", DV_DISK
 };
 
 struct xyc_attach_args {       /* this is the "aux" args to xyattach */
@@ -683,7 +691,7 @@ xyclose(dev, flag, fmt)
        int     flag, fmt;
 
 {
-       struct xy_softc *xy = xycd.cd_devs[DISKUNIT(dev)];
+       struct xy_softc *xy = xy_cd.cd_devs[DISKUNIT(dev)];
        int     part = DISKPART(dev);
 
        /* clear mask bits */
@@ -713,11 +721,11 @@ xydump(dev)
        struct xy_softc *xy;
 
        unit = DISKUNIT(dev);
-       if (unit >= xycd.cd_ndevs)
+       if (unit >= xy_cd.cd_ndevs)
                return ENXIO;
        part = DISKPART(dev);
 
-       xy = xycd.cd_devs[unit];
+       xy = xy_cd.cd_devs[unit];
 
        printf("%s%c: crash dump not supported (yet)\n", xy->sc_dev.dv_xname,
            'a' + part);
@@ -756,7 +764,7 @@ xyioctl(dev, command, addr, flag, p)
 
        unit = DISKUNIT(dev);
 
-       if (unit >= xycd.cd_ndevs || (xy = xycd.cd_devs[unit]) == NULL)
+       if (unit >= xy_cd.cd_ndevs || (xy = xy_cd.cd_devs[unit]) == NULL)
                return (ENXIO);
 
        /* switch on ioctl type */
@@ -849,7 +857,7 @@ xyopen(dev, flag, fmt)
        /* first, could it be a valid target? */
 
        unit = DISKUNIT(dev);
-       if (unit >= xycd.cd_ndevs || (xy = xycd.cd_devs[unit]) == NULL)
+       if (unit >= xy_cd.cd_ndevs || (xy = xy_cd.cd_devs[unit]) == NULL)
                return (ENXIO);
        part = DISKPART(dev);
 
@@ -927,7 +935,7 @@ xysize(dev)
 
        /* do it */
 
-       xysc = xycd.cd_devs[DISKUNIT(dev)];
+       xysc = xy_cd.cd_devs[DISKUNIT(dev)];
        part = DISKPART(dev);
        if (xysc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
                size = -1;      /* only give valid size for swap partitions */
@@ -957,7 +965,7 @@ xystrategy(bp)
 
        /* check for live device */
 
-       if (unit >= xycd.cd_ndevs || (xy = xycd.cd_devs[unit]) == 0 ||
+       if (unit >= xy_cd.cd_ndevs || (xy = xy_cd.cd_devs[unit]) == 0 ||
            bp->b_blkno < 0 ||
            (bp->b_bcount % xy->sc_dk.dk_label->d_secsize) != 0) {
                bp->b_error = EINVAL;
@@ -1126,11 +1134,11 @@ xyc_rqtopb(iorq, iopb, cmd, subfun)
                iopb->cyl = block;
        }
        iopb->scnt = iorq->sectcnt;
-       dp = dvma_kvtopa((long)iorq->dbuf, BUS_VME16);
        if (iorq->dbuf == NULL) {
                iopb->dataa = 0;
                iopb->datar = 0;
        } else {
+               dp = dvma_kvtopa((long)iorq->dbuf, BUS_VME16);
                iopb->dataa = (dp & 0xffff);
                iopb->datar = ((dp & 0xff0000) >> 16);
        }
@@ -1284,6 +1292,9 @@ xyc_startbuf(xycsc, xysc, bp)
        /* Instrumentation. */
        disk_busy(&xysc->sc_dk);
 
+       /* Instrumentation. */
+       disk_busy(&xysc->sc_dk);
+
        return (XY_ERR_AOK);
 }
 
@@ -1623,7 +1634,8 @@ xyc_reset(xycsc, quiet, blastmode, error, xysc)
                            iorq->xy->xyq.b_actf =
                                iorq->buf->b_actf;
                            disk_unbusy(&iorq->xy->sc_dk,
-                               (iorq->buf->b_bcount - iorq->buf->b_resid));
+                                               (iorq->buf->b_bcount -
+                                                iorq->buf->b_resid));
                            biodone(iorq->buf);
                            iorq->mode = XY_SUB_FREE;
                            break;
index 152b40b..e70f967 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: zs.c,v 1.31 1996/01/24 22:40:25 gwr Exp $      */
+/*     $NetBSD: zs.c,v 1.36 1996/04/04 06:26:15 cgd Exp $      */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
@@ -76,6 +76,7 @@
 #define ZSHARD_PRI     6       /* Wired on the CPU board... */
 #define ZSSOFT_PRI     3       /* Want tty pri (4) but this is OK. */
 
+#define ZS_DELAY()                     delay(2)
 
 /* The layout of this is hardware-dependent (padding, order). */
 struct zschan {
@@ -164,12 +165,16 @@ static u_char zs_init_reg[16] = {
  ****************************************************************/
 
 /* Definition of the driver for autoconfig. */
-static int     zsc_match(struct device *, void *, void *);
-static void    zsc_attach(struct device *, struct device *, void *);
+static int     zsc_match __P((struct device *, void *, void *));
+static void    zsc_attach __P((struct device *, struct device *, void *));
+static int  zsc_print __P((void *, char *name));
 
-struct cfdriver zsccd = {
-       NULL, "zsc", zsc_match, zsc_attach,
-       DV_DULL, sizeof(struct zsc_softc), NULL,
+struct cfattach zsc_ca = {
+       sizeof(struct zsc_softc), zsc_match, zsc_attach
+};
+
+struct cfdriver zsc_cd = {
+       NULL, "zsc", DV_DULL
 };
 
 static int zshard(void *);
@@ -182,49 +187,44 @@ static int zssoft(void *);
 static int
 zsc_match(parent, vcf, aux)
        struct device *parent;
-       void *vcf;
-       void *aux;
+       void *vcf, *aux;
 {
        struct cfdata *cf = vcf;
        struct confargs *ca = aux;
-       int unit, x;
-       void *zsva;
+       int pa, unit, x;
+       void *va;
 
        unit = cf->cf_unit;
        if (unit < 0 || unit >= NZS)
                return (0);
 
-       /* Make sure zs_init() found mappings. */
-       zsva = zsaddr[unit];
-       if (zsva == NULL)
+       /*
+        * OBIO match functions may be called for every possible
+        * physical address, so match only our physical address.
+        * This driver only supports its default mappings, so
+        * non-default locators must match our defaults.
+        */
+       if ((pa = cf->cf_paddr) == -1) {
+               /* Use our default PA. */
+               pa = zs_physaddr[unit];
+       } else {
+               /* Validate the given PA. */
+               if (pa != zs_physaddr[unit])
+                       return (0);
+       }
+       if (pa != ca->ca_paddr)
                return (0);
 
-       if (ca->ca_paddr == -1)
-               ca->ca_paddr = zs_physaddr[unit];
-       if (ca->ca_intpri == -1)
-               ca->ca_intpri = ZSHARD_PRI;
+       /* Make sure zs_init() found mappings. */
+       va = zsaddr[unit];
+       if (va == NULL)
+               return (0);
 
        /* This returns -1 on a fault (bus error). */
-       x = peek_byte(zsva);
+       x = peek_byte(va);
        return (x != -1);
 }
 
-static int
-zsc_print(aux, name)
-       void *aux;
-       char *name;
-{
-       struct zsc_attach_args *args = aux;
-
-       if (name != NULL)
-               printf("%s: ", name);
-
-       if (args->channel != -1)
-               printf(" channel %d", args->channel);
-
-       return UNCONF;
-}
-
 /*
  * Attach a found zs.
  *
@@ -238,17 +238,21 @@ zsc_attach(parent, self, aux)
        void *aux;
 {
        struct zsc_softc *zsc = (void *) self;
+       struct cfdata *cf = self->dv_cfdata;
        struct confargs *ca = aux;
        struct zsc_attach_args zsc_args;
        volatile struct zschan *zc;
        struct zs_chanstate *cs;
-       int zsc_unit, channel;
+       int zsc_unit, intpri, channel;
        int reset, s;
        static int didintr;
 
        zsc_unit = zsc->zsc_dev.dv_unit;
 
-       printf(" softpri %d\n", ZSSOFT_PRI);
+       if ((intpri = cf->cf_intpri) == -1)
+               intpri = ZSHARD_PRI;
+
+       printf(" level %d (softpri %d)\n", intpri, ZSSOFT_PRI);
 
        /* Use the mapping setup by the Sun PROM. */
        if (zsaddr[zsc_unit] == NULL)
@@ -283,7 +287,7 @@ zsc_attach(parent, self, aux)
                 * so just do it on the A channel.
                 */
                if (channel == 0) {
-                       ZS_WRITE(cs, 9, 0);
+                       zs_write_reg(cs, 9, 0);
                }
 
                /*
@@ -292,12 +296,12 @@ zsc_attach(parent, self, aux)
                 */
                zsc_args.channel = channel;
                zsc_args.hwflags = zs_hwflags[zsc_unit][channel];
-               if (!config_found(self, (void *) &zsc_args, zsc_print)) {
+               if (config_found(self, (void *)&zsc_args, zsc_print) == NULL) {
                        /* No sub-driver.  Just reset it. */
                        reset = (channel == 0) ?
                                ZSWR9_A_RESET : ZSWR9_B_RESET;
                        s = splzs();
-                       ZS_WRITE(cs,  9, reset);
+                       zs_write_reg(cs,  9, reset);
                        splx(s);
                }
        }
@@ -316,12 +320,28 @@ zsc_attach(parent, self, aux)
        cs = &zsc->zsc_cs[0];
        s = splzs();
        /* interrupt vector */
-       ZS_WRITE(cs, 2, zs_init_reg[2]);
+       zs_write_reg(cs, 2, zs_init_reg[2]);
        /* master interrupt control (enable) */
-       ZS_WRITE(cs, 9, zs_init_reg[9]);
+       zs_write_reg(cs, 9, zs_init_reg[9]);
        splx(s);
 }
 
+static int
+zsc_print(aux, name)
+       void *aux;
+       char *name;
+{
+       struct zsc_attach_args *args = aux;
+
+       if (name != NULL)
+               printf("%s: ", name);
+
+       if (args->channel != -1)
+               printf(" channel %d", args->channel);
+
+       return UNCONF;
+}
+
 static int
 zshard(arg)
        void *arg;
@@ -331,9 +351,9 @@ zshard(arg)
        
        /* Do ttya/ttyb first, because they go faster. */
        rval = 0;
-       unit = zsccd.cd_ndevs;
+       unit = zsc_cd.cd_ndevs;
        while (--unit >= 0) {
-               zsc = zsccd.cd_devs[unit];
+               zsc = zsc_cd.cd_devs[unit];
                if (zsc != NULL) {
                        rval |= zsc_intr_hard(zsc);
                }
@@ -375,9 +395,9 @@ zssoft(arg)
        zssoftpending = 0;
 
        /* Do ttya/ttyb first, because they go faster. */
-       unit = zsccd.cd_ndevs;
+       unit = zsc_cd.cd_ndevs;
        while (--unit >= 0) {
-               zsc = zsccd.cd_devs[unit];
+               zsc = zsc_cd.cd_devs[unit];
                if (zsc != NULL) {
                        (void) zsc_intr_soft(zsc);
                }
@@ -415,6 +435,42 @@ zs_write_reg(cs, reg, val)
        ZS_DELAY();
 }
 
+u_char zs_read_csr(cs)
+       struct zs_chanstate *cs;
+{
+       register u_char v;
+
+       v = *cs->cs_reg_csr;
+       ZS_DELAY();
+       return v;
+}
+
+u_char zs_read_data(cs)
+       struct zs_chanstate *cs;
+{
+       register u_char v;
+
+       v = *cs->cs_reg_data;
+       ZS_DELAY();
+       return v;
+}
+
+void  zs_write_csr(cs, val)
+       struct zs_chanstate *cs;
+       u_char val;
+{
+       *cs->cs_reg_csr = val;
+       ZS_DELAY();
+}
+
+void  zs_write_data(cs, val)
+       struct zs_chanstate *cs;
+       u_char val;
+{
+       *cs->cs_reg_data = val;
+       ZS_DELAY();
+}
+
 /****************************************************************
  * Console support functions (Sun3 specific!)
  ****************************************************************/
index 5793efa..3ba5769 100644 (file)
 /*
  * Hooks for kgdb when attached vi the z8530 driver
  * XXX - not tested yet...
+ *
+ * To use this, build a kernel with: option KGDB, and
+ * boot that kernel with "-d".  (The kernel will call
+ * zs_kgdb_init, kgdb_connect.)  When the console prints
+ * "kgdb waiting..." you run "gdb -k kernel" and then
+ * connect to the remote using: "target remote /dev/ttyX"
  */
 
 #include <sys/param.h>
@@ -66,6 +72,8 @@
 /* The Sun3 provides a 4.9152 MHz clock to the ZS chips. */
 #define PCLK   (9600 * 512)    /* PCLK pin input clock rate */
 
+#define ZS_DELAY()                     delay(2)
+
 extern int kgdb_dev;
 extern int kgdb_rate;
 
@@ -175,7 +183,7 @@ zs_check_kgdb(cs, dev)
         * Yes, this is the kgdb port.  Finish the autoconfig
         * message and set up the port for our exclusive use.
         */
-       printf(" (kgdb,%d)\n", kgdb_rate);
+       printf(" (kgdb)\n");
 
        cs->cs_private = NULL;
        cs->cs_ops = &zsops_kgdb;
@@ -213,16 +221,14 @@ zs_kgdb_rxint(cs)
        register u_char c, rr1;
 
        /* Read the input data ASAP. */
-       c = *(cs->cs_reg_data);
-       ZS_DELAY();
+       c = zs_read_data(cs);
 
        /* Save the status register too. */
-       rr1 = ZS_READ(cs, 1);
+       rr1 = zs_read_reg(cs, 1);
 
        if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE)) {
                /* Clear the receive error. */
-               *(cs->cs_reg_csr) = ZSWR0_RESET_ERRORS;
-               ZS_DELAY();
+               zs_write_csr(cs, ZSWR0_RESET_ERRORS);
        }
 
        if (c == FRAME_START) {
@@ -238,11 +244,10 @@ static int
 zs_kgdb_txint(cs)
        register struct zs_chanstate *cs;
 {
-       register int count, rval;
-
-       *(cs->cs_reg_csr) = ZSWR0_RESET_TXINT;
-       ZS_DELAY();
+       register int rr0;
 
+       rr0 = zs_read_csr(cs);
+       zs_write_csr(cs, ZSWR0_RESET_TXINT);
        return (0);
 }
 
@@ -252,11 +257,8 @@ zs_kgdb_stint(cs)
 {
        register int rr0;
 
-       rr0 = *(cs->cs_reg_csr);
-       ZS_DELAY();
-
-       *(cs->cs_reg_csr) = ZSWR0_RESET_STATUS;
-       ZS_DELAY();
+       rr0 = zs_read_csr(cs);
+       zs_write_csr(cs, ZSWR0_RESET_STATUS);
 
        return (0);
 }
index 60b7e47..9b90ac4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: autoconf.h,v 1.9 1995/01/11 20:38:33 gwr Exp $ */
+/*     $NetBSD: autoconf.h,v 1.10 1996/03/26 15:16:28 gwr Exp $        */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
@@ -41,8 +41,6 @@
 #define        BUS_OBIO        1       /* "obio"  */
 #define        BUS_VME16       2       /* "vmes"  */
 #define        BUS_VME32       3       /* "vmel"  */
-/* These are pseudo buses: */
-#define        BUS_OBCTL       4
 
 /*
  * This is the "args" parameter to the bus match/attach functions.
@@ -54,8 +52,13 @@ struct confargs {
        int ca_intvec;          /* interrupt vector index */
 };
 
-int always_match __P((struct device *, void *, void *));
-void bus_scan __P((struct device *, void *, int));
+/* Locator aliases */
+#define cf_paddr       cf_loc[0]
+#define cf_intpri      cf_loc[1]
+#define cf_intvec      cf_loc[2]
+
+int bus_scan __P((struct device *, void *, void *));
 int  bus_print __P((void *, char *));
 int  bus_peek __P((int, int, int));
 char * bus_mapin __P((int, int, int));
+
index a48a2a1..abe533f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: dvma.h,v 1.1 1995/09/26 04:02:08 gwr Exp $     */
+/*     $NetBSD: dvma.h,v 1.3 1996/02/20 22:06:28 gwr Exp $     */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
  * when calculating the alias address for slave access.
  */
 
-/*
- * This range could be managed as whole MMU segments.
- * The last segment is pre-allocated (see below)
- */
-#define DVMA_SEGMAP_BASE       0x0FF00000
-#define DVMA_SEGMAP_SIZE       0x000E0000
-#define DVMA_SEGMAP_END (DVMA_SEGMAP_BASE+DVMA_SEGMAP_SIZE)
-
-/*
- * This range is managed as individual pages.
- * The last page is owned by the PROM monitor.
- */
-#define DVMA_PAGEMAP_BASE      0x0FFE0000
-#define DVMA_PAGEMAP_SIZE      0x0001E000
-#define DVMA_PAGEMAP_END (DVMA_PAGEMAP_BASE+DVMA_PAGEMAP_SIZE)
-
 /*
  * To convert an address in DVMA space to a slave address,
  * just use a logical AND with one of the following masks.
- * To convert back, use logical OR with DVMA_SEGMAP_BASE.
+ * To convert back, just logical OR with the base address.
  */
 #define DVMA_OBIO_SLAVE_BASE 0x0F000000
 #define DVMA_OBIO_SLAVE_MASK 0x00FFffff        /* 16MB */
 #define DVMA_VME_SLAVE_MASK  0x000Fffff        /*  1MB */
 
 
-#if 1  /* XXX - temporary */
-/*
- * XXX - For compatibility, until DVMA is re-worked.
- * Total DVMA space covers SEGMAP + PAGEMAP
- */
-#define        DVMA_SPACE_START DVMA_SEGMAP_BASE
-#define DVMA_SPACE_END   DVMA_PAGEMAP_END
-#define DVMA_SPACE_SIZE         (DVMA_SPACE_END - DVMA_SPACE_START)
-#endif /* XXX */
-
-/*
- * XXX - These will change!  (will be like the sparc)
- */
+/* DVMA is the last 1MB, but the PROM gets the last page. */
+#define        DVMA_SPACE_START        0x0FF00000
+#define DVMA_SPACE_END         0x0FFFE000
 
+/* Allocate/free actual pages of DVMA space. */
 caddr_t dvma_malloc(size_t bytes);
 void dvma_free(caddr_t addr, size_t bytes);
 
+/* Remap/unmap kernel memory in DVMA space. */
 caddr_t dvma_mapin(char *kva, int len);
 void dvma_mapout(caddr_t dvma_addr, int len);
 
+/* Convert a kernel DVMA pointer to a slave address. */
 long dvma_kvtopa(long kva, int bus);
 
index 414726f..b348e2e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: obio.h,v 1.13 1994/12/12 18:59:42 gwr Exp $    */
+/*     $NetBSD: obio.h,v 1.14 1996/03/26 15:16:32 gwr Exp $    */
 
 /*
  * Copyright (c) 1993 Adam Glass
 #define OBIO_DES_SIZE          0x00004         
 #define OBIO_ECCREG_SIZE       0x00100                 
 
+#ifdef _KERNEL
+
 caddr_t obio_alloc __P((int, int));
 caddr_t obio_vm_alloc __P((int));
 caddr_t obio_find_mapping __P((int pa, int size));
 
+#endif /* _KERNEL */
index aaaa50c..561a62f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: param.h,v 1.30 1995/11/10 22:04:48 gwr Exp $   */
+/*     $NetBSD: param.h,v 1.34 1996/03/04 05:04:40 cgd Exp $   */
 
 /*
  * Copyright (c) 1994, 1995 Gordon W. Ross
@@ -48,7 +48,9 @@
 /*
  * Machine dependent constants for the Sun3 series.
  */
+#define        _MACHINE     sun3
 #define        MACHINE     "sun3"
+#define        _MACHINE_ARCH   m68k
 #define        MACHINE_ARCH    "m68k"
 #define MID_MACHINE MID_M68K
 
 /* XXX - Does this really belong here? -gwr */
 #include <machine/psl.h>
 
-#ifdef _KERNEL
-#ifndef LOCORE
+#if defined(_KERNEL) && !defined(_LOCORE)
+extern void _delay __P((unsigned));
+#define delay(us)      _delay((us)<<8)
 #define        DELAY(n)        delay(n)
-extern int cpuspeed;
-static inline void delay2us()
-{
-       register int n = cpuspeed;
-
-       __asm __volatile ("0: subql #4,%0; jgt 0b" : "=d" (n) : "0" (n));
-}
-#endif /* !LOCORE */
-#endif /* _KERNEL */
+#endif /* _KERNEL && !_LOCORE */
 
 #endif /* MACHINE */
index 275fdce..d4def4b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.13 1995/04/10 12:42:29 mycroft Exp $        */
+/*     $NetBSD: pmap.h,v 1.14 1996/02/28 22:50:43 gwr Exp $    */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
@@ -59,6 +59,9 @@ struct pmap   kernel_pmap_store;
 #define PMAP_DEACTIVATE(pmap, pcbp) \
        pmap_deactivate(pmap, pcbp)
 
+extern void pmap_prefer(vm_offset_t, vm_offset_t *);
+#define PMAP_PREFER(fo, ap) pmap_prefer((fo), (ap))
+
 /* XXX - Need a (silly) #define get code in kern_sysctl.c */
 extern segsz_t pmap_resident_pages(pmap_t);
 #define        pmap_resident_count(pmap)       pmap_resident_pages(pmap)
index d716133..0419d10 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: psl.h,v 1.8 1995/10/10 21:28:00 gwr Exp $      */
+/*     $NetBSD: psl.h,v 1.9 1996/02/01 22:33:10 mycroft Exp $  */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
@@ -35,7 +35,7 @@
 
 /* Could define this in the common <m68k/psl.h> instead. */
 
-#if defined(_KERNEL) && !defined(LOCORE)
+#if defined(_KERNEL) && !defined(_LOCORE)
 
 #ifndef __GNUC__
 /* No inline, use real function in locore.s */
@@ -102,5 +102,5 @@ extern __inline__ int _spl(int new)
 #define splhigh()       spl7()
 #define splsched()      spl7()
 
-#endif /* KERNEL && !LOCORE */
+#endif /* KERNEL && !_LOCORE */
 #endif /* PSL_C */
index 9eb9551..86f029e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: z8530var.h,v 1.2 1996/01/24 22:40:48 gwr Exp $ */
+/*     $NetBSD: z8530var.h,v 1.3 1996/01/30 22:35:04 gwr Exp $ */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
 #include <dev/ic/z8530sc.h>
 
 /*
- * Macros to read and write individual registers (except 0) in a channel.
- * The ZS chip requires a 1.6 uSec. recovery time between accesses, and
- * the Sun3 hardware does NOT take care of this for you.
+ * Functions to read and write individual registers in a channel.
+ * The ZS chip requires a 1.6 uSec. recovery time between accesses,
+ * and the Sun3 hardware does NOT take care of this for you.
+ * The delay is now handled inside the chip access functions.
+ * These could be inlines, but with the delay, speed is moot.
  */
-#define        ZS_READ(c, r)           zs_read_reg(c, r)
-#define        ZS_WRITE(c, r, v)       zs_write_reg(c, r, v)
-#define ZS_DELAY()                     delay2us()
 
-u_char zs_read_reg __P((struct zs_chanstate *zc, u_char reg));
-void  zs_write_reg __P((struct zs_chanstate *zc, u_char reg, u_char val));
+u_char zs_read_reg __P((struct zs_chanstate *cs, u_char reg));
+u_char zs_read_csr __P((struct zs_chanstate *cs));
+u_char zs_read_data __P((struct zs_chanstate *cs));
+
+void  zs_write_reg __P((struct zs_chanstate *cs, u_char reg, u_char val));
+void  zs_write_csr __P((struct zs_chanstate *cs, u_char val));
+void  zs_write_data __P((struct zs_chanstate *cs, u_char val));
+
 
 /*
  * How to request a "soft" interrupt.
index 800b6f9..c17569f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: SRT1.c,v 1.3 1995/09/23 03:42:35 gwr Exp $     */
+/*     $NetBSD: SRT1.c,v 1.4 1996/01/29 23:41:03 gwr Exp $     */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
 
 extern int edata[], end[];
 extern int * getvbr();
-extern volatile void abort();
+extern __dead void abort();
 extern void main();
 
-volatile void
+__dead void
 exit()
 {
        mon_exit_to_mon();
@@ -52,7 +52,7 @@ exit()
  * This is called by SRT0.S
  * to do final prep for main
  */
-void
+__dead void
 _start()
 {
        register int *p;
index a6506ee..2d967f4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: dev_disk.c,v 1.3 1995/10/17 23:07:19 gwr Exp $ */
+/*     $NetBSD: dev_disk.c,v 1.4 1996/04/10 18:31:14 gwr Exp $ */
 
 /*
  * Copyright (c) 1993 Paul Kranenburg
 #include "dvma.h"
 #include "promdev.h"
 
+#define RETRY_COUNT    5
+
+extern int debug;
+int    disk_opencount;
 struct saioreq disk_ioreq;
 
 int
@@ -61,24 +65,25 @@ disk_open(f, devname)
        int     error;
 
 #ifdef DEBUG_PROM
+       if (debug)
        printf("disk_open: %s\n", devname);
 #endif
 
+       si = &disk_ioreq;
+       if (disk_opencount == 0) {
        /*
         * Setup our part of the saioreq.
         * (determines what gets opened)
         */
-       si = &disk_ioreq;
-       bzero((caddr_t)si, sizeof(*si));
        bp = *romp->bootParam;
-
        si->si_boottab = bp->bootDevice;
        si->si_ctlr = bp->ctlrNum;
        si->si_unit = bp->unitNum;
        si->si_boff = bp->partNum;
-
        if ((error = prom_iopen(si)) != 0)
                return (error);
+       }
+       disk_opencount++;
 
        f->f_devdata = si;
        return 0;
@@ -90,9 +95,17 @@ disk_close(f)
 {
        struct saioreq *si;
 
+#ifdef DEBUG_PROM
+       if (debug)
+               printf("disk_close: ocnt=%d\n", disk_opencount);
+#endif
+
        si = f->f_devdata;
-       prom_iclose(si);
        f->f_devdata = NULL;
+       if (disk_opencount <= 0)
+               return 0;
+       if (--disk_opencount == 0)
+               prom_iclose(si);
        return 0;
 }
 
@@ -108,27 +121,37 @@ disk_strategy(devdata, flag, dblk, size, buf, rsize)
        struct saioreq *si;
        struct boottab *ops;
        char *dmabuf;
-       int     si_flag, xcnt;
+       int retry, si_flag, xcnt;
 
        si = devdata;
        ops = si->si_boottab;
 
 #ifdef DEBUG_PROM
+       if (debug > 1)
        printf("disk_strategy: size=%d dblk=%d\n", size, dblk);
 #endif
 
        dmabuf = dvma_mapin(buf, size);
+       si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE;
        
+       /*
+        * The PROM strategy will occasionally return -1 and expect
+        * us to try again.  From mouse@Collatz.McRCIM.McGill.EDU
+        */
+       retry = RETRY_COUNT;
+       do {
        si->si_bn = dblk;
        si->si_ma = dmabuf;
        si->si_cc =     size;
-
-       si_flag = (flag == F_READ) ? SAIO_F_READ : SAIO_F_WRITE;
        xcnt = (*ops->b_strategy)(si, si_flag);
+       } while ((xcnt <= 0) && (--retry > 0));
+
        dvma_mapout(dmabuf, size);
 
 #ifdef DEBUG_PROM
-       printf("disk_strategy: xcnt = %x\n", xcnt);
+       if (debug > 1)
+               printf("disk_strategy: xcnt = %x retries=%d\n",
+                  xcnt, RETRY_COUNT - retry);
 #endif
 
        if (xcnt <= 0)
index 618408f..deb039e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: dvma.c,v 1.4 1995/09/26 21:29:25 gwr Exp $     */
+/*     $NetBSD: dvma.c,v 1.6 1996/01/31 17:20:39 gwr Exp $     */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
@@ -54,6 +54,9 @@ extern void set_segmap __P((int, int));
 #define SA_MIN_VA      0x200000
 #define SA_MAX_VA      (SA_MIN_VA + DVMA_MAPLEN)
 
+/* This points to the end of the free DVMA space. */
+u_int dvma_end = DVMA_BASE + DVMA_MAPLEN;
+
 void
 dvma_init()
 {
@@ -105,20 +108,13 @@ dvma_mapout(char *addr, int len)
 char *
 dvma_alloc(int len)
 {
-       char *mem;
-
-       mem = alloc(len);
-       if (!mem)
-               return(mem);
-       return(dvma_mapin(mem, len));
+       len = sun3_round_page(len);
+       dvma_end -= len;
+       return((char*)dvma_end);
 }
 
 void
 dvma_free(char *dvma, int len)
 {
-       char *mem;
-
-       mem = dvma_mapout(dvma, len);
-       if (mem)
-               free(mem, len);
+       /* not worth the trouble */
 }
index 559a2a9..c22e9db 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec_sun.c,v 1.4 1995/09/23 03:42:40 gwr Exp $ */
+/*     $NetBSD: exec_sun.c,v 1.5 1996/01/29 23:41:06 gwr Exp $ */
 
 /*-
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -42,6 +42,7 @@
 #include "stand.h"
 
 extern int debug;
+int errno;
 
 /*ARGSUSED*/
 int
@@ -159,13 +160,8 @@ exec_sun(file, loadaddr)
        printf("=0x%x\n", cp - loadaddr);
        close(io);
 
-       if (debug) {
-               printf("Debug mode - enter c to continue...");
-               /* This will print "\nAbort at ...\n" */
-               asm("   trap #0");
-       }
-
        printf("Starting program at 0x%x\n", (int)entry);
+       asm("_exec_sun_call_entry:");
        (*entry)();
        panic("exec returned");
 
index 1636735..09bb609 100644 (file)
@@ -2,7 +2,7 @@
 #include "iodesc.h"
 
 struct netif {
-       void *devdata;
+       void *nif_devdata;
 };
 
 ssize_t                netif_get __P((struct iodesc *, void *, size_t, time_t));
index df921f9..f1d7753 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: netif_sun.c,v 1.3 1995/10/13 21:45:18 gwr Exp $        */
+/*     $NetBSD: netif_sun.c,v 1.4 1996/01/29 23:41:07 gwr Exp $        */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
 #include "dvma.h"
 #include "promdev.h"
 
-static struct netif netif_prom;
-static void sun3_getether __P((u_char *));
+#define        PKT_BUF_SIZE 2048
 
-#ifdef NETIF_DEBUG
-int netif_debug;
-#endif
+int debug;
+int errno;
+
+static void sun3_getether __P((u_char *));
 
-struct saioreq net_ioreq;
 struct iodesc sockets[SOPEN_MAX];
 
-struct iodesc *
-socktodesc(sock)
-       int sock;
+static struct netif prom_nif;
+static struct devdata {
+       struct saioreq dd_si;
+       int rbuf_len;
+       char *rbuf;
+       int tbuf_len;
+       char *tbuf;
+       u_short dd_opens;
+       char dd_myea[6];
+} prom_dd;
+
+static struct idprom sun3_idprom;
+
+
+void
+sun3_getether(ea)
+       u_char *ea;
 {
-       if (sock != 0) {
-               return(NULL);
+       u_char *src, *dst;
+       int len, x;
+
+       if (sun3_idprom.idp_format == 0) {
+               dst = (char*)&sun3_idprom;
+               src = (char*)IDPROM_BASE;
+               len = IDPROM_SIZE;
+               do {
+                       x = get_control_byte(src++);
+                       *dst++ = x;
+               } while (--len > 0);
        }
-       return (sockets);
+       MACPY(sun3_idprom.idp_etheraddr, ea);
 }
 
-int
-netif_open(machdep_hint)
-       void *machdep_hint;
+
+/*
+ * Open the PROM device.
+ * Return netif ptr on success.
+ */
+struct devdata *
+netif_init(aux)
+       void *aux;
 {
-       struct bootparam *bp;
+       struct devdata *dd = &prom_dd;
        struct saioreq *si;
-       struct iodesc *io;
+       struct bootparam *bp;
        int error;
 
-       /* find a free socket */
-       io = sockets;
-       if (io->io_netif) {
-#ifdef DEBUG
-               printf("netif_open: device busy\n");
-#endif
-               return (-1);
-       }
-       bzero(io, sizeof(*io));
-
        /*
         * Setup our part of the saioreq.
         * (determines what gets opened)
         */
-       si = &net_ioreq;
+       si = &dd->dd_si;
        bzero((caddr_t)si, sizeof(*si));
        bp = *romp->bootParam;
-
        si->si_boottab = bp->bootDevice;
        si->si_ctlr = bp->ctlrNum;
        si->si_unit = bp->unitNum;
        si->si_boff = bp->partNum;
 
+#ifdef NETIF_DEBUG
+       if (debug)
+               printf("netif_init: calling prom_iopen\n");
+#endif
+
        /*
         * Note: Sun PROMs will do RARP on open, but does not tell
         * you the IP address it gets, so it is just noise to us...
         */
        if ((error = prom_iopen(si)) != 0) {
-#ifdef DEBUG
-               printf("netif_open: prom_iopen, error=%d\n", error);
-#endif
-               return (-1);
+               printf("netif_init: prom_iopen, error=%d\n", error);
+               return (NULL);
        }
+
        if (si->si_sif == NULL) {
-#ifdef DEBUG
-               printf("netif_open: not a network device\n");
-#endif
+               printf("netif_init: not a network device\n");
                prom_iclose(si);
-               return (-1);
+               return (NULL);
        }
 
-       netif_prom.devdata = si;
-       io->io_netif = &netif_prom;
+#ifdef NETIF_DEBUG
+       if (debug)
+               printf("netif_init: allocating buffers\n");
+#endif
+
+       /* Allocate the transmit/receive buffers. */
+       if (dd->rbuf == NULL) {
+               dd->rbuf_len = PKT_BUF_SIZE;
+               dd->rbuf = dvma_alloc(dd->rbuf_len);
+       }
+       if (dd->tbuf == NULL) {
+               dd->tbuf_len = PKT_BUF_SIZE;
+               dd->tbuf = dvma_alloc(dd->tbuf_len);
+       }
+       if ((dd->rbuf == NULL) ||
+           (dd->tbuf == NULL))
+               panic("netif_init: malloc failed\n");
 
-       /* Put our ethernet address in io->myea */
-       sun3_getether(io->myea);
+#ifdef NETIF_DEBUG
+       if (debug)
+               printf("netif_init: rbuf=0x%x, tbuf=0x%x\n",
+                          dd->rbuf, dd->tbuf);
+#endif
 
+       /* Record our ethernet address. */
+       sun3_getether(dd->dd_myea);
+       dd->dd_opens = 0;
+
+       return(dd);
+}
+
+void
+netif_fini(dd)
+       struct devdata *dd;
+{
+       struct saioreq *si;
+
+       si = &dd->dd_si;
+
+#ifdef NETIF_DEBUG
+       if (debug)
+               printf("netif_fini: calling prom_iclose\n");
+#endif
+
+       prom_iclose(si);
+       /* Dellocate the transmit/receive buffers. */
+       if (dd->rbuf) {
+               dvma_free(dd->rbuf, dd->rbuf_len);
+               dd->rbuf = NULL;
+       }
+       if (dd->tbuf) {
+               dvma_free(dd->tbuf, dd->tbuf_len);
+               dd->tbuf = NULL;
+       }
+}
+
+int
+netif_attach(nif, s, aux)
+       struct netif *nif;
+       struct iodesc *s;
+       void *aux;
+{
+       struct devdata *dd;
+
+       dd = nif->nif_devdata;
+       if (dd == NULL) {
+               dd = netif_init(aux);
+               if (dd == NULL)
+                       return (ENXIO);
+               nif->nif_devdata = dd;
+       }
+       dd->dd_opens++;
+       MACPY(dd->dd_myea, s->myea);
+       s->io_netif = nif;
        return(0);
 }
 
+void
+netif_detach(nif)
+       struct netif *nif;
+{
+       struct devdata *dd;
+
+       dd = nif->nif_devdata;
+       if (dd == NULL)
+               return;
+       dd->dd_opens--;
+       if (dd->dd_opens > 0)
+               return;
+       netif_fini(dd);
+       nif->nif_devdata = NULL;
+}
+
+int
+netif_open(aux)
+       void *aux;
+{
+       struct netif *nif;
+       struct iodesc *s;
+       int fd, error;
+
+       /* find a free socket */
+       for (fd = 0, s = sockets; fd < SOPEN_MAX; fd++, s++)
+               if (s->io_netif == NULL)
+                       goto found;
+       errno = EMFILE;
+       return (-1);
+
+found:
+       bzero(s, sizeof(*s));
+       nif = &prom_nif;
+       error = netif_attach(nif, s);
+       if (error != 0) {
+               errno = error;
+               return (-1);
+       }
+       return (fd);
+}
+
 int
 netif_close(fd)
        int fd;
 {
-       struct saioreq *si;
-       struct iodesc *io;
-       struct netif *ni;
+       struct iodesc *s;
+       struct netif *nif;
 
-       if (fd != 0) {
+       if (fd < 0 || fd >= SOPEN_MAX) {
                errno = EBADF;
                return(-1);
        }
+       s = &sockets[fd];
+       nif = s->io_netif;
+       /* Already closed? */
+       if (nif == NULL)
+               return(0);
+       netif_detach(nif);
+       s->io_netif = NULL;
+       return(0);
+}
 
-       io = sockets;
-       ni = io->io_netif;
-       if (ni != NULL) {
-               si = ni->devdata;
-               prom_iclose(si);
-               ni->devdata = NULL;
-               io->io_netif = NULL;
+
+struct iodesc *
+socktodesc(fd)
+       int fd;
+{
+       if (fd < 0 || fd >= SOPEN_MAX) {
+               errno = EBADF;
+               return (NULL);
        }
-       return(0);
+       return (&sockets[fd]);
 }
 
+
 /*
  * Send a packet.  The ether header is already there.
  * Return the length sent (or -1 on error).
@@ -173,13 +311,15 @@ netif_put(desc, pkt, len)
        void *pkt;
        size_t len;
 {
+       struct netif *nif;
+       struct devdata *dd;
        struct saioreq *si;
        struct saif *sif;
        char *dmabuf;
-       int rv, sendlen;
+       int rv, slen;
 
 #ifdef NETIF_DEBUG
-       if (netif_debug) {
+       if (debug > 1) {
                struct ether_header *eh;
 
                printf("netif_put: desc=0x%x pkt=0x%x len=%d\n",
@@ -191,33 +331,44 @@ netif_put(desc, pkt, len)
        }
 #endif
 
-       si = desc->io_netif->devdata;
+       nif = desc->io_netif;
+       dd = nif->nif_devdata;
+       si = &dd->dd_si;
        sif = si->si_sif;
-       sendlen = len;
-       if (sendlen < 60) {
-               sendlen = 60;
-#ifdef NETIF_DEBUG
-               printf("netif_put: length padded to %d\n", sendlen);
-#endif
-       }
+       slen = len;
 
 #ifdef PARANOID
        if (sif == NULL)
                panic("netif_put: no saif ptr\n");
 #endif
 
-       dmabuf = dvma_mapin(pkt, sendlen);
-       rv = sif->sif_xmit(si->si_devdata, dmabuf, sendlen);
-       dvma_mapout(dmabuf, sendlen);
+       /*
+        * Copy into our transmit buffer because the PROM
+        * network driver might continue using the packet
+        * after the sif_xmit call returns.  We never send
+        * very much data anyway, so the copy is fine.
+        */
+       if (slen > dd->tbuf_len)
+               panic("netif_put: slen=%d\n", slen);
+       bcopy(pkt, dd->tbuf, slen);
+
+       if (slen < 60) {
+               slen = 60;
+       }
+
+       rv = (*sif->sif_xmit)(si->si_devdata, dd->tbuf, slen);
 
 #ifdef NETIF_DEBUG
-       if (netif_debug)
+       if (debug > 1)
                printf("netif_put: xmit returned %d\n", rv);
 #endif
-       if (rv == 0) rv = len;
-       else rv = -1;
+       /*
+        * Just ignore the return value.  If the PROM transmit
+        * function fails, it will make some noise, such as:
+        *      le: No Carrier
+        */
 
-       return rv;
+       return len;
 }
 
 /*
@@ -229,46 +380,65 @@ netif_get(desc, pkt, maxlen, timo)
        struct iodesc *desc;
        void *pkt;
        size_t maxlen;
-       time_t timo;
+       time_t timo;    /* seconds */
 {
+       struct netif *nif;
+       struct devdata *dd;
        struct saioreq *si;
        struct saif *sif;
-       char *dmabuf;
        int tick0, tmo_ticks;
-       int len;
+       int rlen = 0;
 
 #ifdef NETIF_DEBUG
-       if (netif_debug)
+       if (debug > 1)
                printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
                           pkt, maxlen, timo);
 #endif
 
-       si = desc->io_netif->devdata;
+       nif = desc->io_netif;
+       dd = nif->nif_devdata;
+       si = &dd->dd_si;
        sif = si->si_sif;
 
-#ifdef PARANOID
-       if (sif == NULL)
-               panic("netif_get: no saif ptr\n");
-#endif
-
        tmo_ticks = timo * hz;
+
+       /* Have to receive into our own buffer and copy. */
+       do {
        tick0 = getticks();
+               do {
+                       rlen = (*sif->sif_poll)(si->si_devdata, dd->rbuf);
+                       if (rlen != 0)
+                               goto break2;
+               } while (getticks() == tick0);
+       } while (--tmo_ticks > 0);
 
-       dmabuf = dvma_mapin(pkt, maxlen);
-       do  len = sif->sif_poll(si->si_devdata, dmabuf);
-       while ((len == 0) && ((getticks() - tick0) < tmo_ticks));
-       dvma_mapout(dmabuf, maxlen);
+       /* No packet arrived.  Better reset the interface. */
+       printf("netif_get: timeout; resetting\n");
+       (*sif->sif_reset)(si->si_devdata, si);
+
+break2:
 
 #ifdef NETIF_DEBUG
-       if (netif_debug)
-               printf("netif_get: received len=%d\n", len);
+       if (debug > 1)
+               printf("netif_get: received rlen=%d\n", rlen);
 #endif
 
-       if (len < 12)
+       /* Need at least a valid Ethernet header. */
+       if (rlen < 12)
                return -1;
 
+       /* If we went beyond our buffer, were dead! */
+       if (rlen > dd->rbuf_len)
+               panic("netif_get: rlen=%d\n", rlen);
+
+       /* The caller's buffer may be smaller... */
+       if (rlen > maxlen)
+               rlen = maxlen;
+
+       bcopy(dd->rbuf, pkt, rlen);
+
 #ifdef NETIF_DEBUG
-       if (netif_debug) {
+       if (debug > 1) {
                struct ether_header *eh = pkt;
 
                printf("dst: %s ", ether_sprintf(eh->ether_dhost));
@@ -277,27 +447,5 @@ netif_get(desc, pkt, maxlen, timo)
        }
 #endif
 
-       return len;
+       return rlen;
 }
-
-static struct idprom sun3_idprom;
-
-static void
-sun3_getether(ea)
-       u_char *ea;
-{
-       u_char *src, *dst;
-       int len, x;
-
-       if (sun3_idprom.idp_format == 0) {
-               dst = (char*)&sun3_idprom;
-               src = (char*)IDPROM_BASE;
-               len = IDPROM_SIZE;
-               do {
-                       x = get_control_byte(src++);
-                       *dst++ = x;
-               } while (--len > 0);
-       }
-       MACPY(sun3_idprom.idp_etheraddr, ea);
-}
-
index 6705fea..97fddd3 100644 (file)
@@ -2,15 +2,15 @@
 #include <stdarg.h>
 #include "stand.h"
 
-extern volatile void abort();
+extern __dead void abort();
 
-volatile void
+__dead void
 panic(const char *fmt, ...)
 {
     va_list ap;
 
     va_start(ap, fmt);
-    printf(fmt, ap);
+       vprintf(fmt, ap);
     printf("\n");
     va_end(ap);
        abort();
index d360652..1a1cad0 100644 (file)
@@ -10,7 +10,7 @@
 char prom_bootdev[32];
 char *prom_bootfile;
 int prom_boothow;
-int debug;
+int debug = 0;
 
 /*
  * Get useful info from the PROM bootparams struct, i.e.:
@@ -59,13 +59,15 @@ prom_get_boot_info()
                                break;
                        case 'd':
                                prom_boothow |= RB_KDB;
-                               debug = 1;
+                               debug++;
                                break;
                        }
                }
        }
-#ifdef DEBUG
-       printf("promboot: device=\"%s\" file=\"%s\" how=0x%x\n",
-                  prom_bootdev, prom_bootfile, prom_boothow);
-#endif
+
+       if (debug) {
+               printf("Debug level %d - enter c to continue...", debug);
+               /* This will print "\nAbort at ...\n" */
+               asm("   trap #0");
+       }
 }
index 3f0e2b4..130e4d8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: promdev.c,v 1.6 1995/10/13 21:45:21 gwr Exp $ */
+/*     $NetBSD: promdev.c,v 1.7 1996/01/29 23:41:10 gwr Exp $ */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
@@ -40,6 +40,7 @@
 #include "dvma.h"
 
 extern void set_pte __P((int, int));
+extern int debug;
 
 static int promdev_inuse;
 
@@ -69,15 +70,17 @@ prom_iopen(si)
        dip = ops->b_devinfo;
 
 #ifdef DEBUG_PROM
-       printf("Boot device type: %s\n", ops->b_desc);
-       printf("d_devbytes=%d\n", dip->d_devbytes);
-       printf("d_dmabytes=%d\n", dip->d_dmabytes);
-       printf("d_localbytes=%d\n", dip->d_localbytes);
-       printf("d_stdcount=%d\n", dip->d_stdcount);
-       printf("d_stdaddrs[%d]=%x\n", si->si_ctlr,
+       if (debug) {
+               printf("Boot device type: %s\n", ops->b_desc);
+               printf("d_devbytes=%d\n", dip->d_devbytes);
+               printf("d_dmabytes=%d\n", dip->d_dmabytes);
+               printf("d_localbytes=%d\n", dip->d_localbytes);
+               printf("d_stdcount=%d\n", dip->d_stdcount);
+               printf("d_stdaddrs[%d]=%x\n", si->si_ctlr,
                      dip->d_stdaddrs[si->si_ctlr]);
-       printf("d_devtype=%d\n", dip->d_devtype);
-       printf("d_maxiobytes=%d\n", dip->d_maxiobytes);
+               printf("d_devtype=%d\n", dip->d_devtype);
+               printf("d_maxiobytes=%d\n", dip->d_maxiobytes);
+       }
 #endif
 
        if (si->si_ctlr > dip->d_stdcount) {
@@ -91,14 +94,21 @@ prom_iopen(si)
                si->si_devaddr = prom_mapin(dip->d_stdaddrs[si->si_ctlr],
                        dip->d_devbytes, dip->d_devtype);
 #ifdef DEBUG_PROM
-               printf("prom_iopen: devaddr=0x%x pte=0x%x\n",
+               if (debug)
+                       printf("prom_iopen: devaddr=0x%x pte=0x%x\n",
                           si->si_devaddr, get_pte(si->si_devaddr));
 #endif
        }
 
        if (dip->d_dmabytes) {
-               si->si_dmaaddr = dvma_alloc(dip->d_dmabytes);
+               int addr, size;
+               /* try page-aligned address... */
+               size = dip->d_dmabytes + NBPG;
+               addr = (int) dvma_alloc(size);
+               addr = sun3_round_page(addr);
+               si->si_dmaaddr = (char*) addr;
 #ifdef DEBUG_PROM
+               if (debug)
                printf("prom_iopen: dmaaddr=0x%x\n", si->si_dmaaddr);
 #endif
        }
@@ -106,7 +116,8 @@ prom_iopen(si)
        if (dip->d_localbytes) {
                si->si_devdata = alloc(dip->d_localbytes);
 #ifdef DEBUG_PROM
-               printf("prom_iopen: devdata=0x%x\n", si->si_devdata);
+               if (debug)
+                       printf("prom_iopen: devdata=0x%x\n", si->si_devdata);
 #endif
        }
 
@@ -118,7 +129,8 @@ prom_iopen(si)
                return (ENXIO);
        }
 #ifdef DEBUG_PROM
-       printf("prom_iopen: succeeded, error=%d\n", error);
+       if (debug)
+               printf("prom_iopen: prom open returned %d\n", error);
 #endif
 
        promdev_inuse++;
@@ -138,13 +150,12 @@ prom_iclose(si)
        ops = si->si_boottab;
        dip = ops->b_devinfo;
 
+#ifdef DEBUG_PROM
+       if (debug)
+               printf("prom_iclose: calling prom close...\n");
+#endif
        (*ops->b_close)(si);
 
-       if (si->si_dmaaddr) {
-               dvma_free(si->si_dmaaddr, dip->d_dmabytes);
-               si->si_dmaaddr = NULL;
-       }
-
        promdev_inuse = 0;
 }
 
index 9f455eb..6b51da9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: conf.c,v 1.2 1995/09/23 03:42:50 gwr Exp $     */
+/*     $NetBSD: conf.c,v 1.3 1996/01/29 23:54:14 gwr Exp $     */
 
 #include <sys/types.h>
 #include <netinet/in.h>
@@ -17,7 +17,3 @@ struct devsw devsw[] = {
 };
 int    ndevs = 1;
 
-/* XXX */
-int netif_debug;
-int debug;
-int errno;
index 48a9064..069b58a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: dev_net.c,v 1.3 1995/09/23 03:42:51 gwr Exp $  */
+/*     $NetBSD: dev_net.c,v 1.4 1996/01/29 23:54:15 gwr Exp $  */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
@@ -48,6 +48,7 @@
  * for use by the NFS open code (NFS/lookup).
  */
 
+#include <stdarg.h>
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <net/if.h>
@@ -59,7 +60,9 @@
 #include "net.h"
 #include "netif.h"
 #include "bootparam.h"
+#include "dev_net.h"
 
+extern int debug;
 extern int nfs_root_node[];    /* XXX - get from nfs_mount() */
 
 /*
@@ -86,28 +89,63 @@ char domainname[FNAME_SIZE];
  * Local things...
  */
 static int netdev_sock = -1;
-static int open_count;
+static int netdev_opens;
 
 /*
  * Called by devopen after it sets f->f_dev to our devsw entry.
  * This opens the low-level device and sets f->f_devdata.
+ * This is declared with variable arguments...
  */
 int
-net_open(f, devname)
-       struct open_file *f;
-       char *devname;          /* Device part of file name (or NULL). */
+net_open(struct open_file *f, ...)
 {
+       va_list ap;
+       char *devname;          /* Device part of file name (or NULL). */
        int error = 0;
 
+       va_start(ap, f);
+       devname = va_arg(ap, char*);
+       va_end(ap);
+
+#ifdef NETIF_DEBUG
+       if (debug)
+               printf("net_open: %s\n", devname);
+#endif
+
        /* On first open, do netif open, mount, etc. */
-       if (open_count == 0) {
+       if (netdev_opens == 0) {
                /* Find network interface. */
-               if ((netdev_sock = netif_open(devname)) < 0)
-                       return (error=ENXIO);
-               if ((error = net_mountroot(f, devname)) != 0)
+               if (netdev_sock < 0) {
+                       netdev_sock = netif_open(devname);
+                       if (netdev_sock < 0) {
+                               printf("net_open: netif_open() failed\n");
+                               return (ENXIO);
+                       }
+                       if (debug)
+                               printf("net_open: netif_open() succeeded\n");
+               }
+               if (rootip.s_addr == 0) {
+                       /* Get root IP address, and path, etc. */
+                       error = net_getparams(netdev_sock);
+                       if (error) {
+                               /* getparams makes its own noise */
+                               goto fail;
+                       }
+                       /* Get the NFS file handle (mountd). */
+                       error = nfs_mount(netdev_sock, rootip, rootpath);
+                       if (error) {
+                               printf("net_open: NFS mount error=%d\n", error);
+                               rootip.s_addr = 0;
+                       fail:
+                               netif_close(netdev_sock);
+                               netdev_sock = -1;
                        return (error);
        }
-       open_count++;
+                       if (debug)
+                               printf("net_open: NFS mount succeeded\n");
+               }
+       }
+       netdev_opens++;
        f->f_devdata = nfs_root_node;
        return (error);
 }
@@ -116,11 +154,29 @@ int
 net_close(f)
        struct open_file *f;
 {
+
+#ifdef NETIF_DEBUG
+       if (debug)
+               printf("net_close: opens=%d\n", netdev_opens);
+#endif
+
        /* On last close, do netif close, etc. */
-       if (open_count > 0)
-               if (--open_count == 0)
-                       netif_close(netdev_sock);
        f->f_devdata = NULL;
+       /* Extra close call? */
+       if (netdev_opens <= 0)
+               return (0);
+       netdev_opens--;
+       /* Not last close? */
+       if (netdev_opens > 0)
+               return(0);
+       rootip.s_addr = 0;
+       if (netdev_sock >= 0) {
+               if (debug)
+                       printf("net_close: calling netif_close()\n");
+               netif_close(netdev_sock);
+               netdev_sock = -1;
+       }
+       return (0);
 }
 
 int
@@ -136,16 +192,9 @@ net_strategy()
 }
 
 int
-net_mountroot(f, devname)
-       struct open_file *f;
-       char *devname;          /* Device part of file name (or NULL). */
+net_getparams(sock)
+       int sock;
 {
-       int error;
-
-#ifdef DEBUG
-       printf("net_mountroot: %s\n", devname);
-#endif
-
        /*
         * Get info for NFS boot: our IP address, our hostname,
         * server IP address, and our root path on the server.
@@ -155,23 +204,31 @@ net_mountroot(f, devname)
 
 #ifdef SUN_BOOTPARAMS
        /* Get our IP address.  (rarp.c) */
-       if (rarp_getipaddress(netdev_sock))
+       if (rarp_getipaddress(sock)) {
+               printf("net_open: RARP failed\n");
                return (EIO);
+       }
 #else  /* BOOTPARAMS */
        /*
         * Get boot info using BOOTP. (RFC951, RFC1048)
         * This also gets the server IP address, gateway,
         * root path, etc.
         */
-       bootp(netdev_sock);     /* XXX - Error return? */
+       bootp(sock);
+       if (myip.s_addr == 0) {
+               printf("net_open: BOOTP failed\n");
+               return (EIO);
+       }
 #endif /* BOOTPARAMS */
 
        printf("boot: client addr: %s\n", inet_ntoa(myip));
 
 #ifdef SUN_BOOTPARAMS
        /* Get our hostname, server IP address, gateway. */
-       if (bp_whoami(netdev_sock))
+       if (bp_whoami(sock)) {
+               printf("net_open: bootparam/whoami RPC failed\n");
                return (EIO);
+       }
 #endif /* BOOTPARAMS */
 
        printf("boot: client name: %s\n", hostname);
@@ -182,15 +239,14 @@ net_mountroot(f, devname)
 
 #ifdef SUN_BOOTPARAMS
        /* Get the root pathname. */
-       if (bp_getfile(netdev_sock, "root", &rootip, rootpath))
+       if (bp_getfile(sock, "root", &rootip, rootpath)) {
+               printf("net_open: bootparam/getfile RPC failed\n");
                return (EIO);
+       }
 #endif /* BOOTPARAMS */
 
        printf("boot: server addr: %s\n", inet_ntoa(rootip));
        printf("boot: server path: %s\n", rootpath);
 
-       /* Get the NFS file handle (mount). */
-       error = nfs_mount(netdev_sock, rootip, rootpath);
-
-       return (error);
+       return (0);
 }
index c8f33eb..aa92d77 100644 (file)
@@ -1,7 +1,7 @@
-/*     $NetBSD: version.c,v 1.2 1995/10/13 21:33:09 gwr Exp $ */
+/*     $NetBSD: version.c,v 1.5 1996/03/17 02:04:20 thorpej Exp $ */
 
 /*
  *     NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.
  */
 
-char *version = "$Revision: 1.2 $";
+char *version = "$Revision: 1.3 $";
index 37e2abc..8f44b32 100644 (file)
@@ -7,4 +7,4 @@
  *     device access stays strictly on block boundaries.
  */
 
-char *version = "$Revision: 1.2 $";
+char *version = "$Revision: 1.3 $";
index c8da822..ce19dab 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: autoconf.c,v 1.27 1995/09/26 04:02:14 gwr Exp $        */
+/*     $NetBSD: autoconf.c,v 1.33 1996/04/07 05:45:08 gwr Exp $        */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
 
 extern int soft1intr();
 
-void mainbusattach __P((struct device *, struct device *, void *));
 void swapgeneric();
 void swapconf(), dumpconf();
 
 int cold;
 
-struct mainbus_softc {
-       struct device mainbus_dev;
-};
-       
-struct cfdriver mainbuscd = 
-{ NULL, "mainbus", always_match, mainbusattach, DV_DULL,
-       sizeof(struct mainbus_softc), 0};
-
-void mainbusattach(parent, self, args)
-       struct device *parent;
-       struct device *self;
-       void *args;
-{
-       struct cfdata *new_match;
-       
-       printf("\n");
-       while (1) {
-               new_match = config_search(NULL, self, NULL);
-               if (!new_match) break;
-               config_attach(self, new_match, NULL, NULL);
-       }
-}
-
 void configure()
 {
-       int root_found;
-
-       /* Install non-device interrupt handlers. */
-       isr_config();
+       struct device *mainbus;
 
        /* General device autoconfiguration. */
-       root_found = config_rootfound("mainbus", NULL);
-       if (!root_found)
+       mainbus = config_rootfound("mainbus", NULL);
+       if (mainbus == NULL)
                panic("configure: mainbus not found");
 
-#ifdef GENERIC
        /* Choose root and swap devices. */
        swapgeneric();
-#endif
        swapconf();
        dumpconf();
        cold = 0;
@@ -137,25 +108,30 @@ swapconf()
        }
 }
 
-int always_match(parent, cf, args)
-       struct device *parent;
-       void *cf;
-       void *args;
-{
-       return 1;
-}
-
 /*
  * Generic "bus" support functions.
+ *
+ * bus_scan:
+ * This function is passed to config_search() by the attach function
+ * for each of the "bus" drivers (obctl, obio, obmem, vmes, vmel).
+ * The purpose of this function is to copy the "locators" into our
+ * confargs structure, so child drivers may use the confargs both
+ * as match parameters and as temporary storage for the defaulted
+ * locator values determined in the child_match and preserved for
+ * the child_attach function.  If the bus attach functions just
+ * used config_found, then we would not have an opportunity to
+ * setup the confargs for each child match and attach call.
+ *
+ * bus_print:
+ * Just prints out the final (non-default) locators.
  */
-void bus_scan(parent, child, bustype)
+int bus_scan(parent, child, aux)
        struct device *parent;
-       void *child;
-       int bustype;
+       void *child, *aux;
 {
        struct cfdata *cf = child;
-       struct confargs ca;
-       cfmatch_t match;
+       struct confargs *ca = aux;
+       cfmatch_t mf;
 
 #ifdef DIAGNOSTIC
        if (parent->dv_cfdata->cf_driver->cd_indirect)
@@ -164,22 +140,33 @@ void bus_scan(parent, child, bustype)
                panic("bus_scan: FSTATE_STAR");
 #endif
 
-       ca.ca_bustype = bustype;
-       ca.ca_paddr  = cf->cf_loc[0];
-       ca.ca_intpri = cf->cf_loc[1];
+       /* ca->ca_bustype set by parent */
+       ca->ca_paddr  = cf->cf_loc[0];
+       ca->ca_intpri = cf->cf_loc[1];
+       ca->ca_intvec = -1;
 
-       if ((bustype == BUS_VME16) || (bustype == BUS_VME32)) {
-               ca.ca_intvec = cf->cf_loc[2];
-       } else {
-               ca.ca_intvec = -1;
+       if ((ca->ca_bustype == BUS_VME16) ||
+               (ca->ca_bustype == BUS_VME32))
+       {
+               ca->ca_intvec = cf->cf_loc[2];
        }
 
-       match = cf->cf_driver->cd_match;
-       if ((*match)(parent, cf, &ca) > 0) {
-               config_attach(parent, cf, &ca, bus_print);
+       /*
+        * Note that this allows the match function to save
+        * defaulted locators in the confargs that will be
+        * preserved for the related attach call.
+        */
+       mf = cf->cf_attach->ca_match;
+       if ((*mf)(parent, cf, ca) > 0) {
+               config_attach(parent, cf, ca, bus_print);
        }
+       return (0);
 }
 
+/*
+ * Print out the confargs.  The parent name is non-NULL
+ * when there was no match found by config_found().
+ */
 int
 bus_print(args, name)
        void *args;
@@ -187,14 +174,17 @@ bus_print(args, name)
 {
        struct confargs *ca = args;
 
+       if (name)
+               printf("%s:", name);
+
        if (ca->ca_paddr != -1)
                printf(" addr 0x%x", ca->ca_paddr);
        if (ca->ca_intpri != -1)
                printf(" level %d", ca->ca_intpri);
        if (ca->ca_intvec != -1)
                printf(" vector 0x%x", ca->ca_intvec);
-       /* XXXX print flags? */
-       return(QUIET);
+
+       return(UNCONF);
 }
 
 extern vm_offset_t tmp_vpages[];
@@ -269,7 +259,7 @@ bus_mapin(bustype, paddr, sz)
        int bustype, paddr, sz;
 {
        int off, pa, pgs, pmt;
-       vm_offset_t va;
+       vm_offset_t va, retval;
 
        if (bustype & ~3)
                return (NULL);
@@ -286,9 +276,19 @@ bus_mapin(bustype, paddr, sz)
        va = kmem_alloc_wait(kernel_map, sz);
        if (va == 0)
                panic("bus_mapin");
+       retval = va + off;
 
        /* Map it to the specified bus. */
+#if 0  /* XXX */
+       /* This has a problem with wrap-around... */
        pmap_map((int)va, pa | pmt, pa + sz, VM_PROT_ALL);
+#else
+       do {
+               pmap_enter(pmap_kernel(), va, pa | pmt, VM_PROT_ALL, FALSE);
+               va += NBPG;
+               pa += NBPG;
+       } while ((sz -= NBPG) > 0);
+#endif
 
-       return ((char*)(va + off));
+       return ((char*)retval);
 }      
index fdb6dc8..eb53ac6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: clock.c,v 1.26 1995/08/21 21:37:36 gwr Exp $   */
+/*     $NetBSD: clock.c,v 1.28 1996/03/26 15:16:42 gwr Exp $   */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
@@ -65,6 +65,8 @@
 #include "intersil7170.h"
 #include "interreg.h"
 
+#define        CLOCK_PRI       5
+
 extern volatile u_char *interrupt_reg;
 volatile char *clock_va;
 
@@ -76,40 +78,63 @@ volatile char *clock_va;
 
 #define intersil_clear() (void)intersil_clock->clk_intr_reg
 
-int clockmatch __P((struct device *, void *vcf, void *args));
-void clockattach __P((struct device *, struct device *, void *));
+static int  clock_match __P((struct device *, void *vcf, void *args));
+static void clock_attach __P((struct device *, struct device *, void *));
+
+struct cfattach clock_ca = {
+       sizeof(struct device), clock_match, clock_attach
+};
 
-struct cfdriver clockcd = {
-       NULL, "clock", clockmatch, clockattach,
-       DV_DULL, sizeof(struct device), 0 };
+struct cfdriver clock_cd = {
+       NULL, "clock", DV_DULL
+};
 
-int clockmatch(parent, vcf, args)
+static int
+clock_match(parent, vcf, args)
     struct device *parent;
     void *vcf, *args;
 {
     struct cfdata *cf = vcf;
        struct confargs *ca = args;
+       int pa;
 
        /* This driver only supports one unit. */
        if (cf->cf_unit != 0)
                return (0);
-       if (ca->ca_paddr == -1)
-               ca->ca_paddr = OBIO_CLOCK;
-       if (ca->ca_intpri == -1)
-               ca->ca_intpri = 5;
+
+       if ((pa = cf->cf_paddr) == -1) {
+               /* Use our default PA. */
+               pa = OBIO_CLOCK;
+       } else {
+               /* Validate the given PA. */
+               if (pa != OBIO_CLOCK)
+                       panic("clock: wrong address");
+       }
+       if (pa != ca->ca_paddr)
+               return (0);
+
        return (1);
 }
 
-void clockattach(parent, self, args)
+static void
+clock_attach(parent, self, args)
        struct device *parent;
        struct device *self;
        void *args;
 {
+       struct cfdata *cf = self->dv_cfdata;
        struct confargs *ca = args;
+       int pri;
+
+       if ((pri = cf->cf_intpri) == -1) {
+               pri = CLOCK_PRI;
+       } else {
+               if (pri != CLOCK_PRI)
+                       panic("clock: level != %d", CLOCK_PRI);
+       }
+
+       printf(" level %d\n", pri);
 
-       printf("\n");
-       if (ca->ca_intpri != 5)
-               panic("clock: level != 5");
        /*
         * Can not hook up the ISR until cpu_initclock()
         * because hardclock is not ready until then.
index 63be5b4..f7e6e08 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: conf.c,v 1.46 1996/01/24 22:40:58 gwr Exp $    */
+/*     $NetBSD: conf.c,v 1.48 1996/03/14 21:35:47 christos Exp $       */
 
 /*-
  * Copyright (c) 1994 Adam Glass, Gordon W. Ross
@@ -125,7 +125,7 @@ cdev_decl(ctty);
 #define        mmwrite mmrw
 cdev_decl(mm);
 
-#include "zs.h"
+#define NZS 2 /* XXX: temporary hack */
 cdev_decl(zs);
 cdev_decl(kd);
 cdev_decl(ms);
@@ -164,6 +164,8 @@ cdev_decl(bpf);
 #include "tun.h"
 cdev_decl(tun);
 
+dev_decl(filedesc,open);
+
 
 struct cdevsw  cdevsw[] =
 {
@@ -190,7 +192,7 @@ struct cdevsw       cdevsw[] =
        cdev_tty_init(NPTY,pts),        /* 20: pseudo-tty slave */
        cdev_ptc_init(NPTY,ptc),        /* 21: pseudo-tty master */
        cdev_fb_init(1,fb),             /* 22: /dev/fb indirect driver */
-       cdev_fd_init(1,fd),             /* 23: file descriptor pseudo-device */
+       cdev_fd_init(1,filedesc),       /* 23: file descriptor pseudo-device */
        cdev_bpftun_init(NTUN,tun),     /* 24: network tunnel */
        cdev_notdef(),                  /* 25: sun pi? */
        cdev_notdef(),                  /* 26: bwone */
index b8fc346..bcccb93 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_machdep.c,v 1.6 1995/10/23 18:40:35 gwr Exp $       */
+/*     $NetBSD: db_machdep.c,v 1.7 1996/02/16 20:08:44 gwr Exp $       */
 
 /*
  * Copyright (c) 1994, 1995 Gordon W. Ross
 
 #include <machine/pte.h>
 
-#undef DEBUG
-
-#ifdef DEBUG
-int db_machdep_debug;
-#endif
-
-/*
- * Interface to the debugger for virtual memory read/write.
- *
- * To write in the text segment, we have to first make
- * the page writable, do the write, then restore the PTE.
- * For writes outside the text segment, and all reads,
- * just do the access -- if it causes a fault, the debugger
- * will recover with a longjmp to an appropriate place.
- *
- * ALERT!  If you want to access device registers with a
- * specific size, then the read/write functions have to
- * make sure to do the correct sized pointer access.
- */
-
-/*
- * Read bytes from kernel address space for debugger.
- * This used to check for valid PTEs, but now that
- * traps in DDB work correctly, "Just Do It!"
- */
-void
-db_read_bytes(addr, size, data)
-       vm_offset_t     addr;
-       register int    size;
-       register char   *data;
-{
-       register char   *src;
-       register char   incr;
-
-#ifdef DEBUG
-       if (db_machdep_debug)
-               printf("db_read_bytes: addr=0x%x, size=%d\n", addr, size);
-#endif
-
-       if (size == 4) {
-               *((int*)data) = *((int*)addr);
-               return;
-       }
-
-       if (size == 2) {
-               *((short*)data) = *((short*)addr);
-               return;
-       }
-
-       src = (char *)addr;
-       while (size > 0) {
-               --size;
-               *data++ = *src++;
-       }
-}
-
-/*
- * Write one byte somewhere in kernel text.
- * It does not matter if this is slow.
- */
-static void
-db_write_text(dst, ch)
-       char *dst;
-       int ch;
-{
-       int             oldpte, tmppte;
-       vm_offset_t pgva = sun3_trunc_page((long)dst);
-       extern int cache_size;
-
-       /* Flush read-only VAC entry so we'll see the new one. */
-#ifdef HAVECACHE
-       if (cache_size)
-               cache_flush_page(pgva);
-#endif
-       oldpte = get_pte(pgva);
-       if ((oldpte & PG_VALID) == 0) {
-               db_printf(" address 0x%x not a valid page\n", dst);
-               return;
-       }
-       tmppte = oldpte | PG_WRITE | PG_NC;
-
-       set_pte(pgva, tmppte);
-
-       /* Now we can write in this page of kernel text... */
-       *dst = (char) ch;
-
-       /* Temporary PTE was non-cacheable; no flush needed. */
-       set_pte(pgva, oldpte);
-       ICIA();
-}
-
-/*
- * Write bytes to kernel address space for debugger.
- */
-void
-db_write_bytes(addr, size, data)
-       vm_offset_t     addr;
-       int     size;
-       char    *data;
-{
-       extern char     kernel_text[], etext[] ;
-       register char   *dst = (char *)addr;
-
-#ifdef DEBUG
-       if (db_machdep_debug)
-               printf("db_write_bytes: addr=0x%x, size=%d ", addr, size);
-#endif
-
-       /* If any part is in kernel text, use db_write_text() */
-       if ((dst < etext) && ((dst + size) > kernel_text)) {
-               /* This is slow, but is only used for breakpoints. */
-#ifdef DEBUG
-               if (db_machdep_debug)
-                       printf("(in text)\n");
-#endif
-               while (size > 0) {
-                       --size;
-                       db_write_text(dst, *data);
-                       dst++; data++;
-               }
-               return;
-       }
-
-#ifdef DEBUG
-               if (db_machdep_debug)
-                       printf("(in data)\n");
-#endif
-
-       if (size == 4) {
-               *((int*)addr) = *((int*)data);
-               return;
-       }
-
-       if (size == 2) {
-               *((short*)addr) = *((short*)data);
-               return;
-       }
-
-       while (size > 0) {
-               --size;
-               *dst++ = *data++;
-       }
-}
 
 static char *pgt_names[] = {
        "MEM", "OBIO", "VMES", "VMEL" };
diff --git a/sys/arch/sun3/sun3/db_memrw.c b/sys/arch/sun3/sun3/db_memrw.c
new file mode 100644 (file)
index 0000000..59db0e0
--- /dev/null
@@ -0,0 +1,187 @@
+/*     $NetBSD: db_memrw.c,v 1.11 1996/02/20 02:42:55 gwr Exp $        */
+
+/*
+ * Copyright (c) 1996 Gordon W. Ross
+ * 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. 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.
+ */
+
+/*
+ * Interface to the debugger for virtual memory read/write.
+ *
+ * To write in the text segment, we have to first make
+ * the page writable, do the write, then restore the PTE.
+ * For writes outside the text segment, and all reads,
+ * just do the access -- if it causes a fault, the debugger
+ * will recover with a longjmp to an appropriate place.
+ *
+ * ALERT!  If you want to access device registers with a
+ * specific size, then the read/write functions have to
+ * make sure to do the correct sized pointer access.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+
+#include <vm/vm.h>
+
+#include <machine/pte.h>
+#include <machine/db_machdep.h>
+
+#include <ddb/db_access.h>
+
+#include "cache.h"
+
+/*
+ * Read bytes from kernel address space for debugger.
+ * This used to check for valid PTEs, but now that
+ * traps in DDB work correctly, "Just Do It!"
+ */
+void
+db_read_bytes(addr, size, data)
+       vm_offset_t     addr;
+       register size_t size;
+       register char   *data;
+{
+       register char   *src = (char*)addr;
+
+       if (size == 4) {
+               *((int*)data) = *((int*)src);
+               return;
+       }
+
+       if (size == 2) {
+               *((short*)data) = *((short*)src);
+               return;
+       }
+
+       while (size > 0) {
+               --size;
+               *data++ = *src++;
+       }
+}
+
+/*
+ * Write bytes somewhere in kernel text.
+ * Makes text page writable temporarily.
+ */
+static void
+db_write_text(addr, size, data)
+       vm_offset_t     addr;
+       register size_t size;
+       register char   *data;
+{
+       register char *dst;
+       int             ch, oldpte, tmppte;
+       vm_offset_t pgva, prevpg;
+
+       /* Prevent restoring a garbage PTE. */
+       if (size <= 0)
+               return;
+
+       dst = (char*)addr;
+       pgva = sun3_trunc_page((long)dst);
+
+       goto firstpage;
+       do {
+
+               /*
+                * If we are on a new page, restore the PTE
+                * for the previous page, and make the new
+                * page writable.
+                */
+               pgva = sun3_trunc_page((long)dst);
+               if (pgva != prevpg) {
+                       /*
+                        * Restore old PTE.  No cache flush,
+                        * because the tmp PTE has no-cache.
+                        */
+                       set_pte(prevpg, oldpte);
+
+               firstpage:
+                       /*
+                        * Flush the VAC to prevent a cache hit
+                        * on the old, read-only PTE.
+                        */
+#ifdef HAVECACHE
+                       if (cache_size)
+                               cache_flush_page(pgva);
+#endif
+                       oldpte = get_pte(pgva);
+                       if ((oldpte & PG_VALID) == 0) {
+                               db_printf(" address 0x%x not a valid page\n", dst);
+                               return;
+                       }
+                       tmppte = oldpte | PG_WRITE | PG_NC;
+                       set_pte(pgva, tmppte);
+
+                       prevpg = pgva;
+               }
+
+               /* Now we can write in this page of kernel text... */
+               *dst++ = *data++;
+
+       } while (--size > 0);
+
+       /* Restore old PTE for the last page touched. */
+       set_pte(prevpg, oldpte);
+
+       /* Finally, clear the instruction cache. */
+       ICIA();
+}
+
+/*
+ * Write bytes to kernel address space for debugger.
+ */
+extern char    kernel_text[], etext[];
+void
+db_write_bytes(addr, size, data)
+       vm_offset_t     addr;
+       register size_t size;
+       register char   *data;
+{
+       register char   *dst = (char *)addr;
+
+       /* If any part is in kernel text, use db_write_text() */
+       if ((dst < etext) && ((dst + size) > kernel_text)) {
+               db_write_text(dst, size, data);
+               return;
+       }
+
+       if (size == 4) {
+               *((int*)dst) = *((int*)data);
+               return;
+       }
+
+       if (size == 2) {
+               *((short*)dst) = *((short*)data);
+               return;
+       }
+
+       while (size > 0) {
+               --size;
+               *dst++ = *data++;
+       }
+}
+
index baa89a8..fb78c20 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: disksubr.c,v 1.11 1995/11/17 23:30:19 gwr Exp $        */
+/*     $NetBSD: disksubr.c,v 1.12 1996/04/26 18:37:58 gwr Exp $        */
 
 /*
  * Copyright (c) 1994, 1995 Gordon W. Ross
@@ -273,12 +273,21 @@ bad:
        return(-1);
 }
 
-/* XXX - What is this for?  Where does it belong? -gwr */
+/*
+ * This function appears to be called by each disk driver.
+ * Aparently this is to give this MD code a chance to do
+ * additional "device registration" types of work. (?)
+ * For example, the sparc port uses this to record the
+ * device node for the PROM-specified boot device.
+ *
+ * XXX: return value not documented (ignored everywhere)
+ */
 void
 dk_establish(dk, dev)
-       struct dkdevice *dk;
+       struct disk *dk;
        struct device *dev;
 {
+       return;
 }
 
 /************************************************************************
index 0cf422e..a2e510d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: dvma.c,v 1.3 1995/10/10 21:37:29 gwr Exp $     */
+/*     $NetBSD: dvma.c,v 1.4 1996/02/20 22:05:32 gwr Exp $     */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
 #include "cache.h"
 
 /* Resource map used by dvma_mapin/dvma_mapout */
-#define        NUM_DVMA_SEGS ((DVMA_SEGMAP_SIZE / NBSG) + 1)
+#define        NUM_DVMA_SEGS 10
 struct map dvma_segmap[NUM_DVMA_SEGS];
 
-/* DVMA page map managed with help from the VM system. */
-vm_map_t dvma_pgmap;
+/* XXX: Might need to tune this... */
+vm_size_t dvma_segmap_size = 6 * NBSG;
+
+/* Using phys_map to manage DVMA scratch-memory pages. */
 /* Note: Could use separate pagemap for obio if needed. */
 
 void dvma_init()
 {
-       int size;
+       vm_offset_t segmap_addr;
 
        /*
-        * Create the map used for small, permanent DVMA page
-        * allocations, such as may be needed by drivers for
-        * control structures shared with the device.
+        * Create phys_map covering the entire DVMA space,
+        * then allocate the segment pool from that.  The
+        * remainder will be used as the DVMA page pool.
         */
-       dvma_pgmap = vm_map_create(pmap_kernel(),
-           DVMA_PAGEMAP_BASE, DVMA_PAGEMAP_END, TRUE);
-       if (dvma_pgmap == NULL)
-               panic("dvma_init: unable to create DVMA page map.");
+       phys_map = vm_map_create(pmap_kernel(),
+               DVMA_SPACE_START, DVMA_SPACE_END, 1);
+       if (phys_map == NULL)
+               panic("unable to create DVMA map");
+
+       /*
+        * Reserve the DVMA space used for segment remapping.
+        * The remainder of phys_map is used for DVMA scratch
+        * memory pages (i.e. driver control blocks, etc.)
+        */
+       segmap_addr = kmem_alloc_wait(phys_map, dvma_segmap_size);
+       if (segmap_addr != DVMA_SPACE_START)
+               panic("dvma_init: unable to allocate DVMA segments");
 
        /*
         * Create the VM pool used for mapping whole segments
         * into DVMA space for the purpose of data transfer.
         */
-       rminit(dvma_segmap,
-                  DVMA_SEGMAP_SIZE,
-                  DVMA_SEGMAP_BASE,
-                  "dvma_segmap",
-                  NUM_DVMA_SEGS);
+       rminit(dvma_segmap, dvma_segmap_size, segmap_addr,
+                  "dvma_segmap", NUM_DVMA_SEGS);
 }
 
 /*
@@ -101,9 +109,9 @@ caddr_t dvma_malloc(bytes)
     if (!bytes)
                return NULL;
     new_size = sun3_round_page(bytes);
-    new_mem = (caddr_t) kmem_alloc(dvma_pgmap, new_size);
+    new_mem = (caddr_t) kmem_alloc(phys_map, new_size);
     if (!new_mem)
-               panic("dvma_malloc: no space in dvma_pgmap");
+               panic("dvma_malloc: no space in phys_map");
     /* The pmap code always makes DVMA pages non-cached. */
     return new_mem;
 }
@@ -115,7 +123,9 @@ void dvma_free(addr, size)
        caddr_t addr;
        size_t  size;
 {
-       kmem_free(dvma_pgmap, (vm_offset_t)addr, (vm_size_t)size);
+       vm_size_t sz = sun3_round_page(size);
+
+       kmem_free(phys_map, (vm_offset_t)addr, sz);
 }
 
 /*
index f19a1de..c6023af 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu.c,v 1.2 1995/06/27 14:40:14 gwr Exp $      */
+/*     $NetBSD: fpu.c,v 1.6 1996/03/26 15:16:45 gwr Exp $      */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
 #include <sys/kernel.h>
 #include <sys/device.h>
 
-#include <machine/autoconf.h>
 #include <machine/psl.h>
 #include <machine/cpu.h>
 #include <machine/frame.h>
 #include <machine/mon.h>
 #include <machine/control.h>
 
-#include <setjmp.h>
-
 #include "interreg.h"
 
 extern int fpu_type;
 extern long *nofault;
 
-int fpu_match __P((struct device *, void *vcf, void *args));
-void fpu_attach __P((struct device *, struct device *, void *));
 int fpu_probe();
 
-struct cfdriver fpucd = {
-       NULL, "fpu", fpu_match, fpu_attach,
-       DV_DULL, sizeof(struct device), 0 };
-
-int fpu_match(parent, vcf, args)
-    struct device *parent;
-    void *vcf, *args;
-{
-    struct cfdata *cf = vcf;
-       struct confargs *ca = args;
-
-       /* This driver only supports one unit. */
-       if (cf->cf_unit != 0)
-               return (0);
-
-       return (1);
-}
-
 static char *fpu_descr[] = {
 #ifdef FPU_EMULATE
        "emulator",             /* 0 */
@@ -87,12 +64,8 @@ static char *fpu_descr[] = {
        "mc68882",                      /* 2 */
        "?" };
 
-void fpu_attach(parent, self, args)
-       struct device *parent;
-       struct device *self;
-       void *args;
+void initfpu()
 {
-       struct confargs *ca = args;
        char *descr;
        int enab_reg;
 
@@ -107,7 +80,7 @@ void fpu_attach(parent, self, args)
        else
                descr = "unknown type";
 
-       printf(" (%s)\n", descr);
+       printf("fpu: %s\n", descr);
 
        if (fpu_type == 0) {
                /* Might as well turn the enable bit back off. */
@@ -119,11 +92,11 @@ void fpu_attach(parent, self, args)
 
 int fpu_probe()
 {
-       jmp_buf faultbuf;
+       label_t faultbuf;
        int null_fpframe[2];
 
        nofault = (long *) &faultbuf;
-       if (setjmp(nofault)) {
+       if (setjmp(&faultbuf)) {
                nofault = NULL;
                return(0);
        }
index eb69087..a8f40b8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: genassym.c,v 1.29 1995/09/26 04:02:19 gwr Exp $        */
+/*     $NetBSD: genassym.c,v 1.31 1996/02/16 23:36:52 gwr Exp $        */
 
 /*
  * Copyright (c) 1994, 1995 Gordon W. Ross
@@ -38,8 +38,6 @@
  *     from: genassym.c,v 1.9 1994/05/23 06:14:19 mycroft
  */
 
-#define _KERNEL
-
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/cdefs.h>
@@ -171,6 +169,7 @@ main()
        def("FR_SP", &fp->f_regs[15]);
        def("FR_HW", &fp->f_sr);
        def("FR_ADJ", &fp->f_stackadj);
+       def("FR_SIZE", sizeof(struct trapframe));
 
        /* FP frame offsets */
        def("FPF_REGS", &fpf->fpf_regs[0]);
diff --git a/sys/arch/sun3/sun3/intreg.c b/sys/arch/sun3/sun3/intreg.c
new file mode 100644 (file)
index 0000000..63e4eb1
--- /dev/null
@@ -0,0 +1,217 @@
+/*     $NetBSD: intreg.c,v 1.1 1996/03/26 15:03:11 gwr Exp $   */
+
+/*
+ * Copyright (c) 1994 Gordon W. Ross
+ * Copyright (c) 1993 Adam Glass
+ * 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 Adam Glass.
+ * 4. The name of the authors may not 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 handles multiple attach of autovectored interrupts,
+ * and the handy software interrupt request register.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/vmmeter.h>
+
+#include <machine/autoconf.h>
+#include <machine/cpu.h>
+#include <machine/mon.h>
+#include <machine/obio.h>
+#include <machine/isr.h>
+
+#include "interreg.h"
+
+struct intreg_softc {
+       struct device sc_dev;
+       volatile u_char *sc_reg;
+};
+
+static int  intreg_match __P((struct device *, void *vcf, void *args));
+static void intreg_attach __P((struct device *, struct device *, void *));
+static int soft1intr();
+
+struct cfattach intreg_ca = {
+       sizeof(struct intreg_softc), intreg_match, intreg_attach
+};
+
+struct cfdriver intreg_cd = {
+       NULL, "intreg", DV_DULL
+};
+
+volatile u_char *interrupt_reg;
+
+
+/* called early (by internal_configure) */
+void intreg_init()
+{
+       interrupt_reg = obio_find_mapping(OBIO_INTERREG, 1);
+       if (!interrupt_reg)
+               mon_panic("interrupt reg VA not found\n");
+       /* Turn off all interrupts until clock_attach */
+       *interrupt_reg = 0;
+}
+
+
+static int
+intreg_match(parent, vcf, args)
+    struct device *parent;
+    void *vcf, *args;
+{
+    struct cfdata *cf = vcf;
+       struct confargs *ca = args;
+       int pa;
+
+       /* This driver only supports one unit. */
+       if (cf->cf_unit != 0)
+               return (0);
+
+       if ((pa = cf->cf_paddr) == -1) {
+               /* Use our default PA. */
+               pa = OBIO_INTERREG;
+       } else {
+               /* Validate the given PA. */
+               if (pa != OBIO_INTERREG)
+                       panic("clock: wrong address");
+       }
+       if (pa != ca->ca_paddr)
+               return (0);
+
+       return (1);
+}
+
+
+static void
+intreg_attach(parent, self, args)
+       struct device *parent;
+       struct device *self;
+       void *args;
+{
+       struct intreg_softc *sc = (void *)self;
+       struct cfdata *cf = self->dv_cfdata;
+
+       printf("\n");
+
+       sc->sc_reg = interrupt_reg;
+
+       /* Install handler for our "soft" interrupt. */
+       isr_add_autovect(soft1intr, (void *)sc, 1);
+}
+
+
+/*
+ * Level 1 software interrupt.
+ * Possible reasons:
+ *     Network software interrupt
+ *     Soft clock interrupt
+ */
+int soft1intr(arg)
+       void *arg;
+{
+       union sun3sir sir;
+       int n, s;
+
+       s = splhigh();
+       sir.sir_any = sun3sir.sir_any;
+       sun3sir.sir_any = 0;
+       isr_soft_clear(1);
+       splx(s);
+
+       if (sir.sir_any) {
+               cnt.v_soft++;
+               if (sir.sir_which[SIR_NET]) {
+                       sir.sir_which[SIR_NET] = 0;
+                       netintr();
+               }
+               if (sir.sir_which[SIR_CLOCK]) {
+                       sir.sir_which[SIR_CLOCK] = 0;
+                       softclock();
+               }
+               if (sir.sir_which[SIR_SPARE2]) {
+                       sir.sir_which[SIR_SPARE2] = 0;
+                       /* spare2intr(); */
+               }
+               if (sir.sir_which[SIR_SPARE3]) {
+                       sir.sir_which[SIR_SPARE3] = 0;
+                       /* spare3intr(); */
+               }
+               return (1);
+       }
+       return(0);
+}
+
+
+static int isr_soft_pending;
+void isr_soft_request(level)
+       int level;
+{
+       u_char bit, reg_val;
+       int s;
+
+       if ((level < 1) || (level > 3))
+               panic("isr_soft_request");
+
+       bit = 1 << level;
+
+       /* XXX - Should do this in the callers... */
+       if (isr_soft_pending & bit)
+               return;
+
+       s = splhigh();
+       isr_soft_pending |= bit;
+       reg_val = *interrupt_reg;
+       *interrupt_reg &= ~IREG_ALL_ENAB;
+
+       *interrupt_reg |= bit;
+       *interrupt_reg |= IREG_ALL_ENAB;
+       splx(s);
+}
+
+void isr_soft_clear(level)
+       int level;
+{
+       u_char bit, reg_val;
+       int s;
+
+       if ((level < 1) || (level > 3))
+               panic("isr_soft_clear");
+
+       bit = 1 << level;
+
+       s = splhigh();
+       isr_soft_pending &= ~bit;
+       reg_val = *interrupt_reg;
+       *interrupt_reg &= ~IREG_ALL_ENAB;
+
+       *interrupt_reg &= ~bit;
+       *interrupt_reg |= IREG_ALL_ENAB;
+       splx(s);
+}
+
index de638e7..6a7312d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: isr.c,v 1.21 1995/10/08 23:47:34 gwr Exp $     */
+/*     $NetBSD: isr.c,v 1.22 1996/03/26 15:16:47 gwr Exp $     */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
@@ -49,7 +49,6 @@
 #include <machine/isr.h>
 
 #include "vector.h"
-#include "interreg.h"
 
 #include "ether.h"     /* for NETHER */
 
@@ -64,30 +63,8 @@ struct isr {
        int     isr_ipl;
 };
 
-
 void set_vector_entry __P((int, void (*handler)()));
 unsigned int get_vector_entry __P((int));
-static int nmi_intr();
-static int soft1intr();
-
-volatile u_char *interrupt_reg;
-
-/* called early (by internal_configure) */
-void isr_init()
-{
-       interrupt_reg = obio_find_mapping(OBIO_INTERREG, 1);
-       if (!interrupt_reg)
-               mon_panic("interrupt reg VA not found\n");
-       /* Turn off all interrupts until clock_attach */
-       *interrupt_reg = 0;
-}
-
-/* called later, by configure */
-void isr_config()
-{
-       isr_add_autovect(nmi_intr, 0, 7);
-       isr_add_autovect(soft1intr, 0, 1);
-}
 
 void isr_add_custom(level, handler)
        int level;
@@ -96,53 +73,6 @@ void isr_add_custom(level, handler)
        set_vector_entry(AUTOVEC_BASE + level, handler);
 }
 
-static int isr_soft_pending;
-void isr_soft_request(level)
-       int level;
-{
-       u_char bit, reg_val;
-       int s;
-
-       if ((level < 1) || (level > 3))
-               panic("isr_soft_request");
-
-       bit = 1 << level;
-
-       /* XXX - Should do this in the callers... */
-       if (isr_soft_pending & bit)
-               return;
-
-       s = splhigh();
-       isr_soft_pending |= bit;
-       reg_val = *interrupt_reg;
-       *interrupt_reg &= ~IREG_ALL_ENAB;
-
-       *interrupt_reg |= bit;
-       *interrupt_reg |= IREG_ALL_ENAB;
-       splx(s);
-}
-
-void isr_soft_clear(level)
-       int level;
-{
-       u_char bit, reg_val;
-       int s;
-
-       if ((level < 1) || (level > 3))
-               panic("isr_soft_clear");
-
-       bit = 1 << level;
-
-       s = splhigh();
-       isr_soft_pending &= ~bit;
-       reg_val = *interrupt_reg;
-       *interrupt_reg &= ~IREG_ALL_ENAB;
-
-       *interrupt_reg &= ~bit;
-       *interrupt_reg |= IREG_ALL_ENAB;
-       splx(s);
-}
-
 /*
  * XXX - This really belongs in some common file,
  *     i.e.  src/sys/net/netisr.c
@@ -188,63 +118,6 @@ void netintr()
 }
 
 
-/*
- * Level 1 software interrupt.
- * Possible reasons:
- *     Network software interrupt
- *     Soft clock interrupt
- */
-int soft1intr(arg)
-       void *arg;
-{
-       union sun3sir sir;
-       int n, s;
-
-       s = splhigh();
-       sir.sir_any = sun3sir.sir_any;
-       sun3sir.sir_any = 0;
-       isr_soft_clear(1);
-       splx(s);
-
-       if (sir.sir_any) {
-               cnt.v_soft++;
-               if (sir.sir_which[SIR_NET]) {
-                       sir.sir_which[SIR_NET] = 0;
-                       netintr();
-               }
-               if (sir.sir_which[SIR_CLOCK]) {
-                       sir.sir_which[SIR_CLOCK] = 0;
-                       softclock();
-               }
-               if (sir.sir_which[SIR_SPARE2]) {
-                       sir.sir_which[SIR_SPARE2] = 0;
-                       /* spare2intr(); */
-               }
-               if (sir.sir_which[SIR_SPARE3]) {
-                       sir.sir_which[SIR_SPARE3] = 0;
-                       /* spare3intr(); */
-               }
-               return (1);
-       }
-       return(0);
-}
-
-/*
- * Generic handler for the non-maskable interrupt.
- * XXX: Should check memory error register here!
- */
-int nmi_intr(arg)
-       void *arg;
-{
-       static int nmi_cnt;
-       if (!nmi_cnt++) {
-               printf("nmi interrupt received\n");
-               Debugger();
-       }
-       return 1;
-}
-
-
 static struct isr *isr_autovec_list[NUM_LEVELS];
 
 /*
index f4a66ac..b7f384f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.s,v 1.34 1995/12/11 02:38:13 thorpej Exp $      */
+/*     $NetBSD: locore.s,v 1.38 1996/04/07 05:42:17 gwr Exp $  */
 
 /*
  * Copyright (c) 1994, 1995 Gordon W. Ross
@@ -43,7 +43,7 @@
  *     @(#)locore.s    8.6 (Berkeley) 5/27/94
  */
 
-#include "assym.s"
+#include "assym.h"
 #include <machine/trap.h>
 
 | Remember this is a fun project.  (Thanks, Adam.  I try! 8^)
@@ -421,6 +421,9 @@ _badtrap:
        addql   #4, sp                  | stack adjust count
        jra     rei                     | all done
 
+/*
+ * Trap 0 is for system calls
+ */
        .globl  _syscall
 _trap0:
        clrl    sp@-                    | stack adjust count
@@ -437,69 +440,16 @@ _trap0:
        jra     rei                     | all done
 
 /*
- * Our native 4.3 implementation uses trap 1 as sigreturn() and trap 2
- * as a breakpoint trap.
+ * Trap 1 is either:
+ * sigreturn (native NetBSD executable)
+ * breakpoint (HPUX executable)
  */
 _trap1:
-       jra     sigreturn
-
-_trap2:
-       jra     _trace
-
-/*
- * Trap 12 is the entry point for the cachectl "syscall"
- *     cachectl(command, addr, length)
- * command in d0, addr in a1, length in d1
- */
-       .globl  _cachectl
-_trap12:
-       movl    d1,sp@-                 | push length
-       movl    a1,sp@-                 | push addr
-       movl    d0,sp@-                 | push command
-       jbsr    _cachectl               | do it
-       lea     sp@(12),sp              | pop args
-       jra     rei                     | all done
-
-/*
- * Trap 15 is used for:
- *     - KGDB traps
- *     - trace traps for SUN binaries (not fully supported yet)
- * We just pass it on and let trap() sort it all out
- */
-_trap15:
-       clrl    sp@-
-       moveml  #0xFFFF,sp@-
-#ifdef KGDB
-       moveq   #T_TRAP15,d0
-       movw    sp@(FR_HW),d1           | get PSW
-       andw    #PSL_S,d1               | from user mode?
-       jeq     fault                   | yes, just a regular fault
-       movl    d0,sp@-
-       .globl  _kgdb_trap_glue
-       jbsr    _kgdb_trap_glue         | returns if no debugger
-       addl    #4,sp
+#if 0 /* COMPAT_HPUX */
+       /* If process is HPUX, this is a user breakpoint. */
+       jne     trap15                  | breakpoint
 #endif
-       moveq   #T_TRAP15,d0
-       jra     fault
-
-/*
- * Hit a breakpoint (trap 1 or 2) instruction.
- * Push the code and treat as a normal fault.
- */
-_trace:
-       clrl    sp@-
-       moveml  #0xFFFF,sp@-
-#ifdef KGDB
-       moveq   #T_TRACE,d0
-       movw    sp@(FR_HW),d1           | get SSW
-       andw    #PSL_S,d1               | from user mode?
-       jeq     fault                   | no, regular fault
-       movl    d0,sp@-
-       jbsr    _kgdb_trap_glue         | returns if no debugger
-       addl    #4,sp
-#endif
-       moveq   #T_TRACE,d0
-       jra     fault
+       /* fall into sigreturn */
 
 /*
  * The sigreturn() syscall comes here.  It requires special handling
@@ -538,6 +488,104 @@ Lsigr1:
        movl    sp@,sp                  | and our SP
        jra     rei                     | all done
 
+/*
+ * Trap 2 is one of:
+ * NetBSD: not used (ignore)
+ * SunOS:  Some obscure FPU operation
+ * HPUX:   sigreturn
+ */
+_trap2:
+#if 0 /* COMPAT_HPUX */
+       /* XXX: If HPUX, this is a user breakpoint. */
+       jne     sigreturn
+#endif
+       /* fall into trace (NetBSD or SunOS) */
+
+/*
+ * Trace (single-step) trap.  Kernel-mode is special.
+ * User mode traps are simply passed on to trap().
+ */
+_trace:
+       clrl    sp@-                    | stack adjust count
+       moveml  #0xFFFF,sp@-
+       moveq   #T_TRACE,d0
+       movw    sp@(FR_HW),d1           | get PSW
+       andw    #PSL_S,d1               | from system mode?
+       jne     kbrkpt                  | yes, kernel breakpoint
+       jra     fault                   | no, user-mode fault
+
+/*
+ * Trap 15 is used for:
+ *     - GDB breakpoints (in user programs)
+ *     - KGDB breakpoints (in the kernel)
+ *     - trace traps for SUN binaries (not fully supported yet)
+ * User mode traps are passed simply passed to trap()
+ */
+_trap15:
+       clrl    sp@-                    | stack adjust count
+       moveml  #0xFFFF,sp@-
+       moveq   #T_TRAP15,d0
+       movw    sp@(FR_HW),d1           | get PSW
+       andw    #PSL_S,d1               | from system mode?
+       jne     kbrkpt                  | yes, kernel breakpoint
+       jra     fault                   | no, user-mode fault
+
+kbrkpt:        | Kernel-mode breakpoint or trace trap.
+       | Save system sp rather than user sp.
+       lea     sp@(FR_SIZE),a6         | Save stack pointer
+       movl    a6,sp@(FR_SP)           |  from before trap
+
+       | If we are not on tmpstk switch to it.
+       | (allows debugger to frob the stack)
+       movl    a6,d1
+       cmpl    #tmpstk,d1
+       jls     Lbrkpt2                 | already on tmpstk
+       | Copy frame to the temporary stack
+       movl    sp,a0                   | a0=src
+       lea     tmpstk-96,a1            | a1=dst
+       movl    a1,sp                   | sp=new frame
+       moveq   #FR_SIZE,d1
+Lbrkpt1:
+       movl    a0@+,a1@+
+       subql   #4,d1
+       bgt     Lbrkpt1
+
+Lbrkpt2:
+       | Now call the trap handler as usual.
+       clrl    sp@-                    | no VA arg
+       clrl    sp@-                    | or code arg
+       movl    d0,sp@-                 | push trap type
+       jbsr    _trap                   | handle trap
+       lea     sp@(12),sp              | pop value args
+
+       | The stack pointer may have been modified, or
+       | data below it modified (by kgdb push call),
+       | so push the hardware frame at the current sp
+       | before restoring registers and returning.
+
+       movl    sp@(FR_SP),a0           | modified sp
+       lea     sp@(FR_SIZE),a1         | end of our frame
+       movl    a1@-,a0@-               | copy 2 longs with
+       movl    a1@-,a0@-               | ... predecrement
+       movl    a0,sp@(FR_SP)           | sp = h/w frame
+       moveml  sp@+,#0x7FFF            | restore all but sp
+       movl    sp@,sp                  | ... and sp
+       rte                             | all done
+
+/*
+ * Trap 12 is the entry point for the cachectl "syscall"
+ *     cachectl(command, addr, length)
+ * command in d0, addr in a1, length in d1
+ */
+       .globl  _cachectl
+_trap12:
+       movl    d1,sp@-                 | push length
+       movl    a1,sp@-                 | push addr
+       movl    d0,sp@-                 | push command
+       jbsr    _cachectl               | do it
+       lea     sp@(12),sp              | pop args
+       jra     rei                     | all done
+
 /*
  * Interrupt handlers.  Most are auto-vectored,
  * and hard-wired the same way on all sun3 models.
@@ -1182,26 +1230,23 @@ Lm68881rdone:
        frestore a0@                    | restore state
        rts
 
-| delay(int usecs)
-| Delay for "usec" microseconds.  Minimum delay is about 5 uS.
-|
-| This routine depends on the variable "cpuspeed"
-| which should be set based on the CPU clock rate.
-| XXX - Currently this is set in sun3_startup.c based on the
-| CPU model but this should be determined at run time...
-|
-       .globl  _delay
-_delay:
-       | d0 = (cpuspeed * usecs)
-       movel   _cpuspeed,d0
-       mulsl   sp@(4),d0
-       | subtract some overhead
-       moveq   #80,d1
+/*
+ * _delay(unsigned N)
+ * Delay for at least (N/256) microseconds.
+ * This routine depends on the variable:  delay_divisor
+ * which should be set based on the CPU clock rate.
+ * XXX: Currently this is set in sun3_startup.c based on the
+ * XXX: CPU model but this should be determined at run time...
+ */
+       .globl  __delay
+__delay:
+       | d0 = arg = (usecs << 8)
+       movl    sp@(4),d0
+       | d1 = delay_divisor;
+       movl    _delay_divisor,d1
+L_delay:
        subl    d1,d0
-| This loop takes 8 clocks per cycle.
-Ldelay:
-       subql   #8,d0
-       jgt     Ldelay
+       jgt     L_delay
        rts
 
 
index 073f777..156c0e1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.67 1996/01/04 22:22:54 jtc Exp $ */
+/*     $NetBSD: machdep.c,v 1.71 1996/03/26 15:16:53 gwr Exp $ */
 
 /*
  * Copyright (c) 1994, 1995 Gordon W. Ross
 
 #include <net/netisr.h>
 
-#include <setjmp.h>
-
 #include "cache.h"
 
 extern char *cpu_string;
 extern char version[];
 extern short exframesize[];
 extern vm_offset_t vmmap;      /* XXX - poor name.  See mem.c */
+extern int cold;
 
 int physmem;
 int fpu_type;
@@ -221,7 +220,8 @@ allocsys(v)
  * kernel memory allocator is ready for use, but before
  * the creation of processes 1,2, and mountroot, etc.
  */
-void cpu_startup()
+void
+cpu_startup()
 {
        caddr_t v;
        int sz, i;
@@ -239,6 +239,8 @@ void cpu_startup()
         */
        printf(version);
        identifycpu();
+       initfpu();      /* also prints FPU type */
+
        printf("real mem = %d\n", ctob(physmem));
 
        /*
@@ -293,10 +295,11 @@ void cpu_startup()
                                 16*NCARGS, TRUE);
 
        /*
-        * Allocate a submap for physio
+        * We don't use a submap for physio, and use a separate map
+        * for DVMA allocations.  Our vmapbuf just maps pages into
+        * the kernel map (any kernel mapping is OK) and then the
+        * device drivers clone the kernel mappings into DVMA space.
         */
-       phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
-                                VM_PHYS_SIZE, TRUE);
 
        /*
         * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
@@ -379,6 +382,7 @@ setregs(p, pack, stack, retval)
  */
 char   machine[] = "sun3";             /* cpu "architecture" */
 char   cpu_model[120];
+extern long hostid;
 
 void
 identifycpu()
@@ -393,7 +397,7 @@ identifycpu()
     /* should eventually include whether it has a VAC, mc6888x version, etc */
        strcat(cpu_model, cpu_string);
 
-       printf("Model: %s\n", cpu_model);
+       printf("Model: %s (hostid %x)\n", cpu_model, hostid);
 }
 
 /*
@@ -760,6 +764,8 @@ static void reboot_sync()
        vfs_shutdown();
 }
 
+struct pcb dumppcb;
+
 /*
  * Common part of the BSD and SunOS reboot system calls.
  */
@@ -770,9 +776,9 @@ int reboot2(howto, user_boot_string)
        char *bs, *p;
        char default_boot_string[8];
 
-       /* take a snap shot before clobbering any registers */
-       if (curproc && curproc->p_addr)
-               savectx(curproc->p_addr);
+       /* If system is cold, just halt. (early panic?) */
+       if (cold)
+               goto haltsys;
 
        if ((howto & RB_NOSYNC) == 0) {
                reboot_sync();
@@ -787,12 +793,20 @@ int reboot2(howto, user_boot_string)
                /* resettodr(); */
        }
 
-       /* Write out a crash dump if asked. */
+       /* Disable interrupts. */
        splhigh();
-       if (howto & RB_DUMP)
+
+       /* Write out a crash dump if asked. */
+       if (howto & RB_DUMP) {
+               savectx(&dumppcb);
                dumpsys();
+       }
+
+       /* run any shutdown hooks */
+       doshutdownhooks();
 
        if (howto & RB_HALT) {
+       haltsys:
                printf("Kernel halted.\n");
                sun3_mon_halt();
        }
@@ -839,6 +853,8 @@ void boot(howto)
        int howto;
 {
        (void) reboot2(howto, NULL);
+       for(;;);
+       /* NOTREACHED */
 }
 
 /*
@@ -936,11 +952,11 @@ int
 peek_word(addr)
        register caddr_t addr;
 {
-       jmp_buf         faultbuf;
+       label_t         faultbuf;
        register int x;
 
        nofault = (long*)&faultbuf;
-       if (setjmp(nofault)) {
+       if (setjmp(&faultbuf)) {
                nofault = NULL;
                return(-1);
        }
@@ -954,11 +970,11 @@ int
 peek_byte(addr)
        register caddr_t addr;
 {
-       jmp_buf         faultbuf;
+       label_t         faultbuf;
        register int x;
 
        nofault = (long*)&faultbuf;
-       if (setjmp(nofault)) {
+       if (setjmp(&faultbuf)) {
                nofault = NULL;
                return(-1);
        }
diff --git a/sys/arch/sun3/sun3/mainbus.c b/sys/arch/sun3/sun3/mainbus.c
new file mode 100644 (file)
index 0000000..1565d6f
--- /dev/null
@@ -0,0 +1,91 @@
+/*     $NetBSD: mainbus.c,v 1.1 1996/03/26 15:03:58 gwr Exp $  */
+
+/*
+ * Copyright (c) 1996 Gordon W. Ross
+ * 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. The name of the author 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
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Gordon Ross
+ *
+ * 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/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/autoconf.h>
+
+static int     main_match __P((struct device *, void *, void *));
+static void    main_attach __P((struct device *, struct device *, void *));
+
+struct cfattach mainbus_ca = {
+       sizeof(struct device), main_match, main_attach
+};
+
+struct cfdriver mainbus_cd = {
+       NULL, "mainbus", DV_DULL
+};
+
+/*
+ * Probe for the mainbus; always succeeds.
+ */
+static int
+main_match(parent, match, aux)
+       struct device *parent;
+       void *match, *aux;
+{
+
+       return 1;
+}
+
+/*
+ * Do "direct" configuration for the bus types on mainbus.
+ * This controls the order of autoconfig for important things
+ * used early.  For example, idprom is used by Ether drivers.
+ */
+static int bus_order[] = {
+       BUS_OBIO,       /* eeprom, clock */
+       BUS_OBMEM,
+       BUS_VME16,
+       BUS_VME32
+};
+#define BUS_ORDER_SZ (sizeof(bus_order)/sizeof(bus_order[0]))
+
+static void
+main_attach(parent, self, args)
+       struct device *parent;
+       struct device *self;
+       void *args;
+{
+       struct confargs ca;
+       struct cfdata *new_match;
+       int i;
+
+       printf("\n");
+
+       for (i = 0; i < BUS_ORDER_SZ; i++) {
+               ca.ca_bustype = bus_order[i];
+               (void) config_found(self, &ca, NULL);
+       }
+}
index b2823c5..8395d0e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.58 1995/10/10 21:39:04 gwr Exp $    */
+/*     $NetBSD: pmap.c,v 1.60 1996/02/28 22:51:05 gwr Exp $    */
 
 /*
  * Copyright (c) 1994, 1995 Gordon W. Ross
@@ -110,6 +110,8 @@ struct pmap_stats {
        int     ps_changewire;          /* useless wiring changes */
        int     ps_npg_prot_all;        /* of active pages protected */
        int     ps_npg_prot_actual;     /* pages actually affected */
+       int     ps_vac_uncached;        /* non-cached due to bad alias */
+       int     ps_vac_recached;        /* re-cached when bad alias gone */
 } pmap_stats;
 
 struct context_state {
@@ -1279,6 +1281,7 @@ pv_link(pmap, pa, va, flags)
                        if (BADALIAS(va, npv->pv_va)) {
                                head->pv_flags |= PV_NC;
                                pv_changepte(head, PG_NC, 0);
+                               pmap_stats.ps_vac_uncached++;
                                break;
                        }
                }
@@ -1370,6 +1373,7 @@ pv_unlink(pmap, pa, va)
                                return;
                head->pv_flags &= ~PV_NC;
                pv_changepte(head, 0, PG_NC);
+               pmap_stats.ps_vac_recached++;
        }
 }
 
@@ -1546,7 +1550,7 @@ pmap_next_page(paddr)
  *
  * XXX - Should make this a macro in pmap.h
  */
-u_long
+int
 pmap_page_index(pa)
        vm_offset_t pa;
 {
@@ -3196,6 +3200,26 @@ pmap_collect(pmap)
 {
 }
 
+/*
+ * Find first virtual address >= *va that is
+ * least likely to cause cache aliases.
+ * (This will just seg-align mappings.)
+ */
+void
+pmap_prefer(fo, va)
+       register vm_offset_t fo;
+       register vm_offset_t *va;
+{
+       register long   d;
+
+       d = fo - *va;
+       d &= SEGOFSET;
+       *va += d;
+}
+
+/*
+ * Helper functions for changing unloaded PMEGs
+ */
 static int temp_seg_inuse;
 
 static int
index a220182..fda67bc 100644 (file)
@@ -1,7 +1,7 @@
-/*     $NetBSD: stub.c,v 1.10 1994/11/23 08:16:26 gwr Exp $    */
+/*     $NetBSD: stub.c,v 1.11 1996/03/26 15:16:55 gwr Exp $    */
 
 /*
- * Copyright (c) 1993 Adam Glass
+ * Copyright (c) 1996 Gordon W. Ross
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * 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 Adam Glass.
- * 4. The name of the Author may not be used to endorse or promote products
+ * 3. The name of the author 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
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Gordon Ross
  *
- * THIS SOFTWARE IS PROVIDED BY Adam Glass ``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 REGENTS 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 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.
+ */
+
+/*
+ * Stubs to supply things needed when some options are OFF.
+ */
+
+
+/* Called by autoconf.c */
+#ifndef        GENERIC
+void swapgeneric() {}
+#endif
+
+/*
+ * XXX: isr.c:netintr() - move to conf.c?
  */
 
-char   *memcpy(dst, src, cnt)
-       char *dst;
-       const char *src;
-       unsigned cnt;
+/* sun3_startup.c */
+#if !defined(DDB) && !defined(KGDB)
+/*
+ * When DDB is included, Debugger() comes from db_interface.c
+ * otherwise provide this function.  This will just stop in
+ * the Sun PROM monitor.  (You can look around, or continue.)
+ */
+void Debugger()
 {
-    bcopy(src, dst, cnt);
-    return dst;
+       sun3_mon_abort();
 }
+#endif /* !DDB && !KGDB */
      
+/* sys_machdep.c */
+/* trap.c */
index d6fa52d..d0ce50b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: sun3_startup.c,v 1.48 1995/10/17 23:16:40 gwr Exp $    */
+/*     $NetBSD: sun3_startup.c,v 1.51 1996/03/26 15:16:59 gwr Exp $    */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
@@ -192,18 +192,6 @@ void sun3_mon_reboot(bootstring)
        /*NOTREACHED*/
 }
 
-#ifndef DDB
-/*
- * When DDB is included, Debugger() comes from db_interface.c
- * otherwise provide this function.  This will just stop in
- * the Sun PROM monitor.  (You can look around, or continue.)
- */
-void Debugger()
-{
-       sun3_mon_abort();
-}
-#endif /* DDB */
-
 /*
  * Duplicate all mappings in the current context into
  * every other context.  We have to let the PROM do the
@@ -489,9 +477,11 @@ void sun3_vm_init(kehp)
 
        /*
         * Clear-out pmegs left in DVMA space by the PROM.
+        * DO NOT kill the last one! (owned by the PROM!)
         */
-       va = sun3_trunc_seg(DVMA_SEGMAP_BASE);
-       while (va < DVMA_SEGMAP_END) {
+       va  = sun3_trunc_seg(DVMA_SPACE_START);
+       eva = sun3_trunc_seg(DVMA_SPACE_END);  /* Yes trunc! */
+       while (va < eva) {
                set_segmap(va, SEGINV);
                va += NBSG;
        }
@@ -591,8 +581,13 @@ void sun3_vm_init(kehp)
 }
 
 
-/* XXX - Should just estimate this instead... */
-int cpuspeed = 25;     /* initial guess */
+/*
+ * XXX - Should empirically estimate the divisor...
+ * Note that the value of delay_divisor is roughly
+ * 2048 / cpuclock     (where cpuclock is in MHz).
+ */
+int delay_divisor = 82;                /* assume the fastest (3/260) */
+
 void sun3_verify_hardware()
 {
        unsigned char machtype;
@@ -613,33 +608,33 @@ void sun3_verify_hardware()
                hole_start = OBMEM_BW50_ADDR;
                hole_size  = OBMEM_BW2_SIZE;
                cpu_string = "50";
-               cpuspeed = 16; /* MHz */
+               delay_divisor = 128;    /* 16 MHz */
                break;
 
        case SUN3_MACH_60 :
                cpu_match++;
                cpu_string = "60";
-               cpuspeed = 20; /* MHz */
+               delay_divisor = 102;    /* 20 MHz */
                break;
 
        case SUN3_MACH_110:
                cpu_match++;
                cpu_string = "110";
-               cpuspeed = 17; /* MHz */
+               delay_divisor = 120;    /* 17 MHz */
                cpu_has_vme = TRUE;
                break;
 
        case SUN3_MACH_160:
                cpu_match++;
                cpu_string = "160";
-               cpuspeed = 17; /* MHz */
+               delay_divisor = 120;    /* 17 MHz */
                cpu_has_vme = TRUE;
                break;
 
        case SUN3_MACH_260:
                cpu_match++;
                cpu_string = "260";
-               cpuspeed = 25; /* MHz */
+               delay_divisor = 82;     /* 25 MHz */
                cpu_has_vme = TRUE;
 #ifdef HAVECACHE
                cache_size = 0x10000;   /* 64K */
@@ -649,7 +644,7 @@ void sun3_verify_hardware()
        case SUN3_MACH_E  :
                cpu_match++;
                cpu_string = "E";
-               cpuspeed = 20; /* MHz */        /* XXX - Correct? */
+               delay_divisor = 102;    /* 20 MHz  XXX: Correct? */
                cpu_has_vme = TRUE;
                break;
 
@@ -822,7 +817,7 @@ void internal_configure()
        /* Drivers that use those OBIO mappings from the PROM */
        zs_init();
        eeprom_init();
-       isr_init();
+       intreg_init();
        clock_init();
 }
 
index 2470219..1baf087 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.55 1995/10/10 21:33:33 gwr Exp $    */
+/*     $NetBSD: trap.c,v 1.56 1996/03/21 23:03:49 gwr Exp $    */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
@@ -78,7 +78,7 @@ extern struct emul emul_sunos;
  */
 
 extern int fubail(), subail();
-extern int *nofault;
+extern label_t *nofault;
 
 /* XXX - put these in some header file? */
 extern vm_offset_t virtual_avail;
@@ -522,7 +522,7 @@ trap(type, code, v, frame)
                        goto dopanic;
                }
                ucode = v;
-               sig = SIGSEGV;
+               sig = (rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV;
                break;
        } /* T_MMUFLT */
        } /* switch */
index a362866..7fb819d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: vector.c,v 1.13 1995/08/21 21:37:41 gwr Exp $  */
+/*     $NetBSD: vector.c,v 1.14 1996/02/16 20:17:58 gwr Exp $  */
 
 /*
  * Copyright (c) 1994 Gordon W. Ross
@@ -66,7 +66,7 @@ void (*vector_table[NVECTORS])() = {
        chkinst,                        /* 6: CHK instruction */
        trapvinst,                      /* 7: TRAPV instruction */
        privinst,                       /* 8: privilege violation */
-       trace,                          /* 9: trace */
+       trace,                          /* 9: trace (single-step) */
        illinst,                        /* 10: line 1010 emulator */
        fpfline,                        /* 11: line 1111 emulator */
        badtrap,                        /* 12: unassigned, reserved */
@@ -90,8 +90,8 @@ void (*vector_table[NVECTORS])() = {
        _isr_autovec,                   /* 30: level 6 interrupt autovector */
        _isr_autovec,                   /* 31: level 7 interrupt autovector */
        trap0,                          /* 32: syscalls (at least on hp300) */
-       trap1,                          /* 33: sigreturn syscall or breakpoi */
-       trap2,                          /* 34: breakpoint or sigreturn sysca */
+       trap1,                          /* 33: sigreturn syscall */
+       trap2,                          /* 34: HPUX breakpoint */
        illinst,                        /* 35: TRAP instruction vector */
        illinst,                        /* 36: TRAP instruction vector */
        illinst,                        /* 37: TRAP instruction vector */
@@ -101,10 +101,10 @@ void (*vector_table[NVECTORS])() = {
        illinst,                        /* 41: TRAP instruction vector */
        illinst,                        /* 42: TRAP instruction vector */
        illinst,                        /* 43: TRAP instruction vector */
-       trap12,                         /* 44: TRAP instruction vector */
+       trap12,                         /* 44: TRAP 12: cachectl */
        illinst,                        /* 45: TRAP instruction vector */
        illinst,                        /* 46: TRAP instruction vector */
-       trap15,                         /* 47: TRAP instruction vector */
+       trap15,                         /* 47: TRAP 15: breakpoint */
        fpbsun,                         /* 48: FPCP branch/set on unordered */
        fpinex,                         /* 49: FPCP inexact result */
        fpdz,                           /* 50: FPCP divide by zero */
index d23fbfb..b6d2fcb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: vm_machdep.c,v 1.32 1995/12/09 04:37:58 mycroft Exp $  */
+/*     $NetBSD: vm_machdep.c,v 1.35 1996/04/26 18:38:06 gwr Exp $      */
 
 /*
  * Copyright (c) 1994, 1995 Gordon W. Ross
@@ -66,9 +66,6 @@
 
 extern int fpu_type;
 
-/* XXX - Put this in some header file? */
-void cpu_set_kpc __P((struct proc *p, u_long func));
-
 
 /*
  * Finish a fork operation, with process p2 nearly set up.
@@ -131,7 +128,7 @@ cpu_fork(p1, p2)
         * onto the stack of p2, very much like signal delivery.
         * When p2 runs, it will find itself in child_return().
         */
-       cpu_set_kpc(p2, (long)child_return);
+       cpu_set_kpc(p2, child_return);
 }
 
 /*
@@ -158,14 +155,14 @@ cpu_fork(p1, p2)
 void
 cpu_set_kpc(proc, func)
        struct proc *proc;
-       u_long func;
+       void (*func)(struct proc *);
 {
        struct pcb *pcbp;
        struct switchframe *sf;
        extern void proc_trampoline();
        struct ksigframe {
                struct switchframe sf;
-               u_long func;
+               void (*func)(struct proc *);
                void *proc;
        } *ksfp;
 
@@ -282,9 +279,10 @@ cpu_coredump(p, vp, cred, chdr)
  * Both addresses are assumed to reside in the kernel map,
  * and size must be a multiple of CLSIZE.
  */
+void
 pagemove(from, to, size)
        register caddr_t from, to;
-       int size;
+       size_t size;
 {
        register vm_offset_t pa;
 
@@ -309,8 +307,6 @@ pagemove(from, to, size)
        }
 }
 
-extern vm_map_t phys_map;
-
 /*
  * Map an IO request into kernel virtual address space.
  * Requests fall into one of five catagories:
@@ -326,8 +322,7 @@ extern vm_map_t phys_map;
  *     B_PHYS:         User "raw" IO request.
  *                     Address is VA in user's address space.
  *
- * All requests are (re)mapped into kernel VA space via the phys_map
- * (a name with only slightly more meaning than "kernelmap")
+ * All requests are (re)mapped into kernel VA space via the kernel_map
  *
  * This routine has user context and can sleep
  * (called only by physio).
@@ -337,28 +332,33 @@ extern vm_map_t phys_map;
  * is a total crock, the multiple mappings of these physical pages should
  * be reflected in the higher-level VM structures to avoid problems.
  */
-vmapbuf(bp)
+void
+vmapbuf(bp, sz)
        register struct buf *bp;
+       vm_size_t sz;
 {
+       register vm_offset_t addr, kva, pa;
+       register vm_size_t size, off;
        register int npf;
-       register caddr_t addr;
-       register long flags = bp->b_flags;
        struct proc *p;
-       int off;
-       vm_offset_t kva;
-       register vm_offset_t pa;
+       register struct vm_map *map;
 
-       if ((flags & B_PHYS) == 0)
+       if ((bp->b_flags & B_PHYS) == 0)
                panic("vmapbuf");
-       addr = bp->b_saveaddr = bp->b_data;
-       off = (int)addr & PGOFSET;
        p = bp->b_proc;
-       npf = btoc(round_page(bp->b_bcount + off));
-       kva = kmem_alloc_wait(phys_map, ctob(npf));
-       bp->b_data = (caddr_t) (kva + off);
+       map = &p->p_vmspace->vm_map;
+       bp->b_saveaddr = bp->b_data;
+       addr = (vm_offset_t)bp->b_saveaddr;
+       off = addr & PGOFSET;
+       addr = trunc_page(addr);
+       size = round_page(bp->b_bcount + off);
+       kva = kmem_alloc_wait(kernel_map, size);
+       bp->b_data = (caddr_t)(kva + off);
+
+       npf = btoc(size);
        while (npf--) {
-               pa = pmap_extract(vm_map_pmap(&p->p_vmspace->vm_map),
-                   (vm_offset_t)addr);
+               pa = pmap_extract(vm_map_pmap(map), (vm_offset_t)addr);
+               pa = trunc_page(pa);    /* page type in low bits? */
                if (pa == 0)
                        panic("vmapbuf: null page frame");
 #ifdef HAVECACHE
@@ -366,16 +366,16 @@ vmapbuf(bp)
                if (cache_size)
                        cache_flush_page((vm_offset_t)addr);
 #endif
-               pmap_enter(vm_map_pmap(phys_map), kva,
-                       trunc_page(pa) | PMAP_NC,
+               pmap_enter(pmap_kernel(), kva,
+                       pa | PMAP_NC,
                        VM_PROT_READ|VM_PROT_WRITE, TRUE);
-               addr += PAGE_SIZE;
-               kva += PAGE_SIZE;
+               addr += NBPG;
+               kva  += NBPG;
        }
 }
 
 /*
- * Free the io map PTEs associated with this I/O operation.
+ * Free the io mappings associated with this I/O operation.
  * The mappings in the I/O map (phys_map) were non-cached,
  * so there are no write-back modifications to flush.
  * Also note, kmem_free_wakeup will remove the mappings.
@@ -383,21 +383,31 @@ vmapbuf(bp)
  * This routine has user context and can sleep
  * (called only by physio).
  */
-vunmapbuf(bp)
+void
+vunmapbuf(bp, sz)
        register struct buf *bp;
+       vm_size_t sz;
 {
-       register caddr_t addr;
-       vm_offset_t pgva;
-       register int off, npf;
+       register vm_offset_t kva, pgva;
+       register vm_size_t size, off;
 
        if ((bp->b_flags & B_PHYS) == 0)
                panic("vunmapbuf");
-       addr = bp->b_data;
-       off = (int)addr & PGOFSET;
-       pgva = (vm_offset_t)((int)addr & ~PGOFSET);
 
-       npf = btoc(round_page(bp->b_bcount + off));
-       kmem_free_wakeup(phys_map, pgva, ctob(npf));
+       kva = (vm_offset_t)bp->b_data;
+       off = kva & PGOFSET;
+       pgva = trunc_page(kva);
+       size = round_page(bp->b_bcount + off);
+
+       /* Actually remove mappings, which does cache flush. */
+       pmap_remove(pmap_kernel(), pgva, pgva + size);
+
+       /*
+        * Now remove the map entry, which may also call
+        * pmap_remove but that will do nothing since we
+        * already removed the actual mappings.
+        */
+       kmem_free_wakeup(kernel_map, pgva, size);
        bp->b_data = bp->b_saveaddr;
        bp->b_saveaddr = NULL;
 }