Deleted Added
full compact
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