Forgotten files from NetBSD merge
authorniklas <niklas@openbsd.org>
Sun, 8 Dec 1996 14:13:08 +0000 (14:13 +0000)
committerniklas <niklas@openbsd.org>
Sun, 8 Dec 1996 14:13:08 +0000 (14:13 +0000)
sys/dev/tc/asc_ioasic.c [new file with mode: 0644]
sys/dev/tc/asc_tc.c [new file with mode: 0644]
sys/dev/tc/ascvar.h [new file with mode: 0644]

diff --git a/sys/dev/tc/asc_ioasic.c b/sys/dev/tc/asc_ioasic.c
new file mode 100644 (file)
index 0000000..14c6e98
--- /dev/null
@@ -0,0 +1,244 @@
+/*     $NetBSD: asc_ioasic.c,v 1.3 1996/10/13 01:38:36 christos Exp $  */
+
+/*
+ * Copyright 1996 The Board of Trustees of The Leland Stanford
+ * Junior University. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies.  Stanford University
+ * makes no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without
+ * express or implied warranty.
+ *
+ */
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <dev/tc/tcvar.h>
+#include <dev/tc/ioasicvar.h>
+#include <machine/autoconf.h>
+
+#include <pmax/dev/device.h>   /* XXX */
+#include <pmax/dev/scsi.h>     /* XXX */
+
+#include <pmax/dev/ascreg.h>   /* XXX */
+#include <dev/tc/ascvar.h>
+
+#include <mips/locore.h> /* XXX XXX bus.h needs cache-consistency*/
+
+/*XXX*/
+#include <pmax/pmax/asic.h>            /* XXX ioasic register defs? */
+#include <pmax/pmax/kmin.h>    /* XXX ioasic register defs? */
+#include <pmax/pmax/pmaxtype.h>
+extern int pmax_boardtype;
+
+
+/*
+ * Autoconfiguration data for config.
+ */
+int asc_ioasic_match __P((struct device *, void *, void *));
+void asc_ioasic_attach __P((struct device *, struct device *, void *));
+
+struct cfattach asc_ioasic_ca = {
+       sizeof(struct asc_softc), asc_ioasic_match, asc_ioasic_attach
+};
+
+/*
+ * DMA callback declarations
+ */
+
+extern u_long asc_iomem;
+static void
+asic_dma_start __P((asc_softc_t asc, State *state, caddr_t cp, int flag));
+
+static void
+asic_dma_end __P((asc_softc_t asc, State *state, int flag));
+
+int
+asc_ioasic_match(parent, match, aux)
+       struct device *parent;
+       void *match;
+       void *aux;
+{
+       struct ioasicdev_attach_args *d = aux;
+       void *ascaddr;
+
+       if (strncmp(d->iada_modname, "asc", TC_ROM_LLEN) &&
+           strncmp(d->iada_modname, "PMAZ-AA ", TC_ROM_LLEN))
+               return (0);
+
+       /* probe for chip */
+       ascaddr = (void*)d->iada_addr;
+       if (tc_badaddr(ascaddr + ASC_OFFSET_53C94))
+               return (0);
+
+       return (1);
+}
+
+void
+asc_ioasic_attach(parent, self, aux)
+       struct device *parent;
+       struct device *self;
+       void *aux;
+{
+       register struct ioasicdev_attach_args *d = aux;
+       register asc_softc_t asc = (asc_softc_t) self;
+       int bufsiz, speed;
+
+       void *ascaddr;
+       int unit;
+
+       ascaddr = (void*)MACH_PHYS_TO_UNCACHED(d->iada_addr);
+       unit = asc->sc_dev.dv_unit;
+       
+       /*
+        * Initialize hw descriptor, cache some pointers
+        */
+       asc->regs = (asc_regmap_t *)(ascaddr + ASC_OFFSET_53C94);
+
+       /*
+        * Set up machine dependencies.
+        * (1) how to do dma
+        * (2) timing based on turbochannel frequency
+        */
+
+       asc->buff = (u_char *)MACH_PHYS_TO_UNCACHED(asc_iomem);
+       bufsiz = 8192;
+       *((volatile int *)IOASIC_REG_SCSI_DMAPTR(ioasic_base)) = -1;
+       *((volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base)) = -1;
+       *((volatile int *)IOASIC_REG_SCSI_SCR(ioasic_base)) = 0;
+       asc->dma_start = asic_dma_start;
+       asc->dma_end = asic_dma_end;
+
+       /*
+        * Now for timing. The 3max has a 25Mhz tb whereas the 3min and
+        * maxine are 12.5Mhz.
+        */
+
+       /*printf(" (bus speed: %d) ", t->ta_busspeed);*/
+       /* XXX don't these run at 25MHz on any ioasic??*/
+       switch (pmax_boardtype) {
+       case DS_3MAX:
+       case DS_3MAXPLUS:
+               speed = ASC_SPEED_25_MHZ;
+               break;
+       case DS_3MIN:
+       case DS_MAXINE:
+       default:
+               speed = ASC_SPEED_12_5_MHZ;
+               break;
+       };
+
+       ascattach(asc, bufsiz, speed);
+
+       /* tie pseudo-slot to device */
+
+       ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_BIO,
+                             asc_intr, asc);
+}
+
+
+/*
+ * DMA handling routines. For a turbochannel device, just set the dmar.
+ * For the I/O ASIC, handle the actual DMA interface.
+ */
+static void
+asic_dma_start(asc, state, cp, flag)
+       asc_softc_t asc;
+       State *state;
+       caddr_t cp;
+       int flag;
+{
+       register volatile u_int *ssr = (volatile u_int *)
+               IOASIC_REG_CSR(ioasic_base);
+       u_int phys, nphys;
+
+       /* stop DMA engine first */
+       *ssr &= ~IOASIC_CSR_DMAEN_SCSI;
+       *((volatile int *)IOASIC_REG_SCSI_SCR(ioasic_base)) = 0;
+
+       phys = MACH_CACHED_TO_PHYS(cp);
+       cp = (caddr_t)mips_trunc_page(cp + NBPG);
+       nphys = MACH_CACHED_TO_PHYS(cp);
+
+       asc->dma_next = cp;
+       asc->dma_xfer = state->dmalen - (nphys - phys);
+
+       *(volatile int *)IOASIC_REG_SCSI_DMAPTR(ioasic_base) =
+               IOASIC_DMA_ADDR(phys);
+       *(volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base) =
+               IOASIC_DMA_ADDR(nphys);
+       if (flag == ASCDMA_READ)
+               *ssr |= IOASIC_CSR_SCSI_DIR | IOASIC_CSR_DMAEN_SCSI;
+       else
+               *ssr = (*ssr & ~IOASIC_CSR_SCSI_DIR) | IOASIC_CSR_DMAEN_SCSI;
+       wbflush();
+}
+
+static void
+asic_dma_end(asc, state, flag)
+       asc_softc_t asc;
+       State *state;
+       int flag;
+{
+       register volatile u_int *ssr = (volatile u_int *)
+               IOASIC_REG_CSR(ioasic_base);
+       register volatile u_int *dmap = (volatile u_int *)
+               IOASIC_REG_SCSI_DMAPTR(ioasic_base);
+       register u_short *to;
+       register int w;
+       int nb;
+
+       *ssr &= ~IOASIC_CSR_DMAEN_SCSI;
+       to = (u_short *)MACH_PHYS_TO_CACHED(*dmap >> 3);
+       *dmap = -1;
+       *((volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base)) = -1;
+       wbflush();
+
+       if (flag == ASCDMA_READ) {
+               MachFlushDCache(MACH_PHYS_TO_CACHED(
+                   MACH_UNCACHED_TO_PHYS(state->dmaBufAddr)), state->dmalen);
+               if ( (nb = *((int *)IOASIC_REG_SCSI_SCR(ioasic_base))) != 0) {
+                       /* pick up last upto6 bytes, sigh. */
+       
+                       /* Last byte really xferred is.. */
+                       w = *(int *)IOASIC_REG_SCSI_SDR0(ioasic_base);
+                       *to++ = w;
+                       if (--nb > 0) {
+                               w >>= 16;
+                               *to++ = w;
+                       }
+                       if (--nb > 0) {
+                               w = *(int *)IOASIC_REG_SCSI_SDR1(ioasic_base);
+                               *to++ = w;
+                       }
+               }
+       }
+}
+
+#ifdef notdef
+/*
+ * Called by asic_intr() for scsi dma pointer update interrupts.
+ */
+void
+asc_dma_intr()
+{
+       asc_softc_t asc =  &asc_cd.cd_devs[0]; /*XXX*/
+       u_int next_phys;
+
+       asc->dma_xfer -= NBPG;
+       if (asc->dma_xfer <= -NBPG) {
+               volatile u_int *ssr = (volatile u_int *)
+                       IOASIC_REG_CSR(ioasic_base);
+               *ssr &= ~IOASIC_CSR_DMAEN_SCSI;
+       } else {
+               asc->dma_next += NBPG;
+               next_phys = MACH_CACHED_TO_PHYS(asc->dma_next);
+       }
+       *(volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base) =
+               IOASIC_DMA_ADDR(next_phys);
+       wbflush();
+}
+#endif /*notdef*/
diff --git a/sys/dev/tc/asc_tc.c b/sys/dev/tc/asc_tc.c
new file mode 100644 (file)
index 0000000..42417f1
--- /dev/null
@@ -0,0 +1,167 @@
+/*     $NetBSD: asc_tc.c,v 1.4 1996/10/13 01:38:37 christos Exp $      */
+
+/*
+ * Copyright 1996 The Board of Trustees of The Leland Stanford
+ * Junior University. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies.  Stanford University
+ * makes no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without
+ * express or implied warranty.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <dev/tc/tcvar.h>
+#include <machine/autoconf.h>
+#include <dev/tc/ioasicvar.h>
+
+#include <pmax/dev/device.h>   /* XXX */
+#include <pmax/dev/scsi.h>     /* XXX */
+
+#include <pmax/dev/ascreg.h>   /* XXX */
+#include <dev/tc/ascvar.h>
+
+/*XXX*/
+
+
+/*
+ * Autoconfiguration data for config.
+ */
+int asc_tc_match __P((struct device *, void *, void *));
+void asc_tc_attach __P((struct device *, struct device *, void *));
+
+struct cfattach asc_tc_ca = {
+       sizeof(struct asc_softc), asc_tc_match, asc_tc_attach
+};
+
+/*
+ * DMA callbacks
+ */
+
+static void
+tc_dma_start __P((struct asc_softc *asc, struct scsi_state *state,
+                 caddr_t cp, int flag));
+
+static void
+tc_dma_end __P((struct asc_softc *asc, struct scsi_state *state,
+               int flag));
+
+
+int
+asc_tc_match(parent, match, aux)
+       struct device *parent;
+       void *match;
+       void *aux;
+{
+       struct tc_attach_args *t = aux;
+       void *ascaddr;
+
+       if (strncmp(t->ta_modname, "PMAZ-AA ", TC_ROM_LLEN))
+               return (0);
+
+       ascaddr = (void*)t->ta_addr;
+
+       if (tc_badaddr(ascaddr + ASC_OFFSET_53C94))
+               return (0);
+
+       return (1);
+}
+
+
+
+void
+asc_tc_attach(parent, self, aux)
+       struct device *parent;
+       struct device *self;
+       void *aux;
+{
+       register struct tc_attach_args *t = aux;
+       register asc_softc_t asc = (asc_softc_t) self;
+       int bufsiz, speed;
+
+       void *ascaddr;
+       int unit;
+
+       ascaddr = (void*)MACH_PHYS_TO_UNCACHED(t->ta_addr);
+       unit = asc->sc_dev.dv_unit;
+       
+       /*
+        * Initialize hw descriptor, cache some pointers
+        */
+       asc->regs = (asc_regmap_t *)(ascaddr + ASC_OFFSET_53C94);
+
+       /*
+        * Set up machine dependencies.
+        * (1) how to do dma
+        * (2) timing based on turbochannel frequency
+        */
+
+       /*
+        * Fall through for turbochannel option.
+        */
+       asc->dmar = (volatile int *)(ascaddr + ASC_OFFSET_DMAR);
+       asc->buff = (u_char *)(ascaddr + ASC_OFFSET_RAM);
+       bufsiz = PER_TGT_DMA_SIZE;
+       asc->dma_start = tc_dma_start;
+       asc->dma_end = tc_dma_end;
+
+       /*
+        * Now for timing. The 3max has a 25Mhz tb whereas the 3min and
+        * maxine are 12.5Mhz.
+        */
+       printf(" (bus speed: %d) ", t->ta_busspeed);
+
+       switch (t->ta_busspeed) {
+       case TC_SPEED_25_MHZ:
+               speed = ASC_SPEED_25_MHZ;
+               break;
+
+       default:
+               printf(" (unknown TC speed, assuming 12.5MHz) ");
+               /* FALLTHROUGH*/
+       case TC_SPEED_12_5_MHZ:
+               speed = ASC_SPEED_12_5_MHZ;
+               break;
+       };
+
+       ascattach(asc, bufsiz, speed);
+
+       /* tie pseudo-slot to device */
+       tc_intr_establish(parent, t->ta_cookie, TC_IPL_BIO,
+                         asc_intr, asc);
+}
+
+
+/*
+ * DMA handling routines. For a turbochannel device, just set the dmar.
+ * For the I/O ASIC, handle the actual DMA interface.
+ */
+static void
+tc_dma_start(asc, state, cp, flag)
+       asc_softc_t asc;
+       State *state;
+       caddr_t cp;
+       int flag;
+{
+
+       if (flag == ASCDMA_WRITE)
+               *asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(cp);
+       else
+               *asc->dmar = ASC_DMA_ADDR(cp);
+}
+
+static void
+tc_dma_end(asc, state, flag)
+       asc_softc_t asc;
+       State *state;
+       int flag;
+{
+
+}
diff --git a/sys/dev/tc/ascvar.h b/sys/dev/tc/ascvar.h
new file mode 100644 (file)
index 0000000..966d048
--- /dev/null
@@ -0,0 +1,92 @@
+/*     $NetBSD: ascvar.h,v 1.1 1996/09/25 21:07:56 jonathan Exp $      */
+
+
+/*
+ * State kept for each active SCSI device.
+ */
+struct script;
+
+typedef struct scsi_state {
+       struct script *script;  /* saved script while processing error */
+       int     statusByte;     /* status byte returned during STATUS_PHASE */
+       int     error;          /* errno to pass back to device driver */
+       u_char  *dmaBufAddr;    /* DMA buffer address */
+       u_int   dmaBufSize;     /* DMA buffer size */
+       int     dmalen;         /* amount to transfer in this chunk */
+       int     dmaresid;       /* amount not transfered if chunk suspended */
+       int     buflen;         /* total remaining amount of data to transfer */
+       char    *buf;           /* current pointer within scsicmd->buf */
+       int     flags;          /* see below */
+       int     msglen;         /* number of message bytes to read */
+       int     msgcnt;         /* number of message bytes received */
+       u_char  sync_period;    /* DMA synchronous period */
+       u_char  sync_offset;    /* DMA synchronous xfer offset or 0 if async */
+       u_char  msg_out;        /* next MSG_OUT byte to send */
+       u_char  msg_in[16];     /* buffer for multibyte messages */
+} State;
+
+/* state flags */
+#define DISCONN                0x001   /* true if currently disconnected from bus */
+#define DMA_IN_PROGRESS        0x002   /* true if data DMA started */
+#define DMA_IN         0x004   /* true if reading from SCSI device */
+#define DMA_OUT                0x010   /* true if writing to SCSI device */
+#define DID_SYNC       0x020   /* true if synchronous offset was negotiated */
+#define TRY_SYNC       0x040   /* true if try neg. synchronous offset */
+#define PARITY_ERR     0x080   /* true if parity error seen */
+#define CHECK_SENSE    0x100   /* true if doing sense command */
+
+
+/*
+ * State kept for each active SCSI host interface (53C94).
+ */
+
+struct asc_softc {
+       struct device sc_dev;                   /* us as a device */
+       asc_regmap_t    *regs;          /* chip address */
+       volatile int    *dmar;          /* DMA address register address */
+       u_char          *buff;          /* RAM buffer address (uncached) */
+       int             sc_id;          /* SCSI ID of this interface */
+       int             myidmask;       /* ~(1 << myid) */
+       int             state;          /* current SCSI connection state */
+       int             target;         /* target SCSI ID if busy */
+       struct script   *script;        /* next expected interrupt & action */
+       ScsiCmd         *cmd[ASC_NCMD]; /* active command indexed by SCSI ID */
+       State           st[ASC_NCMD];   /* state info for each active command */
+       /* Start dma routine */
+       void  (*dma_start) __P((struct asc_softc *asc,
+                               struct scsi_state *state,
+                               caddr_t cp, int flag));
+       /* End dma routine */
+       void    (*dma_end) __P((struct asc_softc *asc,
+                               struct scsi_state *state, int flag));
+
+       u_char          *dma_next;
+       int             dma_xfer;       /* Dma len still to go */
+       int             min_period;     /* Min transfer period clk/byte */
+       int             max_period;     /* Max transfer period clk/byte */
+       int             ccf;            /* CCF, whatever that really is? */
+       int             timeout_250;    /* 250ms timeout */
+       int             tb_ticks;       /* 4ns. ticks/tb channel ticks */
+#ifdef USE_NEW_SCSI
+       struct scsi_link sc_link;               /* scsi link struct */
+#endif
+};
+typedef struct asc_softc *asc_softc_t;
+
+#define        ASC_STATE_IDLE          0       /* idle state */
+#define        ASC_STATE_BUSY          1       /* selecting or currently connected */
+#define ASC_STATE_TARGET       2       /* currently selected as target */
+#define ASC_STATE_RESEL                3       /* currently waiting for reselect */
+
+
+#define ASC_SPEED_25_MHZ       250
+#define ASC_SPEED_12_5_MHZ     125
+
+void   ascattach __P((struct asc_softc *asc, int dmabufsiz, int bus_speed));
+int    asc_intr __P ((void *asc));
+
+/*
+ * Dma operations.
+ */
+#define        ASCDMA_READ     1
+#define        ASCDMA_WRITE    2