mac68k-specific portion of m.i. ncr53c9x driver.
authorbriggs <briggs@openbsd.org>
Thu, 27 Feb 1997 14:02:37 +0000 (14:02 +0000)
committerbriggs <briggs@openbsd.org>
Thu, 27 Feb 1997 14:02:37 +0000 (14:02 +0000)
sys/arch/mac68k/dev/esp.c
sys/arch/mac68k/dev/espreg.h [deleted file]
sys/arch/mac68k/dev/espvar.h

index 8a57d93..2f417f4 100644 (file)
 #include <machine/cpu.h>
 #include <machine/param.h>
 
-#if defined(__sparc__)
-#define        SPARC_DRIVER
-#include <machine/autoconf.h>
-#include <sparc/dev/sbusvar.h>
-#include <sparc/dev/dmareg.h>
-#include <sparc/dev/dmavar.h>
-#include <sparc/dev/espreg.h>
-#include <sparc/dev/espvar.h>
-#else
-#if (_MACHINE == mac68k)
-#define MAC68K_DRIVER
+#include <dev/ic/ncr53c9xreg.h>
+#include <dev/ic/ncr53c9xvar.h>
+
 #include <machine/macinfo.h>
 #include <machine/viareg.h>
 
-struct dma_softc {
-       struct esp_softc        *sc_esp;
-       int             sc_active;
-       int             sc_tc;
-       int             sc_datain;
-       size_t          sc_dmasize;
-       size_t          sc_dmatrans;
-       char            **sc_dmaaddr;
-       size_t          *sc_pdmalen;
-};
-
-#include <mac68k/dev/espreg.h>
 #include <mac68k/dev/espvar.h>
-#undef ESPCMD_DMA
-#define ESPCMD_DMA     0       /* No DMA */
-#undef ESPCMD_TRPAD
-#define ESPCMD_TRPAD   0x98    /* TRPAD needs DMA flag*/
-
-static __inline__ void dma_intr __P((struct dma_softc *sc));
-
-static __inline__ void
-dma_intr(sc)
-       struct dma_softc *sc;
-{
-       register struct esp_softc       *sc_esp;
-       register u_char *p;
-       register u_int  espphase, espstat, espintr;
-       register int    cnt;
-
-       if (sc->sc_active == 0) {
-               printf("dma_intr--inactive DMA\n");
-               return;
-       }
-
-       if ((sc->sc_esp->sc_espintr & ESPINTR_BS) == 0) {
-               sc->sc_active = 0;
-               return;
-       }
 
-       cnt = *sc->sc_pdmalen;
-       if (*sc->sc_pdmalen == 0) {
-               printf("data interrupt, but no count left.");
-       }
-
-       p = *sc->sc_dmaaddr;
-       sc_esp = sc->sc_esp;
-       espphase = sc_esp->sc_phase;
-       espstat = (u_int) sc_esp->sc_espstat;
-       espintr = (u_int) sc_esp->sc_espintr;
-       do {
-               if (sc->sc_datain) {
-                       *p++ = ESP_READ_REG(sc_esp, ESP_FIFO);
-                       cnt--;
-                       if (espphase == DATA_IN_PHASE) {
-                               ESPCMD(sc_esp, ESPCMD_TRANS);
-                       } else {
-                               sc->sc_active = 0;
-                       }
-               } else {
-                       if (   (espphase == DATA_OUT_PHASE)
-                           || (espphase == MESSAGE_OUT_PHASE)) {
-                               ESP_WRITE_REG(sc_esp, ESP_FIFO, *p++);
-                               cnt--;
-                               ESPCMD(sc_esp, ESPCMD_TRANS);
-                       } else {
-                               sc->sc_active = 0;
-                       }
-               }
-
-               if (sc->sc_active) {
-                       while (!DMA_ISINTR(sc));
-                       espstat = ESP_READ_REG(sc_esp, ESP_STAT);
-                       espintr = ESP_READ_REG(sc_esp, ESP_INTR);
-                       espphase = (espintr & ESPINTR_DIS)
-                                   ? /* Disconnected */ BUSFREE_PHASE
-                                   : espstat & ESPSTAT_PHASE;
-               }
-       } while (sc->sc_active && (espintr & ESPINTR_BS));
-       sc_esp->sc_phase = espphase;
-       sc_esp->sc_espstat = (u_char) espstat;
-       sc_esp->sc_espintr = (u_char) espintr;
-       *sc->sc_dmaaddr = p;
-       *sc->sc_pdmalen = cnt;
-
-       if (*sc->sc_pdmalen == 0) {
-               sc->sc_tc = ESPSTAT_TC;
-       }
-       sc->sc_esp->sc_espstat |= sc->sc_tc;
-}
-#else
-#include <dev/tc/tcvar.h>
-#include <alpha/tc/tcdsvar.h>
-#include <alpha/tc/espreg.h>
-#include <alpha/tc/espvar.h>
-#endif
-#endif
-
-int esp_debug = 0; /*ESP_SHOWPHASE|ESP_SHOWMISC|ESP_SHOWTRAC|ESP_SHOWCMDS;*/
-
-/*static*/ void        espattach       __P((struct device *, struct device *, void *));
-/*static*/ int espmatch        __P((struct device *, void *, void *));
-/*static*/ u_int       esp_adapter_info __P((struct esp_softc *));
-/*static*/ void        espreadregs     __P((struct esp_softc *));
-/*static*/ void        esp_select      __P((struct esp_softc *, struct esp_ecb *));
-/*static*/ int esp_reselect    __P((struct esp_softc *, int));
-/*static*/ void        esp_scsi_reset  __P((struct esp_softc *));
-/*static*/ void        esp_reset       __P((struct esp_softc *));
-/*static*/ void        esp_init        __P((struct esp_softc *, int));
-/*static*/ int esp_scsi_cmd    __P((struct scsi_xfer *));
-/*static*/ int esp_poll        __P((struct esp_softc *, struct scsi_xfer *, int));
-/*static*/ void        esp_sched       __P((struct esp_softc *));
-/*static*/ void        esp_done        __P((struct esp_softc *, struct esp_ecb *));
-/*static*/ void        esp_msgin       __P((struct esp_softc *));
-/*static*/ void        esp_msgout      __P((struct esp_softc *));
-/*static*/ int espintr         __P((struct esp_softc *));
-/*static*/ void        esp_timeout     __P((void *arg));
-/*static*/ void        esp_abort       __P((struct esp_softc *, struct esp_ecb *));
-/*static*/ void esp_dequeue    __P((struct esp_softc *, struct esp_ecb *));
-void esp_sense __P((struct esp_softc *, struct esp_ecb *));
-void esp_free_ecb __P((struct esp_softc *, struct esp_ecb *, int));
-struct esp_ecb *esp_get_ecb __P((struct esp_softc *, int));
-static __inline int esp_stp2cpb __P((struct esp_softc *, int));
-static __inline int esp_cpb2stp __P((struct esp_softc *, int));
-static __inline void esp_setsync __P((struct esp_softc *, struct esp_tinfo *));
+void   espattach       __P((struct device *, struct device *, void *));
+int    espmatch        __P((struct device *, void *, void *));
 
 /* Linkup to the rest of the kernel */
 struct cfattach esp_ca = {
@@ -237,7 +109,7 @@ struct cfdriver esp_cd = {
 };
 
 struct scsi_adapter esp_switch = {
-       esp_scsi_cmd,
+       ncr53c9x_scsi_cmd,
        minphys,                /* no max at this level; handled by DMA code */
        NULL,
        NULL,
@@ -250,37 +122,45 @@ struct scsi_device esp_dev = {
        NULL,                   /* Use default 'done' routine */
 };
 
+/*
+ * Functions and the switch for the MI code.
+ */
+u_char esp_read_reg __P((struct ncr53c9x_softc *, int));
+void   esp_write_reg __P((struct ncr53c9x_softc *, int, u_char));
+int    esp_dma_isintr __P((struct ncr53c9x_softc *));
+void   esp_dma_reset __P((struct ncr53c9x_softc *));
+int    esp_dma_intr __P((struct ncr53c9x_softc *));
+int    esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
+           size_t *, int, size_t *));
+void   esp_dma_go __P((struct ncr53c9x_softc *));
+void   esp_dma_stop __P((struct ncr53c9x_softc *));
+int    esp_dma_isactive __P((struct ncr53c9x_softc *));
+
+struct ncr53c9x_glue esp_glue = {
+       esp_read_reg,
+       esp_write_reg,
+       esp_dma_isintr,
+       esp_dma_reset,
+       esp_dma_intr,
+       esp_dma_setup,
+       esp_dma_go,
+       esp_dma_stop,
+       esp_dma_isactive,
+       NULL,                   /* gl_clear_latched_intr */
+};
+
 int
 espmatch(parent, vcf, aux)
        struct device *parent;
        void *vcf, *aux;
 {
        struct cfdata *cf = vcf;
-#ifdef SPARC_DRIVER
-       register struct confargs *ca = aux;
-       register struct romaux *ra = &ca->ca_ra;
 
-       if (strcmp(cf->cf_driver->cd_name, ra->ra_name))
-               return (0);
-       if (ca->ca_bustype == BUS_SBUS)
-               return (1);
-       ra->ra_len = NBPG;
-       return (probeget(ra->ra_vaddr, 1) != -1);
-#else
-#ifdef MAC68K_DRIVER
        if ((cf->cf_unit == 0) && mac68k_machine.scsi96)
                return (1);
        if ((cf->cf_unit == 1) && mac68k_machine.scsi96_2)
                return (1);
        return (0);
-#else
-       struct tcdsdev_attach_args *tcdsdev = aux;
-
-       if (strncmp(tcdsdev->tcdsda_modname, "PMAZ-AA ", TC_ROM_LLEN))
-               return (0);
-       return (!tc_badaddr(tcdsdev->tcdsda_addr));
-#endif
-#endif
 }
 
 /*
@@ -291,52 +171,25 @@ espattach(parent, self, aux)
        struct device *parent, *self;
        void *aux;
 {
-#ifdef SPARC_DRIVER
-       register struct confargs *ca = aux;
-#else
-#ifdef MAC68K_DRIVER
        extern vm_offset_t      SCSIBase;
-#else
-       register struct tcdsdev_attach_args *tcdsdev = aux;
-#endif
-#endif
-       struct esp_softc *sc = (void *)self;
-#ifdef SPARC_DRIVER
-       struct bootpath *bp;
-       int dmachild = strncmp(parent->dv_xname, "dma", 3) == 0;
-#endif
+       struct esp_softc *esc = (void *)self;
+       struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
 
-#ifdef SPARC_DRIVER
        /*
-        * Make sure things are sane. I don't know if this is ever
-        * necessary, but it seem to be in all of Torek's code.
+        * Set up the glue for MI code early; we use some of it here.
         */
-       if (ca->ca_ra.ra_nintr != 1) {
-               printf(": expected 1 interrupt, got %d\n", ca->ca_ra.ra_nintr);
-               return;
-       }
-
-       sc->sc_pri = ca->ca_ra.ra_intr[0].int_pri;
-       printf(" pri %d", sc->sc_pri);
+       sc->sc_glue = &esp_glue;
 
        /*
-        * Map my registers in, if they aren't already in virtual
-        * address space.
+        * Save the regs
         */
-       if (ca->ca_ra.ra_vaddr)
-               sc->sc_reg = (volatile u_char *) ca->ca_ra.ra_vaddr;
-       else {
-               sc->sc_reg = (volatile u_char *)
-                   mapiodev(ca->ca_ra.ra_reg, 0, ca->ca_ra.ra_len, ca->ca_bustype);
-       }
-#else
-#ifdef MAC68K_DRIVER
        if (sc->sc_dev.dv_unit == 0) {
                unsigned long   reg_offset;
 
-               sc->sc_reg = (volatile u_char *) SCSIBase;
-               mac68k_register_scsi_irq((void (*)(void *)) espintr, sc);
-               sc->irq_mask = V2IF_SCSIIRQ;
+               esc->sc_reg = (volatile u_char *) SCSIBase;
+               mac68k_register_scsi_irq(
+                               (void (*)(void *)) ncr53c9x_intr, esc);
+               esc->irq_mask = V2IF_SCSIIRQ;
                reg_offset = SCSIBase - IOBase;
                if (reg_offset == 0x10000) {
                        sc->sc_freq = 16500000;
@@ -344,136 +197,33 @@ espattach(parent, self, aux)
                        sc->sc_freq = 25000000;
                }
        } else {
-               sc->sc_reg = (volatile u_char *) SCSIBase + 0x402;
-               mac68k_register_scsi_b_irq((void (*)(void *)) espintr, sc);
-               sc->irq_mask = V2IF_SCSIDRQ; /* V2IF_T1? */
+               esc->sc_reg = (volatile u_char *) SCSIBase + 0x402;
+               mac68k_register_scsi_b_irq(
+                               (void (*)(void *)) ncr53c9x_intr, sc);
+               esc->irq_mask = V2IF_SCSIDRQ; /* V2IF_T1? */
                sc->sc_freq = 25000000;
        }
-       sc->sc_dma = &sc->_sc_dma;
-       printf(": address %p", sc->sc_reg);
 
-       sc->sc_id = 7;
-#else
-       sc->sc_reg = (volatile u_int32_t *)tcdsdev->tcdsda_addr;
-       sc->sc_cookie = tcdsdev->tcdsda_cookie;
-       sc->sc_dma = tcdsdev->tcdsda_sc;
-
-       printf(": address %x", sc->sc_reg);
-       tcds_intr_establish(parent, sc->sc_cookie, TC_IPL_BIO,
-           (int (*)(void *))espintr, sc);
-#endif
-#endif
+       printf(": address %p", esc->sc_reg);
 
-#ifdef SPARC_DRIVER
-       /* Other settings */
-       sc->sc_node = ca->ca_ra.ra_node;
-       if (ca->ca_bustype == BUS_SBUS) {
-               sc->sc_id = getpropint(sc->sc_node, "initiator-id", 7);
-               sc->sc_freq = getpropint(sc->sc_node, "clock-frequency", -1);
-       } else {
-               sc->sc_id = 7;
-               sc->sc_freq = 24000000;
-       }
-       if (sc->sc_freq < 0)
-               sc->sc_freq = ((struct sbus_softc *)
-                   sc->sc_dev.dv_parent)->sc_clockfreq;
-#else
-#ifdef MAC68K_DRIVER
-#else
-       if (parent->dv_cfdata->cf_driver == &tcds_cd) {
-               sc->sc_id = tcdsdev->tcdsda_id;
-               sc->sc_freq = tcdsdev->tcdsda_freq;
-       } else {
-               /* XXX */
-               sc->sc_id = 7;
-               sc->sc_freq = 24000000;
-       }
-#endif
-#endif
+       sc->sc_id = 7;
 
        /* gimme Mhz */
        sc->sc_freq /= 1000000;
 
-#ifdef SPARC_DRIVER
-       if (dmachild) {
-               sc->sc_dma = (struct dma_softc *)parent;
-               sc->sc_dma->sc_esp = sc;
-       } else {
-               /*
-                * find the DMA by poking around the dma device structures
-                *
-                * What happens here is that if the dma driver has not been
-                * configured, then this returns a NULL pointer. Then when the
-                * dma actually gets configured, it does the opposing test, and
-                * if the sc->sc_esp field in it's softc is NULL, then tries to
-                * find the matching esp driver.
-                *
-                */
-               sc->sc_dma = (struct dma_softc *)
-                       getdevunit("dma", sc->sc_dev.dv_unit);
-
-               /*
-                * and a back pointer to us, for DMA
-                */
-               if (sc->sc_dma)
-                       sc->sc_dma->sc_esp = sc;
-               else
-                       panic("espattach: no dma found");
-       }
-#else
-       sc->sc_dma->sc_esp = sc;                /* XXX */
-#endif
-
        /*
         * It is necessary to try to load the 2nd config register here,
         * to find out what rev the esp chip is, else the esp_reset
         * will not set up the defaults correctly.
         */
-       sc->sc_cfg1 = sc->sc_id | ESPCFG1_PARENB;
-#ifdef SPARC_DRIVER
-       sc->sc_cfg2 = ESPCFG2_SCSI2 | ESPCFG2_RPE;
-       sc->sc_cfg3 = ESPCFG3_CDB;
-       ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
-
-       if ((ESP_READ_REG(sc, ESP_CFG2) & ~ESPCFG2_RSVD) != (ESPCFG2_SCSI2 | ESPCFG2_RPE)) {
-               printf(": ESP100");
-               sc->sc_rev = ESP100;
-       } else {
-               sc->sc_cfg2 = ESPCFG2_SCSI2;
-               ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
-               sc->sc_cfg3 = 0;
-               ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
-               sc->sc_cfg3 = (ESPCFG3_CDB | ESPCFG3_FCLK);
-               ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
-               if (ESP_READ_REG(sc, ESP_CFG3) != (ESPCFG3_CDB | ESPCFG3_FCLK)) {
-                       printf(": ESP100A");
-                       sc->sc_rev = ESP100A;
-               } else {
-                       /* ESPCFG2_FE enables > 64K transfers */
-                       sc->sc_cfg2 |= ESPCFG2_FE;
-                       sc->sc_cfg3 = 0;
-                       ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
-                       printf(": ESP200");
-                       sc->sc_rev = ESP200;
-               }
-       }
-#else
-#ifdef MAC68K_DRIVER
-       sc->sc_cfg2 = ESPCFG2_SCSI2;
+       sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
+       sc->sc_cfg2 = NCRCFG2_SCSI2;
        sc->sc_cfg3 = 0;
-       printf(": NCR53C96");
-       sc->sc_rev = NCR53C96;
-#else
-       sc->sc_cfg2 = ESPCFG2_SCSI2;
-       sc->sc_cfg3 = 0x4;              /* Save residual byte. XXX??? */
-       printf(": NCR53C94");
-       sc->sc_rev = NCR53C94;
-#endif
-#endif
+       sc->sc_rev = NCR_VARIANT_NCR53C96;
 
        /*
         * This is the value used to start sync negotiations
-        * Note that the ESP register "SYNCTP" is programmed
+        * Note that the NCR register "SYNCTP" is programmed
         * in "clocks per byte", and has a minimum value of 4.
         * The SCSI period used in negotiation is one-fourth
         * of the time (in nanoseconds) needed to transfer one byte.
@@ -482,1814 +232,190 @@ espattach(parent, self, aux)
         */
        sc->sc_minsync = 1000 / sc->sc_freq;
 
-#ifdef SPARC_DRIVER
-       /*
-        * Alas, we must now modify the value a bit, because it's
-        * only valid when can switch on FASTCLK and FASTSCSI bits
-        * in config register 3...
-        */
-       switch (sc->sc_rev) {
-       case ESP100:
-               sc->sc_maxxfer = 64 * 1024;
-               sc->sc_minsync = 0;     /* No synch on old chip? */
-               break;
-       case ESP100A:
-               sc->sc_maxxfer = 64 * 1024;
-               sc->sc_minsync = esp_cpb2stp(sc, 5); /* Min clocks/byte is 5 */
-               break;
-       case ESP200:
-               sc->sc_maxxfer = 16 * 1024 * 1024;
-               /* XXX - do actually set FAST* bits */
-       }
-#else
-#ifdef MAC68K_DRIVER
        sc->sc_minsync = 0;     /* No synchronous xfers w/o DMA */
        /* Really no limit, but since we want to fit into the TCR... */
        sc->sc_maxxfer = 64 * 1024;
-#else
-       sc->sc_maxxfer = 64 * 1024;
-#endif
-#endif
-
-       sc->sc_ccf = FREQTOCCF(sc->sc_freq);
-
-       /* The value *must not* be == 1. Make it 2 */
-       if (sc->sc_ccf == 1)
-               sc->sc_ccf = 2;
-
-       /*
-        * The recommended timeout is 250ms. This register is loaded
-        * with a value calculated as follows, from the docs:
-        *
-        *              (timout period) x (CLK frequency)
-        *      reg = -------------------------------------
-        *               8192 x (Clock Conversion Factor)
-        *
-        * Since CCF has a linear relation to CLK, this generally computes
-        * to the constant of 153.
-        */
-       sc->sc_timeout = ((250 * 1000) * sc->sc_freq) / (8192 * sc->sc_ccf);
-
-       /* CCF register only has 3 bits; 0 is actually 8 */
-       sc->sc_ccf &= 7;
-
-       /* Reset state & bus */
-       sc->sc_state = 0;
-       esp_init(sc, 1);
-
-       printf(" %dMhz, target %d\n", sc->sc_freq, sc->sc_id);
-
-#ifdef SPARC_DRIVER
-       /* add me to the sbus structures */
-       sc->sc_sd.sd_reset = (void *) esp_reset;
-#if defined(SUN4C) || defined(SUN4M)
-       if (ca->ca_bustype == BUS_SBUS) {
-               if (dmachild)
-                       sbus_establish(&sc->sc_sd, sc->sc_dev.dv_parent);
-               else
-                       sbus_establish(&sc->sc_sd, &sc->sc_dev);
-       }
-#endif /* SUN4C || SUN4M */
-#endif
-
-#ifdef SPARC_DRIVER
-       /* and the interuppts */
-       sc->sc_ih.ih_fun = (void *) espintr;
-       sc->sc_ih.ih_arg = sc;
-       intr_establish(sc->sc_pri, &sc->sc_ih);
-       evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt);
-#endif
-
-       /*
-        * fill in the prototype scsi_link.
-       sc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE;
-        */
-       sc->sc_link.adapter_softc = sc;
-       sc->sc_link.adapter_target = sc->sc_id;
-       sc->sc_link.adapter = &esp_switch;
-       sc->sc_link.device = &esp_dev;
-       sc->sc_link.openings = 2;
-
-       /*
-        * If the boot path is "esp" at the moment and it's me, then
-        * walk our pointer to the sub-device, ready for the config
-        * below.
-        */
-#ifdef SPARC_DRIVER
-       bp = ca->ca_ra.ra_bp;
-       switch (ca->ca_bustype) {
-       case BUS_SBUS:
-               if (bp != NULL && strcmp(bp->name, "esp") == 0 &&
-                   SAME_ESP(sc, bp, ca))
-                       bootpath_store(1, bp + 1);
-               break;
-       default:
-               if (bp != NULL && strcmp(bp->name, "esp") == 0 &&
-                       bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit)
-                       bootpath_store(1, bp + 1);
-               break;
-       }
-#endif
 
        /*
         * Now try to attach all the sub-devices
         */
-       config_found(self, &sc->sc_link, scsiprint);
-
-#ifdef MAC68K_DRIVER
-       via2_reg(vPCR) = 0x22;
-       via2_reg(vIFR) = sc->irq_mask;
-       via2_reg(vIER) = 0x80 | sc->irq_mask;
-#endif
-#ifdef SPARC_DRIVER
-       bootpath_store(1, NULL);
-#endif
-}
-
-/*
- * This is the generic esp reset function. It does not reset the SCSI bus,
- * only this controllers, but kills any on-going commands, and also stops
- * and resets the DMA.
- *
- * After reset, registers are loaded with the defaults from the attach
- * routine above.
- */
-void
-esp_reset(sc)
-       struct esp_softc *sc;
-{
+       ncr53c9x_attach(sc, &esp_switch, &esp_dev);
 
-       /* reset DMA first */
-       DMA_RESET(sc->sc_dma);
-
-       /* reset SCSI chip */
-       ESPCMD(sc, ESPCMD_RSTCHIP);
-       ESPCMD(sc, ESPCMD_NOP);
-       DELAY(500);
-
-       /* do these backwards, and fall through */
-       switch (sc->sc_rev) {
-#ifndef SPARC_DRIVER
-       case NCR53C96:
-       case NCR53C94:
-#endif
-       case ESP200:
-               ESP_WRITE_REG(sc, ESP_CFG3, sc->sc_cfg3);
-       case ESP100A:
-               ESP_WRITE_REG(sc, ESP_CFG2, sc->sc_cfg2);
-       case ESP100:
-               ESP_WRITE_REG(sc, ESP_CFG1, sc->sc_cfg1);
-               ESP_WRITE_REG(sc, ESP_CCF, sc->sc_ccf);
-               ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
-               ESP_WRITE_REG(sc, ESP_TIMEOUT, sc->sc_timeout);
-               break;
-       default:
-               printf("%s: unknown revision code, assuming ESP100\n",
-                   sc->sc_dev.dv_xname);
-               ESP_WRITE_REG(sc, ESP_CFG1, sc->sc_cfg1);
-               ESP_WRITE_REG(sc, ESP_CCF, sc->sc_ccf);
-               ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
-               ESP_WRITE_REG(sc, ESP_TIMEOUT, sc->sc_timeout);
-       }
-}
-
-/*
- * Reset the SCSI bus, but not the chip
- */
-void
-esp_scsi_reset(sc)
-       struct esp_softc *sc;
-{
-#ifdef SPARC_DRIVER
-       /* stop DMA first, as the chip will return to Bus Free phase */
-       DMACSR(sc->sc_dma) &= ~D_EN_DMA;
-#else
        /*
-        * XXX STOP DMA FIRST
+        * Configure interrupts.
         */
-#endif
-
-       printf("esp: resetting SCSI bus\n");
-       ESPCMD(sc, ESPCMD_RSTSCSI);
-}
-
-/*
- * Initialize esp state machine
- */
-void
-esp_init(sc, doreset)
-       struct esp_softc *sc;
-       int doreset;
-{
-       struct esp_ecb *ecb;
-       int r;
-
-       ESP_TRACE(("[ESP_INIT(%d)] ", doreset));
-
-       if (sc->sc_state == 0) {
-               /* First time through; initialize. */
-               TAILQ_INIT(&sc->ready_list);
-               TAILQ_INIT(&sc->nexus_list);
-               TAILQ_INIT(&sc->free_list);
-               sc->sc_nexus = NULL;
-               ecb = sc->sc_ecb;
-               bzero(ecb, sizeof(sc->sc_ecb));
-               for (r = 0; r < sizeof(sc->sc_ecb) / sizeof(*ecb); r++) {
-                       TAILQ_INSERT_TAIL(&sc->free_list, ecb, chain);
-                       ecb++;
-               }
-               bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
-       } else {
-               /* Cancel any active commands. */
-               sc->sc_state = ESP_CLEANING;
-               if ((ecb = sc->sc_nexus) != NULL) {
-                       ecb->xs->error = XS_DRIVER_STUFFUP;
-                       untimeout(esp_timeout, ecb);
-                       esp_done(sc, ecb);
-               }
-               while ((ecb = sc->nexus_list.tqh_first) != NULL) {
-                       ecb->xs->error = XS_DRIVER_STUFFUP;
-                       untimeout(esp_timeout, ecb);
-                       esp_done(sc, ecb);
-               }
-       }
-
-       /*
-        * reset the chip to a known state
-        */
-       esp_reset(sc);
-
-       sc->sc_phase = sc->sc_prevphase = INVALID_PHASE;
-       for (r = 0; r < 8; r++) {
-               struct esp_tinfo *ti = &sc->sc_tinfo[r];
-/* XXX - config flags per target: low bits: no reselect; high bits: no synch */
-               int fl = sc->sc_dev.dv_cfdata->cf_flags;
-
-               ti->flags = ((sc->sc_minsync && !(fl & (1<<(r+8))))
-                               ? T_NEGOTIATE : 0) |
-                               ((fl & (1<<r)) ? T_RSELECTOFF : 0) |
-                               T_NEED_TO_RESET;
-               ti->period = sc->sc_minsync;
-               ti->offset = 0;
-       }
-
-       if (doreset) {
-               sc->sc_state = ESP_SBR;
-               ESPCMD(sc, ESPCMD_RSTSCSI);
-       } else {
-               sc->sc_state = ESP_IDLE;
-       }
-}
-
-/*
- * Read the ESP registers, and save their contents for later use.
- * ESP_STAT, ESP_STEP & ESP_INTR are mostly zeroed out when reading
- * ESP_INTR - so make sure it is the last read.
- *
- * I think that (from reading the docs) most bits in these registers
- * only make sense when he DMA CSR has an interrupt showing. Call only
- * if an interrupt is pending.
- */
-void
-espreadregs(sc)
-       struct esp_softc *sc;
-{
-
-       sc->sc_espstat = ESP_READ_REG(sc, ESP_STAT);
-       /* Only the stepo bits are of interest */
-       sc->sc_espstep = ESP_READ_REG(sc, ESP_STEP) & ESPSTEP_MASK;
-       sc->sc_espintr = ESP_READ_REG(sc, ESP_INTR);
-
-#if !defined(SPARC_DRIVER) && !defined(MAC68K_DRIVER)
-       /* Clear the TCDS interrupt bit. */
-       (void)tcds_scsi_isintr(sc->sc_dma, 1);
-#endif
-
-       /*
-        * Determine the SCSI bus phase, return either a real SCSI bus phase
-        * or some pseudo phase we use to detect certain exceptions.
-        */
-
-       sc->sc_phase = (sc->sc_espintr & ESPINTR_DIS)
-                       ? /* Disconnected */ BUSFREE_PHASE
-                       : sc->sc_espstat & ESPSTAT_PHASE;
-
-       ESP_MISC(("regs[intr=%02x,stat=%02x,step=%02x] ",
-               sc->sc_espintr, sc->sc_espstat, sc->sc_espstep));
-}
-
-/*
- * Convert chip register Clock Per Byte value to Synchronous Transfer Period.
- */
-static __inline int
-esp_cpb2stp(sc, cpb)
-       struct esp_softc *sc;
-       int cpb;
-{
-       return ((250 * cpb) / sc->sc_freq);
+       via2_reg(vPCR) = 0x22;
+       via2_reg(vIFR) = esc->irq_mask;
+       via2_reg(vIER) = 0x80 | esc->irq_mask;
 }
 
 /*
- * Convert Synchronous Transfer Period to chip register Clock Per Byte value.
+ * Glue functions.
  */
-static __inline int
-esp_stp2cpb(sc, period)
-       struct esp_softc *sc;
-       int period;
-{
-       int v;
-       v = (sc->sc_freq * period) / 250;
-       if (esp_cpb2stp(sc, v) < period)
-               /* Correct round-down error */
-               v++;
-       return v;
-}
 
-static __inline void
-esp_setsync(sc, ti)
-       struct esp_softc *sc;
-       struct esp_tinfo *ti;
+u_char
+esp_read_reg(sc, reg)
+       struct ncr53c9x_softc *sc;
+       int reg;
 {
+       struct esp_softc *esc = (struct esp_softc *)sc;
 
-       if (ti->flags & T_SYNCMODE) {
-               ESP_WRITE_REG(sc, ESP_SYNCOFF, ti->offset);
-               ESP_WRITE_REG(sc, ESP_SYNCTP, esp_stp2cpb(sc, ti->period));
-       } else {
-               ESP_WRITE_REG(sc, ESP_SYNCOFF, 0);
-               ESP_WRITE_REG(sc, ESP_SYNCTP, 0);
-       }
-}
-
-/*
- * Send a command to a target, set the driver state to ESP_SELECTING
- * and let the caller take care of the rest.
- *
- * Keeping this as a function allows me to say that this may be done
- * by DMA instead of programmed I/O soon.
- */
-void
-esp_select(sc, ecb)
-       struct esp_softc *sc;
-       struct esp_ecb *ecb;
-{
-       struct scsi_link *sc_link = ecb->xs->sc_link;
-       int target = sc_link->target;
-       struct esp_tinfo *ti = &sc->sc_tinfo[target];
-       u_char *cmd;
-       int clen;
-
-       ESP_TRACE(("[esp_select(t%d,l%d,cmd:%x)] ", sc_link->target, sc_link->lun, ecb->cmd.opcode));
-
-       /* new state ESP_SELECTING */
-       sc->sc_state = ESP_SELECTING;
-
-       ESPCMD(sc, ESPCMD_FLUSH);
-
-       /*
-        * The docs say the target register is never reset, and I
-        * can't think of a better place to set it
-        */
-       ESP_WRITE_REG(sc, ESP_SELID, target);
-       esp_setsync(sc, ti);
-
-       /*
-        * Who am I. This is where we tell the target that we are
-        * happy for it to disconnect etc.
-        */
-       ESP_WRITE_REG(sc, ESP_FIFO,
-               MSG_IDENTIFY(sc_link->lun, (ti->flags & T_RSELECTOFF)?0:1));
-
-       if (ti->flags & T_NEGOTIATE) {
-               /* Arbitrate, select and stop after IDENTIFY message */
-               ESPCMD(sc, ESPCMD_SELATNS);
-               return;
-       }
-
-       /* Now the command into the FIFO */
-       cmd = (u_char *)&ecb->cmd;
-       clen = ecb->clen;
-       while (clen--)
-               ESP_WRITE_REG(sc, ESP_FIFO, *cmd++);
-
-       /* And get the targets attention */
-       ESPCMD(sc, ESPCMD_SELATN);
+       return esc->sc_reg[reg * 16];
 }
 
 void
-esp_free_ecb(sc, ecb, flags)
-       struct esp_softc *sc;
-       struct esp_ecb *ecb;
-       int flags;
-{
-       int s;
-
-       s = splbio();
-
-       ecb->flags = 0;
-       TAILQ_INSERT_HEAD(&sc->free_list, ecb, chain);
-
-       /*
-        * If there were none, wake anybody waiting for one to come free,
-        * starting with queued entries.
-        */
-       if (ecb->chain.tqe_next == 0)
-               wakeup(&sc->free_list);
-
-       splx(s);
-}
-
-struct esp_ecb *
-esp_get_ecb(sc, flags)
-       struct esp_softc *sc;
-       int flags;
-{
-       struct esp_ecb *ecb;
-       int s;
-
-       s = splbio();
-
-       while ((ecb = sc->free_list.tqh_first) == NULL &&
-              (flags & SCSI_NOSLEEP) == 0)
-               tsleep(&sc->free_list, PRIBIO, "especb", 0);
-       if (ecb) {
-               TAILQ_REMOVE(&sc->free_list, ecb, chain);
-               ecb->flags |= ECB_ALLOC;
-       }
-
-       splx(s);
-       return ecb;
-}
-
-/*
- * DRIVER FUNCTIONS CALLABLE FROM HIGHER LEVEL DRIVERS
- */
-
-/*
- * Start a SCSI-command
- * This function is called by the higher level SCSI-driver to queue/run
- * SCSI-commands.
- */
-int
-esp_scsi_cmd(xs)
-       struct scsi_xfer *xs;
+esp_write_reg(sc, reg, val)
+       struct ncr53c9x_softc *sc;
+       int reg;
+       u_char val;
 {
-       struct scsi_link *sc_link = xs->sc_link;
-       struct esp_softc *sc = sc_link->adapter_softc;
-       struct esp_ecb *ecb;
-       int s, flags;
-
-       ESP_TRACE(("[esp_scsi_cmd] "));
-       ESP_CMDS(("[0x%x, %d]->%d ", (int)xs->cmd->opcode, xs->cmdlen,
-           sc_link->target));
-
-       flags = xs->flags;
-       if ((ecb = esp_get_ecb(sc, flags)) == NULL) {
-               xs->error = XS_DRIVER_STUFFUP;
-               return TRY_AGAIN_LATER;
-       }
-
-       /* Initialize ecb */
-       ecb->xs = xs;
-       ecb->timeout = xs->timeout;
-
-       if (xs->flags & SCSI_RESET) {
-               ecb->flags |= ECB_RESET;
-               ecb->clen = 0;
-               ecb->dleft = 0;
-       } else {
-               bcopy(xs->cmd, &ecb->cmd, xs->cmdlen);
-               ecb->clen = xs->cmdlen;
-               ecb->daddr = xs->data;
-               ecb->dleft = xs->datalen;
-       }
-       ecb->stat = 0;
-
-       s = splbio();
-
-       TAILQ_INSERT_TAIL(&sc->ready_list, ecb, chain);
-       if (sc->sc_state == ESP_IDLE)
-               esp_sched(sc);
-
-       splx(s);
+       struct esp_softc *esc = (struct esp_softc *)sc;
+       u_char v = val;
 
-       if ((flags & SCSI_POLL) == 0)
-               return SUCCESSFULLY_QUEUED;
-
-       /* Not allowed to use interrupts, use polling instead */
-       if (esp_poll(sc, xs, ecb->timeout)) {
-               esp_timeout(ecb);
-               if (esp_poll(sc, xs, ecb->timeout))
-                       esp_timeout(ecb);
+       if (reg == NCR_CMD && v == (NCRCMD_TRANS|NCRCMD_DMA)) {
+               v = NCRCMD_TRANS;
        }
-       return COMPLETE;
+       esc->sc_reg[reg * 16] = v;
 }
 
-/*
- * Used when interrupt driven I/O isn't allowed, e.g. during boot.
- */
 int
-esp_poll(sc, xs, count)
-       struct esp_softc *sc;
-       struct scsi_xfer *xs;
-       int count;
-{
-
-       ESP_TRACE(("[esp_poll] "));
-       while (count) {
-               if (DMA_ISINTR(sc->sc_dma)) {
-                       espintr(sc);
-               }
-#if alternatively
-               if (ESP_READ_REG(sc, ESP_STAT) & ESPSTAT_INT)
-                       espintr(sc);
-#endif
-               if ((xs->flags & ITSDONE) != 0)
-                       return 0;
-               if (sc->sc_state == ESP_IDLE) {
-                       ESP_TRACE(("[esp_poll: rescheduling] "));
-                       esp_sched(sc);
-               }
-               DELAY(1000);
-               count--;
-       }
-       return 1;
-}
-
-
-/*
- * LOW LEVEL SCSI UTILITIES
- */
-
-/*
- * Schedule a scsi operation.  This has now been pulled out of the interrupt
- * handler so that we may call it from esp_scsi_cmd and esp_done.  This may
- * save us an unecessary interrupt just to get things going.  Should only be
- * called when state == ESP_IDLE and at bio pl.
- */
-void
-esp_sched(sc)
-       struct esp_softc *sc;
-{
-       struct esp_ecb *ecb;
-       struct scsi_link *sc_link;
-       struct esp_tinfo *ti;
-
-       ESP_TRACE(("[esp_sched] "));
-       if (sc->sc_state != ESP_IDLE)
-               panic("esp_sched: not IDLE (state=%d)", sc->sc_state);
-
-       /*
-        * Find first ecb in ready queue that is for a target/lunit
-        * combinations that is not busy.
-        */
-       for (ecb = sc->ready_list.tqh_first; ecb; ecb = ecb->chain.tqe_next) {
-               sc_link = ecb->xs->sc_link;
-               ti = &sc->sc_tinfo[sc_link->target];
-               if ((ti->lubusy & (1 << sc_link->lun)) == 0) {
-                       TAILQ_REMOVE(&sc->ready_list, ecb, chain);
-                       sc->sc_nexus = ecb;
-                       esp_select(sc, ecb);
-                       break;
-               } else
-                       ESP_MISC(("%d:%d busy\n",
-                           sc_link->target, sc_link->lun));
-       }
-}
-
-void
-esp_sense(sc, ecb)
-       struct esp_softc *sc;
-       struct esp_ecb *ecb;
+esp_dma_isintr(sc)
+       struct ncr53c9x_softc *sc;
 {
-       struct scsi_xfer *xs = ecb->xs;
-       struct scsi_link *sc_link = xs->sc_link;
-       struct esp_tinfo *ti = &sc->sc_tinfo[sc_link->target];
-       struct scsi_sense *ss = (void *)&ecb->cmd;
+       struct esp_softc *esc = (struct esp_softc *)sc;
 
-       ESP_MISC(("requesting sense "));
-       /* Next, setup a request sense command block */
-       bzero(ss, sizeof(*ss));
-       ss->opcode = REQUEST_SENSE;
-       ss->byte2 = sc_link->lun << 5;
-       ss->length = sizeof(struct scsi_sense_data);
-       ecb->clen = sizeof(*ss);
-       ecb->daddr = (char *)&xs->sense;
-       ecb->dleft = sizeof(struct scsi_sense_data);
-       ecb->flags |= ECB_SENSE;
-       ti->senses++;
-       if (ecb->flags & ECB_NEXUS)
-               ti->lubusy &= ~(1 << sc_link->lun);
-       if (ecb == sc->sc_nexus) {
-               esp_select(sc, ecb);
-       } else {
-               esp_dequeue(sc, ecb);
-               TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
-               if (sc->sc_state == ESP_IDLE)
-                       esp_sched(sc);
-       }
+       return esc->sc_reg[NCR_STAT * 16] & 0x80;
 }
 
-/*
- * POST PROCESSING OF SCSI_CMD (usually current)
- */
 void
-esp_done(sc, ecb)
-       struct esp_softc *sc;
-       struct esp_ecb *ecb;
+esp_dma_reset(sc)
+       struct ncr53c9x_softc *sc;
 {
-       struct scsi_xfer *xs = ecb->xs;
-       struct scsi_link *sc_link = xs->sc_link;
-       struct esp_tinfo *ti = &sc->sc_tinfo[sc_link->target];
+       struct esp_softc *esc = (struct esp_softc *)sc;
 
-       ESP_TRACE(("[esp_done(error:%x)] ", xs->error));
-
-       /*
-        * Now, if we've come here with no error code, i.e. we've kept the
-        * initial XS_NOERROR, and the status code signals that we should
-        * check sense, we'll need to set up a request sense cmd block and
-        * push the command back into the ready queue *before* any other
-        * commands for this target/lunit, else we lose the sense info.
-        * We don't support chk sense conditions for the request sense cmd.
-        */
-       if (xs->error == XS_NOERROR) {
-               if ((ecb->flags & ECB_ABORT) != 0) {
-                       xs->error = XS_DRIVER_STUFFUP;
-               } else if ((ecb->flags & ECB_SENSE) != 0) {
-                       xs->error = XS_SENSE;
-               } else if ((ecb->stat & ST_MASK) == SCSI_CHECK) {
-                       /* First, save the return values */
-                       xs->resid = ecb->dleft;
-                       xs->status = ecb->stat;
-                       esp_sense(sc, ecb);
-                       return;
-               } else {
-                       xs->resid = ecb->dleft;
-               }
-       }
-
-       xs->flags |= ITSDONE;
-
-#if ESP_DEBUG > 0
-       if (esp_debug & ESP_SHOWMISC) {
-               if (xs->resid != 0)
-                       printf("resid=%d ", xs->resid);
-               if (xs->error == XS_SENSE)
-                       printf("sense=0x%02x\n", xs->sense.error_code);
-               else
-                       printf("error=%d\n", xs->error);
-       }
-#endif
-
-       /*
-        * Remove the ECB from whatever queue it's on.
-        */
-       if (ecb->flags & ECB_NEXUS)
-               ti->lubusy &= ~(1 << sc_link->lun);
-       if (ecb == sc->sc_nexus) {
-               sc->sc_nexus = NULL;
-               sc->sc_state = ESP_IDLE;
-               esp_sched(sc);
-       } else
-               esp_dequeue(sc, ecb);
-               
-       esp_free_ecb(sc, ecb, xs->flags);
-       ti->cmds++;
-       scsi_done(xs);
+       esc->sc_active = 0;
+       esc->sc_tc = 0;
 }
 
-void
-esp_dequeue(sc, ecb)
-       struct esp_softc *sc;
-       struct esp_ecb *ecb;
-{
-
-       if (ecb->flags & ECB_NEXUS) {
-               TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
-       } else {
-               TAILQ_REMOVE(&sc->ready_list, ecb, chain);
-       }
-}
-
-/*
- * INTERRUPT/PROTOCOL ENGINE
- */
-
-/*
- * Schedule an outgoing message by prioritizing it, and asserting
- * attention on the bus. We can only do this when we are the initiator
- * else there will be an illegal command interrupt.
- */
-#define esp_sched_msgout(m) \
-       do {                                            \
-               ESP_MISC(("esp_sched_msgout %d ", m));  \
-               ESPCMD(sc, ESPCMD_SETATN);              \
-               sc->sc_flags |= ESP_ATN;                \
-               sc->sc_msgpriq |= (m);                  \
-       } while (0)
-
 int
-esp_reselect(sc, message)
-       struct esp_softc *sc;
-       int message;
+esp_dma_intr(sc)
+       struct ncr53c9x_softc *sc;
 {
-       u_char selid, target, lun;
-       struct esp_ecb *ecb;
-       struct scsi_link *sc_link;
-       struct esp_tinfo *ti;
-
-       /*
-        * The SCSI chip made a snapshot of the data bus while the reselection
-        * was being negotiated.  This enables us to determine which target did
-        * the reselect.
-        */
-       selid = sc->sc_selid & ~(1 << sc->sc_id);
-       if (selid & (selid - 1)) {
-               printf("%s: reselect with invalid selid %02x; sending DEVICE RESET\n",
-                   sc->sc_dev.dv_xname, selid);
-               goto reset;
-       }
-
-       /*
-        * Search wait queue for disconnected cmd
-        * The list should be short, so I haven't bothered with
-        * any more sophisticated structures than a simple
-        * singly linked list.
-        */
-       target = ffs(selid) - 1;
-       lun = message & 0x07;
-       for (ecb = sc->nexus_list.tqh_first; ecb != NULL;
-            ecb = ecb->chain.tqe_next) {
-               sc_link = ecb->xs->sc_link;
-               if (sc_link->target == target && sc_link->lun == lun)
-                       break;
-       }
-       if (ecb == NULL) {
-               printf("%s: reselect from target %d lun %d with no nexus; sending ABORT\n",
-                   sc->sc_dev.dv_xname, target, lun);
-               goto abort;
-       }
-
-       /* Make this nexus active again. */
-       TAILQ_REMOVE(&sc->nexus_list, ecb, chain);
-       sc->sc_state = ESP_CONNECTED;
-       sc->sc_nexus = ecb;
-       ti = &sc->sc_tinfo[target];
-       ti->lubusy |= (1 << lun);
-       esp_setsync(sc, ti);
-
-       if (ecb->flags & ECB_RESET)
-               esp_sched_msgout(SEND_DEV_RESET);
-       else if (ecb->flags & ECB_ABORT)
-               esp_sched_msgout(SEND_ABORT);
-
-       /* Do an implicit RESTORE POINTERS. */
-       sc->sc_dp = ecb->daddr;
-       sc->sc_dleft = ecb->dleft;
-
-       return (0);
-
-reset:
-       esp_sched_msgout(SEND_DEV_RESET);
-       return (1);
-
-abort:
-       esp_sched_msgout(SEND_ABORT);
-       return (1);
-}
-
-#define IS1BYTEMSG(m) (((m) != 1 && (m) < 0x20) || (m) & 0x80)
-#define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
-#define ISEXTMSG(m) ((m) == 1)
-
-/*
- * Get an incoming message as initiator.
- *
- * The SCSI bus must already be in MESSAGE_IN_PHASE and there is a
- * byte in the FIFO
- */
-void
-esp_msgin(sc)
-       register struct esp_softc *sc;
-{
-       register int v;
-
-       ESP_TRACE(("[esp_msgin(curmsglen:%d)] ", sc->sc_imlen));
-
-       if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) == 0) {
-               printf("%s: msgin: no msg byte available\n",
-                       sc->sc_dev.dv_xname);
-               return;
-       }
-
-       /*
-        * Prepare for a new message.  A message should (according
-        * to the SCSI standard) be transmitted in one single
-        * MESSAGE_IN_PHASE. If we have been in some other phase,
-        * then this is a new message.
-        */
-       if (sc->sc_prevphase != MESSAGE_IN_PHASE) {
-               sc->sc_flags &= ~ESP_DROP_MSGI;
-               sc->sc_imlen = 0;
-       }
-
-       v = ESP_READ_REG(sc, ESP_FIFO);
-       ESP_MISC(("<msgbyte:0x%02x>", v));
+       register struct esp_softc *esc = (struct esp_softc *)sc;
+       register u_char *p;
+       volatile u_char *cmdreg, *intrreg, *statreg, *fiforeg;
+       register u_int  espphase, espstat, espintr;
+       register int    cnt;
 
-#if 0
-       if (sc->sc_state == ESP_RESELECTED && sc->sc_imlen == 0) {
-               /*
-                * Which target is reselecting us? (The ID bit really)
-                */
-               sc->sc_selid = v;
-               ESP_MISC(("selid=0x%2x ", sc->sc_selid));
-               return;
+       if (esc->sc_active == 0) {
+               printf("dma_intr--inactive DMA\n");
+               return -1;
        }
-#endif
-
-       sc->sc_imess[sc->sc_imlen] = v;
 
-       /*
-        * If we're going to reject the message, don't bother storing
-        * the incoming bytes.  But still, we need to ACK them.
-        */
-
-       if ((sc->sc_flags & ESP_DROP_MSGI)) {
-               ESPCMD(sc, ESPCMD_MSGOK);
-               printf("<dropping msg byte %x>",
-                       sc->sc_imess[sc->sc_imlen]);
-               return;
+       if ((sc->sc_espintr & NCRINTR_BS) == 0) {
+               esc->sc_active = 0;
+               return 0;
        }
 
-       if (sc->sc_imlen >= ESP_MAX_MSG_LEN) {
-               esp_sched_msgout(SEND_REJECT);
-               sc->sc_flags |= ESP_DROP_MSGI;
-       } else {
-               sc->sc_imlen++;
-               /*
-                * This testing is suboptimal, but most
-                * messages will be of the one byte variety, so
-                * it should not effect performance
-                * significantly.
-                */
-               if (sc->sc_imlen == 1 && IS1BYTEMSG(sc->sc_imess[0]))
-                       goto gotit;
-               if (sc->sc_imlen == 2 && IS2BYTEMSG(sc->sc_imess[0]))
-                       goto gotit;
-               if (sc->sc_imlen >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
-                   sc->sc_imlen == sc->sc_imess[1] + 2)
-                       goto gotit;
+       cnt = *esc->sc_pdmalen;
+       if (*esc->sc_pdmalen == 0) {
+               printf("data interrupt, but no count left.");
        }
-       /* Ack what we have so far */
-       ESPCMD(sc, ESPCMD_MSGOK);
-       return;
-
-gotit:
-       ESP_MSGS(("gotmsg(%x)", sc->sc_imess[0]));
-       /*
-        * Now we should have a complete message (1 byte, 2 byte
-        * and moderately long extended messages).  We only handle
-        * extended messages which total length is shorter than
-        * ESP_MAX_MSG_LEN.  Longer messages will be amputated.
-        */
-       switch (sc->sc_state) {
-               struct esp_ecb *ecb;
-               struct esp_tinfo *ti;
 
-       case ESP_CONNECTED:
-               ecb = sc->sc_nexus;
-               ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
-
-               switch (sc->sc_imess[0]) {
-               case MSG_CMDCOMPLETE:
-                       ESP_MSGS(("cmdcomplete "));
-                       if (sc->sc_dleft < 0) {
-                               struct scsi_link *sc_link = ecb->xs->sc_link;
-                               printf("%s: %d extra bytes from %d:%d\n",
-                                   sc->sc_dev.dv_xname, -sc->sc_dleft,
-                                   sc_link->target, sc_link->lun);
-                               sc->sc_dleft = 0;
-                       }
-                       ecb->xs->resid = ecb->dleft = sc->sc_dleft;
-                       sc->sc_state = ESP_CMDCOMPLETE;
-                       break;
-
-               case MSG_MESSAGE_REJECT:
-                       if (esp_debug & ESP_SHOWMSGS)
-                               printf("%s: our msg rejected by target\n",
-                                   sc->sc_dev.dv_xname);
-                       switch (sc->sc_msgout) {
-                       case SEND_SDTR:
-                               sc->sc_flags &= ~ESP_SYNCHNEGO;
-                               ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
-                               esp_setsync(sc, ti);
-                               break;
-                       case SEND_INIT_DET_ERR:
-                               goto abort;
+       p = *esc->sc_dmaaddr;
+       espphase = sc->sc_phase;
+       espstat = (u_int) sc->sc_espstat;
+       espintr = (u_int) sc->sc_espintr;
+       cmdreg = esc->sc_reg + NCR_CMD * 16;
+       fiforeg = esc->sc_reg + NCR_FIFO * 16;
+       statreg = esc->sc_reg + NCR_STAT * 16;
+       intrreg = esc->sc_reg + NCR_INTR * 16;
+       do {
+               if (esc->sc_datain) {
+                       *p++ = *fiforeg;
+                       cnt--;
+                       if (espphase == DATA_IN_PHASE) {
+                               *cmdreg = NCRCMD_TRANS;
+                       } else {
+                               esc->sc_active = 0;
                        }
-                       break;
-
-               case MSG_NOOP:
-                       ESP_MSGS(("noop "));
-                       break;
-
-               case MSG_DISCONNECT:
-                       ESP_MSGS(("disconnect "));
-                       ti->dconns++;
-                       sc->sc_state = ESP_DISCONNECT;
-                       if ((ecb->xs->sc_link->quirks & SDEV_AUTOSAVE) == 0)
-                               break;
-                       /*FALLTHROUGH*/
-
-               case MSG_SAVEDATAPOINTER:
-                       ESP_MSGS(("save datapointer "));
-                       ecb->daddr = sc->sc_dp;
-                       ecb->dleft = sc->sc_dleft;
-                       break;
-
-               case MSG_RESTOREPOINTERS:
-                       ESP_MSGS(("restore datapointer "));
-                       sc->sc_dp = ecb->daddr;
-                       sc->sc_dleft = ecb->dleft;
-                       break;
-
-               case MSG_EXTENDED:
-                       ESP_MSGS(("extended(%x) ", sc->sc_imess[2]));
-                       switch (sc->sc_imess[2]) {
-                       case MSG_EXT_SDTR:
-                               ESP_MSGS(("SDTR period %d, offset %d ",
-                                       sc->sc_imess[3], sc->sc_imess[4]));
-                               if (sc->sc_imess[1] != 3)
-                                       goto reject;
-                               ti->period = sc->sc_imess[3];
-                               ti->offset = sc->sc_imess[4];
-                               ti->flags &= ~T_NEGOTIATE;
-                               if (sc->sc_minsync == 0 ||
-                                   ti->offset == 0 ||
-                                   ti->period > 124) {
-                                       printf("%s:%d: async\n", "esp",
-                                               ecb->xs->sc_link->target);
-                                       if ((sc->sc_flags&ESP_SYNCHNEGO) == 0) {
-                                               /* target initiated negotiation */
-                                               ti->offset = 0;
-                                               ti->flags &= ~T_SYNCMODE;
-                                               esp_sched_msgout(SEND_SDTR);
-                                       } else {
-                                               /* we are async */
-                                               ti->flags &= ~T_SYNCMODE;
-                                       }
-                               } else {
-                                       int r = 250/ti->period;
-                                       int s = (100*250)/ti->period - 100*r;
-                                       int p;
-
-                                       p =  esp_stp2cpb(sc, ti->period);
-                                       ti->period = esp_cpb2stp(sc, p);
-#ifdef ESP_DEBUG
-                                       sc_print_addr(ecb->xs->sc_link);
-                                       printf("max sync rate %d.%02dMb/s\n",
-                                               r, s);
-#endif
-                                       if ((sc->sc_flags&ESP_SYNCHNEGO) == 0) {
-                                               /* target initiated negotiation */
-                                               if (ti->period < sc->sc_minsync)
-                                                       ti->period = sc->sc_minsync;
-                                               if (ti->offset > 15)
-                                                       ti->offset = 15;
-                                               ti->flags &= ~T_SYNCMODE;
-                                               esp_sched_msgout(SEND_SDTR);
-                                       } else {
-                                               /* we are sync */
-                                               ti->flags |= T_SYNCMODE;
-                                       }
-                               }
-                               sc->sc_flags &= ~ESP_SYNCHNEGO;
-                               esp_setsync(sc, ti);
-                               break;
-
-                       default:
-                               printf("%s: unrecognized MESSAGE EXTENDED; sending REJECT\n",
-                                   sc->sc_dev.dv_xname);
-                               goto reject;
+               } else {
+                       if (   (espphase == DATA_OUT_PHASE)
+                           || (espphase == MESSAGE_OUT_PHASE)) {
+                               *fiforeg = *p++;
+                               cnt--;
+                               *cmdreg = NCRCMD_TRANS;
+                       } else {
+                               esc->sc_active = 0;
                        }
-                       break;
-
-               default:
-                       ESP_MSGS(("ident "));
-                       printf("%s: unrecognized MESSAGE; sending REJECT\n",
-                           sc->sc_dev.dv_xname);
-               reject:
-                       esp_sched_msgout(SEND_REJECT);
-                       break;
-               }
-               break;
-
-       case ESP_RESELECTED:
-               if (!MSG_ISIDENTIFY(sc->sc_imess[0])) {
-                       printf("%s: reselect without IDENTIFY; sending DEVICE RESET\n",
-                           sc->sc_dev.dv_xname);
-                       goto reset;
                }
 
-               (void) esp_reselect(sc, sc->sc_imess[0]);
-               break;
-
-       default:
-               printf("%s: unexpected MESSAGE IN; sending DEVICE RESET\n",
-                   sc->sc_dev.dv_xname);
-       reset:
-               esp_sched_msgout(SEND_DEV_RESET);
-               break;
-
-       abort:
-               esp_sched_msgout(SEND_ABORT);
-               break;
-       }
-
-       /* Ack last message byte */
-       ESPCMD(sc, ESPCMD_MSGOK);
-
-       /* Done, reset message pointer. */
-       sc->sc_flags &= ~ESP_DROP_MSGI;
-       sc->sc_imlen = 0;
-}
-
-
-/*
- * Send the highest priority, scheduled message
- */
-void
-esp_msgout(sc)
-       register struct esp_softc *sc;
-{
-       struct esp_tinfo *ti;
-       struct esp_ecb *ecb;
-       size_t size;
-
-       ESP_TRACE(("[esp_msgout(priq:%x, prevphase:%x)]", sc->sc_msgpriq, sc->sc_prevphase));
-
-       if (sc->sc_flags & ESP_ATN) {
-               if (sc->sc_prevphase != MESSAGE_OUT_PHASE) {
-               new:
-                       ESPCMD(sc, ESPCMD_FLUSH);
-                       DELAY(1);
-                       sc->sc_msgoutq = 0;
-                       sc->sc_omlen = 0;
-               }
-       } else {
-               if (sc->sc_prevphase == MESSAGE_OUT_PHASE) {
-                       esp_sched_msgout(sc->sc_msgoutq);
-                       goto new;
-               } else {
-                       printf("esp at line %d: unexpected MESSAGE OUT phase\n", __LINE__);
-               }
-       }
-                       
-       if (sc->sc_omlen == 0) {
-               /* Pick up highest priority message */
-               sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
-               sc->sc_msgoutq |= sc->sc_msgout;
-               sc->sc_msgpriq &= ~sc->sc_msgout;
-               sc->sc_omlen = 1;               /* "Default" message len */
-               switch (sc->sc_msgout) {
-               case SEND_SDTR:
-                       ecb = sc->sc_nexus;
-                       ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
-                       sc->sc_omess[0] = MSG_EXTENDED;
-                       sc->sc_omess[1] = 3;
-                       sc->sc_omess[2] = MSG_EXT_SDTR;
-                       sc->sc_omess[3] = ti->period;
-                       sc->sc_omess[4] = ti->offset;
-                       sc->sc_omlen = 5;
-                       if ((sc->sc_flags & ESP_SYNCHNEGO) == 0) {
-                               ti->flags |= T_SYNCMODE;
-                               esp_setsync(sc, ti);
-                       }
-                       break;
-               case SEND_IDENTIFY:
-                       if (sc->sc_state != ESP_CONNECTED) {
-                               printf("esp at line %d: no nexus\n", __LINE__);
-                       }
-                       ecb = sc->sc_nexus;
-                       sc->sc_omess[0] = MSG_IDENTIFY(ecb->xs->sc_link->lun,0);
-                       break;
-               case SEND_DEV_RESET:
-                       sc->sc_flags |= ESP_ABORTING;
-                       sc->sc_omess[0] = MSG_BUS_DEV_RESET;
-                       ecb = sc->sc_nexus;
-                       ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
-                       ti->flags &= ~T_SYNCMODE;
-                       ti->flags |= T_NEGOTIATE;
-                       break;
-               case SEND_PARITY_ERROR:
-                       sc->sc_omess[0] = MSG_PARITY_ERROR;
-                       break;
-               case SEND_ABORT:
-                       sc->sc_flags |= ESP_ABORTING;
-                       sc->sc_omess[0] = MSG_ABORT;
-                       break;
-               case SEND_INIT_DET_ERR:
-                       sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
-                       break;
-               case SEND_REJECT:
-                       sc->sc_omess[0] = MSG_MESSAGE_REJECT;
-                       break;
-               default:
-                       ESPCMD(sc, ESPCMD_RSTATN);
-                       sc->sc_flags &= ~ESP_ATN;
-                       sc->sc_omess[0] = MSG_NOOP;
-                       break;
+               if (esc->sc_active) {
+                       while (!(*statreg & 0x80));
+                       espstat = *statreg;
+                       espintr = *intrreg;
+                       espphase = (espintr & NCRINTR_DIS)
+                                   ? /* Disconnected */ BUSFREE_PHASE
+                                   : espstat & PHASE_MASK;
                }
-               sc->sc_omp = sc->sc_omess;
-       }
-
-#if 1
-       /* (re)send the message */
-       size = min(sc->sc_omlen, sc->sc_maxxfer);
-       DMA_SETUP(sc->sc_dma, &sc->sc_omp, &sc->sc_omlen, 0, &size);
-#ifndef MAC68K_DRIVER
-       /* Program the SCSI counter */
-       ESP_WRITE_REG(sc, ESP_TCL, size);
-       ESP_WRITE_REG(sc, ESP_TCM, size >> 8);
-       if (sc->sc_cfg2 & ESPCFG2_FE) {
-               ESP_WRITE_REG(sc, ESP_TCH, size >> 16);
-       }
-       /* load the count in */
-       ESPCMD(sc, ESPCMD_NOP|ESPCMD_DMA);
-#endif
-       ESPCMD(sc, ESPCMD_TRANS|ESPCMD_DMA);
-       DMA_GO(sc->sc_dma);
-#else
-       {       int i;
-               for (i = 0; i < sc->sc_omlen; i++)
-                       ESP_WRITE_REG(sc, FIFO, sc->sc_omess[i]);
-               ESPCMD(sc, ESPCMD_TRANS);
-               sc->sc_omlen = 0;
-       }
-#endif
+       } while (esc->sc_active && (espintr & NCRINTR_BS));
+       sc->sc_phase = espphase;
+       sc->sc_espstat = (u_char) espstat;
+       sc->sc_espintr = (u_char) espintr;
+       *esc->sc_dmaaddr = p;
+       *esc->sc_pdmalen = cnt;
+
+       if (*esc->sc_pdmalen == 0) {
+               esc->sc_tc = NCRSTAT_TC;
+       }
+       sc->sc_espstat |= esc->sc_tc;
+       return 0;
 }
 
-/*
- * This is the most critical part of the driver, and has to know
- * how to deal with *all* error conditions and phases from the SCSI
- * bus. If there are no errors and the DMA was active, then call the
- * DMA pseudo-interrupt handler. If this returns 1, then that was it
- * and we can return from here without further processing.
- *
- * Most of this needs verifying.
- */
 int
-espintr(sc)
-       register struct esp_softc *sc;
+esp_dma_setup(sc, addr, len, datain, dmasize)
+       struct ncr53c9x_softc *sc;
+       caddr_t *addr;
+       size_t *len;
+       int datain;
+       size_t *dmasize;
 {
-       register struct esp_ecb *ecb;
-       register struct scsi_link *sc_link;
-       struct esp_tinfo *ti;
-       int loop;
-       size_t size;
-
-       ESP_TRACE(("[espintr]"));
-
-       /*
-        * I have made some (maybe seriously flawed) assumptions here,
-        * but basic testing (uncomment the printf() below), show that
-        * certainly something happens when this loop is here.
-        *
-        * The idea is that many of the SCSI operations take very little
-        * time, and going away and getting interrupted is too high an
-        * overhead to pay. For example, selecting, sending a message
-        * and command and then doing some work can be done in one "pass".
-        *
-        * The DELAY is not variable because I do not understand that the
-        * DELAY loop should be fixed-time regardless of CPU speed, but
-        * I am *assuming* that the faster SCSI processors get things done
-        * quicker (sending a command byte etc), and so there is no
-        * need to be too slow.
-        *
-        * This is a heuristic. It is 2 when at 20Mhz, 2 at 25Mhz and 1
-        * at 40Mhz. This needs testing.
-        */
-       for (loop = 0; 1;loop++, DELAY(50/sc->sc_freq)) {
-               /* a feeling of deja-vu */
-               if (!DMA_ISINTR(sc->sc_dma))
-                       return (loop != 0);
-#if 0
-               if (loop)
-                       printf("*");
-#endif
-
-               /* and what do the registers say... */
-               espreadregs(sc);
-
-errintr:
-               sc->sc_intrcnt.ev_count++;
-
-               /*
-                * At the moment, only a SCSI Bus Reset or Illegal
-                * Command are classed as errors. A disconnect is a
-                * valid condition, and we let the code check is the
-                * "ESP_BUSFREE_OK" flag was set before declaring it
-                * and error.
-                *
-                * Also, the status register tells us about "Gross
-                * Errors" and "Parity errors". Only the Gross Error
-                * is really bad, and the parity errors are dealt
-                * with later
-                *
-                * TODO
-                *      If there are too many parity error, go to slow
-                *      cable mode ?
-                */
-
-               /* SCSI Reset */
-               if (sc->sc_espintr & ESPINTR_SBR) {
-                       if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
-                               ESPCMD(sc, ESPCMD_FLUSH);
-                               DELAY(1);
-                       }
-                       if (sc->sc_state != ESP_SBR) {
-                               printf("%s: SCSI bus reset\n",
-                                       sc->sc_dev.dv_xname);
-                               esp_init(sc, 0); /* Restart everything */
-                               return 1;
-                       }
-#if 0
-       /*XXX*/         printf("<expected bus reset: "
-                               "[intr %x, stat %x, step %d]>\n",
-                               sc->sc_espintr, sc->sc_espstat,
-                               sc->sc_espstep);
-#endif
-                       if (sc->sc_nexus)
-                               panic("%s: nexus in reset state",
-                                     sc->sc_dev.dv_xname);
-                       goto sched;
-               }
-
-               ecb = sc->sc_nexus;
-
-#define ESPINTR_ERR (ESPINTR_SBR|ESPINTR_ILL)
-               if (sc->sc_espintr & ESPINTR_ERR ||
-                   sc->sc_espstat & ESPSTAT_GE) {
-
-                       if (sc->sc_espstat & ESPSTAT_GE) {
-                               /* no target ? */
-                               if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
-                                       ESPCMD(sc, ESPCMD_FLUSH);
-                                       DELAY(1);
-                               }
-                               if (sc->sc_state == ESP_CONNECTED ||
-                                   sc->sc_state == ESP_SELECTING) {
-                                       ecb->xs->error = XS_DRIVER_STUFFUP;
-                                       esp_done(sc, ecb);
-                               }
-                               return 1;
-                       }
-
-                       if (sc->sc_espintr & ESPINTR_ILL) {
-                               /* illegal command, out of sync ? */
-                               printf("%s: illegal command: 0x%x (state %d, phase %x, prevphase %x)\n",
-                                       sc->sc_dev.dv_xname, sc->sc_lastcmd,
-                                       sc->sc_state, sc->sc_phase,
-                                       sc->sc_prevphase);
-                               if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
-                                       ESPCMD(sc, ESPCMD_FLUSH);
-                                       DELAY(1);
-                               }
-                               esp_init(sc, 0); /* Restart everything */
-                               return 1;
-                       }
-               }
-
-               /*
-                * Call if DMA is active.
-                *
-                * If DMA_INTR returns true, then maybe go 'round the loop
-                * again in case there is no more DMA queued, but a phase
-                * change is expected.
-                */
-               if (DMA_ISACTIVE(sc->sc_dma)) {
-                       DMA_INTR(sc->sc_dma);
-                       /* If DMA active here, then go back to work... */
-                       if (   (sc->sc_espstat & ESPSTAT_GE)
-                           || (sc->sc_espintr & ESPINTR_ERR))
-                               goto errintr;
-                       if (DMA_ISACTIVE(sc->sc_dma))
-                               return 1;
-
-                       if (sc->sc_dleft == 0 &&
-                           (sc->sc_espstat & ESPSTAT_TC) == 0)
-                               printf("%s: !TC [intr %x, stat %x, step %d]"
-                                      " prevphase %x, resid %x\n",
-                                       sc->sc_dev.dv_xname,
-                                       sc->sc_espintr,
-                                       sc->sc_espstat,
-                                       sc->sc_espstep,
-                                       sc->sc_prevphase,
-                                       ecb?ecb->dleft:-1);
-               }
-
-#if 0  /* Unreliable on some ESP revisions? */
-               if ((sc->sc_espstat & ESPSTAT_INT) == 0) {
-                       printf("%s: spurious interrupt\n", sc->sc_dev.dv_xname);
-                       return 1;
-               }
-#endif
-
-               /*
-                * check for less serious errors
-                */
-               if (sc->sc_espstat & ESPSTAT_PE) {
-                       printf("%s: SCSI bus parity error\n",
-                               sc->sc_dev.dv_xname);
-                       if (sc->sc_prevphase == MESSAGE_IN_PHASE)
-                               esp_sched_msgout(SEND_PARITY_ERROR);
-                       else
-                               esp_sched_msgout(SEND_INIT_DET_ERR);
-               }
-
-               if (sc->sc_espintr & ESPINTR_DIS) {
-                       ESP_MISC(("<DISC [intr %x, stat %x, step %d]>",
-                               sc->sc_espintr,sc->sc_espstat,sc->sc_espstep));
-                       if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
-                               ESPCMD(sc, ESPCMD_FLUSH);
-                               DELAY(1);
-                       }
-                       /*
-                        * This command must (apparently) be issued within
-                        * 250mS of a disconnect. So here you are...
-                        */
-                       ESPCMD(sc, ESPCMD_ENSEL);
-                       switch (sc->sc_state) {
-                       case ESP_RESELECTED:
-                               goto sched;
-
-                       case ESP_SELECTING:
-                               ecb->xs->error = XS_SELTIMEOUT;
-                               goto finish;
+       struct esp_softc *esc = (struct esp_softc *)sc;
 
-                       case ESP_CONNECTED:
-                               if ((sc->sc_flags & ESP_SYNCHNEGO)) {
-#ifdef ESP_DEBUG
-                                       if (ecb)
-                                               sc_print_addr(ecb->xs->sc_link);
-                                       printf("sync nego not completed!\n");
-#endif
-                                       ti = &sc->sc_tinfo[ecb->xs->sc_link->target];
-                                       sc->sc_flags &= ~ESP_SYNCHNEGO;
-                                       ti->flags &= ~(T_NEGOTIATE | T_SYNCMODE);
-                               }
+       esc->sc_dmaaddr = addr;
+       esc->sc_pdmalen = len;
+       esc->sc_datain = datain;
+       esc->sc_dmasize = *dmasize;
+       esc->sc_tc = 0;
 
-                               /* it may be OK to disconnect */
-                               if ((sc->sc_flags & ESP_ABORTING) == 0) {
-                                       /*  
-                                        * Section 5.1.1 of the SCSI 2 spec
-                                        * suggests issuing a REQUEST SENSE
-                                        * following an unexpected disconnect.
-                                        * Some devices go into a contingent
-                                        * allegiance condition when
-                                        * disconnecting, and this is necessary
-                                        * to clean up their state.
-                                        */     
-                                       printf("%s: unexpected disconnect; ",
-                                           sc->sc_dev.dv_xname);
-                                       if (ecb->flags & ECB_SENSE) {
-                                               printf("resetting\n");
-                                               goto reset;
-                                       }
-                                       printf("sending REQUEST SENSE\n");
-                                       esp_sense(sc, ecb);
-                                       goto out;
-                               }
-
-                               ecb->xs->error = XS_DRIVER_STUFFUP;
-                               goto finish;
-
-                       case ESP_DISCONNECT:
-                               TAILQ_INSERT_HEAD(&sc->nexus_list, ecb, chain);
-                               sc->sc_nexus = NULL;
-                               goto sched;
-
-                       case ESP_CMDCOMPLETE:
-                               goto finish;
-                       }
-               }
-
-               switch (sc->sc_state) {
-
-               case ESP_SBR:
-                       printf("%s: waiting for SCSI Bus Reset to happen\n",
-                               sc->sc_dev.dv_xname);
-                       return 1;
-
-               case ESP_RESELECTED:
-                       /*
-                        * we must be continuing a message ?
-                        */
-                       if (sc->sc_phase != MESSAGE_IN_PHASE) {
-                               printf("%s: target didn't identify\n",
-                                       sc->sc_dev.dv_xname);
-                               esp_init(sc, 1);
-                               return 1;
-                       }
-printf("<<RESELECT CONT'd>>");
-#if XXXX
-                       esp_msgin(sc);
-                       if (sc->sc_state != ESP_CONNECTED) {
-                               /* IDENTIFY fail?! */
-                               printf("%s: identify failed\n",
-                                       sc->sc_dev.dv_xname);
-                               esp_init(sc, 1);
-                               return 1;
-                       }
-#endif
-                       break;
-
-               case ESP_IDLE:
-if (sc->sc_flags & ESP_ICCS) printf("[[esp: BUMMER]]");
-               case ESP_SELECTING:
-                       sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0;
-                       sc->sc_flags = 0;
-
-                       if (sc->sc_espintr & ESPINTR_RESEL) {
-                               /*
-                                * If we're trying to select a
-                                * target ourselves, push our command
-                                * back into the ready list.
-                                */
-                               if (sc->sc_state == ESP_SELECTING) {
-                                       ESP_MISC(("backoff selector "));
-                                       sc_link = sc->sc_nexus->xs->sc_link;
-                                       ti = &sc->sc_tinfo[sc_link->target];
-                                       TAILQ_INSERT_HEAD(&sc->ready_list,
-                                           sc->sc_nexus, chain);
-                                       ecb = sc->sc_nexus = NULL;
-                               }
-                               sc->sc_state = ESP_RESELECTED;
-                               if (sc->sc_phase != MESSAGE_IN_PHASE) {
-                                       /*
-                                        * Things are seriously fucked up.
-                                        * Pull the brakes, i.e. reset
-                                        */
-                                       printf("%s: target didn't identify\n",
-                                               sc->sc_dev.dv_xname);
-                                       esp_init(sc, 1);
-                                       return 1;
-                               }
-                               if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) != 2) {
-                                       printf("%s: RESELECT: %d bytes in FIFO!\n",
-                                               sc->sc_dev.dv_xname,
-                                               ESP_READ_REG(sc, ESP_FFLAG) &
-                                               ESPFIFO_FF);
-                                       esp_init(sc, 1);
-                                       return 1;
-                               }
-                               sc->sc_selid = ESP_READ_REG(sc, ESP_FIFO);
-                               ESP_MISC(("selid=0x%2x ", sc->sc_selid));
-                               esp_msgin(sc);  /* Handle identify message */
-                               if (sc->sc_state != ESP_CONNECTED) {
-                                       /* IDENTIFY fail?! */
-                                       printf("%s: identify failed\n",
-                                               sc->sc_dev.dv_xname);
-                                       esp_init(sc, 1);
-                                       return 1;
-                               }
-                               continue; /* ie. next phase expected soon */
-                       }
-
-#define        ESPINTR_DONE    (ESPINTR_FC|ESPINTR_BS)
-                       if ((sc->sc_espintr & ESPINTR_DONE) == ESPINTR_DONE) {
-                               ecb = sc->sc_nexus;
-                               if (!ecb)
-                                       panic("esp: not nexus at sc->sc_nexus");
-
-                               sc_link = ecb->xs->sc_link;
-                               ti = &sc->sc_tinfo[sc_link->target];
-
-                               switch (sc->sc_espstep) {
-                               case 0:
-                                       printf("%s: select timeout/no disconnect\n",
-                                               sc->sc_dev.dv_xname);
-                                       ecb->xs->error = XS_SELTIMEOUT;
-                                       goto finish;
-                               case 1:
-                                       if ((ti->flags & T_NEGOTIATE) == 0) {
-                                               printf("%s: step 1 & !NEG\n",
-                                                       sc->sc_dev.dv_xname);
-                                               goto reset;
-                                       }
-                                       if (sc->sc_phase != MESSAGE_OUT_PHASE) {
-                                               printf("%s: !MSGOUT\n",
-                                                       sc->sc_dev.dv_xname);
-                                               goto reset;
-                                       }
-                                       /* Start negotiating */
-                                       ti->period = sc->sc_minsync;
-                                       ti->offset = 15;
-                                       sc->sc_flags |= ESP_SYNCHNEGO;
-                                       esp_sched_msgout(SEND_SDTR);
-                                       break;
-                               case 3:
-                                       /*
-                                        * Grr, this is supposed to mean
-                                        * "target left command phase
-                                        *  prematurely". It seems to happen
-                                        * regularly when sync mode is on.
-                                        * Look at FIFO to see if command
-                                        * went out.
-                                        * (Timing problems?)
-                                        */
-                                       if ((ESP_READ_REG(sc, ESP_FFLAG)&ESPFIFO_FF) == 0) {
-                                               /* Hope for the best.. */
-                                               break;
-                                       }
-                                       printf("(%s:%d:%d): selection failed;"
-                                               " %d left in FIFO "
-                                               "[intr %x, stat %x, step %d]\n",
-                                               sc->sc_dev.dv_xname,
-                                               sc_link->target,
-                                               sc_link->lun,
-                                               ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF,
-                                               sc->sc_espintr, sc->sc_espstat,
-                                               sc->sc_espstep);
-                                       ESPCMD(sc, ESPCMD_FLUSH);
-                                       esp_sched_msgout(SEND_ABORT);
-                                       return 1;
-                               case 2:
-                                       /* Select stuck at Command Phase */
-                                       ESPCMD(sc, ESPCMD_FLUSH);
-                               case 4:
-                                       /* So far, everything went fine */
-                                       break;
-                               }
-#if 0
-                               if (ecb->xs->flags & SCSI_RESET)
-                                       esp_sched_msgout(SEND_DEV_RESET);
-                               else if (ti->flags & T_NEGOTIATE)
-                                       esp_sched_msgout(
-                                           SEND_IDENTIFY | SEND_SDTR);
-                               else
-                                       esp_sched_msgout(SEND_IDENTIFY);
-#endif
-
-                               ecb->flags |= ECB_NEXUS;
-                               ti->lubusy |= (1 << sc_link->lun);
-
-                               sc->sc_prevphase = INVALID_PHASE; /* ?? */
-                               /* Do an implicit RESTORE POINTERS. */
-                               sc->sc_dp = ecb->daddr;
-                               sc->sc_dleft = ecb->dleft;
-
-                               /* On our first connection, schedule a timeout. */
-                               if ((ecb->xs->flags & SCSI_POLL) == 0)
-                                       timeout(esp_timeout, ecb, (ecb->timeout * hz) / 1000);
-
-                               sc->sc_state = ESP_CONNECTED;
-                               break;
-                       } else {
-                               printf("%s: unexpected status after select"
-                                       ": [intr %x, stat %x, step %x]\n",
-                                       sc->sc_dev.dv_xname,
-                                       sc->sc_espintr, sc->sc_espstat,
-                                       sc->sc_espstep);
-                               ESPCMD(sc, ESPCMD_FLUSH);
-                               DELAY(1);
-                               goto reset;
-                       }
-                       if (sc->sc_state == ESP_IDLE) {
-                               printf("%s: stray interrupt\n", sc->sc_dev.dv_xname);
-                                       return 0;
-                       }
-                       break;
-
-               case ESP_CONNECTED:
-                       if (sc->sc_flags & ESP_ICCS) {
-                               u_char msg;
-
-                               sc->sc_flags &= ~ESP_ICCS;
-
-                               if (!(sc->sc_espintr & ESPINTR_DONE)) {
-                                       printf("%s: ICCS: "
-                                             ": [intr %x, stat %x, step %x]\n",
-                                               sc->sc_dev.dv_xname,
-                                               sc->sc_espintr, sc->sc_espstat,
-                                               sc->sc_espstep);
-                               }
-                               if ((ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) != 2) {
-                                       int i = (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) - 2;
-                                       while (i--)
-                                               (void) ESP_READ_REG(sc, ESP_FIFO);
-                               }
-                               ecb->stat = ESP_READ_REG(sc, ESP_FIFO);
-                               msg = ESP_READ_REG(sc, ESP_FIFO);
-                               ESP_PHASE(("<stat:(%x,%x)>", ecb->stat, msg));
-                               if (msg == MSG_CMDCOMPLETE) {
-                                       ecb->xs->resid = ecb->dleft = sc->sc_dleft;
-                                       sc->sc_state = ESP_CMDCOMPLETE;
-                               } else
-                                       printf("%s: STATUS_PHASE: msg %d\n",
-                                               sc->sc_dev.dv_xname, msg);
-                               ESPCMD(sc, ESPCMD_MSGOK);
-                               continue; /* ie. wait for disconnect */
-                       }
-                       break;
-               default:
-                       panic("%s: invalid state: %d",
-                             sc->sc_dev.dv_xname,
-                             sc->sc_state);
-               }
-
-               /*
-                * Driver is now in state ESP_CONNECTED, i.e. we
-                * have a current command working the SCSI bus.
-                */
-               if (sc->sc_state != ESP_CONNECTED || ecb == NULL) {
-                       panic("esp no nexus");
-               }
-
-               switch (sc->sc_phase) {
-               case MESSAGE_OUT_PHASE:
-                       ESP_PHASE(("MESSAGE_OUT_PHASE "));
-                       esp_msgout(sc);
-                       sc->sc_prevphase = MESSAGE_OUT_PHASE;
-                       break;
-               case MESSAGE_IN_PHASE:
-                       ESP_PHASE(("MESSAGE_IN_PHASE "));
-                       if (sc->sc_espintr & ESPINTR_BS) {
-                               ESPCMD(sc, ESPCMD_FLUSH);
-                               sc->sc_flags |= ESP_WAITI;
-                               ESPCMD(sc, ESPCMD_TRANS);
-                       } else if (sc->sc_espintr & ESPINTR_FC) {
-                               if ((sc->sc_flags & ESP_WAITI) == 0) {
-                                       printf("%s: MSGIN: unexpected FC bit: "
-                                               "[intr %x, stat %x, step %x]\n",
-                                       sc->sc_dev.dv_xname,
-                                       sc->sc_espintr, sc->sc_espstat,
-                                       sc->sc_espstep);
-                               }
-                               sc->sc_flags &= ~ESP_WAITI;
-                               esp_msgin(sc);
-                       } else {
-                               printf("%s: MSGIN: weird bits: "
-                                       "[intr %x, stat %x, step %x]\n",
-                                       sc->sc_dev.dv_xname,
-                                       sc->sc_espintr, sc->sc_espstat,
-                                       sc->sc_espstep);
-                       }
-                       sc->sc_prevphase = MESSAGE_IN_PHASE;
-                       break;
-               case COMMAND_PHASE: {
-                       /* well, this means send the command again */
-                       u_char *cmd = (u_char *)&ecb->cmd;
-                       int i;
-
-                       ESP_PHASE(("COMMAND_PHASE 0x%02x (%d) ",
-                               ecb->cmd.opcode, ecb->clen));
-                       if (ESP_READ_REG(sc, ESP_FFLAG) & ESPFIFO_FF) {
-                               ESPCMD(sc, ESPCMD_FLUSH);
-                               DELAY(1);
-                       }
-                       /* Now the command into the FIFO */
-                       for (i = 0; i < ecb->clen; i++)
-                               ESP_WRITE_REG(sc, ESP_FIFO, *cmd++);
-                       ESPCMD(sc, ESPCMD_TRANS);
-                       sc->sc_prevphase = COMMAND_PHASE;
-                       }
-                       break;
-               case DATA_OUT_PHASE:
-                       ESP_PHASE(("DATA_OUT_PHASE [%d] ",  sc->sc_dleft));
-                       ESPCMD(sc, ESPCMD_FLUSH);
-                       size = min(sc->sc_dleft, sc->sc_maxxfer);
-                       DMA_SETUP(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft,
-                                 0, &size);
-                       sc->sc_prevphase = DATA_OUT_PHASE;
-                       goto setup_xfer;
-               case DATA_IN_PHASE:
-                       ESP_PHASE(("DATA_IN_PHASE "));
-                       if (sc->sc_rev == ESP100)
-                               ESPCMD(sc, ESPCMD_FLUSH);
-                       size = min(sc->sc_dleft, sc->sc_maxxfer);
-                       DMA_SETUP(sc->sc_dma, &sc->sc_dp, &sc->sc_dleft,
-                                 1, &size);
-                       sc->sc_prevphase = DATA_IN_PHASE;
-               setup_xfer:
-#ifdef MAC68K_DRIVER
-                       if (!size) {
-#endif
-                       /* Program the SCSI counter */
-                       ESP_WRITE_REG(sc, ESP_TCL, size);
-                       ESP_WRITE_REG(sc, ESP_TCM, size >> 8);
-                       if (sc->sc_cfg2 & ESPCFG2_FE) {
-                               ESP_WRITE_REG(sc, ESP_TCH, size >> 16);
-                       }
-                       /* load the count in */
-                       ESPCMD(sc, ESPCMD_NOP|ESPCMD_DMA);
-#ifdef MAC68K_DRIVER
-                       }
-#endif
-
-                       /*
-                        * Note that if `size' is 0, we've already transceived
-                        * all the bytes we want but we're still in DATA PHASE.
-                        * Apparently, the device needs padding. Also, a
-                        * transfer size of 0 means "maximum" to the chip
-                        * DMA logic.
-                        */
-                       ESPCMD(sc,
-                              (size==0?ESPCMD_TRPAD:ESPCMD_TRANS)|ESPCMD_DMA);
-                       DMA_GO(sc->sc_dma);
-                       return 1;
-               case STATUS_PHASE:
-                       ESP_PHASE(("STATUS_PHASE "));
-                       sc->sc_flags |= ESP_ICCS;
-                       ESPCMD(sc, ESPCMD_ICCS);
-                       sc->sc_prevphase = STATUS_PHASE;
-                       break;
-               case INVALID_PHASE:
-                       break;
-               default:
-                       printf("%s: unexpected bus phase; resetting\n",
-                           sc->sc_dev.dv_xname);
-                       goto reset;
-               }
-       }
-       panic("esp: should not get here..");
-
-reset:
-       esp_init(sc, 1);
-       return 1;
-
-finish:
-       untimeout(esp_timeout, ecb);
-       esp_done(sc, ecb);
-       goto out;
-
-sched:
-       sc->sc_state = ESP_IDLE;
-       esp_sched(sc);
-       goto out;
-
-out:
-       return 1;
+       return 0;
 }
 
 void
-esp_abort(sc, ecb)
-       struct esp_softc *sc;
-       struct esp_ecb *ecb;
+esp_dma_go(sc)
+       struct ncr53c9x_softc *sc;
 {
+       struct esp_softc *esc = (struct esp_softc *)sc;
 
-       /* 2 secs for the abort */
-       ecb->timeout = ESP_ABORT_TIMEOUT;
-       ecb->flags |= ECB_ABORT;
-
-       if (ecb == sc->sc_nexus) {
-               /*
-                * If we're still selecting, the message will be scheduled
-                * after selection is complete.
-                */
-               if (sc->sc_state == ESP_CONNECTED)
-                       esp_sched_msgout(SEND_ABORT);
-       } else {
-               esp_dequeue(sc, ecb);
-               TAILQ_INSERT_HEAD(&sc->ready_list, ecb, chain);
-               if (sc->sc_state == ESP_IDLE)
-                       esp_sched(sc);
+       if (esc->sc_datain == 0) {
+               esc->sc_reg[NCR_FIFO * 16] = **esc->sc_dmaaddr;
+               (*esc->sc_pdmalen)--;
+               (*esc->sc_dmaaddr)++;
        }
+       esc->sc_active = 1;
 }
 
 void
-esp_timeout(arg)
-       void *arg;
+esp_dma_stop(sc)
+       struct ncr53c9x_softc *sc;
 {
-       struct esp_ecb *ecb = arg;
-       struct scsi_xfer *xs = ecb->xs;
-       struct scsi_link *sc_link = xs->sc_link;
-       struct esp_softc *sc = sc_link->adapter_softc;
-       int s;
-
-       sc_print_addr(sc_link);
-       printf("%s: timed out [ecb %p (flags 0x%x, dleft %x, stat %x)], "
-              "<state %d, nexus %p, phase(c %x, p %x), resid %x, msg(q %x,o %x) %s>",
-               sc->sc_dev.dv_xname,
-               ecb, ecb->flags, ecb->dleft, ecb->stat,
-               sc->sc_state, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase,
-               sc->sc_dleft, sc->sc_msgpriq, sc->sc_msgout,
-               DMA_ISACTIVE(sc->sc_dma) ? "DMA active" : "");
-#if ESP_DEBUG > 0
-       printf("TRACE: %s.", ecb->trace);
-#endif
-
-       s = splbio();
+}
 
-       if (ecb->flags & ECB_ABORT) {
-               /* abort timed out */
-               printf(" AGAIN\n");
-               esp_init(sc, 1);
-       } else {
-               /* abort the operation that has timed out */
-               printf("\n");
-               xs->error = XS_TIMEOUT;
-               esp_abort(sc, ecb);
-       }
+int
+esp_dma_isactive(sc)
+       struct ncr53c9x_softc *sc;
+{
+       struct esp_softc *esc = (struct esp_softc *)sc;
 
-       splx(s);
+       return esc->sc_active;
 }
diff --git a/sys/arch/mac68k/dev/espreg.h b/sys/arch/mac68k/dev/espreg.h
deleted file mode 100644 (file)
index e08eebc..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*     $NetBSD: espreg.h,v 1.7 1995/12/18 23:58:39 pk Exp $ */
-
-/*
- * Copyright (c) 1994 Peter Galbavy.  All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by Peter Galbavy.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Register addresses, relative to some base address
- */
-
-#define        ESP_TCL         0x00            /* RW - Transfer Count Low      */
-#define        ESP_TCM         0x01            /* RW - Transfer Count Mid      */
-#define        ESP_TCH         0x0e            /* RW - Transfer Count High     */
-                                       /*      NOT on 53C90            */
-
-#define        ESP_FIFO        0x02            /* RW - FIFO data               */
-
-#define        ESP_CMD         0x03            /* RW - Command (2 deep)        */
-#define  ESPCMD_DMA    0x80            /*      DMA Bit                 */
-#define  ESPCMD_NOP    0x00            /*      No Operation            */
-#define  ESPCMD_FLUSH  0x01            /*      Flush FIFO              */
-#define  ESPCMD_RSTCHIP        0x02            /*      Reset Chip              */
-#define  ESPCMD_RSTSCSI        0x03            /*      Reset SCSI Bus          */
-#define  ESPCMD_RESEL  0x40            /*      Reselect Sequence       */
-#define  ESPCMD_SELNATN        0x41            /*      Select without ATN      */
-#define  ESPCMD_SELATN 0x42            /*      Select with ATN         */
-#define  ESPCMD_SELATNS        0x43            /*      Select with ATN & Stop  */
-#define  ESPCMD_ENSEL  0x44            /*      Enable (Re)Selection    */
-#define  ESPCMD_DISSEL 0x45            /*      Disable (Re)Selection   */
-#define  ESPCMD_SELATN3        0x46            /*      Select with ATN3        */
-#define  ESPCMD_RESEL3 0x47            /*      Reselect3 Sequence      */
-#define  ESPCMD_SNDMSG 0x20            /*      Send Message            */
-#define  ESPCMD_SNDSTAT        0x21            /*      Send Status             */
-#define  ESPCMD_SNDDATA        0x22            /*      Send Data               */
-#define  ESPCMD_DISCSEQ        0x23            /*      Disconnect Sequence     */
-#define  ESPCMD_TERMSEQ        0x24            /*      Terminate Sequence      */
-#define  ESPCMD_TCCS   0x25            /*      Target Command Comp Seq */
-#define  ESPCMD_DISC   0x27            /*      Disconnect              */
-#define  ESPCMD_RECMSG 0x28            /*      Receive Message         */
-#define  ESPCMD_RECCMD 0x29            /*      Receive Command         */
-#define  ESPCMD_RECDATA        0x2a            /*      Receive Data            */
-#define  ESPCMD_RECCSEQ        0x2b            /*      Receive Command Sequence*/
-#define  ESPCMD_ABORT  0x04            /*      Target Abort DMA        */
-#define  ESPCMD_TRANS  0x10            /*      Transfer Information    */
-#define  ESPCMD_ICCS   0x11            /*      Initiator Cmd Comp Seq  */
-#define  ESPCMD_MSGOK  0x12            /*      Message Accepted        */
-#define  ESPCMD_TRPAD  0x18            /*      Transfer Pad            */
-#define  ESPCMD_SETATN 0x1a            /*      Set ATN                 */
-#define  ESPCMD_RSTATN 0x1b            /*      Reset ATN               */
-
-#define        ESP_STAT        0x04            /* RO - Status                  */
-#define  ESPSTAT_INT   0x80            /*      Interrupt               */
-#define  ESPSTAT_GE    0x40            /*      Gross Error             */
-#define  ESPSTAT_PE    0x20            /*      Parity Error            */
-#define  ESPSTAT_TC    0x10            /*      Terminal Count          */
-#define  ESPSTAT_VGC   0x08            /*      Valid Group Code        */
-#define  ESPSTAT_PHASE 0x07            /*      Phase bits              */
-
-#define        ESP_SELID       0x04            /* WO - Select/Reselect Bus ID  */
-
-#define        ESP_INTR        0x05            /* RO - Interrupt               */
-#define  ESPINTR_SBR   0x80            /*      SCSI Bus Reset          */
-#define  ESPINTR_ILL   0x40            /*      Illegal Command         */
-#define  ESPINTR_DIS   0x20            /*      Disconnect              */
-#define  ESPINTR_BS    0x10            /*      Bus Service             */
-#define  ESPINTR_FC    0x08            /*      Function Complete       */
-#define  ESPINTR_RESEL 0x04            /*      Reselected              */
-#define  ESPINTR_SELATN        0x02            /*      Select with ATN         */
-#define  ESPINTR_SEL   0x01            /*      Selected                */
-
-#define        ESP_TIMEOUT     0x05            /* WO - Select/Reselect Timeout */
-
-#define        ESP_STEP        0x06            /* RO - Sequence Step           */
-#define  ESPSTEP_MASK  0x07            /*      the last 3 bits         */
-#define  ESPSTEP_DONE  0x04            /*      command went out        */
-
-#define        ESP_SYNCTP      0x06            /* WO - Synch Transfer Period   */
-                                       /*      Default 5 (53C9X)       */
-
-#define        ESP_FFLAG       0x07            /* RO - FIFO Flags              */
-#define  ESPFIFO_SS    0xe0            /*      Sequence Step (Dup)     */
-#define  ESPFIFO_FF    0x1f            /*      Bytes in FIFO           */
-
-#define        ESP_SYNCOFF     0x07            /* WO - Synch Offset            */
-                                       /*      0 = ASYNC               */
-                                       /*      1 - 15 = SYNC bytes     */
-
-#define        ESP_CFG1        0x08            /* RW - Configuration #1        */
-#define  ESPCFG1_SLOW  0x80            /*      Slow Cable Mode         */
-#define  ESPCFG1_SRR   0x40            /*      SCSI Reset Rep Int Dis  */
-#define  ESPCFG1_PTEST 0x20            /*      Parity Test Mod         */
-#define  ESPCFG1_PARENB        0x10            /*      Enable Parity Check     */
-#define  ESPCFG1_CTEST 0x08            /*      Enable Chip Test        */
-#define  ESPCFG1_BUSID 0x07            /*      Bus ID                  */
-
-#define        ESP_CCF         0x09            /* WO - Clock Conversion Factor */
-                                       /*      0 = 35.01 - 40Mhz       */
-                                       /*      NEVER SET TO 1          */
-                                       /*      2 = 10Mhz               */
-                                       /*      3 = 10.01 - 15Mhz       */
-                                       /*      4 = 15.01 - 20Mhz       */
-                                       /*      5 = 20.01 - 25Mhz       */
-                                       /*      6 = 25.01 - 30Mhz       */
-                                       /*      7 = 30.01 - 35Mhz       */
-
-#define        ESP_TEST        0x0a            /* WO - Test (Chip Test Only)   */
-
-#define        ESP_CFG2        0x0b            /* RW - Configuration #2        */
-#define         ESPCFG2_RSVD   0xa0            /*      reserved                */
-#define  ESPCFG2_FE    0x40            /*      Features Enable         */
-#define  ESPCFG2_DREQ  0x10            /*      DREQ High Impedance     */
-#define  ESPCFG2_SCSI2 0x08            /*      SCSI-2 Enable           */
-#define  ESPCFG2_BPA   0x04            /*      Target Bad Parity Abort */
-#define  ESPCFG2_RPE   0x02            /*      Register Parity Error   */
-#define  ESPCFG2_DPE   0x01            /*      DMA Parity Error        */
-
-/* Config #3 only on 53C9X */
-#define        ESP_CFG3        0x0c            /* RW - Configuration #3        */
-#define         ESPCFG3_RSVD   0xe0            /*      reserved                */
-#define  ESPCFG3_IDM   0x10            /*      ID Message Res Check    */
-#define  ESPCFG3_QTE   0x08            /*      Queue Tag Enable        */
-#define  ESPCFG3_CDB   0x04            /*      CDB 10-bytes OK         */
-#define  ESPCFG3_FSCSI 0x02            /*      Fast SCSI               */
-#define  ESPCFG3_FCLK  0x01            /*      Fast Clock (>25Mhz)     */
index ba7ab77..90118be 100644 (file)
@@ -1,7 +1,8 @@
 /*     $NetBSD: espvar.h,v 1.16 1996/10/13 02:59:50 christos Exp $     */
 
 /*
- * Copyright (c) 1994 Peter Galbavy.  All rights reserved.
+ * Copyright (c) 1997 Allen Briggs.
+ * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <machine/param.h>
-
-#if defined(__sparc__) && !defined(SPARC_DRIVER)
-#define        SPARC_DRIVER
-#else
-#if (_MACHINE == mac68k) && !defined(MAC68K_DRIVER)
-#define        MAC68K_DRIVER
-#endif
-#endif
-
-#define ESP_DEBUG              0
-
-#define        ESP_ABORT_TIMEOUT       2000    /* time to wait for abort */
-
-#define FREQTOCCF(freq)        (((freq + 4) / 5))
-
-/* esp revisions */
-#define        ESP100          0x01
-#define        ESP100A         0x02
-#define        ESP200          0x03
-#define        NCR53C94        0x04
-#define        NCR53C96        0x05
-
-/*
- * ECB. Holds additional information for each SCSI command Comments: We
- * need a separate scsi command block because we may need to overwrite it
- * with a request sense command.  Basicly, we refrain from fiddling with
- * the scsi_xfer struct (except do the expected updating of return values).
- * We'll generally update: xs->{flags,resid,error,sense,status} and
- * occasionally xs->retries.
- */
-struct esp_ecb {
-       TAILQ_ENTRY(esp_ecb) chain;
-       struct scsi_xfer *xs;   /* SCSI xfer ctrl block from above */
-       int flags;
-#define        ECB_ALLOC       0x01
-#define        ECB_NEXUS       0x02
-#define        ECB_SENSE       0x04
-#define        ECB_ABORT       0x40
-#define        ECB_RESET       0x80
-       int timeout;
-
-       struct scsi_generic cmd;  /* SCSI command block */
-       int      clen;
-       char    *daddr;         /* Saved data pointer */
-       int      dleft;         /* Residue */
-       u_char   stat;          /* SCSI status byte */
-
-#if ESP_DEBUG > 0
-       char trace[1000];
-#endif
-};
-#if ESP_DEBUG > 0
-#define ECB_TRACE(ecb, msg, a, b) do { \
-       const char *f = "[" msg "]"; \
-       int n = strlen((ecb)->trace); \
-       if (n < (sizeof((ecb)->trace)-100)) \
-               sprintf((ecb)->trace + n, f,  a, b); \
-} while(0)
-#else
-#define ECB_TRACE(ecb, msg, a, b)
-#endif
-
-/*
- * Some info about each (possible) target on the SCSI bus.  This should
- * probably have been a "per target+lunit" structure, but we'll leave it at
- * this for now.  Is there a way to reliably hook it up to sc->fordriver??
- */
-struct esp_tinfo {
-       int     cmds;           /* #commands processed */
-       int     dconns;         /* #disconnects */
-       int     touts;          /* #timeouts */
-       int     perrs;          /* #parity errors */
-       int     senses;         /* #request sense commands sent */
-       ushort  lubusy;         /* What local units/subr. are busy? */
-       u_char  flags;
-#define T_NEED_TO_RESET        0x01    /* Should send a BUS_DEV_RESET */
-#define T_NEGOTIATE    0x02    /* (Re)Negotiate synchronous options */
-#define T_BUSY         0x04    /* Target is busy, i.e. cmd in progress */
-#define T_SYNCMODE     0x08    /* sync mode has been negotiated */
-#define T_SYNCHOFF     0x10    /* .. */
-#define T_RSELECTOFF   0x20    /* .. */
-       u_char  period;         /* Period suggestion */
-       u_char  offset;         /* Offset suggestion */
-} tinfo_t;
-
-/* Register a linenumber (for debugging) */
-#define LOGLINE(p)
-
-#define ESP_SHOWECBS   0x01
-#define ESP_SHOWINTS   0x02
-#define ESP_SHOWCMDS   0x04
-#define ESP_SHOWMISC   0x08
-#define ESP_SHOWTRAC   0x10
-#define ESP_SHOWSTART  0x20
-#define ESP_SHOWPHASE  0x40
-#define ESP_SHOWDMA    0x80
-#define ESP_SHOWCCMDS  0x100
-#define ESP_SHOWMSGS   0x200
-
-#ifdef ESP_DEBUG
-extern int esp_debug;
-#define ESP_ECBS(str)  do {if (esp_debug & ESP_SHOWECBS) printf str;} while (0)
-#define ESP_MISC(str)  do {if (esp_debug & ESP_SHOWMISC) printf str;} while (0)
-#define ESP_INTS(str)  do {if (esp_debug & ESP_SHOWINTS) printf str;} while (0)
-#define ESP_TRACE(str) do {if (esp_debug & ESP_SHOWTRAC) printf str;} while (0)
-#define ESP_CMDS(str)  do {if (esp_debug & ESP_SHOWCMDS) printf str;} while (0)
-#define ESP_START(str) do {if (esp_debug & ESP_SHOWSTART) printf str;}while (0)
-#define ESP_PHASE(str) do {if (esp_debug & ESP_SHOWPHASE) printf str;}while (0)
-#define ESP_DMA(str)   do {if (esp_debug & ESP_SHOWDMA) printf str;}while (0)
-#define ESP_MSGS(str)  do {if (esp_debug & ESP_SHOWMSGS) printf str;}while (0)
-#else
-#define ESP_ECBS(str)
-#define ESP_MISC(str)
-#define ESP_INTS(str)
-#define ESP_TRACE(str)
-#define ESP_CMDS(str)
-#define ESP_START(str)
-#define ESP_PHASE(str)
-#define ESP_DMA(str)
-#define ESP_MSGS(str)
-#endif
-
-#define ESP_MAX_MSG_LEN 8
-
 struct esp_softc {
-       struct device sc_dev;                   /* us as a device */
-#ifdef SPARC_DRIVER
-       struct sbusdev sc_sd;                   /* sbus device */
-       struct intrhand sc_ih;                  /* intr handler */
-#endif
-       struct evcnt sc_intrcnt;                /* intr count */
-       struct scsi_link sc_link;               /* scsi lint struct */
-#ifdef SPARC_DRIVER
-       volatile u_char *sc_reg;                /* the registers */
-       struct dma_softc *sc_dma;               /* pointer to my dma */
-#else
-#ifdef MAC68K_DRIVER
-       volatile u_char *sc_reg;                /* the registers */
-       struct dma_softc _sc_dma;               /* my (fake) DMA structure */
-       struct dma_softc *sc_dma;               /* pointer to my (fake) DMA */
-       u_char          irq_mask;               /* mask for clearing IRQ */
-#else
-       volatile u_int32_t *sc_reg;             /* the registers */
-       struct tcds_slotconfig *sc_dma;         /* DMA/slot info lives here. */
-       void    *sc_cookie;                     /* intr. handling cookie */
-#endif
-#endif
-
-       /* register defaults */
-       u_char  sc_cfg1;                        /* Config 1 */
-       u_char  sc_cfg2;                        /* Config 2, not ESP100 */
-       u_char  sc_cfg3;                        /* Config 3, only ESP200 */
-       u_char  sc_ccf;                         /* Clock Conversion */
-       u_char  sc_timeout;
-
-       /* register copies, see espreadregs() */
-       u_char  sc_espintr;
-       u_char  sc_espstat;
-       u_char  sc_espstep;
-       u_char  sc_espfflags;
-
-       /* Lists of command blocks */
-       TAILQ_HEAD(ecb_list, esp_ecb) free_list,
-                                     ready_list,
-                                     nexus_list;
+       struct ncr53c9x_softc   sc_ncr53c9x;    /* glue to MI code */
 
-       struct esp_ecb *sc_nexus;               /* current command */
-       struct esp_ecb sc_ecb[8];               /* one per target */
-       struct esp_tinfo sc_tinfo[8];
-
-       /* Data about the current nexus (updated for every cmd switch) */
-       caddr_t sc_dp;                          /* Current data pointer */
-       ssize_t sc_dleft;                       /* Data left to transfer */
+       volatile u_char *sc_reg;                /* the registers */
 
-       /* Adapter state */
-       int     sc_phase;               /* Copy of what bus phase we are in */
-       int     sc_prevphase;           /* Copy of what bus phase we were in */
-       u_char  sc_state;               /* State applicable to the adapter */
-       u_char  sc_flags;
-       u_char  sc_selid;
-       u_char  sc_lastcmd;
+       u_char          irq_mask;               /* mask for clearing IRQ */
 
-       /* Message stuff */
-       u_char  sc_msgpriq;     /* One or more messages to send (encoded) */
-       u_char  sc_msgout;      /* What message is on its way out? */
-       u_char  sc_msgoutq;     /* What messages have been sent so far? */
-       u_char  sc_omess[ESP_MAX_MSG_LEN];
-       caddr_t sc_omp; /* Message pointer (for multibyte messages) */
-       size_t  sc_omlen;
-       u_char  sc_imess[ESP_MAX_MSG_LEN + 1];
-       caddr_t sc_imp; /* Message pointer (for multibyte messages) */
-       size_t  sc_imlen;
+       int             sc_active;              /* Pseudo-DMA state vars */
+       int             sc_tc;
+       int             sc_datain;
+       size_t          sc_dmasize;
+       size_t          sc_dmatrans;
+       char            **sc_dmaaddr;
+       size_t          *sc_pdmalen;
 
-       /* hardware/openprom stuff */
-       int sc_node;                            /* PROM node ID */
-       int sc_freq;                            /* Freq in HZ */
-#ifdef SPARC_DRIVER
-       int sc_pri;                             /* SBUS priority */
-#endif
-       int sc_id;                              /* our scsi id */
-       int sc_rev;                             /* esp revision */
-       int sc_minsync;                         /* minimum sync period / 4 */
-       int sc_maxxfer;                         /* maximum transfer size */
 };
-
-/* values for sc_state */
-#define ESP_IDLE       1       /* waiting for something to do */
-#define ESP_SELECTING  2       /* SCSI command is arbiting  */
-#define ESP_RESELECTED 3       /* Has been reselected */
-#define ESP_CONNECTED  4       /* Actively using the SCSI bus */
-#define        ESP_DISCONNECT  5       /* MSG_DISCONNECT received */
-#define        ESP_CMDCOMPLETE 6       /* MSG_CMDCOMPLETE received */
-#define        ESP_CLEANING    7
-#define ESP_SBR                8       /* Expect a SCSI RST because we commanded it */
-
-/* values for sc_flags */
-#define ESP_DROP_MSGI  0x01    /* Discard all msgs (parity err detected) */
-#define ESP_ABORTING   0x02    /* Bailing out */
-#define ESP_DOINGDMA   0x04    /* The FIFO data path is active! */
-#define ESP_SYNCHNEGO  0x08    /* Synch negotiation in progress. */
-#define ESP_ICCS       0x10    /* Expect status phase results */
-#define ESP_WAITI      0x20    /* Waiting for non-DMA data to arrive */
-#define        ESP_ATN         0x40    /* ATN asserted */
-
-/* values for sc_msgout */
-#define SEND_DEV_RESET         0x01
-#define SEND_PARITY_ERROR      0x02
-#define SEND_INIT_DET_ERR      0x04
-#define SEND_REJECT            0x08
-#define SEND_IDENTIFY                  0x10
-#define SEND_ABORT             0x20
-#define SEND_SDTR              0x40
-#define SEND_WDTR              0x80
-
-/* SCSI Status codes */
-#define ST_MASK                        0x3e /* bit 0,6,7 is reserved */
-
-/* phase bits */
-#define IOI                    0x01
-#define CDI                    0x02
-#define MSGI                   0x04
-
-/* Information transfer phases */
-#define DATA_OUT_PHASE         (0)
-#define DATA_IN_PHASE          (IOI)
-#define COMMAND_PHASE          (CDI)
-#define STATUS_PHASE           (CDI|IOI)
-#define MESSAGE_OUT_PHASE      (MSGI|CDI)
-#define MESSAGE_IN_PHASE       (MSGI|CDI|IOI)
-
-#define PHASE_MASK             (MSGI|CDI|IOI)
-
-/* Some pseudo phases for getphase()*/
-#define BUSFREE_PHASE          0x100   /* Re/Selection no longer valid */
-#define INVALID_PHASE          0x101   /* Re/Selection valid, but no REQ yet */
-#define PSEUDO_PHASE           0x100   /* "pseudo" bit */
-
-/*
- * Macros to read and write the chip's registers.
- */
-#ifdef SPARC_DRIVER
-#define        ESP_READ_REG(sc, reg)                   \
-       ((sc)->sc_reg[(reg) * 4])
-#define        ESP_WRITE_REG(sc, reg, val)             \
-       do {                                    \
-               u_char v = (val);               \
-               (sc)->sc_reg[(reg) * 4] = v;    \
-       } while (0)
-#else /* ! SPARC_DRIVER */
-#ifdef MAC68K_DRIVER
-#define        ESP_READ_REG(sc, reg)                   \
-       ((sc)->sc_reg[(reg) * 16])
-#define        ESP_WRITE_REG(sc, reg, val)             \
-       do {                                    \
-               u_char v = (val);               \
-               (sc)->sc_reg[(reg) * 16] = v;   \
-       } while (0)
-#else
-#if 1
-static inline u_char
-ESP_READ_REG(sc, reg)
-       struct esp_softc *sc;
-       int reg;
-{
-       u_char v;
-
-       v = sc->sc_reg[reg * 2] & 0xff;
-       alpha_mb();
-       return v;
-}
-#else
-#define        ESP_READ_REG(sc, reg)                   \
-       ((u_char)((sc)->sc_reg[(reg) * 2] & 0xff))
-#endif
-#define        ESP_WRITE_REG(sc, reg, val)             \
-       do {                                    \
-               u_char v = (val);               \
-               (sc)->sc_reg[(reg) * 2] = v;    \
-               alpha_mb();                     \
-       } while (0)
-#endif /* MAC68K_DRIVER */
-#endif /* SPARC_DRIVER */
-
-#ifdef ESP_DEBUG
-#define        ESPCMD(sc, cmd) do {                            \
-       if (esp_debug & ESP_SHOWCCMDS)                  \
-               printf("<cmd:0x%x>", (unsigned)cmd);    \
-       sc->sc_lastcmd = cmd;                           \
-       ESP_WRITE_REG(sc, ESP_CMD, cmd);                \
-} while (0)
-#else
-#define        ESPCMD(sc, cmd)         ESP_WRITE_REG(sc, ESP_CMD, cmd)
-#endif
-
-#define SAME_ESP(sc, bp, ca) \
-       ((bp->val[0] == ca->ca_slot && bp->val[1] == ca->ca_offset) || \
-        (bp->val[0] == -1 && bp->val[1] == sc->sc_dev.dv_unit))
-
-#ifndef SPARC_DRIVER
-
-#ifdef MAC68K_DRIVER
-
-/* DMA macros for ESP */
-#define DMA_ISINTR(sc)         (ESP_READ_REG((sc)->sc_esp, ESP_STAT) & 0x80)
-#define DMA_RESET(sc)          do { (sc)->sc_active = 0; \
-                                    (sc)->sc_tc = 0;} while(0)
-#define DMA_INTR(sc)           dma_intr(sc)
-#define DMA_SETUP(sc, paddr, plen, datain, pdmasize)   \
-       do { \
-               (sc)->sc_dmaaddr = paddr; \
-               (sc)->sc_pdmalen = plen; \
-               (sc)->sc_datain = datain; \
-               (sc)->sc_dmasize = *pdmasize; \
-               (sc)->sc_tc = 0; \
-       } while (0)
-
-#define DMA_GO(sc) \
-       do { \
-               if ((sc)->sc_datain == 0) { \
-                       ESP_WRITE_REG((sc)->sc_esp, \
-                                       ESP_FIFO, **(sc)->sc_dmaaddr); \
-                       (*(sc)->sc_pdmalen)--; \
-                       (*(sc)->sc_dmaaddr)++; \
-               } \
-               (sc)->sc_active = 1; \
-       } while (0)
-
-#define DMA_ISACTIVE(sc)       ((sc)->sc_active)
-
-#else MAC68K_DRIVER
-
-/* DMA macros for ESP */
-#define        DMA_ISINTR(sc)          tcds_dma_isintr(sc)
-#define        DMA_RESET(sc)           tcds_dma_reset(sc)
-#define        DMA_INTR(sc)            tcds_dma_intr(sc)
-#define        DMA_SETUP(sc, addr, len, datain, dmasize) \
-                               tcds_dma_setup(sc, addr, len, datain, dmasize)
-#define        DMA_GO(sc)              tcds_dma_go(sc)
-#define        DMA_ISACTIVE(sc)        tcds_dma_isactive(sc)
-
-#endif /* MAC68K_DRIVER */
-#endif /* SPARC_DRIVER */