summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorbjh21 <bjh21@NetBSD.org>2006-08-26 23:55:22 +0000
committerbjh21 <bjh21@NetBSD.org>2006-08-26 23:55:22 +0000
commiteb74489b57d30d60d16932ee6ff46986147dde43 (patch)
tree4bad8450ba682444a55289936fd1679b6414b52e /sys/dev
parent286856d0982bc683311c4e15205637953eaf8eaf (diff)
When receiving a SCSI message, it's important not to deassert ACK on the last
byte until we've worked out what to do with the message, since if we plan to reply to it we have to assert ATN before deasserting ACK. Implement this.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/wd33c93.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/sys/dev/ic/wd33c93.c b/sys/dev/ic/wd33c93.c
index ce31752c29e..1139c5c08d9 100644
--- a/sys/dev/ic/wd33c93.c
+++ b/sys/dev/ic/wd33c93.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wd33c93.c,v 1.3 2006/08/26 22:37:07 bjh21 Exp $ */
+/* $NetBSD: wd33c93.c,v 1.4 2006/08/26 23:55:22 bjh21 Exp $ */
/*
* Copyright (c) 1990 The Regents of the University of California.
@@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd33c93.c,v 1.3 2006/08/26 22:37:07 bjh21 Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd33c93.c,v 1.4 2006/08/26 23:55:22 bjh21 Exp $");
#include "opt_ddb.h"
@@ -1421,6 +1421,9 @@ wd33c93_msgin_phase(struct wd33c93_softc *dev, int reselect)
SBIC_WAIT(dev, SBIC_ASR_INT, 0);
GET_SBIC_csr(dev, csr);
+ if (__verify_msg_format(dev->sc_imsg, len))
+ break; /* Complete message recieved */
+
/*
* Clear ACK, and wait for the interrupt
* for the next byte or phase change
@@ -1428,15 +1431,25 @@ wd33c93_msgin_phase(struct wd33c93_softc *dev, int reselect)
SET_SBIC_cmd(dev, SBIC_CMD_CLR_ACK);
SBIC_WAIT(dev, SBIC_ASR_INT, 0);
- if (__verify_msg_format(dev->sc_imsg, len))
- break; /* Complete message recieved */
-
GET_SBIC_csr(dev, csr);
} while (len < SBIC_MAX_MSGLEN);
+ /*
+ * Handle the message before deasserting ACK, since if we need to
+ * reply we have to assert ATN first.
+ */
if (__verify_msg_format(dev->sc_imsg, len))
wd33c93_msgin(dev, dev->sc_imsg, len);
+ /*
+ * Clear ACK, and wait for the interrupt
+ * for the phase change
+ */
+ SET_SBIC_cmd(dev, SBIC_CMD_CLR_ACK);
+ SBIC_WAIT(dev, SBIC_ASR_INT, 0);
+
+ GET_SBIC_csr(dev, csr);
+
/* Should still have one CSR to read */
return SBIC_STATE_RUNNING;
}