Update to latest Atari driver, but with some local modifications.
This commit is contained in:
parent
a9012450ec
commit
ab3f741911
@ -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()
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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 *));
|
||||||
|
Loading…
Reference in New Issue
Block a user