aic7xxx.seq (16260) | aic7xxx.seq (18762) |
---|---|
1/*+M*********************************************************************** 2 *Adaptec 274x/284x/294x device driver for Linux and FreeBSD. 3 * 4 *Copyright (c) 1994 John Aycock 5 * The University of Calgary Department of Computer Science. 6 * All rights reserved. 7 * 8 *FreeBSD, Twin, Wide, 2 command per target support, tagged queuing, --- 25 unchanged lines hidden (view full) --- 34 *OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 *HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 *OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 *SUCH DAMAGE. 39 * 40 *-M************************************************************************/ 41 | 1/*+M*********************************************************************** 2 *Adaptec 274x/284x/294x device driver for Linux and FreeBSD. 3 * 4 *Copyright (c) 1994 John Aycock 5 * The University of Calgary Department of Computer Science. 6 * All rights reserved. 7 * 8 *FreeBSD, Twin, Wide, 2 command per target support, tagged queuing, --- 25 unchanged lines hidden (view full) --- 34 *OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 *HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 *OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 *SUCH DAMAGE. 39 * 40 *-M************************************************************************/ 41 |
42VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.41 1996/06/08 06:54:06 gibbs Exp $" | 42VERSION AIC7XXX_SEQ_VER "$Id: aic7xxx.seq,v 1.42 1996/06/09 17:29:11 gibbs Exp $" |
43 44#if defined(__NetBSD__) 45#include "../../../../dev/ic/aic7xxxreg.h" | 43 44#if defined(__NetBSD__) 45#include "../../../../dev/ic/aic7xxxreg.h" |
46#include "../../../../scsi/scsi_message.h" |
|
46#elif defined(__FreeBSD__) 47#include "../../dev/aic7xxx/aic7xxx_reg.h" | 47#elif defined(__FreeBSD__) 48#include "../../dev/aic7xxx/aic7xxx_reg.h" |
49#include "../../scsi/scsi_message.h" |
|
48#endif 49 50/* 51 * We can't just use ACCUM in the sequencer code because it 52 * must be treated specially by the assembler, and it currently 53 * looks for the symbol 'A'. This is the only register defined in 54 * the assembler's symbol space. 55 */ --- 125 unchanged lines hidden (view full) --- 181/* 182 * As soon as we get a successful selection, the target should go 183 * into the message out phase since we have ATN asserted. Prepare 184 * the message to send. 185 * 186 * Messages are stored in scratch RAM starting with a length byte 187 * followed by the message itself. 188 */ | 50#endif 51 52/* 53 * We can't just use ACCUM in the sequencer code because it 54 * must be treated specially by the assembler, and it currently 55 * looks for the symbol 'A'. This is the only register defined in 56 * the assembler's symbol space. 57 */ --- 125 unchanged lines hidden (view full) --- 183/* 184 * As soon as we get a successful selection, the target should go 185 * into the message out phase since we have ATN asserted. Prepare 186 * the message to send. 187 * 188 * Messages are stored in scratch RAM starting with a length byte 189 * followed by the message itself. 190 */ |
189 test SCB_CMDLEN,0xff jnz mk_identify /* 0 Length Command? */ | |
190 | 191 |
191/* 192 * The kernel has sent us an SCB with no command attached. This implies 193 * that the kernel wants to send a message of some sort to this target, 194 * so we interrupt the driver, allow it to fill the message buffer, and 195 * then go back into the arbitration loop 196 */ 197 mvi INTSTAT,AWAITING_MSG 198 jmp wait_for_selection 199 | |
200mk_identify: 201 and A,DISCENB,SCB_CONTROL /* mask off disconnect privledge */ 202 203 and MSG0,0x7,SCB_TCL /* lun */ 204 or MSG0,A /* or in disconnect privledge */ | 192mk_identify: 193 and A,DISCENB,SCB_CONTROL /* mask off disconnect privledge */ 194 195 and MSG0,0x7,SCB_TCL /* lun */ 196 or MSG0,A /* or in disconnect privledge */ |
205 or MSG0,MSG_IDENTIFY | 197 or MSG0,MSG_IDENTIFYFLAG |
206 mvi MSG_LEN, 1 207 | 198 mvi MSG_LEN, 1 199 |
208 test SCB_CONTROL,0xb0 jz !message /* WDTR, SDTR or TAG?? */ | |
209/* 210 * Send a tag message if TAG_ENB is set in the SCB control block. 211 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. 212 */ | 200/* 201 * Send a tag message if TAG_ENB is set in the SCB control block. 202 * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. 203 */ |
213 | |
214mk_tag: | 204mk_tag: |
205 test SCB_CONTROL,TAG_ENB jz mk_message |
|
215 mvi DINDEX, MSG1 | 206 mvi DINDEX, MSG1 |
216 test SCB_CONTROL,TAG_ENB jz mk_tag_done | |
217 and DINDIR,0x23,SCB_CONTROL 218 mov DINDIR,SCB_TAG 219 220 add MSG_LEN,COMP_MSG0,DINDEX /* update message length */ 221 | 207 and DINDIR,0x23,SCB_CONTROL 208 mov DINDIR,SCB_TAG 209 210 add MSG_LEN,COMP_MSG0,DINDEX /* update message length */ 211 |
222mk_tag_done: | 212/* 213 * Interrupt the driver, and allow it to tweak the message buffer 214 * if it asks. 215 */ 216mk_message: 217 test SCB_CONTROL,MK_MESSAGE jz wait_for_selection |
223 | 218 |
224 test SCB_CONTROL,0x90 jz !message /* NEEDWDTR|NEEDSDTR */ 225 mov DINDEX call mk_dtr /* build DTR message if needed */ | 219 mvi INTSTAT,AWAITING_MSG |
226 | 220 |
227!message: | |
228wait_for_selection: 229 test SSTAT0,SELDO jnz select 230 test SSTAT0,SELDI jz wait_for_selection 231 232/* 233 * Reselection has been initiated by a target. Make a note that we've been 234 * reselected, but haven't seen an IDENTIFY message from the target 235 * yet. --- 270 unchanged lines hidden (view full) --- 506 jmp mesgin_done 507 508/* 509 * Message out phase. If there is not an active message, but the target 510 * took us into this phase anyway, build a no-op message and send it. 511 */ 512p_mesgout: 513 test MSG_LEN, 0xff jnz p_mesgout_start | 221wait_for_selection: 222 test SSTAT0,SELDO jnz select 223 test SSTAT0,SELDI jz wait_for_selection 224 225/* 226 * Reselection has been initiated by a target. Make a note that we've been 227 * reselected, but haven't seen an IDENTIFY message from the target 228 * yet. --- 270 unchanged lines hidden (view full) --- 499 jmp mesgin_done 500 501/* 502 * Message out phase. If there is not an active message, but the target 503 * took us into this phase anyway, build a no-op message and send it. 504 */ 505p_mesgout: 506 test MSG_LEN, 0xff jnz p_mesgout_start |
514 mvi MSG_NOP call mk_mesg /* build NOP message */ | 507 mvi MSG_NOOP call mk_mesg /* build NOP message */ |
515 516p_mesgout_start: 517/* 518 * Set up automatic PIO transfer from MSG0. Bit 3 in 519 * SXFRCTL0 (SPIOEN) is already on. 520 */ 521 mvi SINDEX,MSG0 522 mov DINDEX,MSG_LEN --- 41 unchanged lines hidden (view full) --- 564 565/* 566 * Message in phase. Bytes are read using Automatic PIO mode. 567 */ 568p_mesgin: 569 mvi A call inb_first /* read the 1st message byte */ 570 mov REJBYTE,A /* save it for the driver */ 571 | 508 509p_mesgout_start: 510/* 511 * Set up automatic PIO transfer from MSG0. Bit 3 in 512 * SXFRCTL0 (SPIOEN) is already on. 513 */ 514 mvi SINDEX,MSG0 515 mov DINDEX,MSG_LEN --- 41 unchanged lines hidden (view full) --- 557 558/* 559 * Message in phase. Bytes are read using Automatic PIO mode. 560 */ 561p_mesgin: 562 mvi A call inb_first /* read the 1st message byte */ 563 mov REJBYTE,A /* save it for the driver */ 564 |
572 test A,MSG_IDENTIFY jnz mesgin_identify | 565 test A,MSG_IDENTIFYFLAG jnz mesgin_identify |
573 cmp A,MSG_DISCONNECT je mesgin_disconnect | 566 cmp A,MSG_DISCONNECT je mesgin_disconnect |
574 cmp A,MSG_SDPTRS je mesgin_sdptrs | 567 cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs |
575 cmp ALLZEROS,A je mesgin_complete | 568 cmp ALLZEROS,A je mesgin_complete |
576 cmp A,MSG_RDPTRS je mesgin_rdptrs | 569 cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs |
577 cmp A,MSG_EXTENDED je mesgin_extended | 570 cmp A,MSG_EXTENDED je mesgin_extended |
578 cmp A,MSG_REJECT je mesgin_reject | 571 cmp A,MSG_MESSAGE_REJECT je mesgin_reject |
579 580rej_mesgin: 581/* 582 * We have no idea what this message in is, and there's no way 583 * to pass it up to the kernel, so we issue a message reject and 584 * hope for the best. Since we're now using manual PIO mode to 585 * read in the message, there should no longer be a race condition 586 * present when we assert ATN. In any case, rejection should be a 587 * rare occurrence - signal the driver when it happens. 588 */ 589 or SCSISIGO,ATNO /* turn on ATNO */ 590 mvi INTSTAT,SEND_REJECT /* let driver know */ 591 | 572 573rej_mesgin: 574/* 575 * We have no idea what this message in is, and there's no way 576 * to pass it up to the kernel, so we issue a message reject and 577 * hope for the best. Since we're now using manual PIO mode to 578 * read in the message, there should no longer be a race condition 579 * present when we assert ATN. In any case, rejection should be a 580 * rare occurrence - signal the driver when it happens. 581 */ 582 or SCSISIGO,ATNO /* turn on ATNO */ 583 mvi INTSTAT,SEND_REJECT /* let driver know */ 584 |
592 mvi MSG_REJECT call mk_mesg | 585 mvi MSG_MESSAGE_REJECT call mk_mesg |
593 594mesgin_done: 595 call inb_last /*ack & turn auto PIO back on*/ 596 jmp ITloop 597 598 599mesgin_complete: 600/* --- 59 unchanged lines hidden (view full) --- 660 jmp start 661complete: 662 mov QOUTFIFO,SCB_TAG 663 mvi INTSTAT,CMDCMPLT 664 jmp mesgin_done 665 666 667/* | 586 587mesgin_done: 588 call inb_last /*ack & turn auto PIO back on*/ 589 jmp ITloop 590 591 592mesgin_complete: 593/* --- 59 unchanged lines hidden (view full) --- 653 jmp start 654complete: 655 mov QOUTFIFO,SCB_TAG 656 mvi INTSTAT,CMDCMPLT 657 jmp mesgin_done 658 659 660/* |
668 * Is it an extended message? We only support the synchronous and wide data 669 * transfer request messages, which will probably be in response to 670 * WDTR or SDTR message outs from us. If it's not SDTR or WDTR, reject it - 671 * apparently this can be done after any message in byte, according 672 * to the SCSI-2 spec. | 661 * Is it an extended message? Copy the message to our message buffer and 662 * notify the host. The host will tell us whether to reject this message, 663 * respond to it with the message that the host placed in our message buffer, 664 * or simply to do nothing. |
673 */ 674mesgin_extended: | 665 */ 666mesgin_extended: |
675 mvi ARG_1 call inb_next /* extended message length */ 676 mvi REJBYTE_EXT call inb_next /* extended message code */ 677 678 cmp REJBYTE_EXT,MSG_SDTR je p_mesginSDTR 679 cmp REJBYTE_EXT,MSG_WDTR je p_mesginWDTR 680 jmp rej_mesgin 681 682p_mesginWDTR: 683 cmp ARG_1,2 jne rej_mesgin /* extended mesg length=2 */ 684 mvi ARG_1 call inb_next /* Width of bus */ 685 mvi INTSTAT,WDTR_MSG /* let driver know */ 686 test RETURN_1,0xff jz mesgin_done /* Do we need to send WDTR? */ 687 cmp RETURN_1,SEND_REJ je rej_mesgin /* 688 * Bus width was too large 689 * Reject it. 690 */ 691 692/* We didn't initiate the wide negotiation, so we must respond to the request */ 693 and RETURN_1,0x7f /* Clear the SEND_WDTR Flag */ 694 mvi DINDEX,MSG0 695 mvi MSG0 call mk_wdtr /* build WDTR message */ | 667 mvi MSGIN_EXT_LEN call inb_next 668 mvi MSGIN_EXT_OPCODE call inb_next 669 mov A, MSGIN_EXT_LEN 670 dec A /* Length counts the op code */ 671 mvi SINDEX, MSGIN_EXT_BYTE0 672mesgin_extended_loop: 673 test A, 0xFF jz mesgin_extended_intr 674 cmp SINDEX, MSGIN_EXT_LASTBYTE je mesgin_extended_dump 675 call inb_next 676 dec A 677/* 678 * We pass the arg to inb in SINDEX, but DINDEX is the one incremented 679 * so update SINDEX with DINDEX's value before looping again. 680 */ 681 mov DINDEX jmp mesgin_extended_loop 682mesgin_extended_dump: 683/* We have no more storage space, so dump the rest */ 684 test A, 0xFF jz mesgin_extended_intr 685 mvi NONE call inb_next 686 dec A 687 jmp mesgin_extended_dump 688mesgin_extended_intr: 689 mvi INTSTAT,EXTENDED_MSG /* let driver know */ 690 cmp RETURN_1,SEND_REJ je rej_mesgin 691 cmp RETURN_1,SEND_MSG jne mesgin_done 692/* The kernel has setup a message to be sent */ |
696 or SCSISIGO,ATNO /* turn on ATNO */ 697 jmp mesgin_done 698 | 693 or SCSISIGO,ATNO /* turn on ATNO */ 694 jmp mesgin_done 695 |
699p_mesginSDTR: 700 cmp ARG_1,3 jne rej_mesgin /* extended mesg length=3 */ 701 mvi ARG_1 call inb_next /* xfer period */ 702 mvi A call inb_next /* REQ/ACK offset */ 703 mvi INTSTAT,SDTR_MSG /* call driver to convert */ 704 705 test RETURN_1,0xff jz mesgin_done /* Do we need to mk_sdtr/rej */ 706 cmp RETURN_1,SEND_REJ je rej_mesgin /* 707 * Requested SDTR too small 708 * Reject it. 709 */ 710 clr ARG_1 /* Use the scratch ram rate */ 711 mvi DINDEX, MSG0 712 mvi MSG0 call mk_sdtr 713 or SCSISIGO,ATNO /* turn on ATNO */ 714 jmp mesgin_done 715 | |
716/* 717 * Is it a disconnect message? Set a flag in the SCB to remind us 718 * and await the bus going free. 719 */ 720mesgin_disconnect: 721 or SCB_CONTROL,DISCONNECTED 722 test FLAGS, PAGESCBS jz mesgin_done 723/* --- 54 unchanged lines hidden (view full) --- 778 * If we get one, we use the tag returned to switch to find the proper 779 * SCB. With SCB paging, this requires using findSCB for both tagged 780 * and non-tagged transactions since the SCB may exist in any slot. 781 * If we're not using SCB paging, we can use the tag as the direct 782 * index to the SCB. 783 */ 784 mvi ARG_1,SCB_LIST_NULL /* Default to no-tag */ 785snoop_tag_loop: | 696/* 697 * Is it a disconnect message? Set a flag in the SCB to remind us 698 * and await the bus going free. 699 */ 700mesgin_disconnect: 701 or SCB_CONTROL,DISCONNECTED 702 test FLAGS, PAGESCBS jz mesgin_done 703/* --- 54 unchanged lines hidden (view full) --- 758 * If we get one, we use the tag returned to switch to find the proper 759 * SCB. With SCB paging, this requires using findSCB for both tagged 760 * and non-tagged transactions since the SCB may exist in any slot. 761 * If we're not using SCB paging, we can use the tag as the direct 762 * index to the SCB. 763 */ 764 mvi ARG_1,SCB_LIST_NULL /* Default to no-tag */ 765snoop_tag_loop: |
786 test SSTAT1,BUSFREE jnz use_findSCB 787 test SSTAT1,REQINIT jz snoop_tag_loop 788 test SSTAT1,PHASEMIS jnz use_findSCB 789 mvi A call inb_first 790 cmp A,MSG_SIMPLE_TAG jne use_findSCB | 766 test SSTAT1,BUSFREE jnz use_findSCB 767 test SSTAT1,REQINIT jz snoop_tag_loop 768 test SSTAT1,PHASEMIS jnz use_findSCB 769 mvi A call inb_first 770 cmp A,MSG_SIMPLE_Q_TAG jne use_findSCB |
791get_tag: 792 mvi ARG_1 call inb_next /* tag value */ 793/* 794 * See if the tag is in range. The tag is < SCBCOUNT if we add 795 * the complement of SCBCOUNT to the incomming tag and there is 796 * no carry. 797 */ 798 mov A,COMP_SCBCOUNT --- 143 unchanged lines hidden (view full) --- 942 * Now shut the DMA enables off and make sure that the DMA enables are 943 * actually off first lest we get an ILLSADDR. 944 */ 945dma5: 946 /* disable DMA, but maintain WIDEODD */ 947 and DFCNTRL,WIDEODD 948dma6: 949 test DFCNTRL,0x38 jnz dma6 /* SCSIENACK|SDMAENACK|HDMAENACK */ | 771get_tag: 772 mvi ARG_1 call inb_next /* tag value */ 773/* 774 * See if the tag is in range. The tag is < SCBCOUNT if we add 775 * the complement of SCBCOUNT to the incomming tag and there is 776 * no carry. 777 */ 778 mov A,COMP_SCBCOUNT --- 143 unchanged lines hidden (view full) --- 922 * Now shut the DMA enables off and make sure that the DMA enables are 923 * actually off first lest we get an ILLSADDR. 924 */ 925dma5: 926 /* disable DMA, but maintain WIDEODD */ 927 and DFCNTRL,WIDEODD 928dma6: 929 test DFCNTRL,0x38 jnz dma6 /* SCSIENACK|SDMAENACK|HDMAENACK */ |
950 | 930return: |
951 ret 952 953/* 954 * Common SCSI initialization for selection and reselection. Expects 955 * the target SCSI ID to be in the upper four bits of SINDEX, and A's 956 * contents are stomped on return. 957 */ 958initialize_scsiid: --- 123 unchanged lines hidden (view full) --- 1082 * contains the 3->8 decoding of the target ID on return. 1083 */ 1084ndx_dtr: 1085 shr A,SCSIID,4 1086 test SBLKCTL,SELBUSB jz ndx_dtr_2 1087 or A,0x08 /* Channel B entries add 8 */ 1088ndx_dtr_2: 1089 add SINDEX,TARG_SCRATCH,A ret | 931 ret 932 933/* 934 * Common SCSI initialization for selection and reselection. Expects 935 * the target SCSI ID to be in the upper four bits of SINDEX, and A's 936 * contents are stomped on return. 937 */ 938initialize_scsiid: --- 123 unchanged lines hidden (view full) --- 1062 * contains the 3->8 decoding of the target ID on return. 1063 */ 1064ndx_dtr: 1065 shr A,SCSIID,4 1066 test SBLKCTL,SELBUSB jz ndx_dtr_2 1067 or A,0x08 /* Channel B entries add 8 */ 1068ndx_dtr_2: 1069 add SINDEX,TARG_SCRATCH,A ret |
1090 1091/* 1092 * If we need to negotiate transfer parameters, build the WDTR or SDTR message 1093 * starting at the address passed in SINDEX. DINDEX is modified on return. 1094 * The SCSI-II spec requires that Wide negotiation occur first and you can 1095 * only negotiat one or the other at a time otherwise in the event of a message 1096 * reject, you wouldn't be able to tell which message was the culpret. 1097 */ 1098mk_dtr: 1099 test SCB_CONTROL,NEEDWDTR jnz mk_wdtr_16bit 1100 mvi ARG_1, MAXOFFSET /* Force an offset of 15 or 8 if WIDE */ 1101 1102mk_sdtr: 1103 mvi DINDIR,1 /* extended message */ 1104 mvi DINDIR,3 /* extended message length = 3 */ 1105 mvi DINDIR,1 /* SDTR code */ 1106 call sdtr_to_rate 1107 mov DINDIR,RETURN_1 /* REQ/ACK transfer period */ 1108 cmp ARG_1, MAXOFFSET je mk_sdtr_max_offset 1109 and DINDIR,0x0f,SINDIR /* Sync Offset */ 1110 1111mk_sdtr_done: 1112 add MSG_LEN,COMP_MSG0,DINDEX ret /* update message length */ 1113 1114mk_sdtr_max_offset: 1115/* 1116 * We're initiating sync negotiation, so request the max offset we can (15 or 8) 1117 */ 1118 /* Talking to a WIDE device? */ 1119 test SCSIRATE, WIDEXFER jnz wmax_offset 1120 mvi DINDIR, MAX_OFFSET_8BIT 1121 jmp mk_sdtr_done 1122 1123wmax_offset: 1124 mvi DINDIR, MAX_OFFSET_16BIT 1125 jmp mk_sdtr_done 1126 1127mk_wdtr_16bit: 1128 mvi ARG_1,BUS_16_BIT 1129mk_wdtr: 1130 mvi DINDIR,1 /* extended message */ 1131 mvi DINDIR,2 /* extended message length = 2 */ 1132 mvi DINDIR,3 /* WDTR code */ 1133 mov DINDIR,ARG_1 /* bus width */ 1134 1135 add MSG_LEN,COMP_MSG0,DINDEX ret /* update message length */ 1136 1137sdtr_to_rate: 1138 call ndx_dtr /* index scratch space for target */ 1139 shr A,SINDIR,0x4 1140 dec SINDEX /* Preserve SINDEX */ 1141 and A,0x7 1142 clr RETURN_1 1143sdtr_to_rate_loop: 1144 test A,0x0f jz sdtr_to_rate_done 1145 add RETURN_1,0x19 1146 dec A 1147 jmp sdtr_to_rate_loop 1148sdtr_to_rate_done: 1149 shr RETURN_1,0x2 1150 add RETURN_1,0x19 1151 test SXFRCTL0,ULTRAEN jz return 1152 shr RETURN_1,0x1 1153return: 1154 ret | |