summaryrefslogtreecommitdiffstats
path: root/sys/dev/aic7xxx
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>2001-08-05 22:20:12 +0000
committergibbs <gibbs@FreeBSD.org>2001-08-05 22:20:12 +0000
commit6ce4a14a008a9d729d516393345c1b4937562a3f (patch)
tree435db39e35505b1f2dff6ef3ce045fe6724b73e6 /sys/dev/aic7xxx
parent1c2950a4e5f58f8e06f2e5bdae765e05f3d4325c (diff)
downloadFreeBSD-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.c20
-rw-r--r--sys/dev/aic7xxx/aic7xxx.seq39
-rw-r--r--sys/dev/aic7xxx/aic7xxx_pci.c10
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.
OpenPOWER on IntegriCloud