summaryrefslogtreecommitdiff
path: root/sys/dev/ic/oosiop.c
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2013-10-09 18:22:07 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2013-10-09 18:22:07 +0000
commitf8456f9898fe923beea684990e425d5eb4e8cd87 (patch)
treeef431d8864d4d12d5fd344dbfdad7a4210c38d8f /sys/dev/ic/oosiop.c
parent2027e66af6affd8a1ce6db4e34656a6ecd4bed7b (diff)
Enable synch negotiation; code was there but not enabled since this driver was
ported from NetBSD. Tested on hppa (720) and aviion (4600).
Diffstat (limited to 'sys/dev/ic/oosiop.c')
-rw-r--r--sys/dev/ic/oosiop.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/sys/dev/ic/oosiop.c b/sys/dev/ic/oosiop.c
index 910710c4eb5..232ad2a983a 100644
--- a/sys/dev/ic/oosiop.c
+++ b/sys/dev/ic/oosiop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: oosiop.c,v 1.19 2011/06/27 21:33:20 miod Exp $ */
+/* $OpenBSD: oosiop.c,v 1.20 2013/10/09 18:22:06 miod Exp $ */
/* $NetBSD: oosiop.c,v 1.4 2003/10/29 17:45:55 tsutsui Exp $ */
/*
@@ -82,7 +82,7 @@ void oosiop_minphys(struct buf *, struct scsi_link *);
void oosiop_scsicmd(struct scsi_xfer *);
void oosiop_done(struct oosiop_softc *, struct oosiop_cb *);
void oosiop_timeout(void *);
-void oosiop_reset(struct oosiop_softc *);
+void oosiop_reset(struct oosiop_softc *, int);
void oosiop_reset_bus(struct oosiop_softc *);
void oosiop_scriptintr(struct oosiop_softc *);
void oosiop_msgin(struct oosiop_softc *, struct oosiop_cb *);
@@ -252,7 +252,7 @@ oosiop_attach(struct oosiop_softc *sc)
/*
* Reset all
*/
- oosiop_reset(sc);
+ oosiop_reset(sc, TRUE);
oosiop_reset_bus(sc);
/*
@@ -722,7 +722,7 @@ oosiop_set_syncparam(struct oosiop_softc *sc, int id, int period, int offset)
sc->sc_tgt[id].sxfer = (synctbl[i].tp << 4) | offset;
}
/* XXX print actual ns period... */
- printf(" synchronous");
+ printf("synchronous");
}
printf(" xfers\n");
}
@@ -847,7 +847,7 @@ oosiop_poll(struct oosiop_softc *sc, struct oosiop_cb *cb)
i = 1000;
to--;
if (to <= 0) {
- oosiop_reset(sc);
+ oosiop_reset(sc, TRUE);
splx(s);
return;
}
@@ -882,6 +882,7 @@ oosiop_setup(struct oosiop_softc *sc, struct oosiop_cb *cb)
cb->msgoutlen = 1;
if (sc->sc_tgt[cb->id].flags & TGTF_SYNCNEG) {
+ sc->sc_tgt[cb->id].flags &= ~TGTF_SYNCNEG;
/* Send SDTR */
xfer->msgout[1] = MSG_EXTENDED;
xfer->msgout[2] = MSG_EXT_SDTR_LEN;
@@ -889,7 +890,6 @@ oosiop_setup(struct oosiop_softc *sc, struct oosiop_cb *cb)
xfer->msgout[4] = sc->sc_minperiod;
xfer->msgout[5] = OOSIOP_MAX_OFFSET;
cb->msgoutlen = 6;
- sc->sc_tgt[cb->id].flags &= ~TGTF_SYNCNEG;
sc->sc_tgt[cb->id].flags |= TGTF_WAITSDTR;
}
@@ -1047,7 +1047,7 @@ oosiop_timeout(void *arg)
}
void
-oosiop_reset(struct oosiop_softc *sc)
+oosiop_reset(struct oosiop_softc *sc, int allflags)
{
int i, s;
@@ -1089,7 +1089,10 @@ oosiop_reset(struct oosiop_softc *sc)
/* Set target state to asynchronous */
for (i = 0; i < OOSIOP_NTGT; i++) {
- sc->sc_tgt[i].flags = 0;
+ if (allflags)
+ sc->sc_tgt[i].flags = 0;
+ else
+ sc->sc_tgt[i].flags |= TGTF_SYNCNEG;
sc->sc_tgt[i].scf = 0;
sc->sc_tgt[i].sxfer = 0;
}
@@ -1184,7 +1187,7 @@ oosiop_processintr(struct oosiop_softc *sc, u_int8_t istat)
if (dstat & OOSIOP_DSTAT_WTD) {
printf("%s: DMA time out\n", sc->sc_dev.dv_xname);
- oosiop_reset(sc);
+ oosiop_reset(sc, TRUE);
}
if (dstat & OOSIOP_DSTAT_IID) {
@@ -1199,7 +1202,7 @@ oosiop_processintr(struct oosiop_softc *sc, u_int8_t istat)
sc->sc_dev.dv_xname,
oosiop_read_4(sc, OOSIOP_DSP) - 8, dcmd,
oosiop_read_4(sc, OOSIOP_DSPS));
- oosiop_reset(sc);
+ oosiop_reset(sc, TRUE);
OOSIOP_SCRIPT_SYNC(sc, BUS_DMASYNC_POSTWRITE);
oosiop_load_script(sc);
}
@@ -1230,7 +1233,7 @@ oosiop_processintr(struct oosiop_softc *sc, u_int8_t istat)
if (sstat0 & OOSIOP_SSTAT0_SGE) {
printf("%s: SCSI gross error\n", sc->sc_dev.dv_xname);
- oosiop_reset(sc);
+ oosiop_reset(sc, TRUE);
}
if (sstat0 & OOSIOP_SSTAT0_UDC) {
@@ -1242,8 +1245,13 @@ oosiop_processintr(struct oosiop_softc *sc, u_int8_t istat)
}
}
- if (sstat0 & OOSIOP_SSTAT0_RST)
- oosiop_reset(sc);
+ if (sstat0 & OOSIOP_SSTAT0_RST) {
+ /*
+ * This may happen during sync request negotiation;
+ * be sure not to reset TGTF_WAITSDTR in that case.
+ */
+ oosiop_reset(sc, FALSE);
+ }
if (sstat0 & OOSIOP_SSTAT0_PAR)
printf("%s: parity error\n", sc->sc_dev.dv_xname);