diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2004-01-20 16:48:28 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2004-01-20 16:48:28 +0000 |
commit | 755ca25ca38e90d00b268ac4de7af80c44cda51b (patch) | |
tree | 96620bac4e786fc00aa8fdb108282f7d238d2a52 | |
parent | b55ff22bce1628dc5520f84e175a50fcaf826fd3 (diff) |
In some situations, the MVME328S can be so hung that our current reset code
fails. Unfortunately, in this case, do_vspoll() would invoke the reset
function ad nauseum.
Allow the flow to exit this infernal loop, attach() will correctly fail.
This is temporary band-aid until a stronger reset sequence is found.
-rw-r--r-- | sys/arch/mvme68k/dev/vs.c | 27 | ||||
-rw-r--r-- | sys/arch/mvme88k/dev/vs.c | 27 |
2 files changed, 30 insertions, 24 deletions
diff --git a/sys/arch/mvme68k/dev/vs.c b/sys/arch/mvme68k/dev/vs.c index 45388bfe98c..bfa6f6a01c0 100644 --- a/sys/arch/mvme68k/dev/vs.c +++ b/sys/arch/mvme68k/dev/vs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vs.c,v 1.13 2004/01/14 02:00:41 krw Exp $ */ +/* $OpenBSD: vs.c,v 1.14 2004/01/20 16:48:23 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. @@ -64,7 +64,7 @@ void scopy(void *, void *, u_int); void szero(void *, u_int); -int do_vspoll(struct vs_softc *, int); +int do_vspoll(struct vs_softc *, int, int); void thaw_queue(struct vs_softc *, u_int8_t); int vs_checkintr(struct vs_softc *, struct scsi_xfer *, int *); void vs_chksense(struct scsi_xfer *); @@ -139,9 +139,10 @@ vs_minphys(bp) } int -do_vspoll(sc, to) +do_vspoll(sc, to, canreset) struct vs_softc *sc; int to; + int canreset; { int i; @@ -158,8 +159,10 @@ do_vspoll(sc, to) --to; if (to <= 0) { /*splx(s);*/ - vs_reset(sc); - vs_resync(sc); + if (canreset) { + vs_reset(sc); + vs_resync(sc); + } printf ("timed out: timeout %d crsw 0x%x\n", to, CRSW); return 1; @@ -180,7 +183,7 @@ vs_poll(sc, xs) /*s = splbio();*/ to = xs->timeout / 1000; for (;;) { - if (do_vspoll(sc, to)) break; + if (do_vspoll(sc, to, 1)) break; if (vs_checkintr(sc, xs, &status)) { vs_scsidone(xs, status); } @@ -432,7 +435,7 @@ vs_chksense(xs) mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ s = splbio(); - do_vspoll(sc, 0); + do_vspoll(sc, 0, 1); /* if (xs->cmd->opcode != PREVENT_ALLOW) { xs->error = XS_SENSE; @@ -537,7 +540,7 @@ vs_initialize(sc) mc->cqe_WORK_QUEUE = 0; mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ - do_vspoll(sc, 0); + do_vspoll(sc, 0, 1); CRB_CLR_DONE(CRSW); /* initialize work queues */ @@ -559,7 +562,7 @@ vs_initialize(sc) mc->cqe_WORK_QUEUE = 0; mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ - do_vspoll(sc, 0); + do_vspoll(sc, 0, 1); if (CRSW & M_CRSW_ER) { /*printf("\nerror: queue %d status = 0x%x\n", i, riopb->iopb_STATUS);*/ @@ -573,7 +576,7 @@ vs_initialize(sc) CRSW = 0; mcsb->mcsb_MCR |= M_MCR_SQM; crsw = CRSW; - do_vspoll(sc, 0); + do_vspoll(sc, 0, 1); if (CRSW & M_CRSW_ER) { printf("error: status = 0x%x\n", riopb->iopb_STATUS); CRB_CLR_ER(CRSW); @@ -615,7 +618,7 @@ vs_resync(sc) mc->cqe_WORK_QUEUE = 0; mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ - do_vspoll(sc, 0); + do_vspoll(sc, 0, 0); if (riopb->iopb_STATUS) { sc->sc_tinfo[i].avail = 0; } else { @@ -653,7 +656,7 @@ vs_reset(sc) mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ for (;;) { - do_vspoll(sc, 0); + do_vspoll(sc, 0, 0); /* ack & clear scsi error condition cause by reset */ if (CRSW & M_CRSW_ER) { CRB_CLR_ER(CRSW); diff --git a/sys/arch/mvme88k/dev/vs.c b/sys/arch/mvme88k/dev/vs.c index 7c74566fc65..1603a980607 100644 --- a/sys/arch/mvme88k/dev/vs.c +++ b/sys/arch/mvme88k/dev/vs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vs.c,v 1.27 2004/01/14 20:50:48 miod Exp $ */ +/* $OpenBSD: vs.c,v 1.28 2004/01/20 16:48:27 miod Exp $ */ /* * Copyright (c) 1999 Steve Murphree, Jr. @@ -84,7 +84,7 @@ struct cfdriver vs_cd = { NULL, "vs", DV_DULL, }; -int do_vspoll(struct vs_softc *, int); +int do_vspoll(struct vs_softc *, int, int); void thaw_queue(struct vs_softc *, u_int8_t); M328_SG vs_alloc_scatter_gather(void); M328_SG vs_build_memory_structure(struct scsi_xfer *, M328_IOPB *); @@ -169,9 +169,10 @@ vsattach(parent, self, auxp) } int -do_vspoll(sc, to) +do_vspoll(sc, to, canreset) struct vs_softc *sc; int to; + int canreset; { int i; if (to <= 0 ) to = 50000; @@ -187,8 +188,10 @@ do_vspoll(sc, to) --to; if (to <= 0) { /*splx(s);*/ - vs_reset(sc); - vs_resync(sc); + if (canreset) { + vs_reset(sc); + vs_resync(sc); + } printf ("timed out: timeout %d crsw 0x%x\n", to, CRSW); return 1; } @@ -208,7 +211,7 @@ vs_poll(sc, xs) /*s = splbio();*/ to = xs->timeout / 1000; for (;;) { - if (do_vspoll(sc, to)) { + if (do_vspoll(sc, to, 1)) { xs->error = XS_SELTIMEOUT; xs->status = -1; xs->flags |= ITSDONE; @@ -454,7 +457,7 @@ vs_chksense(xs) mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ s = splbio(); - do_vspoll(sc, 0); + do_vspoll(sc, 0, 1); /* if (xs->cmd->opcode != PREVENT_ALLOW) { xs->error = XS_SENSE; @@ -560,7 +563,7 @@ vs_initialize(sc) mc->cqe_WORK_QUEUE = 0; mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ - do_vspoll(sc, 0); + do_vspoll(sc, 0, 1); CRB_CLR_DONE(CRSW); /* initialize work queues */ @@ -582,7 +585,7 @@ vs_initialize(sc) mc->cqe_WORK_QUEUE = 0; mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ - do_vspoll(sc, 0); + do_vspoll(sc, 0, 1); if (CRSW & M_CRSW_ER) { /*printf("\nerror: queue %d status = 0x%x\n", i, riopb->iopb_STATUS);*/ /*failed = 1;*/ @@ -595,7 +598,7 @@ vs_initialize(sc) CRSW = 0; mcsb->mcsb_MCR |= M_MCR_SQM; crsw = CRSW; - do_vspoll(sc, 0); + do_vspoll(sc, 0, 1); if (CRSW & M_CRSW_ER) { printf("error: status = 0x%x\n", riopb->iopb_STATUS); CRB_CLR_ER(CRSW); @@ -637,7 +640,7 @@ vs_resync(sc) mc->cqe_WORK_QUEUE = 0; mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ - do_vspoll(sc, 0); + do_vspoll(sc, 0, 0); if (riopb->iopb_STATUS) { #ifdef SDEBUG printf("status: %x\n", riopb->iopb_STATUS); @@ -678,7 +681,7 @@ vs_reset(sc) mc->cqe_QECR = M_QECR_GO; /* poll for the command to complete */ while (1) { - do_vspoll(sc, 0); + do_vspoll(sc, 0, 0); /* ack & clear scsi error condition cause by reset */ if (CRSW & M_CRSW_ER) { CRB_CLR_ER(CRSW); |