Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / scsi / 53c700.scr
diff --git a/kernel/drivers/scsi/53c700.scr b/kernel/drivers/scsi/53c700.scr
new file mode 100644 (file)
index 0000000..ec822e3
--- /dev/null
@@ -0,0 +1,411 @@
+; Script for the NCR (or symbios) 53c700 and 53c700-66 chip
+;
+; Copyright (C) 2001 James.Bottomley@HansenPartnership.com
+;;-----------------------------------------------------------------------------
+;;  
+;;  This program is free software; you can redistribute it and/or modify
+;;  it under the terms of the GNU General Public License as published by
+;;  the Free Software Foundation; either version 2 of the License, or
+;;  (at your option) any later version.
+;;
+;;  This program is distributed in the hope that it will be useful,
+;;  but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;  GNU General Public License for more details.
+;;
+;;  You should have received a copy of the GNU General Public License
+;;  along with this program; if not, write to the Free Software
+;;  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+;;
+;;-----------------------------------------------------------------------------
+;
+; This script is designed to be modified for the particular command in
+; operation.  The particular variables pertaining to the commands are:
+;
+ABSOLUTE       Device_ID = 0           ; ID of target for command
+ABSOLUTE       MessageCount = 0        ; Number of bytes in message
+ABSOLUTE       MessageLocation = 0     ; Addr of message
+ABSOLUTE       CommandCount = 0        ; Number of bytes in command
+ABSOLUTE       CommandAddress = 0      ; Addr of Command
+ABSOLUTE       StatusAddress = 0       ; Addr to receive status return
+ABSOLUTE       ReceiveMsgAddress = 0   ; Addr to receive msg
+;
+; This is the magic component for handling scatter-gather.  Each of the
+; SG components is preceded by a script fragment which moves the
+; necessary amount of data and jumps to the next SG segment.  The final
+; SG segment jumps back to .  However, this address is the first SG script
+; segment.
+;
+ABSOLUTE       SGScriptStartAddress = 0
+
+; The following represent status interrupts we use 3 hex digits for
+; this: 0xPRS where 
+
+; P:
+ABSOLUTE       AFTER_SELECTION         = 0x100
+ABSOLUTE       BEFORE_CMD              = 0x200
+ABSOLUTE       AFTER_CMD               = 0x300
+ABSOLUTE       AFTER_STATUS            = 0x400
+ABSOLUTE       AFTER_DATA_IN           = 0x500
+ABSOLUTE       AFTER_DATA_OUT          = 0x600
+ABSOLUTE       DURING_DATA_IN          = 0x700
+
+; R:
+ABSOLUTE       NOT_MSG_OUT             = 0x10
+ABSOLUTE       UNEXPECTED_PHASE        = 0x20
+ABSOLUTE       NOT_MSG_IN              = 0x30
+ABSOLUTE       UNEXPECTED_MSG          = 0x40
+ABSOLUTE       MSG_IN                  = 0x50
+ABSOLUTE       SDTR_MSG_R              = 0x60
+ABSOLUTE       REJECT_MSG_R            = 0x70
+ABSOLUTE       DISCONNECT              = 0x80
+ABSOLUTE       MSG_OUT                 = 0x90
+ABSOLUTE       WDTR_MSG_R              = 0xA0
+
+; S:
+ABSOLUTE       GOOD_STATUS             = 0x1
+
+; Combinations, since the script assembler can't process |
+ABSOLUTE       NOT_MSG_OUT_AFTER_SELECTION = 0x110
+ABSOLUTE       UNEXPECTED_PHASE_BEFORE_CMD = 0x220
+ABSOLUTE       UNEXPECTED_PHASE_AFTER_CMD = 0x320
+ABSOLUTE       NOT_MSG_IN_AFTER_STATUS = 0x430
+ABSOLUTE       GOOD_STATUS_AFTER_STATUS = 0x401
+ABSOLUTE       UNEXPECTED_PHASE_AFTER_DATA_IN = 0x520
+ABSOLUTE       UNEXPECTED_PHASE_AFTER_DATA_OUT = 0x620
+ABSOLUTE       UNEXPECTED_MSG_BEFORE_CMD = 0x240
+ABSOLUTE       MSG_IN_BEFORE_CMD = 0x250
+ABSOLUTE       MSG_IN_AFTER_CMD = 0x350
+ABSOLUTE       SDTR_MSG_BEFORE_CMD = 0x260
+ABSOLUTE       REJECT_MSG_BEFORE_CMD = 0x270
+ABSOLUTE       DISCONNECT_AFTER_CMD = 0x380
+ABSOLUTE       SDTR_MSG_AFTER_CMD = 0x360
+ABSOLUTE       WDTR_MSG_AFTER_CMD = 0x3A0
+ABSOLUTE       MSG_IN_AFTER_STATUS = 0x440
+ABSOLUTE       DISCONNECT_AFTER_DATA = 0x580
+ABSOLUTE       MSG_IN_AFTER_DATA_IN = 0x550
+ABSOLUTE       MSG_IN_AFTER_DATA_OUT = 0x650
+ABSOLUTE       MSG_OUT_AFTER_DATA_IN = 0x590
+ABSOLUTE       DATA_IN_AFTER_DATA_IN = 0x5a0
+ABSOLUTE       MSG_IN_DURING_DATA_IN = 0x750
+ABSOLUTE       DISCONNECT_DURING_DATA = 0x780
+
+;
+; Other interrupt conditions
+; 
+ABSOLUTE       RESELECTED_DURING_SELECTION = 0x1000
+ABSOLUTE       COMPLETED_SELECTION_AS_TARGET = 0x1001
+ABSOLUTE       RESELECTION_IDENTIFIED = 0x1003
+;
+; Fatal interrupt conditions.  If you add to this, also add to the
+; array of corresponding messages
+;
+ABSOLUTE       FATAL = 0x2000
+ABSOLUTE       FATAL_UNEXPECTED_RESELECTION_MSG = 0x2000
+ABSOLUTE       FATAL_SEND_MSG = 0x2001
+ABSOLUTE       FATAL_NOT_MSG_IN_AFTER_SELECTION = 0x2002
+ABSOLUTE       FATAL_ILLEGAL_MSG_LENGTH = 0x2003
+
+ABSOLUTE       DEBUG_INTERRUPT = 0x3000
+ABSOLUTE       DEBUG_INTERRUPT1 = 0x3001
+ABSOLUTE       DEBUG_INTERRUPT2 = 0x3002
+ABSOLUTE       DEBUG_INTERRUPT3 = 0x3003
+ABSOLUTE       DEBUG_INTERRUPT4 = 0x3004
+ABSOLUTE       DEBUG_INTERRUPT5 = 0x3005
+ABSOLUTE       DEBUG_INTERRUPT6 = 0x3006
+
+
+;
+; SCSI Messages we interpret in the script
+;
+ABSOLUTE       COMMAND_COMPLETE_MSG    = 0x00
+ABSOLUTE       EXTENDED_MSG            = 0x01
+ABSOLUTE       SDTR_MSG                = 0x01
+ABSOLUTE       SAVE_DATA_PTRS_MSG      = 0x02
+ABSOLUTE       RESTORE_DATA_PTRS_MSG   = 0x03
+ABSOLUTE       WDTR_MSG                = 0x03
+ABSOLUTE       DISCONNECT_MSG          = 0x04
+ABSOLUTE       REJECT_MSG              = 0x07
+ABSOLUTE       PARITY_ERROR_MSG        = 0x09
+ABSOLUTE       SIMPLE_TAG_MSG          = 0x20
+ABSOLUTE       IDENTIFY_MSG            = 0x80
+ABSOLUTE       IDENTIFY_MSG_MASK       = 0x7F
+ABSOLUTE       TWO_BYTE_MSG            = 0x20
+ABSOLUTE       TWO_BYTE_MSG_MASK       = 0x0F
+
+; This is where the script begins
+
+ENTRY  StartUp
+
+StartUp:
+       SELECT  ATN Device_ID, Reselect
+       JUMP    Finish, WHEN STATUS
+       JUMP    SendIdentifyMsg, IF MSG_OUT
+       INT     NOT_MSG_OUT_AFTER_SELECTION
+
+Reselect:
+       WAIT    RESELECT SelectedAsTarget
+       INT     RESELECTED_DURING_SELECTION, WHEN MSG_IN
+       INT     FATAL_NOT_MSG_IN_AFTER_SELECTION
+
+       ENTRY   GetReselectionData
+GetReselectionData:
+       MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
+       INT     RESELECTION_IDENTIFIED
+
+       ENTRY   GetReselectionWithTag
+GetReselectionWithTag:
+       MOVE    3, ReceiveMsgAddress, WHEN MSG_IN
+       INT     RESELECTION_IDENTIFIED
+       
+       ENTRY   SelectedAsTarget
+SelectedAsTarget:
+; Basically tell the selecting device that there's nothing here
+       SET     TARGET
+       DISCONNECT
+       CLEAR   TARGET
+       INT     COMPLETED_SELECTION_AS_TARGET
+;
+; These are the messaging entries
+;
+; Send a message.  Message count should be correctly patched
+       ENTRY   SendMessage
+SendMessage:
+       MOVE    MessageCount, MessageLocation, WHEN MSG_OUT
+ResumeSendMessage:
+       RETURN, WHEN NOT MSG_OUT
+       INT     FATAL_SEND_MSG
+
+       ENTRY   SendMessagePhaseMismatch
+SendMessagePhaseMismatch:
+       CLEAR   ACK
+       JUMP    ResumeSendMessage
+;
+; Receive a message.  Need to identify the message to
+; receive it correctly
+       ENTRY   ReceiveMessage
+ReceiveMessage:
+       MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
+;
+; Use this entry if we've just tried to look at the first byte
+; of the message and want to process it further
+ProcessReceiveMessage:
+       JUMP    ReceiveExtendedMessage, IF EXTENDED_MSG
+       RETURN, IF NOT TWO_BYTE_MSG, AND MASK TWO_BYTE_MSG_MASK
+       CLEAR   ACK
+       MOVE    1, ReceiveMsgAddress + 1, WHEN MSG_IN
+       RETURN
+ReceiveExtendedMessage:
+       CLEAR   ACK
+       MOVE    1, ReceiveMsgAddress + 1, WHEN MSG_IN
+       JUMP    Receive1Byte, IF 0x01
+       JUMP    Receive2Byte, IF 0x02
+       JUMP    Receive3Byte, IF 0x03
+       JUMP    Receive4Byte, IF 0x04
+       JUMP    Receive5Byte, IF 0x05
+       INT     FATAL_ILLEGAL_MSG_LENGTH
+Receive1Byte:
+       CLEAR   ACK
+       MOVE    1, ReceiveMsgAddress + 2, WHEN MSG_IN
+       RETURN
+Receive2Byte:
+       CLEAR   ACK
+       MOVE    2, ReceiveMsgAddress + 2, WHEN MSG_IN
+       RETURN
+Receive3Byte:
+       CLEAR   ACK
+       MOVE    3, ReceiveMsgAddress + 2, WHEN MSG_IN
+       RETURN
+Receive4Byte:
+       CLEAR   ACK
+       MOVE    4, ReceiveMsgAddress + 2, WHEN MSG_IN
+       RETURN
+Receive5Byte:
+       CLEAR   ACK
+       MOVE    5, ReceiveMsgAddress + 2, WHEN MSG_IN
+       RETURN
+;
+; Come here from the message processor to ignore the message
+;
+       ENTRY   IgnoreMessage
+IgnoreMessage:
+       CLEAR   ACK
+       RETURN
+;
+; Come here to send a reply to a message
+;
+       ENTRY   SendMessageWithATN
+SendMessageWithATN:
+       SET     ATN
+       CLEAR   ACK
+       JUMP    SendMessage
+
+SendIdentifyMsg:
+       CALL    SendMessage
+       CLEAR   ATN
+
+IgnoreMsgBeforeCommand:
+       CLEAR   ACK
+       ENTRY   SendCommand
+SendCommand:
+       JUMP    Finish, WHEN STATUS
+       JUMP    MsgInBeforeCommand, IF MSG_IN
+       INT     UNEXPECTED_PHASE_BEFORE_CMD, IF NOT CMD
+       MOVE    CommandCount, CommandAddress, WHEN CMD
+ResumeSendCommand:
+       JUMP    Finish, WHEN STATUS
+       JUMP    MsgInAfterCmd, IF MSG_IN
+       JUMP    DataIn, IF DATA_IN
+       JUMP    DataOut, IF DATA_OUT
+       INT     UNEXPECTED_PHASE_AFTER_CMD
+
+IgnoreMsgDuringData:
+       CLEAR   ACK
+       ; fall through to MsgInDuringData
+
+Entry MsgInDuringData
+MsgInDuringData:
+;
+; Could be we have nothing more to transfer
+;
+       JUMP    Finish, WHEN STATUS
+       MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
+       JUMP    DisconnectDuringDataIn, IF DISCONNECT_MSG
+       JUMP    IgnoreMsgDuringData, IF SAVE_DATA_PTRS_MSG
+       JUMP    IgnoreMsgDuringData, IF RESTORE_DATA_PTRS_MSG
+       INT     MSG_IN_DURING_DATA_IN
+
+MsgInAfterCmd:
+       MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
+       JUMP    DisconnectAfterCmd, IF DISCONNECT_MSG
+       JUMP    IgnoreMsgInAfterCmd, IF SAVE_DATA_PTRS_MSG
+       JUMP    IgnoreMsgInAfterCmd, IF RESTORE_DATA_PTRS_MSG
+       CALL    ProcessReceiveMessage
+       INT     MSG_IN_AFTER_CMD
+       CLEAR   ACK
+       JUMP    ResumeSendCommand
+
+IgnoreMsgInAfterCmd:
+       CLEAR   ACK
+       JUMP    ResumeSendCommand
+
+DisconnectAfterCmd:
+       CLEAR   ACK
+       WAIT    DISCONNECT
+       ENTRY   Disconnect1
+Disconnect1:
+       INT     DISCONNECT_AFTER_CMD
+       ENTRY   Disconnect2
+Disconnect2:
+; We return here after a reselection
+       CLEAR   ACK
+       JUMP    ResumeSendCommand
+
+MsgInBeforeCommand:
+       MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
+       JUMP    IgnoreMsgBeforeCommand, IF SAVE_DATA_PTRS_MSG
+       JUMP    IgnoreMsgBeforeCommand, IF RESTORE_DATA_PTRS_MSG
+       CALL    ProcessReceiveMessage
+       INT     MSG_IN_BEFORE_CMD
+       CLEAR   ACK
+       JUMP    SendCommand
+
+DataIn:
+       CALL    SGScriptStartAddress
+ResumeDataIn:
+       JUMP    Finish, WHEN STATUS
+       JUMP    MsgInAfterDataIn, IF MSG_IN
+       JUMP    DataInAfterDataIn, if DATA_IN
+       INT     MSG_OUT_AFTER_DATA_IN, if MSG_OUT
+       INT     UNEXPECTED_PHASE_AFTER_DATA_IN
+
+DataInAfterDataIn:
+       INT     DATA_IN_AFTER_DATA_IN
+       JUMP    ResumeDataIn
+
+DataOut:
+       CALL    SGScriptStartAddress
+ResumeDataOut:
+       JUMP    Finish, WHEN STATUS
+       JUMP    MsgInAfterDataOut, IF MSG_IN
+       INT     UNEXPECTED_PHASE_AFTER_DATA_OUT
+
+MsgInAfterDataIn:
+       MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
+       JUMP    DisconnectAfterDataIn, IF DISCONNECT_MSG
+       JUMP    IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG
+       JUMP    IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG
+       CALL    ProcessReceiveMessage
+       INT     MSG_IN_AFTER_DATA_IN
+       CLEAR   ACK
+       JUMP    ResumeDataIn
+
+DisconnectDuringDataIn:
+       CLEAR   ACK
+       WAIT    DISCONNECT
+       ENTRY   Disconnect3
+Disconnect3:
+       INT     DISCONNECT_DURING_DATA
+       ENTRY   Disconnect4
+Disconnect4:
+; we return here after a reselection
+       CLEAR   ACK
+       JUMP    ResumeSendCommand
+
+
+DisconnectAfterDataIn:
+       CLEAR   ACK
+       WAIT    DISCONNECT
+       ENTRY   Disconnect5
+Disconnect5:
+       INT     DISCONNECT_AFTER_DATA
+       ENTRY   Disconnect6
+Disconnect6:
+; we return here after a reselection
+       CLEAR   ACK
+       JUMP    ResumeDataIn
+
+MsgInAfterDataOut:
+       MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
+       JUMP    DisconnectAfterDataOut, if DISCONNECT_MSG
+       JUMP    IgnoreMsgAfterData, IF SAVE_DATA_PTRS_MSG
+       JUMP    IgnoreMsgAfterData, IF RESTORE_DATA_PTRS_MSG
+       CALL    ProcessReceiveMessage
+       INT     MSG_IN_AFTER_DATA_OUT
+       CLEAR   ACK
+       JUMP    ResumeDataOut
+
+IgnoreMsgAfterData:
+       CLEAR   ACK
+; Data in and out do the same thing on resume, so pick one
+       JUMP    ResumeDataIn
+
+DisconnectAfterDataOut:
+       CLEAR   ACK
+       WAIT    DISCONNECT
+       ENTRY   Disconnect7
+Disconnect7:
+       INT     DISCONNECT_AFTER_DATA
+       ENTRY   Disconnect8
+Disconnect8:
+; we return here after a reselection
+       CLEAR   ACK
+       JUMP    ResumeDataOut
+
+Finish:
+       MOVE    1, StatusAddress, WHEN STATUS
+       INT     NOT_MSG_IN_AFTER_STATUS, WHEN NOT MSG_IN
+       MOVE    1, ReceiveMsgAddress, WHEN MSG_IN
+       JUMP    FinishCommandComplete, IF COMMAND_COMPLETE_MSG
+       CALL    ProcessReceiveMessage
+       INT     MSG_IN_AFTER_STATUS
+       ENTRY   FinishCommandComplete
+FinishCommandComplete:
+       CLEAR   ACK
+       WAIT    DISCONNECT
+       ENTRY   Finish1
+Finish1:
+       INT     GOOD_STATUS_AFTER_STATUS
+       ENTRY   Finish2
+Finish2:
+