.SBTTL RQIO request general I/O .TITLE RQIO request I/O from master .PSECT RQIO .IDENT /M002/ ;+ ; RQIO ; Request I/O from auxiliary task on master system. ; ; PURPOSE ; Builds an I/O request packet from the I/O packet and ; sends it to the auxiliary task. Moves any returned ; data to ACP working storage ; ; INPUTS ; R5 I/O packet ; ; OUTPUTS ; R0-R5 preserved ; .RQPK - packet as sent to master ; .RTPK - packet as returned from master ; FID moved to .FILNO, FILSQ if returned ; FNB moved to .DRFNB, if returned ; On error, error code returned to .IOSTS ; ; EXTERNAL REFERENCES ; .NSND ; ; AUTHOR ; Daniel McCoy Informatics Inc. Palo Alto, Ca. ; ; REVISIONS LAST CHANGED 15 May 80 DSM ; DATE PERSON STATEMENT OF CHANGES ; 9 Mar 80 DSM Multi device support ; 11/28/79 DSM Version two of dual porting ; 4/17/79 DSM Return status only on error ; 1/30/79 DSM First coding ; ; NOTES ; RQIO is defined only if the offset in .EXDSP corresponds ; to IO.CRE, IO.EXT, IO.DEL, IO.ENA or IO.RNA. ; Access goes to RQACC and deaccess to RQDAC. ; If an IO.DAC or IO.CLN has been done on a marked ; for delete file, .DLFIL has changed .EXDSP to ; correspond to IO.DEL. ;- ; .RQIO:: PUSH ; Save some registers MOV #.RQPK,R2 ; Get pointer to I/O request packet ; ; Move parameters to request packet ; CLR X.FIDP(R2) ; Assume no FID CLR X.RWAT(R2) ; No attribute stuff MOV I.EXTD(R5),X.EXTD(R2) ; Extend stuff MOV I.EXTD+2(R5),X.EXTD+2(R2) CLR X.RTRV(R2) ; No access stuff CLR X.FNBP(R2) ; Assume no FNB ; ; Move access identification stuff CALL MOVID ; ; Move function code ; MOVB .EXDSP,R0 ; Get function (in offset form) ASR R0 ; Convert it from offset ADD #,R0 ; . back to function code SWAB R0 ; .. inverse of what DSPAT does MOV R0,X.FCN(R2) ; Store function code ; ; Figure out whether to send FID or FNB ; CMP R0,#IO.ACR ; Compare it to access BLO 20$ ; If function code is lower than ; access, we assume it's a directory op ; ; FID is to be sent MOV .FILNO,X.FBLK(R2) ; Move file number MOV .FILSQ,X.FBLK+2(R2) ; Move file sequence number CLR X.FBLK+4(R2) ; Zero unused word MOV #X.FBLK,X.FIDP(R2) ; Set pointer BR 30$ 20$: ; ; FNB to be sent MOV #X.FBLK,X.FNBP(R2) ; Set pointer MOV #S.DRFN/2,R2 ; Length to move (words) MOV #.DRFNB,R0 ; Point to FNB MOV #.RQPK+X.FBLK,R1 ; Point to FNB destination 25$: MOV (R0)+,(R1)+ ; Move the FNB SOB R2,25$ 30$: ; CALL .NSND ; Send it off ; MOV #.RTPK,R2 ; Point to return packet CMPB #IS.SUC,Y.STAT(R2) ; Successful? BEQ 40$ ; Only return status code on error MOVB Y.STAT(R2),.IOSTS ; Return status code 40$: MOVB Y.STAT+1(R2),.IOSTS+1 ; Return status info MOV Y.STAT+2(R2),.IOSTS+2 ; Return status info TST Y.FIDP(R2) ; FID returned? BEQ 50$ ; No, check FNB ; ; FID returned ADD Y.FIDP(R2),R2 ; Add offset to FID MOV (R2)+,.FILNO ; Move file number MOV (R2),.FILSQ ; Move sequence number BR 60$ ; Skip FNB ; 50$: TST Y.FNBP(R2) ; FNB returned? BEQ 60$ ; No ; FNB returned. ADD Y.FNBP(R2),R2 ; Point to start of FNB MOV #S.DRFN/2,R1 ; Length to move (words) MOV #.DRFNB,R0 ; Where to move it. 55$: MOV (R2)+,(R0)+ ; Move it SOB R1,55$ ; 60$: POP ; Restore registers RETURN .PAGE .SBTTL RQACC Request access ;+ ; RQACC Entry to send an access request to the master system ; ; In and out are same as RQIO ; With the addition of: ; R0 points to FCB ; ; Access is governed here by three conditions ; A. This is the first access to this file ; B. Block locking is requested ; C. Block locking is already on ; ; A true, B false: A normal access, just clears the EXBITS (below). ; A true, B true: The access gets done using the FCB address ; for an ID and the NSBITS (below) set. ; A, B & C false: Normal again. ; A false, B & C true: Access not sent to master but IS.SUC returned. ; A false, and ; B & C not the same: Access rejected with IE.LCK error. ; ; Access always gets done and is identified with the task ; if no block locking is involved. ; If block locking is involved, an access gets done only on the ; the first request and is identified with the file (instead of task). ; If block locking is involved, but any task involved didn't request it, ; the current request is rejected. ; ;- ; Some abbreviations for various combinations of access bits LKBITS=&377 ; Bits for block locking request NSBITS=&377 ; Bits for access without share EXBITS=&377 ; Bits which needn't be passed ; .RQACC:: PUSH ; Save any registers that we need ; MOV #.RQPK,R2 ; Point to the request packet ; Set up function code MOV I.FCN(R5),X.FCN(R2) ; Move function code ; Move FID and set up pointer MOV .FILNO,X.FBLK(R2) ; Move file number MOV .FILSQ,X.FBLK+2(R2) ; Move file sequence number CLR X.FBLK+4(R2) ; Zero unused word MOV #X.FBLK,X.FIDP(R2) ; Set offset to FID in packet ; Set up other parameters CLR X.RWAT(R2) ; No attribute stuff CLR X.EXTD(R2) ; No extend stuff either CLR X.EXTD+2(R2) ; " " CLRB X.RTRV(R2) ; Take default window size CLR X.FNBP(R2) ; No FNB pointer ; ; Move access identification stuff CALL MOVID ; ; Set correct access mode depending on request and context ; FCB pointer in R0 ; ; If this is the first accessor CMPB F.NACS(R0),#1 ; The requestor is included in the count BHI 20$ ; If hi, other accessors ;; Then ;; If block locking requested BITB #LKBITS,I.ACTL(R5) ; Check locking bits BEQ 10$ ; If eq, locking not requested ;;; Then MOVB #NSBITS,X.ACTL(R2) ; Access with no share MOV R0,X.ID(R2) ; Use FCB address for ID BR 60$ ; Go do the access ;;; Else (no locking requested) 10$: MOVB I.ACTL(R5),X.ACTL(R2) ; Do access as requested BICB #EXBITS,X.ACTL(R2) ; Clear uneeded bits BR 60$ ; Go do the access ;; Else (not the first accessor) 20$: ;; If block locking requested BITB #LKBITS,I.ACTL(R5) ; Check locking bits BEQ 40$ ; If eq, locking not requested ;;; Then ;;; If block locking on already TST F.LKL(R0) ; Check lock list pointer BEQ 30$ ; If eq, no lock list ;;;; Then MOVB #IS.SUC,.IOSTS ; Simulate successful access BR 70$ ; Go to return ;;;; Else (locking not on already) 30$: MOVB #IE.LCK,.IOSTS ; Say its locked from RW access BR 70$ ; go to return ;;; Else (locking not requested) 40$: ;;; If block locking on already TST F.LKL(R0) ; Check lock list pointer BEQ 50$ ; If eq, no lock list ;;;; Then MOVB #IE.LCK,.IOSTS ; Say its locked from RW access BR 70$ ; Go to return ;;;; Else (locking not on already) 50$: MOVB I.ACTL(R5),X.ACTL(R2) ; Access as requested BICB #EXBITS,X.ACTL(R2) ; Clear uneeded bits 60$: ; And fall through to do the access ; CALL .NSND ; Send it off ; MOV #.RTPK,R2 ; Point to the return packet MOVB Y.STAT(R2),.IOSTS ; Return IO status 70$: ; Here to skip actual access ; POP ; restore any registers we used RETURN .PAGE .SBTTL RQDAC request deaccess ;+ ; RQDAC Request a deaccess from master system ; ; in and out same as RQIO ; With the addition of: ; R0 points to FCB ; ;- .RQDAC:: PUSH MOV #.RQPK,R2 ; Point to request packet ; MOV #IO.DAC,X.FCN(R2) ; Set up to deaccess the file ; ; Move FID and set up pointer MOV .FILNO,X.FBLK(R2) ; Move file number MOV .FILSQ,X.FBLK+2(R2) ; Move file sequence number CLR X.FBLK+4(R2) ; Volume number no supported MOV #X.FBLK,X.FIDP(R2) ; Set offset to FID in packet ; Set up other parameters CLR X.RWAT(R2) ; No attribute stuff CLR X.EXTD(R2) ; No extend stuff either CLR X.EXTD+2(R2) ; " " CLR X.RTRV(R2) ; No access control CLR X.FNBP(R2) ; No FNB pointer ; ; Move access identification stuff CALL MOVID ; ; FCB address in R0 ; ; If block locking was in use TST F.LKL(R0) ; Check lock list pointer BEQ 20$ ; If eq, locking off ; Then ; If this is the final deaccess CMPB F.NACS(R0),#1 ; This guy is still in the count BHI 10$ ; If hi, other accessors ; Then MOV R0,X.ID(R2) ; Use FCB address for ID BR 20$ ; Do the deaccess ; Else (not final deaccess) 10$: MOVB #IS.SUC,.RTPK+Y.STAT ; Say success, without actual deaccess ; ; just in case anybody is interested BR 30$ ; Go to return 20$: ; ; Send it off CALL .NSND ; Send it off ; MOV #.RTPK,R2 ; Point to returned packet MOVB Y.STAT(R2),R2 ; Get return code BPL 30$ ; If successful, just return ; May need to do something interesting here on errors ; 30$: POP ; Restore registers RETURN .PAGE .SBTTL MOVID local subroutine ;+ ; ; MOVID Local subroutine to move device name and unit as well ; as the access identifier. Uses I.LN2 (the address in ; the task's header, not the contents) as a unique ; task/lun identifier for coordination of simultaneous ; accesses. ; ; In R5 = I/O packet ; R2 = Request packet ; ; Out R0-R5 preserved ; U.UNIT of UCB, D.NAM of DCB, and file access window address ; all moved to request packet (X.UNIT, X.NAME, and X.ID) ; ; 25 Sept 80 DSM Fixed register usage bug ;- MOVID: PUSH R0 ; Get a scratch register MOV I.UCB(R5),R0 ; Get UCB address MOVB U.UNIT(R0),X.UNIT(R2) ; Move unit number MOV U.DCB(R0),R0 ; Get DCB address MOV D.NAM(R0),X.NAME(R2) ; Move name ; ; Move users window address as a unique task/lun id ; MOV .WNDOW,X.ID(R2) ; Move window address to ID BIC #1,X.ID(R2) ; Make sure interlock bit isn't on POP R0 ; Restore scratch register RETURN ; .END