Apply by doing cd /sys patch -p0 < esp.patch Index: arch/sparc/dev/dma.c =================================================================== RCS file: /cvs/src/sys/arch/sparc/dev/dma.c,v retrieving revision 1.9 diff -u -r1.9 dma.c --- dma.c 1997/09/17 06:47:08 1.9 +++ dma.c 1998/02/05 19:06:36 @@ -1,4 +1,4 @@ -/* $OpenBSD: dma.c,v 1.9 1997/09/17 06:47:08 downsj Exp $ */ +/* $OpenBSD: dma.c,v 1.11 1998/02/05 19:02:30 jason Exp $ */ /* $NetBSD: dma.c,v 1.46 1997/08/27 11:24:16 bouyer Exp $ */ /* @@ -307,13 +307,27 @@ DMAWAIT(sc, sc->sc_regs->csr & D_DRAINING, "DRAINING", dontpanic);\ } while(0) +#define DMA_FLUSH(sc, dontpanic) do { \ + int csr; \ + /* \ + * DMA rev0 & rev1: we are not allowed to touch the DMA "flush" \ + * and "drain" bits while it is still thinking about a \ + * request. \ + * other revs: D_R_PEND bit reads as 0 \ + */ \ + DMAWAIT(sc, sc->sc_regs->csr & D_R_PEND, "R_PEND", dontpanic); \ + csr = DMACSR(sc); \ + csr &= ~(D_WRITE|D_EN_DMA); \ + csr |= D_INVALIDATE; \ + DMACSR(sc) = csr; \ +} while(0) + void dma_reset(sc, isledma) struct dma_softc *sc; int isledma; { - DMA_DRAIN(sc, 1); - DMACSR(sc) &= ~D_EN_DMA; /* Stop DMA */ + DMA_FLUSH(sc, 1); DMACSR(sc) |= D_RESET; /* reset DMA */ DELAY(200); /* what should this be ? */ /*DMAWAIT1(sc); why was this here? */ @@ -390,7 +404,7 @@ { u_long csr; - DMA_DRAIN(sc, 0); + DMA_FLUSH(sc, 0); #if 0 DMACSR(sc) &= ~D_INT_EN; Index: arch/sparc/fpu/fpu.c =================================================================== RCS file: /cvs/src/sys/arch/sparc/fpu/fpu.c,v retrieving revision 1.7 diff -u -r1.7 fpu.c --- fpu.c 1997/08/08 08:25:46 1.7 +++ fpu.c 1998/02/05 19:06:37 @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu.c,v 1.7 1997/08/08 08:25:46 downsj Exp $ */ +/* $OpenBSD: fpu.c,v 1.8 1998/01/13 22:54:36 jason Exp $ */ /* $NetBSD: fpu.c,v 1.6 1997/07/29 10:09:51 fair Exp $ */ /* @@ -117,7 +117,14 @@ switch ((fsr >> FSR_FTT_SHIFT) & FSR_FTT_MASK) { case FSR_TT_NONE: - panic("fpu_cleanup 1"); /* ??? */ +#if 0 + /* XXX I'm not sure how we get here, but ignoring the trap */ + /* XXX seems to work in my limited tests */ + /* XXX More research to be done =) */ + panic("fpu_cleanup 1"); /* ??? */ +#else + printf("fpu_cleanup 1\n"); +#endif break; case FSR_TT_IEEE: Index: arch/sparc/sparc/memreg.c =================================================================== RCS file: /cvs/src/sys/arch/sparc/sparc/memreg.c,v retrieving revision 1.5 diff -u -r1.5 memreg.c --- memreg.c 1997/08/08 08:27:32 1.5 +++ memreg.c 1998/02/05 19:06:38 @@ -1,4 +1,4 @@ -/* $OpenBSD: memreg.c,v 1.5 1997/08/08 08:27:32 downsj Exp $ */ +/* $OpenBSD: memreg.c,v 1.7 1997/11/11 10:53:12 niklas Exp $ */ /* $NetBSD: memreg.c,v 1.21 1997/07/29 09:42:08 fair Exp $ */ /* @@ -62,8 +62,8 @@ #include /* for trapframe */ #include /* for trap types */ -static int memregmatch __P((struct device *, void *, void *)); -static void memregattach __P((struct device *, struct device *, void *)); +int memregmatch __P((struct device *, void *, void *)); +void memregattach __P((struct device *, struct device *, void *)); struct cfattach memreg_ca = { sizeof(struct device), memregmatch, memregattach @@ -75,31 +75,31 @@ void memerr __P((int, u_int, u_int, u_int, u_int)); #if defined(SUN4M) -static void hardmemerr4m __P((int, u_int, u_int)); +void hardmemerr4m __P((int, u_int, u_int)); #endif /* * The OPENPROM calls this "memory-error". */ -static int +int memregmatch(parent, vcf, aux) struct device *parent; void *vcf, *aux; { - register struct cfdata *cf; + register struct cfdata *cf = vcf; register struct confargs *ca = aux; if (CPU_ISSUN4) { if (ca->ca_bustype == BUS_OBIO) return (strcmp(cf->cf_driver->cd_name, - ca->ca_ra.ra_name) == 0); + ca->ca_ra.ra_name) == 0); return (0); } return (strcmp("memory-error", ca->ca_ra.ra_name) == 0); } /* ARGSUSED */ -static void +void memregattach(parent, self, aux) struct device *parent, *self; void *aux; @@ -188,7 +188,7 @@ * of the error register are printed. */ -static void +void hardmemerr4m(issync, fsr, faddr) int issync; u_int fsr, faddr; @@ -224,8 +224,8 @@ * once, and then fail if we get called again. */ -static int addrold = (int) 0xdeadbeef; /* We pick an unlikely address */ -static int addroldtop = (int) 0xdeadbeef; +static int addrold = (int)0xdeadbeef; /* We pick an unlikely address */ +static int addroldtop = (int)0xdeadbeef; static int oldtype = -1; void Index: dev/ic/ncr53c9x.c =================================================================== RCS file: /cvs/src/sys/dev/ic/ncr53c9x.c,v retrieving revision 1.2 diff -u -r1.2 ncr53c9x.c --- ncr53c9x.c 1997/08/08 08:13:05 1.2 +++ ncr53c9x.c 1998/02/05 19:06:58 @@ -1,5 +1,5 @@ -/* $OpenBSD: ncr53c9x.c,v 1.2 1997/08/08 08:13:05 downsj Exp $ */ -/* $NetBSD: ncr53c9x.c,v 1.16 1997/07/30 12:01:53 pk Exp $ */ +/* $OpenBSD: ncr53c9x.c,v 1.3 1998/02/03 22:02:46 jason Exp $ */ +/* $NetBSD: ncr53c9x.c,v 1.22 1998/01/24 15:33:35 pk Exp $ */ /* * Copyright (c) 1996 Charles M. Hannum. All rights reserved. @@ -134,6 +134,7 @@ "NCR53C96", "ESP406", "FAS408", + "FAS216", }; /* @@ -238,6 +239,7 @@ case NCR_VARIANT_ESP406: case NCR_VARIANT_FAS408: NCR_SCSIREGS(sc); + case NCR_VARIANT_FAS216: case NCR_VARIANT_NCR53C94: case NCR_VARIANT_NCR53C96: case NCR_VARIANT_ESP200: @@ -423,13 +425,13 @@ struct scsi_link *sc_link = ecb->xs->sc_link; int target = sc_link->target; struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[target]; + int tiflags = ti->flags; u_char *cmd; int clen; NCR_TRACE(("[ncr53c9x_select(t%d,l%d,cmd:%x)] ", - sc_link->target, sc_link->lun, ecb->cmd.cmd.opcode)); + sc_link->target, sc_link->lun, ecb->cmd.cmd.opcode)); - /* new state NCR_SELECTING */ sc->sc_state = NCR_SELECTING; /* @@ -441,8 +443,6 @@ timeout(ncr53c9x_timeout, ecb, (ecb->timeout * hz) / 1000); - NCRCMD(sc, NCRCMD_FLUSH); - /* * The docs say the target register is never reset, and I * can't think of a better place to set it @@ -450,29 +450,34 @@ NCR_WRITE_REG(sc, NCR_SELID, target); ncr53c9x_setsync(sc, ti); - if (ncr53c9x_dmaselect && (ti->flags & T_NEGOTIATE) == 0) { - size_t dmacl; + if (ncr53c9x_dmaselect && (tiflags & T_NEGOTIATE) == 0) { + size_t dmasize; + ecb->cmd.id = MSG_IDENTIFY(sc_link->lun, (ti->flags & T_RSELECTOFF)?0:1); /* setup DMA transfer for command */ - clen = ecb->clen + 1; + dmasize = clen = ecb->clen + 1; sc->sc_cmdlen = clen; sc->sc_cmdp = (caddr_t)&ecb->cmd; - dmacl = clen; - NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmacl); + NCRDMA_SETUP(sc, &sc->sc_cmdp, &sc->sc_cmdlen, 0, &dmasize); + /* Program the SCSI counter */ - NCR_WRITE_REG(sc, NCR_TCL, clen); - NCR_WRITE_REG(sc, NCR_TCM, clen >> 8); + NCR_WRITE_REG(sc, NCR_TCL, dmasize); + NCR_WRITE_REG(sc, NCR_TCM, dmasize >> 8); if (sc->sc_cfg2 & NCRCFG2_FE) { - NCR_WRITE_REG(sc, NCR_TCH, clen >> 16); + NCR_WRITE_REG(sc, NCR_TCH, dmasize >> 16); } + /* load the count in */ + NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA); + /* And get the targets attention */ NCRCMD(sc, NCRCMD_SELATN | NCRCMD_DMA); NCRDMA_GO(sc); return; } + /* * Who am I. This is where we tell the target that we are * happy for it to disconnect etc. @@ -671,7 +676,8 @@ break; } else NCR_MISC(("%d:%d busy\n", - sc_link->target, sc_link->lun)); + sc_link->target, + sc_link->lun)); } } @@ -1089,8 +1095,7 @@ printf("max sync rate %d.%02dMb/s\n", r, s); #endif - if ((sc->sc_flags&NCR_SYNCHNEGO) - == 0) { + if ((sc->sc_flags&NCR_SYNCHNEGO) == 0) { /* * target initiated negotiation */ @@ -1174,6 +1179,13 @@ NCR_TRACE(("[ncr53c9x_msgout(priq:%x, prevphase:%x)]", sc->sc_msgpriq, sc->sc_prevphase)); + /* + * XXX - the NCR_ATN flag is not in sync with the actual ATN + * condition on the SCSI bus. The 53c9x chip + * automatically turns off ATN before sending the + * message byte. (see also the comment below in the + * default case when picking out a message to send) + */ if (sc->sc_flags & NCR_ATN) { if (sc->sc_prevphase != MESSAGE_OUT_PHASE) { new: @@ -1244,7 +1256,19 @@ sc->sc_omess[0] = MSG_MESSAGE_REJECT; break; default: - NCRCMD(sc, NCRCMD_RSTATN); + /* + * We normally do not get here, since the chip + * automatically turns off ATN before the last + * byte of a message is sent to the target. + * However, if the target rejects our (multi-byte) + * message early by switching to MSG IN phase + * ATN remains on, so the target may return to + * MSG OUT phase. If there are no scheduled messages + * left we send a NO-OP. + * + * XXX - Note that this leaves no useful purpose for + * the NCR_ATN flag. + */ sc->sc_flags &= ~NCR_ATN; sc->sc_omess[0] = MSG_NOOP; break; @@ -1252,7 +1276,6 @@ sc->sc_omp = sc->sc_omess; } -#if 1 /* (re)send the message */ size = min(sc->sc_omlen, sc->sc_maxxfer); NCRDMA_SETUP(sc, &sc->sc_omp, &sc->sc_omlen, 0, &size); @@ -1262,18 +1285,10 @@ if (sc->sc_cfg2 & NCRCFG2_FE) { NCR_WRITE_REG(sc, NCR_TCH, size >> 16); } - /* load the count in */ + /* Load the count in and start the message-out transfer */ NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA); NCRCMD(sc, NCRCMD_TRANS|NCRCMD_DMA); NCRDMA_GO(sc); -#else - { int i; - for (i = 0; i < sc->sc_omlen; i++) - NCR_WRITE_REG(sc, FIFO, sc->sc_omess[i]); - NCRCMD(sc, NCRCMD_TRANS); - sc->sc_omlen = 0; - } -#endif } /* @@ -1394,7 +1409,16 @@ if (sc->sc_espintr & NCRINTR_ILL) { if (sc->sc_flags & NCR_EXPECT_ILLCMD) { -printf("%s: ILL: ESP100 work-around activated\n", sc->sc_dev.dv_xname); + /* + * Eat away "Illegal command" interrupt + * on a ESP100 caused by a re-selection + * while we were trying to select + * another target. + */ +#ifdef DEBUG + printf("%s: ESP100 work-around activated\n", + sc->sc_dev.dv_xname); +#endif sc->sc_flags &= ~NCR_EXPECT_ILLCMD; continue; } @@ -1432,23 +1456,53 @@ if (NCRDMA_ISACTIVE(sc)) return 1; - /* - * Note that this can happen during normal operation - * if we are reselected while using DMA to select - * a target. If this is the case, don't issue the - * warning. - */ - if (sc->sc_dleft == 0 && - (sc->sc_espstat & NCRSTAT_TC) == 0 && - sc->sc_state != NCR_SELECTING) - 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 ((sc->sc_espstat & NCRSTAT_TC) == 0) { + /* + * DMA not completed. If we can not find a + * acceptable explanation, print a diagnostic. + */ + if (sc->sc_state == NCR_SELECTING) + /* + * This can happen if we are reselected + * while using DMA to select a target. + */ + /*void*/; + else if (sc->sc_prevphase == MESSAGE_OUT_PHASE){ + /* + * Our (multi-byte) message (eg SDTR) + * was interrupted by the target to + * send a MSG REJECT. + * Print diagnostic if current phase + * is not MESSAGE IN. + */ + if (sc->sc_phase != MESSAGE_IN_PHASE) + printf("%s: !TC on MSG OUT" + " [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, + sc->sc_omlen); + } else if (sc->sc_dleft == 0) { + /* + * The DMA operation was started for + * a DATA transfer. Print a diagnostic + * if the DMA counter and TC bit + * appear to be out of sync. + */ + printf("%s: !TC on DATA XFER" + " [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 NCR revisions? */ @@ -1483,6 +1537,7 @@ * 250mS of a disconnect. So here you are... */ NCRCMD(sc, NCRCMD_ENSEL); + switch (sc->sc_state) { case NCR_RESELECTED: goto sched; @@ -1571,7 +1626,6 @@ break; case NCR_IDLE: -if (sc->sc_flags & NCR_ICCS) printf("[[esp: BUMMER]]"); case NCR_SELECTING: sc->sc_msgpriq = sc->sc_msgout = sc->sc_msgoutq = 0; sc->sc_flags = 0; @@ -1635,8 +1689,15 @@ /* Handle identify message */ ncr53c9x_msgin(sc); if (nfifo != 2) { + /* + * Note: this should not happen + * with `dmaselect' on. + */ sc->sc_flags |= NCR_EXPECT_ILLCMD; NCRCMD(sc, NCRCMD_FLUSH); + } else if (ncr53c9x_dmaselect && + sc->sc_rev == NCR_VARIANT_ESP100) { + sc->sc_flags |= NCR_EXPECT_ILLCMD; } if (sc->sc_state != NCR_CONNECTED) { @@ -1660,11 +1721,17 @@ 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; + /* + * The target did not respond with a + * message out phase - probably an old + * device that doesn't recognize ATN. + * Clear ATN and just continue, the + * target should be in the command + * phase. + * XXXX check for command phase? + */ + NCRCMD(sc, NCRCMD_RSTATN); + break; case 1: if ((ti->flags & T_NEGOTIATE) == 0) { printf("%s: step 1 & !NEG\n", @@ -1721,11 +1788,15 @@ if (ncr53c9x_dmaselect && sc->sc_cmdlen != 0) printf("(%s:%d:%d): select; " - "%d left in DMA buffer\n", + "%d left in DMA buffer " + "[intr %x, stat %x, step %d]\n", sc->sc_dev.dv_xname, sc_link->target, sc_link->lun, - sc->sc_cmdlen); + sc->sc_cmdlen, + sc->sc_espintr, + sc->sc_espstat, + sc->sc_espstep); /* So far, everything went fine */ break; } @@ -1854,7 +1925,7 @@ * Send the command block. Normally we don't see this * phase because the SEL_ATN command takes care of * all this. However, we end up here if either the - * target or we wanted exchange some more messages + * target or we wanted to exchange some more messages * first (e.g. to start negotiations). */ @@ -1879,6 +1950,10 @@ NCR_WRITE_REG(sc, NCR_TCH, size >> 16); } + /* load the count in */ + NCRCMD(sc, NCRCMD_NOP|NCRCMD_DMA); + + /* start the command transfer */ NCRCMD(sc, NCRCMD_TRANS | NCRCMD_DMA); NCRDMA_GO(sc); } else { Index: dev/ic/ncr53c9xvar.h =================================================================== RCS file: /cvs/src/sys/dev/ic/ncr53c9xvar.h,v retrieving revision 1.2 diff -u -r1.2 ncr53c9xvar.h --- ncr53c9xvar.h 1997/08/08 08:13:06 1.2 +++ ncr53c9xvar.h 1998/02/05 19:07:00 @@ -1,10 +1,14 @@ -/* $OpenBSD: ncr53c9xvar.h,v 1.2 1997/08/08 08:13:06 downsj Exp $ */ -/* $NetBSD: ncr53c9xvar.h,v 1.8 1997/07/30 11:48:32 pk Exp $ */ +/* $OpenBSD: ncr53c9xvar.h,v 1.3 1998/02/03 22:02:48 jason Exp $ */ +/* $NetBSD: ncr53c9xvar.h,v 1.11 1997/10/05 18:35:09 thorpej Exp $ */ -/* - * Copyright (c) 1997 Jason R. Thorpe. +/*- + * Copyright (c) 1997 The NetBSD Foundation, Inc. * All rights reserved. * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -15,21 +19,23 @@ * 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 for the NetBSD Project - * by Jason R. Thorpe. - * 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 product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE 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. + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /* @@ -80,7 +86,8 @@ #define NCR_VARIANT_NCR53C96 4 #define NCR_VARIANT_ESP406 5 #define NCR_VARIANT_FAS408 6 -#define NCR_VARIANT_MAX 7 +#define NCR_VARIANT_FAS216 7 +#define NCR_VARIANT_MAX 8 /* * ECB. Holds additional information for each SCSI command Comments: We