* Remove unused ncr_minphys prototype.

* Add prototype for ncr_ready.
* Add ncr_wait_not_req function from Ian Dall:
	The ncr_wait_not_req business is to avoid a potential race.
	When the pseudo DMA finishes, the target may not have
	lowered REQ yet. If we just charge ahead, we eventually test
	for phase when REQ is high. However, if REQ has not yet gone
	low for the last byte transferred, this will be the wrong
	phase. This is taken from the dp8490 application notes. The
	last ACK is not deasserted until the dma is completed.
	Deasserting the last ACK should be delayed until the last
	REQ is deasserted. I am not sure if there are ever devices
	this slow, but I believe the code is "more correct".
This commit is contained in:
matthias 1997-03-20 12:03:01 +00:00
parent dd38be40dc
commit 80502accfe
1 changed files with 22 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ncr.c,v 1.35 1997/03/01 09:50:40 matthias Exp $ */
/* $NetBSD: ncr.c,v 1.36 1997/03/20 12:03:01 matthias Exp $ */
/*
* Copyright (c) 1996 Matthias Pfaller.
@ -51,10 +51,11 @@
*/
static int ncr_pdma_in __P((struct ncr5380_softc *, int, int, u_char *));
static int ncr_pdma_out __P((struct ncr5380_softc *, int, int, u_char *));
static void ncr_minphys __P((struct buf *bp));
static void ncr_intr __P((void *));
static void ncr_attach __P((struct device *, struct device *, void *));
static int ncr_match __P((struct device *, struct cfdata *, void *));
static int ncr_ready __P((struct ncr5380_softc *sc));
static void ncr_wait_not_req __P((struct ncr5380_softc *sc));
/*
* Some constants.
@ -136,7 +137,7 @@ ncr_attach(parent, self, aux)
flags = ca->ca_flags | ncr_default_options;
if (flags)
printf(": flags %d\n");
printf(": flags %d\n", flags);
else
printf("\n");
@ -252,6 +253,21 @@ ncr_ready(sc)
return(0);
}
/* Return zero on success. */
static __inline void ncr_wait_not_req(sc)
struct ncr5380_softc *sc;
{
register int timo;
for (timo = TIMEOUT; timo; timo--) {
if ((*sc->sci_bus_csr & SCI_BUS_REQ) == 0 ||
(*sc->sci_csr & SCI_CSR_PHASE_MATCH) == 0 ||
SCI_BUSY(sc) == 0) {
return;
}
}
printf("%s: pdma not_req timeout\n", sc->sc_dev.dv_xname);
}
static int
ncr_pdma_in(sc, phase, datalen, data)
struct ncr5380_softc *sc;
@ -289,6 +305,7 @@ ncr_pdma_in(sc, phase, datalen, data)
ei();
resid = 0;
}
ncr_wait_not_req(sc);
interrupt:
SCI_CLR_INTR(sc);
*sc->sci_mode &= ~SCI_MODE_DMA;
@ -303,7 +320,7 @@ ncr_pdma_out(sc, phase, datalen, data)
u_char *data;
{
volatile u_char *pdma = PDMA_ADDRESS;
int i, s, resid, ready = 1;
int i, s, resid;
u_char icmd;
s = splbio();
@ -365,6 +382,7 @@ ncr_pdma_out(sc, phase, datalen, data)
printf("%s: timeout waiting for final SCI_DSR_DREQ.\n",
sc->sc_dev.dv_xname);
ncr_wait_not_req(sc);
interrupt:
SCI_CLR_INTR(sc);
*sc->sci_mode &= ~SCI_MODE_DMA;