diff options
author | gibbs <gibbs@FreeBSD.org> | 2001-03-19 04:40:35 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 2001-03-19 04:40:35 +0000 |
commit | 90b2a0547e7e74c8e746fac8d0723800b21eccd0 (patch) | |
tree | ba3d7b6ac815952243f08e6b5840c5fc4edf906f | |
parent | 8a937bbc3a9d1a7f410a8dd8d27f0018404e5158 (diff) | |
download | FreeBSD-src-90b2a0547e7e74c8e746fac8d0723800b21eccd0.zip FreeBSD-src-90b2a0547e7e74c8e746fac8d0723800b21eccd0.tar.gz |
This is an MFC candidate.
aic7xxx.c:
Correct code that traverses the phase table. A much too quick
push to staticize this structure resulted in non-functional
lookup code. This corrects the printing of the phase where
a timeout occurred.
aic7xxx.reg:
Use FIFOQWDEMP as the name for bit 5 of DFSTATUS just like
the Adaptec data books.
aic7xxx.seq:
Refine the 2.1 PCI retry bug workaround for certain, non-ULTRA2,
controllers. When the DMA of an SCB completes, it can take
some time for HDONE to come true after MREQPEN (PCI memory request
pending) falls. If HDONE never comes true, we are in the hung
state and must manually drain the FIFO. We used to test HDONE for
3 clock cycles to detect this condition. This works on all of the
hardware I can personally test. Some controllers were reported
to take 4 clock cycles, so the last version of this code waited
4 clock cycles. This still didn't work for everyone. To fix this,
I've adjusted the work around so that even if the hardware hasn't
hung, but we run the work-around code, the result is a long winded
way to complete the transfer, rather than a hang.
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.c | 5 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.reg | 2 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.seq | 5 |
3 files changed, 7 insertions, 5 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c index f6dc8c7..c0192a5 100644 --- a/sys/dev/aic7xxx/aic7xxx.c +++ b/sys/dev/aic7xxx/aic7xxx.c @@ -2006,13 +2006,14 @@ struct ahc_phase_table_entry* ahc_lookup_phase_entry(int phase) { struct ahc_phase_table_entry *entry; - int i; + struct ahc_phase_table_entry *last_entry; /* * num_phases doesn't include the default entry which * will be returned if the phase doesn't match. */ - for (i = 0, entry = ahc_phase_table; i < num_phases; i++) { + last_entry = &ahc_phase_table[num_phases]; + for (entry = ahc_phase_table; entry < last_entry; entry++) { if (phase == entry->phase) break; } diff --git a/sys/dev/aic7xxx/aic7xxx.reg b/sys/dev/aic7xxx/aic7xxx.reg index 93e7d8e..ac966f0 100644 --- a/sys/dev/aic7xxx/aic7xxx.reg +++ b/sys/dev/aic7xxx/aic7xxx.reg @@ -878,7 +878,7 @@ register DFSTATUS { access_mode RO bit PRELOAD_AVAIL 0x80 bit DFCACHETH 0x40 - bit DWORDEMP 0x20 + bit FIFOQWDEMP 0x20 bit MREQPEND 0x10 bit HDONE 0x08 bit DFTHRESH 0x04 diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq index 6152c77..d85c89f 100644 --- a/sys/dev/aic7xxx/aic7xxx.seq +++ b/sys/dev/aic7xxx/aic7xxx.seq @@ -2070,13 +2070,12 @@ dma_scb_fromhost: clr A; /* Wait for some data to arrive. */ dma_scb_hang_fifo: - test DFSTATUS, FIFOEMP jnz dma_scb_hang_fifo; + test DFSTATUS, FIFOQWDEMP jnz dma_scb_hang_fifo; dma_scb_hang_wait: test DFSTATUS, MREQPEND jnz dma_scb_hang_wait; test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; - test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; /* * The PCI module no longer intends to perform * a PCI transaction and HDONE has not come true. @@ -2102,6 +2101,7 @@ dma_scb_hang_empty_fifo: */ not SINDEX; add A, 5, SINDEX; + cmp A, 4 je dma_finish_nowait; jmp dma_scb_hang_fifo; dma_scb_hang_dma_done: and DFCNTRL, ~HDMAEN; @@ -2147,6 +2147,7 @@ copy_to_fifo_4: */ dma_finish: test DFSTATUS,HDONE jz dma_finish; +dma_finish_nowait: /* Turn off DMA */ and DFCNTRL, ~HDMAEN; test DFCNTRL, HDMAEN jnz .; |