Update to latest Atari driver, but with some local modifications.

This commit is contained in:
briggs 1996-02-19 02:51:03 +00:00
parent a9012450ec
commit ab3f741911
3 changed files with 73 additions and 37 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mac68k5380.c,v 1.18 1996/02/03 23:17:53 briggs Exp $ */ /* $NetBSD: mac68k5380.c,v 1.19 1996/02/19 02:51:03 briggs Exp $ */
/* /*
* Copyright (c) 1995 Allen Briggs * Copyright (c) 1995 Allen Briggs
@ -98,6 +98,7 @@
#endif #endif
#undef REAL_DMA /* Use DMA if sensible */ #undef REAL_DMA /* Use DMA if sensible */
#define scsi_ipending() (GET_5380_REG(NCR5380_DMSTAT) & SC_IRQ_SET)
#define fair_to_keep_dma() 1 #define fair_to_keep_dma() 1
#define claimed_dma() 1 #define claimed_dma() 1
#define reconsider_dma() #define reconsider_dma()

View File

@ -1,4 +1,4 @@
/* $NetBSD: ncr5380.c,v 1.19 1996/02/03 23:17:56 briggs Exp $ */ /* $NetBSD: ncr5380.c,v 1.20 1996/02/19 02:51:06 briggs Exp $ */
/* /*
* Copyright (c) 1995 Leo Weppelman. * Copyright (c) 1995 Leo Weppelman.
@ -299,7 +299,8 @@ ncr5380_scsi_cmd(struct scsi_xfer *xs)
* We do not queue RESET commands * We do not queue RESET commands
*/ */
if (flags & SCSI_RESET) { if (flags & SCSI_RESET) {
scsi_reset(xs->sc_link->adapter_softc); scsi_reset_verbose(xs->sc_link->adapter_softc,
"Got reset-command");
return (COMPLETE); return (COMPLETE);
} }
@ -583,7 +584,7 @@ connected:
/* /*
* Let the target guide us through the bus-phases * Let the target guide us through the bus-phases
*/ */
while (information_transfer() == -1) while (information_transfer(sc) == -1)
; ;
} }
} }
@ -600,8 +601,15 @@ main_exit:
*/ */
PID("scsi_main4"); PID("scsi_main4");
scsi_ienable(); scsi_ienable();
SET_5380_REG(NCR5380_IDSTAT, SC_HOST_ID);
if (GET_5380_REG(NCR5380_DMSTAT) & SC_IRQ_SET) { /*
* If we're not currently connected, enable reselection
* interrupts.
*/
if (!connected)
SET_5380_REG(NCR5380_IDSTAT, SC_HOST_ID);
if (scsi_ipending()) {
if ((itype = check_intr(sc)) != INTR_SPURIOUS) { if ((itype = check_intr(sc)) != INTR_SPURIOUS) {
scsi_idisable(); scsi_idisable();
splx(sps); splx(sps);
@ -612,8 +620,9 @@ main_exit:
else dma_ready(); else dma_ready();
#else #else
else { else {
if (!pdma_ready()) if (pdma_ready())
panic("Got DMA interrupt without DMA"); goto connected;
panic("Got DMA interrupt without DMA");
} }
#endif #endif
scsi_clr_ipend(); scsi_clr_ipend();
@ -668,7 +677,7 @@ struct ncr_softc *sc;
int itype; int itype;
int dma_done; int dma_done;
while (GET_5380_REG(NCR5380_DMSTAT) & SC_IRQ_SET) { while (scsi_ipending()) {
scsi_idisable(); scsi_idisable();
if ((itype = check_intr(sc)) != INTR_SPURIOUS) { if ((itype = check_intr(sc)) != INTR_SPURIOUS) {
if (itype == INTR_RESEL) if (itype == INTR_RESEL)
@ -680,9 +689,9 @@ struct ncr_softc *sc;
return; return;
} }
#else #else
if (!pdma_ready()) if (pdma_ready())
panic("Got DMA interrupt without DMA\n"); return;
return; panic("Got DMA interrupt without DMA\n");
#endif #endif
} }
scsi_clr_ipend(); scsi_clr_ipend();
@ -928,7 +937,7 @@ SC_REQ *reqp;
transfer_pio(&phase, &msg, &len, 0); transfer_pio(&phase, &msg, &len, 0);
} }
else scsi_reset(sc); else scsi_reset_verbose(sc, "Connected to unidentified target");
SET_5380_REG(NCR5380_ICOM, 0); SET_5380_REG(NCR5380_ICOM, 0);
reqp->xs->error = code ? code : XS_DRIVER_STUFFUP; reqp->xs->error = code ? code : XS_DRIVER_STUFFUP;
@ -956,11 +965,12 @@ identify_failed:
/* /*
* Return codes: * Return codes:
* -1: quit main, trigger on interrupt * 0: Job has finished or disconnected, find something else
* 0: keep on running main. * -1: keep on calling information_transfer() from scsi_main()
*/ */
static int static int
information_transfer() information_transfer(sc)
struct ncr_softc *sc;
{ {
SC_REQ *reqp = connected; SC_REQ *reqp = connected;
u_char tmp, phase; u_char tmp, phase;
@ -973,28 +983,35 @@ information_transfer()
scsi_clr_ipend(); scsi_clr_ipend();
/* /*
* We only have a valid SCSI-phase when REQ is asserted. Something * The SCSI-spec requires BSY to be true while connected to a target,
* is deadly wrong when BSY has dropped. * loosing it means we lost the target...
* Also REQ needs to be asserted here to indicate that the bus-phase
* is valid. When the target does not supply REQ within a 'reasonable'
* amount of time, it's probably lost in it's own maze of twisting
* passages, we have to reset the bus to free it.
*/ */
if (GET_5380_REG(NCR5380_IDSTAT) & SC_S_BSY)
wait_req_true();
tmp = GET_5380_REG(NCR5380_IDSTAT); tmp = GET_5380_REG(NCR5380_IDSTAT);
if (!(tmp & SC_S_BSY)) {
if ((tmp & (SC_S_BSY|SC_S_REQ)) != (SC_S_BSY|SC_S_REQ)) {
busy &= ~(1 << reqp->targ_id); busy &= ~(1 << reqp->targ_id);
connected = NULL; connected = NULL;
reqp->xs->error = XS_BUSY; reqp->xs->error = XS_TIMEOUT;
finish_req(reqp); finish_req(reqp);
if (!(tmp & SC_S_REQ))
scsi_reset_verbose(sc,
"Timeout waiting for phase-change");
PID("info_transf2"); PID("info_transf2");
return (0); return (0);
} }
if (tmp & SC_S_REQ) { phase = (tmp >> 2) & 7;
phase = (tmp >> 2) & 7; if (phase != reqp->phase) {
if (phase != reqp->phase) { reqp->phase = phase;
reqp->phase = phase; DBG_INFPRINT(show_phase, reqp, phase);
DBG_INFPRINT(show_phase, reqp, phase);
}
} }
else return (-1);
switch (phase) { switch (phase) {
case PH_DATAOUT: case PH_DATAOUT:
@ -1237,7 +1254,7 @@ struct ncr_softc *sc;
} }
if (GET_5380_REG(NCR5380_IDSTAT) & SC_S_SEL) { if (GET_5380_REG(NCR5380_IDSTAT) & SC_S_SEL) {
/* Damn SEL isn't dropping */ /* Damn SEL isn't dropping */
scsi_reset(sc); scsi_reset_verbose(sc, "Target won't drop SEL during Reselect");
return; return;
} }
@ -1291,7 +1308,7 @@ struct ncr_softc *sc;
SET_5380_REG(NCR5380_ICOM, SC_A_ATN); SET_5380_REG(NCR5380_ICOM, SC_A_ATN);
if (transfer_pio(&phase, &msg, &len, 0) || len) if (transfer_pio(&phase, &msg, &len, 0) || len)
scsi_reset(sc); scsi_reset_verbose(sc, "Failure to abort reselection");
} }
else { else {
connected = tmp; connected = tmp;
@ -1658,19 +1675,17 @@ u_long len;
} }
static void static void
scsi_reset(sc) scsi_reset()
struct ncr_softc *sc;
{ {
SC_REQ *tmp, *next; SC_REQ *tmp, *next;
int sps; int sps;
ncr_aprint(sc, "Resetting SCSI-bus\n");
PID("scsi_reset1"); PID("scsi_reset1");
sps = splbio(); sps = splbio();
SET_5380_REG(NCR5380_ICOM, SC_A_RST); SET_5380_REG(NCR5380_ICOM, SC_A_RST);
delay(1); delay(100);
SET_5380_REG(NCR5380_ICOM, 0); SET_5380_REG(NCR5380_ICOM, 0);
scsi_clr_ipend();
/* /*
* None of the jobs in the discon_q will ever be reconnected, * None of the jobs in the discon_q will ever be reconnected,
@ -1703,6 +1718,25 @@ struct ncr_softc *sc;
} }
splx(sps); splx(sps);
PID("scsi_reset2"); PID("scsi_reset2");
/*
* Give the attached devices some time to handle the reset. This
* value is arbitrary but should be relatively long.
*/
delay(100000);
}
static void
scsi_reset_verbose(sc, why)
struct ncr_softc *sc;
const char *why;
{
SC_REQ *tmp, *next;
int sps;
ncr_aprint(sc, "Resetting SCSI-bus (%s)\n", why);
scsi_reset();
} }
/* /*

View File

@ -1,4 +1,4 @@
/* $NetBSD: ncr5380reg.h,v 1.7 1996/02/03 23:18:00 briggs Exp $ */ /* $NetBSD: ncr5380reg.h,v 1.8 1996/02/19 02:51:08 briggs Exp $ */
/* /*
* Copyright (c) 1995 Leo Weppelman. * Copyright (c) 1995 Leo Weppelman.
@ -236,14 +236,15 @@ static int scsi_select __P((SC_REQ *, int));
static int handle_message __P((SC_REQ *, u_int)); static int handle_message __P((SC_REQ *, u_int));
static void ack_message __P((void)); static void ack_message __P((void));
static void nack_message __P((SC_REQ *, u_char)); static void nack_message __P((SC_REQ *, u_char));
static int information_transfer __P((void)); static int information_transfer __P((struct ncr_softc *));
static void reselect __P((struct ncr_softc *)); static void reselect __P((struct ncr_softc *));
static int dma_ready __P((void)); static int dma_ready __P((void));
static void transfer_dma __P((SC_REQ *, u_int, int)); static void transfer_dma __P((SC_REQ *, u_int, int));
static int check_autosense __P((SC_REQ *, int)); static int check_autosense __P((SC_REQ *, int));
static int reach_msg_out __P((struct ncr_softc *, u_long)); static int reach_msg_out __P((struct ncr_softc *, u_long));
static int check_intr __P((struct ncr_softc *)); static int check_intr __P((struct ncr_softc *));
static void scsi_reset __P((struct ncr_softc *)); static void scsi_reset __P((void));
static void scsi_reset_verbose __P((struct ncr_softc *, const char *));
static int scsi_dmaok __P((SC_REQ *)); static int scsi_dmaok __P((SC_REQ *));
static void run_main __P((struct ncr_softc *)); static void run_main __P((struct ncr_softc *));
static void scsi_main __P((struct ncr_softc *)); static void scsi_main __P((struct ncr_softc *));