summaryrefslogtreecommitdiff
path: root/sys/arch/pc532/dev/ncr5380.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-26 01:11:57 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-26 01:11:57 +0000
commit5481a864cda1d6232e8383d11227e2402df106e3 (patch)
tree087702fdf0898359b8f5c3a47903e2b308472dd8 /sys/arch/pc532/dev/ncr5380.c
parent01abe6560db24d2714b306fbed741fe58c83a6bb (diff)
update from netbsd tree
Diffstat (limited to 'sys/arch/pc532/dev/ncr5380.c')
-rw-r--r--sys/arch/pc532/dev/ncr5380.c116
1 files changed, 59 insertions, 57 deletions
diff --git a/sys/arch/pc532/dev/ncr5380.c b/sys/arch/pc532/dev/ncr5380.c
index cbc267873c7..a0372cdef00 100644
--- a/sys/arch/pc532/dev/ncr5380.c
+++ b/sys/arch/pc532/dev/ncr5380.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ncr5380.c,v 1.5 1995/10/10 08:08:01 phil Exp $ */
+/* $NetBSD: ncr5380.c,v 1.5.2.1 1995/10/19 01:33:09 phil Exp $ */
/*
* Copyright (c) 1995 Leo Weppelman.
@@ -35,7 +35,7 @@
# define static
#endif
#ifdef DBG_SEL
-# define DBG_SELPRINT(a,b) printf(a,b)
+# define DBG_SELPRINT(a,b) printf(a,b)
#else
# define DBG_SELPRINT(a,b)
#endif
@@ -165,10 +165,10 @@ extern __inline__ void ack_message()
SET_5380_REG(NCR5380_ICOM, 0);
}
-extern __inline__ void nack_message(SC_REQ *reqp)
+extern __inline__ void nack_message(SC_REQ *reqp, u_char msg)
{
SET_5380_REG(NCR5380_ICOM, SC_A_ATN);
- reqp->msgout = MSG_ABORT;
+ reqp->msgout = msg;
}
extern __inline__ void finish_req(SC_REQ *reqp)
@@ -411,7 +411,6 @@ ncr5380_scsi_cmd(struct scsi_xfer *xs)
return (SUCCESSFULLY_QUEUED);
}
-#define MIN_PHYS 65536 /*BARF!!!!*/
static void
ncr5380_minphys(struct buf *bp)
{
@@ -550,6 +549,7 @@ struct ncr_softc *sc;
else splx(sps);
connected:
if (connected) {
+#ifdef REAL_DMA
/*
* If the host is currently connected but a 'real-dma' transfer
* is in progress, the 'end-of-dma' interrupt restarts main.
@@ -561,7 +561,7 @@ connected:
goto main_exit;
}
splx(sps);
-
+#endif
/*
* Let the target guide us through the bus-phases
*/
@@ -712,7 +712,7 @@ SC_REQ *reqp;
* Interrupts are lowered when the 5380 is setup to arbitrate for the
* bus.
*/
- if (connected || (GET_5380_REG(NCR5380_IDSTAT) & SC_S_BSY)) {
+ if (connected) {
splx(sps);
PID("scsi_select2");
return (-1);
@@ -733,34 +733,15 @@ SC_REQ *reqp;
splx(sps);
- cnt = 10000;
+ cnt = 10;
while (!(GET_5380_REG(NCR5380_ICOM) & SC_AIP) && --cnt)
delay(1);
if (!(GET_5380_REG(NCR5380_ICOM) & SC_AIP)) {
SET_5380_REG(NCR5380_MODE, IMODE_BASE);
- delay(1);
+ SET_5380_REG(NCR5380_ICOM, 0);
+ DBG_SELPRINT ("Arbitration lost, bus not free\n",0);
PID("scsi_select3");
-
- if (GET_5380_REG(NCR5380_IDSTAT) & SC_S_BSY) {
- /*
- * Damn, we have a connected target that we don't know
- * of. Some targets seem to respond to a selection
- * AFTER the selection-timeout. Try to get the target
- * into the Message-out phase so we can send an ABORT
- * message. We try to avoid resetting the SCSI-bus!
- */
- if (!reach_msg_out(sc, sizeof(struct scsi_generic))) {
- u_long len = 1;
- u_char phase = PH_MSGOUT;
- u_char msg = MSG_ABORT;
-
- transfer_pio(&phase, &msg, &len, 0);
- }
- else if (GET_5380_REG(NCR5380_IDSTAT) & SC_S_BSY)
- scsi_reset(sc);
- }
- PID("scsi_select4");
return (-1);
}
@@ -771,36 +752,47 @@ SC_REQ *reqp;
* Check the result of the arbitration. If we failed, return -1.
*/
if (GET_5380_REG(NCR5380_ICOM) & SC_LA) {
- /*
- * The spec requires that we should read the data register to
- * check for higher id's and check the SC_LA again.
- */
- tmp[0] = GET_5380_REG(NCR5380_DATA);
- if (GET_5380_REG(NCR5380_ICOM) & SC_LA) {
- SET_5380_REG(NCR5380_MODE, IMODE_BASE);
- SET_5380_REG(NCR5380_ICOM, 0);
- DBG_SELPRINT ("Arbitration lost,deassert SC_ARBIT\n",0);
- PID("scsi_select5");
- return (-1);
- }
+ SET_5380_REG(NCR5380_MODE, IMODE_BASE);
+ SET_5380_REG(NCR5380_ICOM, 0);
+ PID("scsi_select4");
+ return (-1);
+ }
+
+ /*
+ * The spec requires that we should read the data register to
+ * check for higher id's and check the SC_LA again.
+ */
+ tmp[0] = GET_5380_REG(NCR5380_DATA);
+ if (tmp[0] & ~((SC_HOST_ID << 1) - 1)) {
+ SET_5380_REG(NCR5380_MODE, IMODE_BASE);
+ SET_5380_REG(NCR5380_ICOM, 0);
+ DBG_SELPRINT ("Arbitration lost, higher id present\n",0);
+ PID("scsi_select5");
+ return (-1);
+ }
+ if (GET_5380_REG(NCR5380_ICOM) & SC_LA) {
+ SET_5380_REG(NCR5380_MODE, IMODE_BASE);
+ SET_5380_REG(NCR5380_ICOM, 0);
+ DBG_SELPRINT ("Arbitration lost, deassert SC_ARBIT\n",0);
+ PID("scsi_select6");
+ return (-1);
}
SET_5380_REG(NCR5380_ICOM, SC_A_SEL | SC_A_BSY);
if (GET_5380_REG(NCR5380_ICOM) & SC_LA) {
SET_5380_REG(NCR5380_MODE, IMODE_BASE);
SET_5380_REG(NCR5380_ICOM, 0);
DBG_SELPRINT ("Arbitration lost, deassert SC_A_SEL\n", 0);
- PID("scsi_select6");
+ PID("scsi_select7");
return (-1);
}
/* Bus settle delay + Bus clear delay = 1.2 usecs */
delay(2);
DBG_SELPRINT ("Arbitration complete\n", 0);
- targ_bit = 1 << reqp->targ_id;
-
/*
* Now that we won the arbitration, start the selection.
*/
+ targ_bit = 1 << reqp->targ_id;
SET_5380_REG(NCR5380_DATA, SC_HOST_ID | targ_bit);
if (sc->sc_noselatn & targ_bit)
@@ -833,7 +825,7 @@ SC_REQ *reqp;
* Wait for the target to react, the specs call for a timeout of
* 250 ms.
*/
- cnt = 25000 /* 250 */;
+ cnt = 25000;
while (!(GET_5380_REG(NCR5380_IDSTAT) & SC_S_BSY) && --cnt)
delay(10);
@@ -846,7 +838,7 @@ SC_REQ *reqp;
* When BSY is asserted, we assume the selection succeeded,
* otherwise we release the bus.
*/
- SET_5380_REG(NCR5380_ICOM, SC_A_SEL | SC_A_ATN);
+ SET_5380_REG(NCR5380_ICOM, SC_A_SEL | atn_flag);
delay(201);
if (!(GET_5380_REG(NCR5380_IDSTAT) & SC_S_BSY)) {
SET_5380_REG(NCR5380_ICOM, 0);
@@ -854,7 +846,7 @@ SC_REQ *reqp;
DBG_SELPRINT ("Target %d not responding to sel\n",
reqp->targ_id);
finish_req(reqp);
- PID("scsi_select7");
+ PID("scsi_select8");
return (0);
}
}
@@ -880,7 +872,7 @@ SC_REQ *reqp;
* Allow disconnect only when interrups are allowed.
*/
tmp[0] = MSG_IDENTIFY(reqp->targ_lun,
- (reqp->dr_flag & DRIVER_NOINT) ? 0 : 0);
+ (reqp->dr_flag & DRIVER_NOINT) ? 0 : 1);
cnt = 1;
phase = PH_MSGOUT;
@@ -922,7 +914,7 @@ SC_REQ *reqp;
SET_5380_REG(NCR5380_ICOM, 0);
reqp->xs->error = code ? code : XS_DRIVER_STUFFUP;
finish_req(reqp);
- PID("scsi_select8");
+ PID("scsi_select9");
return (0);
}
reqp->phase = PH_MSGOUT;
@@ -939,7 +931,7 @@ identify_failed:
connected = reqp;
busy |= targ_bit;
- PID("scsi_select9");
+ PID("scsi_select10");
return (0);
}
@@ -987,7 +979,6 @@ information_transfer()
switch (phase) {
case PH_DATAOUT:
-
#ifdef DBG_NOWRITE
ncr_tprint(reqp, "NOWRITE set -- write attempt aborted.");
reqp->msgout = MSG_ABORT;
@@ -1091,7 +1082,7 @@ u_int msg;
case MSG_LINK_CMD_COMPLETEF:
if (reqp->link == NULL) {
ncr_tprint(reqp, "No link for linked command");
- nack_message(reqp);
+ nack_message(reqp, MSG_ABORT);
PID("hmessage2");
return (-1);
}
@@ -1158,11 +1149,11 @@ u_int msg;
PID("hmessage8");
return (-1);
case MSG_EXTENDED:
- nack_message(reqp);
+ nack_message(reqp, MSG_MESSAGE_REJECT);
PID("hmessage9");
return (-1);
default:
- ncr_tprint(reqp, "Unkown message %x\n", msg);
+ ncr_tprint(reqp, "Unknown message %x\n", msg);
return (-1);
}
PID("hmessage10");
@@ -1199,6 +1190,15 @@ struct ncr_softc *sc;
SET_5380_REG(NCR5380_ICOM, SC_A_BSY);
len = 1000;
while ((GET_5380_REG(NCR5380_IDSTAT) & SC_S_SEL) && (len > 0)) {
+#if 0
+ if (!GET_5380_REG(NCR5380_DATA)) {
+ /*
+ * We stepped into the reselection timeout....
+ */
+ SET_5380_REG(NCR5380_ICOM, 0);
+ return;
+ }
+#endif
delay(1);
len--;
}
@@ -1458,9 +1458,11 @@ dma_ready()
/*
* DMA mode should always be reset even when we will continue with the
- * next chain.
+ * next chain. It is also essential to clear the MON_BUSY because
+ * when LOST_BUSY is unexpectedly set, we will not be able to drive
+ * the bus....
*/
- SET_5380_REG(NCR5380_MODE, GET_5380_REG(NCR5380_MODE) & ~SC_M_DMA);
+ SET_5380_REG(NCR5380_MODE, IMODE_BASE);
if ((dmstat & SC_BSY_ERR) || !(dmstat & SC_PHS_MTCH)
@@ -1828,7 +1830,7 @@ struct scsi_xfer *xs;
p1 = (u_char *) xs->cmd;
p2 = (u_char *)&xs->sense;
- if(*p2 == 0)
+ if (*p2 == 0)
return; /* No(n)sense */
printf("cmd[%d,%d]: ", xs->cmdlen, sz = command_size(*p1));
for (i = 0; i < sz; i++)