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