summaryrefslogtreecommitdiff
path: root/sys/arch/pmax/dev/sii.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/pmax/dev/sii.c')
-rw-r--r--sys/arch/pmax/dev/sii.c179
1 files changed, 107 insertions, 72 deletions
diff --git a/sys/arch/pmax/dev/sii.c b/sys/arch/pmax/dev/sii.c
index 4cd2086dd7b..e0d310d8f1a 100644
--- a/sys/arch/pmax/dev/sii.c
+++ b/sys/arch/pmax/dev/sii.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sii.c,v 1.8 1995/09/13 19:35:58 jonathan Exp $ */
+/* $NetBSD: sii.c,v 1.12.4.2 1996/09/09 20:24:36 thorpej Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -118,9 +118,14 @@ int sii_doprobe __P((void *addr, int unit, int flags, int pri,
struct device *self));
int siiintr __P((void *sc));
-extern struct cfdriver siicd;
-struct cfdriver siicd = {
- NULL, "sii", siimatch, siiattach, DV_DULL, sizeof(struct siisoftc)
+extern struct cfdriver sii_cd;
+
+struct cfattach sii_ca = {
+ sizeof(struct siisoftc), siimatch, siiattach
+};
+
+struct cfdriver sii_cd = {
+ NULL, "sii", DV_DULL
};
#ifdef USE_NEW_SCSI
@@ -145,13 +150,15 @@ struct scsi_device sii_dev = {
#endif
/*
- * Definition of the controller for the old auto-configuration program.
+ * Definition of the controller for the old auto-configuration program
+ * and old-style pmax scsi drivers.
*/
void siistart();
struct pmax_driver siidriver = {
"sii", NULL, siistart, 0,
};
+
/*
* MACROS for timing out spin loops.
*
@@ -208,14 +215,29 @@ u_char sii_buf[256]; /* used for extended messages */
#define SII_BUF_ADDR (MACH_PHYS_TO_UNCACHED(KN01_SYS_SII_B_START) \
+ SII_MAX_DMA_XFER_LENGTH * 14)
-static void sii_Reset();
-static void sii_StartCmd();
-static void sii_CmdDone();
-static void sii_DoIntr();
-static void sii_StateChg();
-static void sii_DoSync();
-static void sii_StartDMA();
-static int sii_GetByte();
+
+/*
+ * Other forward references
+ */
+
+static void sii_Reset __P((register struct siisoftc *sc, int resetbus));
+static void sii_StartCmd __P((register struct siisoftc *sc, int target));
+static void sii_CmdDone __P((register struct siisoftc *sc, int target,
+ int error));
+static void sii_DoIntr __P((register struct siisoftc *sc, u_int dstat));
+static void sii_StateChg __P((register struct siisoftc *sc, u_int cstat));
+static int sii_GetByte __P((register SIIRegs *regs, int phase, int ack));
+static void sii_DoSync __P((register SIIRegs *regs, register State *state));
+static void sii_StartDMA __P((register SIIRegs *regs, int phase,
+ u_short *dmaAddr, int size));
+
+void siistart __P((register ScsiCmd *scsicmd));
+void sii_DumpLog __P((void));
+
+void CopyToBuffer __P((u_short *src, /* NOTE: must be short aligned */
+ volatile u_short *dst, int length));
+void CopyFromBuffer __P((volatile u_short *src, char *dst, int length));
+
/*
@@ -227,14 +249,20 @@ siimatch(parent, match, aux)
void *match;
void *aux;
{
- struct cfdata *cf = match;
struct confargs *ca = aux;
- if (!BUS_MATCHNAME(ca, "sii") && !BUS_MATCHNAME(ca, "PMAZ-AA "))
+ if (strcmp(ca->ca_name, "sii") != 0 &&
+ strncmp(ca->ca_name, "PMAZ-AA ", 8) != 0) /*XXX*/
return (0);
/* XXX check for bad address */
- /* XXX kn01s have exactly one SII. Does any other machine use them? */
+ /*
+ * XXX KN01s (3100/2100) have exactly one SII.
+ * the Decsystem 5100 apparently uses them also, but as yet we
+ * don't know at what address.
+ *
+ * XXX PVAXES apparently use the SII also.
+ */
return (1);
}
@@ -249,7 +277,7 @@ siiattach(parent, self, aux)
register void *siiaddr;
register int i;
- siiaddr = (void*)MACH_PHYS_TO_UNCACHED(BUS_CVTADDR(ca));
+ siiaddr = (void*)MACH_PHYS_TO_UNCACHED(ca->ca_addr);
sc->sc_regs = (SIIRegs *)siiaddr;
sc->sc_flags = sc->sc_dev.dv_cfdata->cf_flags;
@@ -288,7 +316,7 @@ siistart(scsicmd)
register ScsiCmd *scsicmd; /* command to start */
{
register struct pmax_scsi_device *sdp = scsicmd->sd;
- register struct siisoftc *sc = siicd.cd_devs[sdp->sd_ctlr];
+ register struct siisoftc *sc = sii_cd.cd_devs[sdp->sd_ctlr];
int s;
s = splbio();
@@ -324,8 +352,12 @@ siiintr(xxxsc)
* Find which controller caused the interrupt.
*/
dstat = sc->sc_regs->dstat;
- if (dstat & (SII_CI | SII_DI))
+ if (dstat & (SII_CI | SII_DI)) {
sii_DoIntr(sc, dstat);
+ return (0); /* XXX */
+ }
+
+ return (1); /* XXX spurious interrupt? */
}
/*
@@ -371,7 +403,7 @@ sii_Reset(sc, reset)
* Delay 250 ms before doing any commands.
*/
regs->comm = SII_DO_RST;
- MachEmptyWriteBuffer();
+ wbflush();
DELAY(250000);
/* rearbitrate synchronous offset */
@@ -389,7 +421,7 @@ sii_Reset(sc, reset)
* Reselect Enable, and Interrupt Enable.
*/
regs->csr = SII_HPM | SII_RSE | SII_PCE | SII_IE;
- MachEmptyWriteBuffer();
+ wbflush();
}
/*
@@ -436,7 +468,7 @@ sii_StartCmd(sc, target)
#ifdef DEBUG
if (sii_debug > 1) {
- printf("sii_StartCmd: %s target %d cmd 0x%x addr %x size %d dma %d\n",
+ printf("sii_StartCmd: %s target %d cmd 0x%x addr %p size %d dma %d\n",
scsicmd->sd->sd_driver->d_name, target,
scsicmd->cmd[0], scsicmd->buf, scsicmd->buflen,
state->dmaDataPhase);
@@ -504,7 +536,7 @@ sii_StartCmd(sc, target)
regs->comm = SII_INXFER | SII_SELECT | SII_ATN | SII_CON |
SII_MSG_OUT_PHASE;
}
- MachEmptyWriteBuffer();
+ wbflush();
/*
* Wait for something to happen
@@ -517,7 +549,7 @@ sii_StartCmd(sc, target)
if ((status & (SII_RST | SII_SCH | SII_STATE_MSK)) ==
(SII_SCH | SII_CON)) {
regs->cstat = status;
- MachEmptyWriteBuffer();
+ wbflush();
#ifdef DEBUG
sii_logp->target = target;
@@ -586,7 +618,7 @@ sii_StartCmd(sc, target)
if (status & SII_SIP) {
error = ENXIO; /* device didn't respond */
regs->comm = SII_DISCON;
- MachEmptyWriteBuffer();
+ wbflush();
SII_WAIT_UNTIL(status, regs->cstat,
!(status & (SII_CON | SII_SIP)),
SII_WAIT_COUNT, retval);
@@ -601,7 +633,7 @@ sii_StartCmd(sc, target)
regs->cstat = 0xffff;
regs->dstat = 0xffff;
regs->comm = 0;
- MachEmptyWriteBuffer();
+ wbflush();
sii_CmdDone(sc, target, error);
}
@@ -643,7 +675,7 @@ again:
#endif
regs->dstat = dstat; /* acknowledge everything */
- MachEmptyWriteBuffer();
+ wbflush();
if (dstat & SII_CI) {
/* deglitch cstat register */
@@ -651,7 +683,7 @@ again:
while (msg != (cstat = regs->cstat))
msg = cstat;
regs->cstat = cstat; /* acknowledge everything */
- MachEmptyWriteBuffer();
+ wbflush();
#ifdef DEBUG
if (sii_logp > sii_log)
sii_logp[-1].cstat = cstat;
@@ -760,7 +792,7 @@ again:
sii_StartDMA(regs,
state->dmaCurPhase = SII_DATA_IN_PHASE,
state->dmaAddr[state->dmaBufIndex],
- state->dmalen = len);
+ state->dmaCnt = state->dmalen = len);
dstat &= ~(SII_IBF | SII_TBE);
}
/* copy in the data */
@@ -782,7 +814,7 @@ again:
sii_StartDMA(regs, state->dmaCurPhase =
SII_DATA_OUT_PHASE,
state->dmaAddr[state->dmaBufIndex],
- state->dmalen =
+ state->dmaCnt = state->dmalen =
SII_MAX_DMA_XFER_LENGTH);
/* prepare for next chunk */
i -= SII_MAX_DMA_XFER_LENGTH;
@@ -796,7 +828,7 @@ again:
sii_StartDMA(regs, state->dmaCurPhase =
SII_DATA_OUT_PHASE,
state->dmaAddr[state->dmaBufIndex],
- state->dmalen = i);
+ state->dmaCnt = state->dmalen = i);
}
dstat &= ~(SII_IBF | SII_TBE);
}
@@ -846,7 +878,7 @@ again:
regs->dmabyte = state->dmaByte;
regs->comm = SII_DMA | SII_INXFER |
(comm & SII_STATE_MSK) | SII_CMD_PHASE;
- MachEmptyWriteBuffer();
+ wbflush();
#ifdef DEBUG
if (sii_debug > 4)
printf("Cmd dcnt %d dadr %x ",
@@ -867,7 +899,7 @@ again:
i);
sii_StartDMA(regs, state->dmaCurPhase =
SII_CMD_PHASE, state->dmaAddr[0],
- state->dmalen = i);
+ state->dmaCnt = state->dmalen = i);
}
/* wait a short time for XFER complete */
SII_WAIT_UNTIL(dstat, regs->dstat,
@@ -914,7 +946,7 @@ again:
regs->comm = SII_DMA | SII_INXFER |
(comm & SII_STATE_MSK) |
state->dmaCurPhase;
- MachEmptyWriteBuffer();
+ wbflush();
#ifdef DEBUG
if (sii_debug > 4)
printf("Data %d dcnt %d dadr %x ",
@@ -950,7 +982,7 @@ again:
sii_StartDMA(regs,
state->dmaCurPhase = SII_DATA_IN_PHASE,
state->dmaAddr[state->dmaBufIndex],
- state->dmalen = i);
+ state->dmaCnt = state->dmalen = i);
break;
}
/* start first chunk */
@@ -963,7 +995,7 @@ again:
sii_StartDMA(regs,
state->dmaCurPhase = SII_DATA_OUT_PHASE,
state->dmaAddr[state->dmaBufIndex],
- state->dmalen = i);
+ state->dmaCnt = state->dmalen = i);
i = state->buflen - SII_MAX_DMA_XFER_LENGTH;
if (i > 0) {
/* prepare for next chunk */
@@ -996,9 +1028,9 @@ again:
regs->dmlotc = 0;
regs->comm = comm &
(SII_STATE_MSK | SII_PHASE_MSK);
- MachEmptyWriteBuffer();
+ wbflush();
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
#ifdef DEBUG
if (sii_debug > 4)
printf("DMA amt %d ", i);
@@ -1056,20 +1088,22 @@ again:
/* save dma registers */
state->dmaPrevPhase = state->dmaCurPhase;
state->dmaCurPhase = -1;
- state->dmaCnt = i = regs->dmlotc;
if (dstat & SII_OBB)
state->dmaByte = regs->dmabyte;
- if (i == 0)
- i = SII_MAX_DMA_XFER_LENGTH;
- i = state->dmalen - i;
+ i = regs->dmlotc;
+ if (i != 0)
+ i = state->dmaCnt - i;
/* note: no carry from dmaddrl to dmaddrh */
state->dmaAddrL = regs->dmaddrl + i;
state->dmaAddrH = regs->dmaddrh;
+ state->dmaCnt = regs->dmlotc;
+ if (state->dmaCnt == 0)
+ state->dmaCnt = SII_MAX_DMA_XFER_LENGTH;
regs->comm = comm &
(SII_STATE_MSK | SII_PHASE_MSK);
- MachEmptyWriteBuffer();
+ wbflush();
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
#ifdef DEBUG
if (sii_debug > 4) {
printf("SavP dcnt %d dadr %x ",
@@ -1114,7 +1148,7 @@ again:
SII_WAIT_UNTIL(dstat, regs->dstat,
dstat & SII_DNE, SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
msg = sc->sc_target;
sc->sc_target = -1;
/*
@@ -1129,7 +1163,7 @@ again:
SII_STATE_MSK)) == SII_SCH) {
regs->cstat = SII_SCH | SII_BER;
regs->comm = 0;
- MachEmptyWriteBuffer();
+ wbflush();
/*
* Double check that we didn't miss a
* state change between seeing it and
@@ -1155,7 +1189,7 @@ again:
SII_WAIT_UNTIL(dstat, regs->dstat,
dstat & SII_DNE, SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
/* read the message length */
msg = sii_GetByte(regs, SII_MSG_IN_PHASE, 1);
if (msg < 0) {
@@ -1190,7 +1224,7 @@ again:
dstat & SII_DNE,
SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
i = (sii_buf[3] << 24) |
(sii_buf[4] << 16) |
(sii_buf[5] << 8) |
@@ -1213,7 +1247,7 @@ again:
dstat & SII_DNE,
SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
sii_DoSync(regs, state);
break;
@@ -1230,7 +1264,7 @@ again:
dstat & SII_DNE,
SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
/* wait for MSG_OUT phase */
SII_WAIT_UNTIL(dstat, regs->dstat,
@@ -1246,7 +1280,7 @@ again:
dstat & SII_DNE,
SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
}
break;
@@ -1258,7 +1292,7 @@ again:
SII_WAIT_UNTIL(dstat, regs->dstat,
dstat & SII_DNE, SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
/* wait a short time for another msg */
SII_WAIT_UNTIL(dstat, regs->dstat,
dstat & (SII_CI | SII_DI),
@@ -1279,7 +1313,7 @@ again:
SII_WAIT_UNTIL(dstat, regs->dstat,
dstat & SII_DNE, SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
state->prevComm = comm;
#ifdef DEBUG
if (sii_debug > 4)
@@ -1304,7 +1338,7 @@ again:
}
regs->cstat = SII_SCH | SII_BER;
regs->comm = 0;
- MachEmptyWriteBuffer();
+ wbflush();
sc->sc_target = -1;
/*
* Double check that we didn't miss a state
@@ -1324,7 +1358,7 @@ again:
SII_WAIT_UNTIL(dstat, regs->dstat,
dstat & SII_DNE, SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
printf("%s: device %d: message reject.\n",
sc->sc_dev.dv_xname, sc->sc_target);
break;
@@ -1345,7 +1379,7 @@ again:
SII_WAIT_UNTIL(dstat, regs->dstat,
dstat & SII_DNE, SII_WAIT_COUNT, i);
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
/* may want to check LUN some day */
/* wait a short time for another msg */
SII_WAIT_UNTIL(dstat, regs->dstat,
@@ -1380,7 +1414,7 @@ again:
regs->data = SCSI_NO_OP;
regs->comm = SII_INXFER | (comm & SII_STATE_MSK) |
SII_MSG_OUT_PHASE;
- MachEmptyWriteBuffer();
+ wbflush();
/* wait a short time for XFER complete */
SII_WAIT_UNTIL(dstat, regs->dstat, dstat & SII_DNE,
@@ -1392,7 +1426,7 @@ again:
/* just clear the DNE bit and check errors later */
if (dstat & SII_DNE) {
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
}
break;
@@ -1442,7 +1476,7 @@ abort:
regs->data = SCSI_ABORT;
regs->comm = SII_INXFER | SII_ATN | (cstat & SII_STATE_MSK) |
SII_MSG_OUT_PHASE;
- MachEmptyWriteBuffer();
+ wbflush();
SII_WAIT_UNTIL(dstat, regs->dstat,
(dstat & (SII_DNE | SII_PHASE_MSK)) ==
(SII_DNE | SII_MSG_OUT_PHASE),
@@ -1451,11 +1485,11 @@ abort:
if (sii_debug > 0)
printf("Abort: cs %x ds %x i %d\n", cstat, dstat, i);
#endif
- if (dstat & (SII_DNE | SII_PHASE_MSK) ==
+ if ((dstat & (SII_DNE | SII_PHASE_MSK)) ==
(SII_DNE | SII_MSG_OUT_PHASE)) {
/* disconnect if command in progress */
regs->comm = SII_DISCON;
- MachEmptyWriteBuffer();
+ wbflush();
SII_WAIT_UNTIL(cstat, regs->cstat,
!(cstat & SII_CON), SII_WAIT_COUNT, i);
}
@@ -1468,7 +1502,7 @@ abort:
regs->cstat = 0xffff;
regs->dstat = 0xffff;
regs->comm = 0;
- MachEmptyWriteBuffer();
+ wbflush();
i = sc->sc_target;
sc->sc_target = -1;
@@ -1544,7 +1578,7 @@ sii_StateChg(sc, cstat)
state = &sc->sc_st[i];
regs->comm = SII_CON | SII_DST | SII_MSG_IN_PHASE;
regs->dmctrl = state->dmaReqAck;
- MachEmptyWriteBuffer();
+ wbflush();
if (!state->prevComm) {
printf("%s: device %d: spurious reselection\n",
sc->sc_dev.dv_xname, i);
@@ -1564,7 +1598,7 @@ sii_StateChg(sc, cstat)
printf("%s: Selected by device %d as target!!\n",
sc->sc_dev.dv_xname, regs->destat);
regs->comm = SII_DISCON;
- MachEmptyWriteBuffer();
+ wbflush();
SII_WAIT_UNTIL(!(regs->cstat & SII_CON),
SII_WAIT_COUNT, i);
regs->cstat = 0xffff;
@@ -1600,7 +1634,7 @@ sii_GetByte(regs, phase, ack)
state = regs->cstat & SII_STATE_MSK;
if (!(dstat & SII_IBF) || (dstat & SII_MIS)) {
regs->comm = state | phase;
- MachEmptyWriteBuffer();
+ wbflush();
/* wait a short time for IBF */
SII_WAIT_UNTIL(dstat, regs->dstat, dstat & SII_IBF,
SII_WAIT_COUNT, i);
@@ -1631,7 +1665,7 @@ sii_GetByte(regs, phase, ack)
if (ack) {
regs->comm = SII_INXFER | state | phase;
- MachEmptyWriteBuffer();
+ wbflush();
/* wait a short time for XFER complete */
SII_WAIT_UNTIL(dstat, regs->dstat, dstat & SII_DNE,
@@ -1640,7 +1674,7 @@ sii_GetByte(regs, phase, ack)
/* clear the DNE */
if (dstat & SII_DNE) {
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
}
}
@@ -1698,7 +1732,7 @@ sii_DoSync(regs, state)
regs->data = sii_buf[j];
regs->comm = comm;
- MachEmptyWriteBuffer();
+ wbflush();
/* wait a short time for XFER complete */
SII_WAIT_UNTIL(dstat, regs->dstat, dstat & SII_DNE,
@@ -1712,7 +1746,7 @@ sii_DoSync(regs, state)
/* clear the DNE, other errors handled later */
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
}
#else
CopyToBuffer((u_short *)sii_buf, (volatile u_short *)SII_BUF_ADDR, 5);
@@ -1726,7 +1760,7 @@ sii_DoSync(regs, state)
regs->dmlotc = 5;
regs->comm = SII_DMA | SII_INXFER | SII_ATN |
(regs->cstat & SII_STATE_MSK) | SII_MSG_OUT_PHASE;
- MachEmptyWriteBuffer();
+ wbflush();
/* wait a short time for XFER complete */
SII_WAIT_UNTIL(dstat, regs->dstat,
@@ -1741,7 +1775,7 @@ sii_DoSync(regs, state)
}
/* clear the DNE, other errors handled later */
regs->dstat = SII_DNE;
- MachEmptyWriteBuffer();
+ wbflush();
#endif
#if 0
@@ -1778,7 +1812,7 @@ sii_StartDMA(regs, phase, dmaAddr, size)
regs->dmlotc = size;
regs->comm = SII_DMA | SII_INXFER | (regs->cstat & SII_STATE_MSK) |
phase;
- MachEmptyWriteBuffer();
+ wbflush();
#ifdef DEBUG
if (sii_debug > 5) {
@@ -1831,6 +1865,7 @@ sii_CmdDone(sc, target, error)
}
#ifdef DEBUG
+void
sii_DumpLog()
{
register struct sii_log *lp;