diff options
author | luoqi <luoqi@FreeBSD.org> | 1999-12-16 16:11:49 +0000 |
---|---|---|
committer | luoqi <luoqi@FreeBSD.org> | 1999-12-16 16:11:49 +0000 |
commit | e8ce4b1d251ac67254b6b31367342c8b19ea95d6 (patch) | |
tree | 412ef9ae2f9b5bc65a6187436f44c4a2e362e0a0 /sys/dev/aic/aic.c | |
parent | 9f40643d81bbfd026db70ca9dc1da6f39f3e9c3b (diff) | |
download | FreeBSD-src-e8ce4b1d251ac67254b6b31367342c8b19ea95d6.zip FreeBSD-src-e8ce4b1d251ac67254b6b31367342c8b19ea95d6.tar.gz |
Adjust data pointers for untransmitted bytes in fifos when there's phase
change during data transfer.
Diffstat (limited to 'sys/dev/aic/aic.c')
-rw-r--r-- | sys/dev/aic/aic.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/dev/aic/aic.c b/sys/dev/aic/aic.c index 9cb2fa9..ad4dc96 100644 --- a/sys/dev/aic/aic.c +++ b/sys/dev/aic/aic.c @@ -920,7 +920,7 @@ static void aic_dataout(struct aic_softc *aic) { struct aic_scb *scb = aic->nexus; - u_int8_t dmastat, dmacntrl0; + u_int8_t dmastat, dmacntrl0, sstat2; int n; CAM_DEBUG_PRINT(CAM_DEBUG_TRACE, ("aic_dataout\n")); @@ -970,10 +970,19 @@ aic_dataout(struct aic_softc *aic) for (;;) { /* wait until all bytes in the fifos are transmitted */ dmastat = aic_inb(aic, DMASTAT); - if (dmastat & INTSTAT) + sstat2 = aic_inb(aic, SSTAT2); + if ((dmastat & DFIFOEMP) && (sstat2 & SEMPTY)) break; - if ((dmastat & DFIFOEMP) && (aic_inb(aic, SSTAT2) & SEMPTY)) + if (dmastat & INTSTAT) { + /* adjust for untransmitted bytes */ + n = aic_inb(aic, FIFOSTAT) + (sstat2 & 0xf); + scb->data_ptr -= n; + scb->data_len += n; + /* clear the fifo */ + aic_outb(aic, SXFRCTL0, CHEN|CLRCH); + aic_outb(aic, DMACNTRL0, RSTFIFO); break; + } } aic_outb(aic, SXFRCTL0, CHEN); @@ -1008,8 +1017,7 @@ aic_cmd(struct aic_softc *aic) aic_outb(aic, SIMODE1, ENSCSIRST|ENPHASEMIS|ENBUSFREE); aic_outb(aic, DMACNTRL0, ENDMA|WRITE); aic_outb(aic, SXFRCTL0, SCSIEN|DMAEN|CHEN); - aic_outsw(aic, DMADATA, (u_int16_t *)scb->cmd_ptr, - scb->cmd_len >> 1); + aic_outsw(aic, DMADATA, (u_int16_t *)scb->cmd_ptr, scb->cmd_len >> 1); while ((aic_inb(aic, SSTAT2) & SEMPTY) == 0 && (aic_inb(aic, DMASTAT) & INTSTAT) == 0) ; |