diff options
author | gibbs <gibbs@FreeBSD.org> | 2001-08-05 22:20:12 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 2001-08-05 22:20:12 +0000 |
commit | 6ce4a14a008a9d729d516393345c1b4937562a3f (patch) | |
tree | 435db39e35505b1f2dff6ef3ce045fe6724b73e6 /sys/dev/aic7xxx | |
parent | 1c2950a4e5f58f8e06f2e5bdae765e05f3d4325c (diff) | |
download | FreeBSD-src-6ce4a14a008a9d729d516393345c1b4937562a3f.zip FreeBSD-src-6ce4a14a008a9d729d516393345c1b4937562a3f.tar.gz |
aic7xxx.c:
Correct an off by one in our critical section handling.
SEQADDR always reads the next instruction to execute,
so we must subtract one from its value before making
comparisons with entries in the critical section table.
Print a few additional registers whenever we dump
card state.
Show the SCB_CONTROL and SCB_TAG values for all pending
SCBs in card SCB ram when dumping card state.
aic7xxx.seq:
Fix a bug introduced while optimizing the SDPTR path.
We would ack the SDPTR message twice on Ultra2 or better
chips if it occurred after all data had been transferred
for a transaction.
Change our workaround for the PCI2.1 retry bug on some
chips. Although the previous workaround was logically
correct, its faster method of draining the FIFO seemed
to occassionally confuse the FIFO state. We now drain
the FIFO at half the speed which avoids the problem.
aic7xxx_pci.c:
Chips with the PCI 2.1 retry bug can't handle a 16byte
cachesize. If the cachesize is set to 16bytes, drop
it to 0.
Diffstat (limited to 'sys/dev/aic7xxx')
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.c | 20 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.seq | 39 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_pci.c | 10 |
3 files changed, 44 insertions, 25 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c index fff8b6b..88a4b1d 100644 --- a/sys/dev/aic7xxx/aic7xxx.c +++ b/sys/dev/aic7xxx/aic7xxx.c @@ -1301,6 +1301,13 @@ ahc_clear_critical_section(struct ahc_softc *ahc) seqaddr = ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8); + /* + * Seqaddr represents the next instruction to execute, + * so we are really executing the instruction just + * before it. + */ + if (seqaddr != 0) + seqaddr -= 1; cs = ahc->critical_sections; for (i = 0; i < ahc->num_critical_sections; i++, cs++) { @@ -6229,6 +6236,10 @@ ahc_dump_card_state(struct ahc_softc *ahc) printf("%s: Dumping Card State %s, at SEQADDR 0x%x\n", ahc_name(ahc), ahc_lookup_phase_entry(last_phase)->phasemsg, ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); + printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n", + ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX), + ahc_inb(ahc, ARG_2)); + printf("HCNT = 0x%x\n", ahc_inb(ahc, HCNT)); printf("SCSISEQ = 0x%x, SBLKCTL = 0x%x\n", ahc_inb(ahc, SCSISEQ), ahc_inb(ahc, SBLKCTL)); printf(" DFCNTRL = 0x%x, DFSTATUS = 0x%x\n", @@ -6306,7 +6317,14 @@ ahc_dump_card_state(struct ahc_softc *ahc) LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) { if (i++ > 256) break; - printf("%d ", scb->hscb->tag); + if (scb != LIST_FIRST(&ahc->pending_scbs)) + printf(", "); + printf("%d", scb->hscb->tag); + if ((ahc->flags & AHC_PAGESCBS) == 0) { + ahc_outb(ahc, SCBPTR, scb->hscb->tag); + printf("(0x%x, 0x%x)", ahc_inb(ahc, SCB_CONTROL), + ahc_inb(ahc, SCB_TAG)); + } } printf("\n"); diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq index 179445c..fa42362 100644 --- a/sys/dev/aic7xxx/aic7xxx.seq +++ b/sys/dev/aic7xxx/aic7xxx.seq @@ -1680,7 +1680,11 @@ mesgin_sdptrs: */ test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz mesgin_sdptrs_full; or SCB_SGPTR, SG_LIST_NULL; - jmp mesgin_done; + if ((ahc->features & AHC_ULTRA2) != 0) { + jmp ITloop; + } else { + jmp mesgin_done; + } mesgin_sdptrs_full: @@ -2205,32 +2209,21 @@ dma_scb_hang_wait: * The PCI module no longer intends to perform * a PCI transaction. Drain the fifo. */ -dma_scb_hang_empty_fifo: - /* - * Skip lines not yet transfered into the FIFO. - */ - add SINDEX, 7, HCNT; - shr SINDEX, 3; - - /* - * Skip lines already copied out of the FIFO. - */ - add A, A, SINDEX; - - call dma_scb_hang_dma_drain_fifo; - - /* - * Set the lines transferred to all but - * those yet to reach the FIFO. - */ - not SINDEX; - add A, 5, SINDEX; - cmp A, 4 je dma_finish_nowait; +dma_scb_hang_dma_drain_fifo: + not A, HCNT; + add A, SCB_DOWNLOAD_SIZE+SCB_BASE+1; + and A, ~0x7; + mov DINDIR,DFDAT; + cmp DINDEX, A jne . - 1; + cmp DINDEX, SCB_DOWNLOAD_SIZE+SCB_BASE + je dma_finish_nowait; + /* Restore A as the lines left to transfer. */ + add A, -SCB_BASE, DINDEX; + shr A, 3; jmp dma_scb_hang_fifo; dma_scb_hang_dma_done: and DFCNTRL, ~HDMAEN; test DFCNTRL, HDMAEN jnz .; -dma_scb_hang_dma_drain_fifo: add SEQADDR0, A; } else { call dma_finish; diff --git a/sys/dev/aic7xxx/aic7xxx_pci.c b/sys/dev/aic7xxx/aic7xxx_pci.c index bee6caf..a4c0f46 100644 --- a/sys/dev/aic7xxx/aic7xxx_pci.c +++ b/sys/dev/aic7xxx/aic7xxx_pci.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx_pci.c#27 $ + * $Id: //depot/src/aic7xxx/aic7xxx_pci.c#28 $ * * $FreeBSD$ */ @@ -840,6 +840,14 @@ ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry) /*bytes*/1) & CACHESIZE; ahc->pci_cachesize *= 4; + if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0 + && ahc->pci_cachesize == 4) { + + ahc_pci_write_config(ahc->dev_softc, CSIZE_LATTIME, + 0, /*bytes*/1); + ahc->pci_cachesize = 0; + } + /* * We cannot perform ULTRA speeds without the presense * of the external precision resistor. |