diff options
Diffstat (limited to 'sys/arch/pmax/dev/sii.c')
-rw-r--r-- | sys/arch/pmax/dev/sii.c | 179 |
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; |