.TITLE XAMESSAGE .IDENT 'V04-001' ;**************************************************************************** ;* * ;* COPYRIGHT (c) 1978, 1980, 1982, 1984 BY * ;* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. * ;* ALL RIGHTS RESERVED. * ;* * ;* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED * ;* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE * ;* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER * ;* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY * ;* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY * ;* TRANSFERRED. * ;* * ;* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE * ;* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT * ;* CORPORATION. * ;* * ;* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS * ;* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. * ;* * ;* * ;**************************************************************************** ;**************************************************************************** ;* * ;* DIGITAL ASSUMES NO RESPONSIBILITY TO SUPPORT THE SOFTWARE DESCRIBED * ;* DESCRIBED IN THIS MODULE, NOR TO ANSWER INQUIRIES ABOUT IT. * ;* * ;* THIS SOFTWARE MODULE IS PART OF A TEMPLATE WHICH MAY REQUIRE CUSTOMER * ;* MODIFICATIONS TO WORK IN ALL CIRCUMSTANCES. * ;* * ;**************************************************************************** ; ;++ ; ; FACILITY: ; ; VAX/VMS Executive, I/O Drivers ; ; ABSTRACT: ; ; This module allows you to connect a DR11-W to a DRV11-WA; or ; a DR11-W to another DR11-W in an interprocessor link and to ; perform data transfers from one processor to the other. ; ; AUTHOR: Donald G. Blair ; ; MODIFIED BY: ; ;-- .SBTTL LOCAL DEFFINITIONS AND STORAGE ;++ ; XAMESSAGE ROUTINE ; ; CALLING SEQUENCE: ; ; CALL (BUFFER_ADDRESS,BUFFER_SIZE,TRANSFER_DIRECTION,CHANNEL,- ; EVENT_FLAG,TIME_OUT,STATUS_ADDRESS,LOCAL_DEVICE,REMOTE_DEVICE) ; ; BUFFER_ADDRESS = ADDRESS OF DATA BUFFER TO TRANSFER ; BUFFER_SIZE = SIZE IN BYTES OF DATA BUFFER TO TRANSFER. ; NOTE THAT RECEIVER AND TRANSMITTER MUST AGREE ON THE ; SIZE OF THE TRANSFER. ; TRANSFER_DIRECTION = DIRECTION FOR DATA TO GO ; 0 = TRANSMIT ; 1 = RECEIVE ; CHANNEL = CHANNEL ASSIGNED TO DEVICE (DR11-W OR DRV11-WA) ; EVENT_FLAG = EVENT FLAG TO SET WHEN TRANSFER COMPLETE ; TIME_OUT = I/O TIME-OUT VALUE IN SECONDS ; STATUS_ADDRESS = ADDRESS OF 20 BYTE ARRAY TO RECEIVE ; FINAL STATUS - ONLY FILLED IN IF USER'S PARAMETERS ARE ; ALL VALID. ; IOSB - 8 BYTES ; I/O STATUS BLOCK FROM QUEUE I/O REQUEST ; ERROR - 4 BYTES - NOT USED - FOR COMPATIBILITY ; WITH OLD VERSIONS OF THIS MODULE. ; STATE - 4 BYTES ; THIS FIELD TRACKS WHICH QIO WAS THE LATEST ; ONE TO BE PERFORMED. ; 01 - LAST QIO WAS ONE IN THE MAIN ROUTINE. ; 02 - LAST QIO WAS ONE IN AST_GO. ; SSRV_STS - 4 BYTES ; VALUE OF R0 RETURNED FROM THE LAST SYSTEM ; SERVICE EXECUTED. ; LOCAL_DEVICE = TYPE OF DEVICE AT LOCAL END OF LINK. ; DR11_W = 1 ; DRV11_WA = 2 ; REMOTE_DEVICE = TYPE OF DEVICE AT REMOTE END OF LINK. ; DR11_W = 1 ; DRV11_WA = 2 ; ;-- $SSDEF ; PARAMETER OFFSETS. BUFFER_P = 4 BUF_SIZE_P = 8 DIRECTION_P = 12 CHAN_P = 16 EFN_P = 20 TIME_P = 24 STS_ADDR_P = 28 LCL_DEVICE_P = 32 REM_DEVICE_P = 36 .PSECT XADATA,LONG ; SAVED PARAMETER VALUES. BUFFER: .LONG 0 ; SAVED BUFFER ADDRESS BUF_SIZE: .LONG 0 ; SAVED BUFFER SIZE DIRECTION: .LONG 0 ; DIRECTION OF TRANSFER CHAN: .LONG 0 ; SAVED CHANNEL ASSIGNED TO DR11-W EFN: .LONG 0 ; SAVED EVENT FLAG NUMBER TIME: .LONG 0 ; SAVED TIME-OUT VALUE STS_ADDR: .LONG 0 ; ADDRESS OF CALLERS STATUS VARIABLE ; DEFINE DEVICE TYPES AT BOTH ENDS OF INTERPROCESSOR LINK. DR11_W = 1 DRV11_WA = 2 LCL_DEVICE: .BLKL 1 ; TYPE OF DEVICE ON THIS SYSTEM. REM_DEVICE: .BLKL 1 ; TYPE OF DEVICE AT OTHER END OF LINK. AST: .BLKL 1 ; NOTE - ORDER IS ASSUMED FOR NEXT FOUR VARIABLES IOSB: .QUAD 0 ; QIO IOSB ERROR: .LONG 0 ; ERROR VALUE PARAMATER STATE: .LONG 0 ; STATE VARIABLE SSRV_STS: .LONG 0 ; SYSTEM SERVICE STATUS .PAGE .SBTTL VALIDATE AND SAVE CALLER'S PARAMETERS .PSECT XACODE,NOWRT .ENTRY XAMESSAGE,^M ; VALIDATE AND SAVE CALLER'S PARAMATERS CLRQ W^IOSB ; CLEAR IOSB CLRL W^ERROR ; CLEAR ERROR FIELD CLRL W^SSRV_STS ; CLEAR SYS SERVICE RETURN STATUS. CMPW (AP),#9 ; MUST HAVE 9 PARAMATERS BEQL 10$ ; BR IF OKAY BRW BADPARAM ; BR TO SIGNAL ERROR 10$: MOVL BUFFER_P(AP),W^BUFFER ; GET BUFFER ADDRESS MOVL @BUF_SIZE_P(AP),W^BUF_SIZE ; GET BUFFER SIZE BNEQ 20$ ; BR IF OKAY BRW BADPARAM ; XFER SIZE IS NON ZERO -- ILLEGAL 20$: MOVZBL @DIRECTION_P(AP),W^DIRECTION ; GET TRANSFER DIRECTION FLAG CMPL W^DIRECTION,#2 ; THE ONLY LEGAL VALUES ARE 0,1 BLEQU 25$ ; BR IF OKAY BRW BADPARAM ; ELSE BR TO SIGNAL ERROR 25$: MOVL @CHAN_P(AP),W^CHAN ; FETCH CHANNEL MOVL @EFN_P(AP),W^EFN ; AND EVENT FLAG BEQL BADPARAM ; MUST SPECIFY EVENT FLAG MOVL @TIME_P(AP),W^TIME ; FETCH TIME-OUT VALUE BNEQ 30$ ; IF NONZERO, USE IT. MOVZBL #5,W^TIME ; ELSE USE SOME "REASONABLE" VALUE 30$: MOVL STS_ADDR_P(AP),W^STS_ADDR ; GET ADDRESS OF STATUS ARRAY BEQL BADPARAM ; IF NOT SPECIFIED, ERROR CLRL @W^STS_ADDR ; INITIALIZE STATUS VALUE MOVZBL @LCL_DEVICE_P(AP),W^LCL_DEVICE ; GET LOCAL DEVICE TYPE CMPL #DRV11_WA,W^LCL_DEVICE ; IS LOCAL DEVICE A DRV11-WA? BEQLU 35$ ; BRANCH IF SO. CMPL #DR11_W,W^LCL_DEVICE ; IS LOCAL DEVICE A DR11-W? BNEQU BADPARAM ; ERROR IF IT'S NOT EITHER. 35$: MOVZBL @REM_DEVICE_P(AP),W^REM_DEVICE ; GET REMOTE DEVICE TYPE CMPL #DRV11_WA,W^REM_DEVICE ; IS REMOTE DEVICE A DRV11-WA? BEQLU 50$ ; BRANCH IF SO. CMPL #DR11_W,W^REM_DEVICE ; IS REMOTE DEVICE A DR11-W? BNEQU BADPARAM ; ERROR IF IT'S NOT EITHER. 50$: $CLREF_S EFN=EFN ; MAKE SURE EFN IS CLEAR BLBS R0,100$ ; BR IF NO SYS SERVICE ERROR RET 100$: CMPL #DRV11_WA,W^LCL_DEVICE ; DISPATCH BASED ON LOCAL DEVICE TYPE BEQL DRV11_WA_START ; LOCAL DEVICE IS DRV11-WA BRW DR11_W_START ; LOCAL DEVICE IS DR11-W BADPARAM: MOVZWL #SS$_BADPARAM,R0 ; ELSE RETURN ERROR. RET .PAGE .SBTTL START MESSAGE PROCESSOR DRV11_WA_START: ; THE LOCAL DEVICE IS A DRV11-WA BLBC W^DIRECTION,10$ ; BRANCH IF IT'S A XMIT OPERATION MOVAL W^AST_COMPLETION,W^AST ; AST_COMPLETION IS THE AST FOR RECEIVE BRB 20$ 10$: MOVAL W^AST_GO,W^AST ; AST_GO IS THE AST FOR XMIT OPERATION 20$: MOVL #01,W^STATE ; STATE = 1 => LAST QIO WAS IN MAIN ; ROUTINE. $QIO_S CHAN=W^CHAN,- ; BLOCK MODE READ - EVEN IF IT'S XMIT FUNC=#,- IOSB=W^IOSB,- ASTADR=@W^AST,- P1=@W^BUFFER,- ; ADDRESS OF CALLER'S DATA BUFFER P2=W^BUF_SIZE,- ; LENGTH OF DATA BUFFER P3=W^TIME,- ; TIMEOUT VALUE P4=#7 ; INTERRUPT+READ BRW MAIN_EXIT ; EXIT MAIN ROUTINE. DR11_W_START: ; LOCAL DEVICE IS DR11-W MOVL #01,W^STATE ; STATE = 1 => LAST QIO WAS IN MAIN ; ROUTINE. $QIO_S CHAN=W^CHAN,- ; QIO TO ENABLE AST'S FUNC=#,- IOSB=W^IOSB,- P1=W^AST_GO BLBC R0,MAIN_EXIT ; BRANCH ON ERROR - ALL DONE. BLBS W^DIRECTION,MAIN_EXIT ; BRANCH IF THIS IS A RECEIVE OPERATION CMPL #DR11_W,W^REM_DEVICE ; IS REMOTE DEVICE A DR11-W? BNEQU MAIN_EXIT ; BRANCH IF NOT. $QIO_S CHAN=W^CHAN,- ; PERFORM 0-LENGTH QIO. THIS FUNC=#,- ; SERVES TO SET THE IOSB=W^IOSB,- ; FNCT BITS (CONTAINED IN P4), P1=@W^BUFFER,- ; IN THE CSR, INTERRUPTING THE REMOTE P2=#0,- ; DR11-W. P4=#2 MAIN_EXIT: MOVL R0,W^SSRV_STS ; SAVE QIO STATUS RETURN MOVC3 #20,W^IOSB,@W^STS_ADDR ; RETURN STATUS TO THE USER BLBS W^SSRV_STS,10$ ; IF SUCCESS, DON'T SET EVFLAG YET $SETEF_S EFN=W^EFN ; IF ERROR, SET EVENT FLAG -- ALL DONE. 10$: MOVL W^SSRV_STS,R0 ; RESTORE R0 STATUS RETURN. RET .PAGE .SBTTL AST_GO - AST WHICH INITIATES THE QIO TO PERFORM ACTUAL XFER. .ENTRY AST_GO,^M ; ; This AST is called to perform the $QIO which begins the actual transfer ; of user data. (Hence the name AST_GO.) ; BLBS W^DIRECTION,AST_RECEIVE ; BRANCH IF RECEIVE OPERATION ; ; On a DR11-W, this AST is delivered as a result of an interrupt from the ; remote device, so no status checking is necessary. On a DRV11-WA, this AST ; is delivered as a result of an intentionally premature I/O completion, so ; we expect the status return to be SS$_OPINCOMPL. ; AST_XMIT: CMPL #DRV11_WA,W^LCL_DEVICE ; IS LOCAL DEVICE A DRV11-WA? BNEQ 20$ ; BRANCH IF NOT. CMPW W^IOSB,#SS$_OPINCOMPL ; STATUS SHOULD BE SS$_OPINCOMPL. BEQL 20$ ; BR IF EXPECTED STATUS BRW IO_DONE ; ELSE ERROR 20$: MOVL #02,W^STATE ; STATE = 2 => LAST QIO WAS IN AST_GO. $QIO_S CHAN=W^CHAN,- ; BLOCK MODE WRITE FUNC=#,- IOSB=W^IOSB,- ASTADR=W^AST_COMPLETION,- P1=@W^BUFFER,- ; ADDRESS OF CALLER'S DATA BUFFER P2=W^BUF_SIZE,- ; LENGTH OF BUFFER P3=W^TIME,- ; TIMEOUT VALUE P4=#4 ; FNCT BITS FOR CSR BLBS R0,40$ ; RETURN IF QIO STARTED OK BRW IO_DONE ; ALL DONE IF ERROR OCCURRED. 40$: RET ; DISMISS THIS AST, AND ; WAIT FOR AST_COMPLETION ; ; AST_RECEIVE is only used by the DR11-W, since the DRV11-WA initiates ; the actual data transfer from the main routine when it is the receiver. ; AST_RECEIVE: MOVL #02,W^STATE ; STATE = 2 => LAST QIO WAS IN AST_GO. $QIO_S CHAN=W^CHAN,- ; BLOCK MODE READ FUNC=#,- IOSB=W^IOSB,- ASTADR=W^AST_COMPLETION,- ; ADDRESS OF AST FOR I/O COMPLETION P1=@W^BUFFER,- ; ADDRESS OF CALLER'S DATA BUFFER P2=W^BUF_SIZE,- ; LENGTH OF DATA BUFFER P3=W^TIME,- ; TIMEOUT VALUE P4=#7 ; INTERRUPT+READ BLBS R0,10$ ; RETURN IF QIO STARTED OK BRW IO_DONE ; ON ERROR, WE'RE ALL DONE. 10$: RET .PAGE .SBTTL AST_COMPLETION - COMPLETION ROUTINE FOR I/O TRANSFER. .ENTRY AST_COMPLETION,^M ; ; This AST is called when the actual transfer of data is complete. Note that ; the status value in the IOSB must be checked by the caller when we're done. ; IO_DONE is also called when an error occurs and the handshaking sequence ; must be terminated. ; IO_DONE: MOVC3 #20,W^IOSB,@W^STS_ADDR ; RETURN STATUS TO THE USER $SETEF_S EFN=W^EFN ; SET THE CALLER'S EVENT FLAG MOVZBL #SS$_NORMAL,R0 ; SIGNAL SUCCESSFUL AST COMPLETION. RET .END