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.
This commit is contained in:
Justin T. Gibbs 2001-08-05 22:20:12 +00:00
parent 41f59e1ce0
commit 9f152ec7d2
3 changed files with 44 additions and 25 deletions

View file

@ -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");

View file

@ -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;

View file

@ -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.