Deleted Added
full compact
aic7xxx.seq (66268) aic7xxx.seq (66647)
1/*
2 * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD.
3 *
4 * Copyright (c) 1994-2000 Justin Gibbs.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 14 unchanged lines hidden (view full) ---

23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
1/*
2 * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD.
3 *
4 * Copyright (c) 1994-2000 Justin Gibbs.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 14 unchanged lines hidden (view full) ---

23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $Id: //depot/src/aic7xxx/aic7xxx.seq#4 $
31 * $Id: //depot/src/aic7xxx/aic7xxx.seq#7 $
32 *
32 *
33 * $FreeBSD: head/sys/dev/aic7xxx/aic7xxx.seq 66268 2000-09-22 22:06:44Z gibbs $
33 * $FreeBSD: head/sys/dev/aic7xxx/aic7xxx.seq 66647 2000-10-05 04:24:14Z gibbs $
34 */
35
36#include "aic7xxx.reg"
37#include "scsi_message.h"
38
39/*
40 * A few words on the waiting SCB list:
41 * After starting the selection hardware, we check for reconnecting targets

--- 30 unchanged lines hidden (view full) ---

72 */
73 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */
74 test SSTAT0, SELDO|SELDI jnz selection;
75 xor SBLKCTL,SELBUSB; /* Toggle back */
76 }
77 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting;
78test_queue:
79 /* Has the driver posted any work for us? */
34 */
35
36#include "aic7xxx.reg"
37#include "scsi_message.h"
38
39/*
40 * A few words on the waiting SCB list:
41 * After starting the selection hardware, we check for reconnecting targets

--- 30 unchanged lines hidden (view full) ---

72 */
73 xor SBLKCTL,SELBUSB; /* Toggle to the other bus */
74 test SSTAT0, SELDO|SELDI jnz selection;
75 xor SBLKCTL,SELBUSB; /* Toggle back */
76 }
77 cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting;
78test_queue:
79 /* Has the driver posted any work for us? */
80BEGIN_CRITICAL
80 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
81 test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop;
82 mov NONE, SNSCB_QOFF;
81 if ((ahc->features & AHC_QUEUE_REGS) != 0) {
82 test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop;
83 mov NONE, SNSCB_QOFF;
83 inc QINPOS;
84 } else {
85 cmp KERNEL_QINPOS, A je poll_for_work_loop;
86 inc QINPOS;
87 }
84 } else {
85 cmp KERNEL_QINPOS, A je poll_for_work_loop;
86 inc QINPOS;
87 }
88 mov ARG_1, NEXT_QUEUED_SCB;
89END_CRITICAL
88
89 /*
90 * We have at least one queued SCB now and we don't have any
90
91 /*
92 * We have at least one queued SCB now and we don't have any
91 * SCBs in the list of SCBs awaiting selection. Pull the tag
92 * from the QINFIFO and get to work on it.
93 * SCBs in the list of SCBs awaiting selection. Allocate a
94 * card SCB for the host's SCB and get to work on it.
93 */
94 if ((ahc->flags & AHC_PAGESCBS) != 0) {
95 mov ALLZEROS call get_free_or_disc_scb;
95 */
96 if ((ahc->flags & AHC_PAGESCBS) != 0) {
97 mov ALLZEROS call get_free_or_disc_scb;
96 }
97
98dequeue_scb:
99 add A, -1, QINPOS;
100 mvi QINFIFO_OFFSET call fetch_byte;
101
102 if ((ahc->flags & AHC_PAGESCBS) == 0) {
98 } else {
103 /* In the non-paging case, the SCBID == hardware SCB index */
99 /* In the non-paging case, the SCBID == hardware SCB index */
104 mov SCBPTR, RETURN_2;
100 mov SCBPTR, ARG_1;
105 }
106dma_queued_scb:
107 /*
108 * DMA the SCB from host ram into the current SCB location.
109 */
110 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
101 }
102dma_queued_scb:
103 /*
104 * DMA the SCB from host ram into the current SCB location.
105 */
106 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
111 mov RETURN_2 call dma_scb;
112start_scb:
107 mov ARG_1 call dma_scb;
113 /*
108 /*
114 * Place us on the waiting list in case our selection
115 * doesn't win during bus arbitration.
109 * Check one last time to see if this SCB was canceled
110 * before we completed the DMA operation. If it was,
111 * the QINFIFO next pointer will not match our saved
112 * value.
116 */
113 */
114 mov A, ARG_1;
115BEGIN_CRITICAL
116 cmp NEXT_QUEUED_SCB, A jne abort_qinscb;
117 mov NEXT_QUEUED_SCB, SCB_NEXT;
117 mov SCB_NEXT,WAITING_SCBH;
118 mov WAITING_SCBH, SCBPTR;
118 mov SCB_NEXT,WAITING_SCBH;
119 mov WAITING_SCBH, SCBPTR;
120END_CRITICAL
119start_waiting:
120 /*
121 * Start the first entry on the waiting SCB list.
122 */
123 mov SCBPTR, WAITING_SCBH;
124 call start_selection;
125 jmp poll_for_work_loop;
126
121start_waiting:
122 /*
123 * Start the first entry on the waiting SCB list.
124 */
125 mov SCBPTR, WAITING_SCBH;
126 call start_selection;
127 jmp poll_for_work_loop;
128
129abort_qinscb:
130 mvi INTSTAT, TRACEPOINT;
131 call add_scb_to_free_list;
132 jmp poll_for_work_loop;
133
127start_selection:
128 if ((ahc->features & AHC_TWIN) != 0) {
129 and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */
130 test SCB_SCSIID, TWIN_CHNLB jz . + 2;
131 or SINDEX, SELBUSB;
132 mov SBLKCTL,SINDEX; /* select channel */
133 }
134initialize_scsiid:

--- 510 unchanged lines hidden (view full) ---

645 /*
646 * Do we need any more segments?
647 */
648 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz return;
649
650 /*
651 * Do we have any prefetch left???
652 */
134start_selection:
135 if ((ahc->features & AHC_TWIN) != 0) {
136 and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */
137 test SCB_SCSIID, TWIN_CHNLB jz . + 2;
138 or SINDEX, SELBUSB;
139 mov SBLKCTL,SINDEX; /* select channel */
140 }
141initialize_scsiid:

--- 510 unchanged lines hidden (view full) ---

652 /*
653 * Do we need any more segments?
654 */
655 test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz return;
656
657 /*
658 * Do we have any prefetch left???
659 */
653 cmp CCSGADDR, CCSGADDR_MAX jne idle_sg_avail;
660 cmp CCSGADDR, SG_PREFETCH_CNT jne idle_sg_avail;
654
655 /*
656 * Need to fetch segments, but we can only do that
657 * if the command channel is completely idle. Make
658 * sure we don't have an SCB prefetch going on.
659 */
660 test CCSCBCTL, CCSCBEN jnz return;
661
662 /*
661
662 /*
663 * Need to fetch segments, but we can only do that
664 * if the command channel is completely idle. Make
665 * sure we don't have an SCB prefetch going on.
666 */
667 test CCSCBCTL, CCSCBEN jnz return;
668
669 /*
663 * The kernel allocates S/G space so that it is 128 byte
664 * aligned and ends on a 128 byte boundary. We fetch
665 * up to the next 128 byte boundary so we don't attempt
666 * to read a non-existent page.
670 * We fetch a "cacheline aligned" and sized amount of data
671 * so we don't end up referencing a non-existant page.
672 * Cacheline aligned is in quotes because the kernel will
673 * set the prefetch amount to a reasonable level if the
674 * cacheline size is unknown.
667 */
675 */
668 mvi CCHCNT, CCSGADDR_MAX;
669 and CCHADDR[0], ~(CCSGADDR_MAX - 1), SCB_RESIDUAL_SGPTR;
676 mvi CCHCNT, SG_PREFETCH_CNT;
677 and CCHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR;
670 bmov CCHADDR[1], SCB_RESIDUAL_SGPTR[1], 3;
671 mvi CCSGCTL, CCSGEN|CCSGRESET ret;
672idle_sgfetch_complete:
673 clr CCSGCTL;
674 test CCSGCTL, CCSGEN jnz .;
678 bmov CCHADDR[1], SCB_RESIDUAL_SGPTR[1], 3;
679 mvi CCSGCTL, CCSGEN|CCSGRESET ret;
680idle_sgfetch_complete:
681 clr CCSGCTL;
682 test CCSGCTL, CCSGEN jnz .;
675 and CCSGADDR, (CCSGADDR_MAX - 1), SCB_RESIDUAL_SGPTR;
683 and CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR;
676idle_sg_avail:
677 if ((ahc->features & AHC_ULTRA2) != 0) {
678 /* Does the hardware have space for another SG entry? */
679 test DFSTATUS, PRELOAD_AVAIL jz return;
680 bmov HADDR, CCSGRAM, 4;
681 bmov SINDEX, CCSGRAM, 1;
682 test SINDEX, 0x1 jz . + 2;
683 xor DATA_COUNT_ODD, 0x1;

--- 78 unchanged lines hidden (view full) ---

762 test LASTPHASE, IOI jnz . + 2;
763 or DMAPARAMS, DIRECTION;
764 call assert; /*
765 * Ensure entering a data
766 * phase is okay - seen identify, etc.
767 */
768 if ((ahc->features & AHC_CMD_CHAN) != 0) {
769 /* We don't have any valid S/G elements */
684idle_sg_avail:
685 if ((ahc->features & AHC_ULTRA2) != 0) {
686 /* Does the hardware have space for another SG entry? */
687 test DFSTATUS, PRELOAD_AVAIL jz return;
688 bmov HADDR, CCSGRAM, 4;
689 bmov SINDEX, CCSGRAM, 1;
690 test SINDEX, 0x1 jz . + 2;
691 xor DATA_COUNT_ODD, 0x1;

--- 78 unchanged lines hidden (view full) ---

770 test LASTPHASE, IOI jnz . + 2;
771 or DMAPARAMS, DIRECTION;
772 call assert; /*
773 * Ensure entering a data
774 * phase is okay - seen identify, etc.
775 */
776 if ((ahc->features & AHC_CMD_CHAN) != 0) {
777 /* We don't have any valid S/G elements */
770 mvi CCSGADDR, CCSGADDR_MAX;
778 mvi CCSGADDR, SG_PREFETCH_CNT;
771 }
772 test SEQ_FLAGS, DPHASE jnz data_phase_reinit;
773
774 /* We have seen a data phase */
775 or SEQ_FLAGS, DPHASE;
776
777 /*
778 * Initialize the DMA address and counter from the SCB.

--- 984 unchanged lines hidden (view full) ---

1763 mov DINDEX, SCB_NEXT;
1764 mov SCBPTR, ARG_2;
1765 mov SCB_NEXT, DINDEX;
1766 mov SCBPTR, SINDEX ret;
1767rHead:
1768 mov DISCONNECTED_SCBH,SCB_NEXT ret;
1769
1770/*
779 }
780 test SEQ_FLAGS, DPHASE jnz data_phase_reinit;
781
782 /* We have seen a data phase */
783 or SEQ_FLAGS, DPHASE;
784
785 /*
786 * Initialize the DMA address and counter from the SCB.

--- 984 unchanged lines hidden (view full) ---

1771 mov DINDEX, SCB_NEXT;
1772 mov SCBPTR, ARG_2;
1773 mov SCB_NEXT, DINDEX;
1774 mov SCBPTR, SINDEX ret;
1775rHead:
1776 mov DISCONNECTED_SCBH,SCB_NEXT ret;
1777
1778/*
1771 * Fetch a byte from host memory given an index of (A + (256 * SINDEX))
1772 * and a base address of SHARED_DATA_ADDR. The byte is returned in RETURN_2.
1773 */
1774fetch_byte:
1775 mov ARG_2, SINDEX;
1776 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1777 mvi DINDEX, CCHADDR;
1778 mvi SHARED_DATA_ADDR call set_1byte_addr;
1779 mvi CCHCNT, 1;
1780 mvi CCSGCTL, CCSGEN|CCSGRESET;
1781 test CCSGCTL, CCSGDONE jz .;
1782 mvi CCSGCTL, CCSGRESET;
1783 bmov RETURN_2, CCSGRAM, 1 ret;
1784 } else {
1785 mvi DINDEX, HADDR;
1786 mvi SHARED_DATA_ADDR call set_1byte_addr;
1787 mvi 1 call set_hcnt;
1788 mvi DFCNTRL, HDMAEN|DIRECTION|FIFORESET;
1789 call dma_finish;
1790 mov RETURN_2, DFDAT ret;
1791 }
1792
1793/*
1794 * Prepare the hardware to post a byte to host memory given an
1795 * index of (A + (256 * SINDEX)) and a base address of SHARED_DATA_ADDR.
1796 */
1797post_byte_setup:
1798 mov ARG_2, SINDEX;
1799 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1800 mvi DINDEX, CCHADDR;
1801 mvi SHARED_DATA_ADDR call set_1byte_addr;

--- 13 unchanged lines hidden (view full) ---

1815 test CCSCBCTL, CCSCBDONE jz .;
1816 clr CCSCBCTL ret;
1817 } else {
1818 mov DFDAT, SINDEX;
1819 or DFCNTRL, HDMAEN|FIFOFLUSH;
1820 jmp dma_finish;
1821 }
1822
1779 * Prepare the hardware to post a byte to host memory given an
1780 * index of (A + (256 * SINDEX)) and a base address of SHARED_DATA_ADDR.
1781 */
1782post_byte_setup:
1783 mov ARG_2, SINDEX;
1784 if ((ahc->features & AHC_CMD_CHAN) != 0) {
1785 mvi DINDEX, CCHADDR;
1786 mvi SHARED_DATA_ADDR call set_1byte_addr;

--- 13 unchanged lines hidden (view full) ---

1800 test CCSCBCTL, CCSCBDONE jz .;
1801 clr CCSCBCTL ret;
1802 } else {
1803 mov DFDAT, SINDEX;
1804 or DFCNTRL, HDMAEN|FIFOFLUSH;
1805 jmp dma_finish;
1806 }
1807
1823get_SCBID_from_host:
1824 mov A, SAVED_LUN;
1825 shr SINDEX, 4, SAVED_SCSIID;
1826 call fetch_byte;
1827 mov RETURN_1, RETURN_2 ret;
1828
1829phase_lock_perr:
1830 mvi INTSTAT, PERR_DETECTED;
1831phase_lock:
1832 /*
1833 * If there is a parity error, wait for the kernel to
1834 * see the interrupt and prepare our message response
1835 * before continuing.
1836 */

--- 215 unchanged lines hidden (view full) ---

2052 test DFSTATUS,HDONE jz dma_finish;
2053 /* Turn off DMA */
2054 and DFCNTRL, ~HDMAEN;
2055 test DFCNTRL, HDMAEN jnz .;
2056 ret;
2057
2058add_scb_to_free_list:
2059 if ((ahc->flags & AHC_PAGESCBS) != 0) {
1808phase_lock_perr:
1809 mvi INTSTAT, PERR_DETECTED;
1810phase_lock:
1811 /*
1812 * If there is a parity error, wait for the kernel to
1813 * see the interrupt and prepare our message response
1814 * before continuing.
1815 */

--- 215 unchanged lines hidden (view full) ---

2031 test DFSTATUS,HDONE jz dma_finish;
2032 /* Turn off DMA */
2033 and DFCNTRL, ~HDMAEN;
2034 test DFCNTRL, HDMAEN jnz .;
2035 ret;
2036
2037add_scb_to_free_list:
2038 if ((ahc->flags & AHC_PAGESCBS) != 0) {
2039BEGIN_CRITICAL
2060 mov SCB_NEXT, FREE_SCBH;
2061 mvi SCB_TAG, SCB_LIST_NULL;
2062 mov FREE_SCBH, SCBPTR ret;
2040 mov SCB_NEXT, FREE_SCBH;
2041 mvi SCB_TAG, SCB_LIST_NULL;
2042 mov FREE_SCBH, SCBPTR ret;
2043END_CRITICAL
2063 } else {
2064 mvi SCB_TAG, SCB_LIST_NULL ret;
2065 }
2066
2067if ((ahc->flags & AHC_PAGESCBS) != 0) {
2068get_free_or_disc_scb:
2069 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb;
2070 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb;

--- 24 unchanged lines hidden ---
2044 } else {
2045 mvi SCB_TAG, SCB_LIST_NULL ret;
2046 }
2047
2048if ((ahc->flags & AHC_PAGESCBS) != 0) {
2049get_free_or_disc_scb:
2050 cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb;
2051 cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb;

--- 24 unchanged lines hidden ---