diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-26 01:11:57 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-26 01:11:57 +0000 |
commit | 5481a864cda1d6232e8383d11227e2402df106e3 (patch) | |
tree | 087702fdf0898359b8f5c3a47903e2b308472dd8 /sys/arch/pc532/dev/ncr5380.c | |
parent | 01abe6560db24d2714b306fbed741fe58c83a6bb (diff) |
update from netbsd tree
Diffstat (limited to 'sys/arch/pc532/dev/ncr5380.c')
-rw-r--r-- | sys/arch/pc532/dev/ncr5380.c | 116 |
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++) |