.TITLE VDC DMO and De-assign VD .IDENT \V01.00\ .ENABL LC .NLIST BEX ; ; ; Written by Rick Webster ; MSDGO, Process Control Applications ; 28-Oct-82 ; Caterpillar Tractor Co. ; ; ; VERSION 01 ; File = VDC.MAC ; ; ;****************************************************************************** ; ; This software is provided on an "as is" basis only. Caterpillar Tractor Co., ; disclaims all warranties on the program, including without limitation, all ; implied warranties of merchantablity and fitness. ; ; Full permission and consent is hereby given to DECUS and to the DECUS ; special interest groups to reproduce, distribute, and publish and permit ; others to reproduce in whole or in part, in any form and without restriction ; this program and any information relating thereto ; ;****************************************************************************** ; ; ; Modifications: ; ; None to date ; ;+ ; File description: ; ; ; This program will dismount and deassign a virtual disk device ; or all virtual disks on a device using DVD. ; ; ; Usage: ; ; VDC VDn: ; or ; VDC /dev[/NQ] ; ; where: ; ; /NQ - Do not ask if it is ok to deassign VD's ; (only significant for 2nd form of command) ; ; The first form of the command will dismount and de-assign ; a single VD unit where n is the unit number. This form spawns ; DVD with the command - DVD VDn:/DMO/NM ; ; The second form of the command will dismount and de-assign ; all VD's on the device 'dev'. For example, DVD /DR1 will ; attempt to dismount and de-assign all VD's on device DR1: ; Unless /NQ is specified, you will be prompted as to whether ; this is really what you intended to do. Anything other than ; a Yes response will terminate the program. ; ;- ; ; ; Local data ; ; ; ; ; Error messages: ; .DSABL GBL ; ; Macro library calls: ; ; Symbolic definitions. ; .MCALL HDRDF$ ;DEFINE TASK HEADER OFFSETS HDRDF$ .MCALL UCBDF$ ;DEFINE UCB OFFSETS UCBDF$ .MCALL F11DF$ ;Define Files 11 table definitions F11DF$ .MCALL DCBDF$ ;Define DCB offsets DCBDF$ ; ; Directive macros. ; .MCALL DIR$ ;ISSUE DIRECTIVE .MCALL ALUN$S ;ASSIGN LUN .MCALL EXST$S ;EXIT WITH STATUS .MCALL GMCR$ ;GET MCR COMMAND LINE .MCALL QIOW$ ;ISSUE QIO AND WAIT .MCALL SVTK$S ;SETUP SST VECTOR TABLE .MCALL GLUN$S ;Get lun info .MCALL SPWN$ ;Spawn task .MCALL WTSE$S ;Wait for single event ; ; FCS macros. ; .MCALL NBOF$L ;DEFINE FNB OFFSETS NBOF$L ; ; TPARS Macros ; .MCALL ISTAT$,STATE$,TRAN$ ; ; Global declarations: ; .GLOBL VDC ;TASK ENTRY ; ; Global references: ; ; System library routines, symbols. ; .GLOBL IO.WVB ;WRITE VIRTUAL BLOCK .GLOBL IO.RVB ;Read virtual block .GLOBL $DSW ;DIRECTIVE STATUS WORD .GLOBL .TPARS ;Table Driven Parser .GLOBL .PCHAR ;TPARS symbol .GLOBL .PNUMB ;TPARS symbol .GLOBL .PSTPT ;TPARS symbol .GLOBL .PSTCN ;TPARS symbol .GLOBL $CBTA ;Convert binary to ascii ; ; RSX11M system routines, variables. ; .GLOBL $HEADR ;CURRENT TASK HEADER ADDRESS .GLOBL $DEVHD ;Device list head .GLOBL $EDMSG ;Edit message routine .SBTTL VDC - Macros ; ; Define error declaration macro. ; .MACRO FATAL MSG,MSGNUM MOV #MSGNUM,EXSTAT TRAP 1 .ASCIZ #Error MSGNUM, MSG# .EVEN .ENDM FATAL ; ; *** TPARS Macro to invoke the table driven parser ; .MACRO TPARS OPT,KEYPT,LTH,ADDR,STLABL MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) MOV OPT,R1 ;BLANK AND TAB SUPPRESS OPTION MOV KEYPT,R2 ;ADDRESS OF KEY TABLE MOV LTH,R3 ;LENGTH OF STRING TO BE PARSED MOV ADDR,R4 ;ADDRESS OF STRING TO BE PARSED MOV STLABL,R5 ;LABEL OF FIRST STATE CALL .TPARS ;PARSE STRING MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 .ENDM ; ; *** EDMWRT MACRO TO USE $EDMSG TO FORMAT A MESSAGE ; .MACRO EDMWRT INSTR,ARGBLK MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) MOV INSTR,R1 ;ADDRESS OF INPUT STRING MOV ARGBLK,R2 ;ADDRESS OF ARGUMENT BLOCK CALL EDMWRT ;GO CALL $EDMSG AND OUTPUT MESSAGE MOV (SP)+,R2 MOV (SP)+,R1 MOV (SP)+,R0 .ENDM .SBTTL VDC - Local data ; ; LOCAL SYMBOLS: ; ; LOGICAL UNITS/EVENT FLAGS. ; TSTLUN = 1 ;VDC WORKING LUN TTYLUN = 2 ;TERMINAL I/O LUN FILLUN = 3 ;FILE I/O LUN EV.QIO = 1 ;QIO WAIT EVENT FLAG ; ; Switch bit masks ; DV.DEV = 1 ;De-assign all on device DV.VDS = 2 ;VD to de-assign, entered DV.NQS = 4 ;No query switch specified ; ; LOCAL DATA: ; ; DIRECTIVES. ; GETCMD: GMCR$ ;GET COMMAND LINE ERRDPB: QIOW$ IO.WVB,TTYLUN,EV.QIO,,,, RDANS: QIOW$ IO.RVB,TTYLUN,EV.QIO,,,, EDMQIO: QIOW$ IO.WVB,TTYLUN,EV.QIO,,,,<0,0,0,0,0,0> SPNDVD: SPWN$ MCR...,,,,,EV.QIO,,SPNSTA,DVDCMD,DVDCML,, SPNVDA: SPWN$ MCR...,,,,,EV.QIO,,SPNSTA,VDACMD,VDACML,, ; ; Error message string. ; ERRMSG: .ASCIZ <15><12>/VDC -- / ERRSTR: .BLKB 40. .EVEN ; ; Edit message format strings ; DVDERR: .ASCIZ /%NVDC -- Deassign failure on VD%Q:, DVD error code (%Q)/ DVDOK: .ASCIZ /%NVDC -- VD%Q: is deassigned/ VDAMSG: .ASCIZ /%NVDC -- The following VD's will be deassigned:/<15> CONMSG: .ASCIZ |%NVDC -- Continue with deassignment? (Y/N) >| .EVEN ; ; SST vector table. ; SSTTBL: .WORD 0 ;ODD ADDRESS .WORD 0 ;MEMORY PROTECTION .WORD 0 ;T-BIT TRAP OR BPT .WORD 0 ;IOT TRAP .WORD 0 ;RESERVED INSTRUCTION .WORD 0 ;NON-RSX EMT INSTRUCTION .WORD ERRSRV ;TRAP INSTRUCTION SSTSIZ = <.-SSTTBL>/2 ; ; OTHER VARIOUS BUFFERS. ; IOSTAT: .WORD 0,0 ;I/O STATUS BLOCK SWFLAG: .WORD 0 ;Switch flag word for TPARS VDUNIT: .WORD 0 ;VD unit to de-assign DEVNAM: .WORD 0 ;Ascii device name from switch /dev DEVUN: .WORD 0 ;Unit number from switch /dev EXSTAT: .WORD 0 ;Task exit status UCBLTH: .WORD 0 ;UCB length CMDLTH: .WORD 0 ;Length of command line ARGBLK: .WORD 0,0,0,0,0,0 ;Argument list for $EDMSG SPNSTA: .WORD 0,0 ;8 word spawn status block ;.. includes GLUNBF GLUNBF: .BLKW 6 ;Get lun input buffer ANS: .BYTE 0 ;Y/N answer buffer ; ; Spawn command lines ; DVDCMD: .ASCII /DVD VD/ DVDUN: .ASCII |XX:/DMO/NM| DVDCML=.-DVDCMD .EVEN VDACMD: .ASCII |VDA /| VDASW: .ASCII | 0 | VDACML=.-VDACMD .EVEN .SBTTL VDC - Main-line task code VDC:: ;REF. LABEL. ; ; SETUP SST VECTOR TABLE FOR PROCESSING. ; SVTK$S #SSTTBL,#SSTSIZ ;SETUP SST VECTOR TABLE ; ; GET COMMAND LINE, ERROR IF NONE AVAIABLE. ; DIR$ #GETCMD ;GET MCR COMMAND LINE BCC 1000$ ; IF CC - OK, CONTINUE FATAL ,101 ;DECLARE ERROR ; ; CHECK COMMAND FOR SYNTACICAL CORRECTNESS. ; 1000$: MOV $DSW,CMDLTH ;Save cmd line length TPARS #0,#KEYTBL,$DSW,#GETCMD+G.MCRB,#CMDLIN ;Parse cmd line BCC 1300$ ;Branch if syntax OK FATAL ,102 ;DECLARE ERROR ; ; Validate switches ; 1300$: BIT #DV.VDS,SWFLAG BEQ 1310$ BIT #DV.DEV,SWFLAG BNE 1305$ JMP 2000$ 1305$: FATAL ,103 1310$: BIT #DV.DEV,SWFLAG BNE 1320$ FATAL ,104 1320$: ALUN$S #FILLUN,DEVNAM,DEVUN BCC 1330$ FATAL ,105 1330$: GLUN$S #FILLUN,#GLUNBF ;Do a get lun to resolve pseudo devices BCC 1340$ ;Branch on success FATAL ,106 ;Shouldn't be here, but just in case... 1340$: MOV GLUNBF+G.LUNA,DEVNAM ;Load resolved device name MOVB GLUNBF+G.LUNU,DEVUN ;Load resolved device unit BIT #DV.NQS,SWFLAG ;/NQ switch specified? BNE 1345$ ;Yes - don't ask user about continuing EDMWRT #VDAMSG,#ARGBLK ;Output pre VDA message DIR$ #SPNVDA ;Execute VDA to display affected VD's WTSE$S #EV.QIO ;Wait for VDA to complete CLRB ANS ;Clear answer buffer EDMWRT #CONMSG,#ARGBLK ;Ask if we should continue DIR$ #RDANS ; " BICB #40,ANS ;Mask out lower case CMPB ANS,#'Y ;Should we continue? BEQ 1345$ ;Yes - branch JMP 4000$ ;No - go exit 1345$: MOV $DEVHD,R0 ;R0 gets device list head 1350$: CMP D.NAM(R0),#"VD ;Is this DCB for the VD's? BEQ 1355$ ;Yes - branch MOV D.LNK(R0),R0 ;No - check next DCB BNE 1350$ ;if non-zero, still more to check FATAL ,107 ;Got a problem, better give up 1355$: MOVB D.UNIT+1(R0),R2 ;R2 gets highest unit number BIC #177400,R2 ;Clear out sign extend, if any MOVB D.UNIT(R0),R3 ;R3 gets lowest unit number BIC #177400,R3 ;Clear out sign extend, if any SUB R3,R2 ;R2 gets the number of units INC R2 ; to check MOV D.UCBL(R0),UCBLTH ;Save UCB length MOV D.UCB(R0),R0 ;R0 get first UCB address 1360$: BITB #US.OFL,U.ST2(R0) ;Is this VD offline? BNE 1370$ ;Yes - Go check next one MOVB U.UNIT(R0),VDUNIT ;Save VD unit number MOV U.NXT(R0),R3 ;R3 points to extension block ADD #X.FNB,R3 ;R3 points to saved filename block ; ; The following code will check the filename block ; stored in all currently assigned VD's to see if ; the device name, and device unit, match the one ; specified in the /dev switch ; CMP DEVNAM,N.DVNM(R3) ;Does device name match? BNE 1370$ ;No - go check next unit CMP DEVUN,N.UNIT(R3) ;Does unit number match BNE 1370$ ;No - go check next unit MOV R0,-(SP) ;Save R0 MOV R2,-(SP) ;Save R2 MOV R3,-(SP) ;Save R3 MOV #DVDUN,R0 ; MOV VDUNIT,R1 MOV #11010,R2 CALL $CBTA DIR$ #SPNDVD ;Try to dismount it WTSE$S #EV.QIO ;Wait for completion MOV (SP)+,R3 ;Unsave R3 MOV (SP)+,R2 ;Unsave R2 MOV (SP)+,R0 ;Unsave R0 MOV VDUNIT,ARGBLK ;Put unit number in $EDMSG argument list CMP SPNSTA,#1 ;Was DVD successful? BEQ 1365$ ;Yes - branch MOV SPNSTA,ARGBLK+2 ;No - put DVD exit status in arg. list EDMWRT #DVDERR,#ARGBLK ;Output DVD failure message MOV #-1,EXSTAT ;Indicate that a DVD failure occurred BR 1370$ ;Get next VD unit to check 1365$: EDMWRT #DVDOK,#ARGBLK ;Output successful deassign message BR 1370$ 1369$: JMP 1360$ 1370$: ADD UCBLTH,R0 ;Step to next UCB SOB R2,1369$ ;Branch if there are any left TST EXSTAT ;Did any DVD errors occur BEQ 4000$ ;No - go exit with success FATAL ,110 2000$: MOV #DVDUN,R0 ; MOV VDUNIT,R1 MOV #11010,R2 CALL $CBTA MOV VDUNIT,ARGBLK ;Put unit number in $EDMSG argument list DIR$ #SPNDVD ;Try to dismount it WTSE$S #EV.QIO ;Wait for completion CMP SPNSTA,#1 ;Was DVD successful? BNE 2010$ ;No - branch EDMWRT #DVDOK,#ARGBLK ;Output successful deassign message BR 4000$ ;Go exit 2010$: MOV SPNSTA,ARGBLK+2 ;No - put DVD exit status in arg. list EDMWRT #DVDERR,#ARGBLK ;Output DVD failure message FATAL ,111 ; ; ALL DONE, EXIT TASK. ; 4000$: EXST$S #1 ;Exit with successful status .SBTTL ERRSRV * ERROR MESSAGE PROCESSING ; ;+ ; THIS ROUTINE IS ENTERED BY AN SST TRAP INSTRUCTION. IT OUTUTS ; THE ERROR MESSAGE AND EXITS THE TASK. ; ; INPUTS: ; ; THE TRAP CAUSED BY THE FATAL MACRO. THE STACK SHOULD ; BE SETUP AS SHOWN BELOW: ; ; SP+04 PS ; SP+02 PC OF TRAP+2 ; SP+00 TRAP OPERAND*2 ; ; THE TRAP INSTRUCTION IS FOLLOWED BY THE ASCIZ ERROR MESSAGE. ; ; OUTPUTS: ; ; THE ERROR MESSAGE IS OUTPUT TO THE USER'S TERMINAL AND ; THE TASK EXITS. ;- ; ERRSRV: MOV #ERRSTR,R0 ;GET START OF VARIABLE ERROR MOV 2(SP),R1 ;GET START OF ERROR MESSAGE 1100$: MOVB (R1)+,(R0)+ ;MOVE ERROR MESSAGE BNE 1100$ ; AND LOOP IF NOT DONE MOVB #15,-1(R0) ;MOVE IN EXTRA SUB #ERRMSG,R0 ;GET LENGTH OF STRING MOV R0,ERRDPB+Q.IOPL+2 ;STORE IN QIO DPB DIR$ #ERRDPB ;ISSUE OUTPUT MOV #GETCMD+G.MCRB,ERRDPB+Q.IOPL ;Also output cmd in error MOV CMDLTH,ERRDPB+Q.IOPL+2 ; " DIR$ #ERRDPB 1200$: EXST$S EXSTAT ;EXIT TASK .PAGE .SBTTL EDMWRT Subroutine ; ; ** EDMWRT ** Subroutine to use $EDMSG to output a message. ; EDMWRT::MOV #50$,R0 ;R0 has output buffer address MOV R0,EDMQIO+Q.IOPL ;Put address in QIO CALL $EDMSG ;Format the message MOV R1,EDMQIO+Q.IOPL+2 ;Put char. count in QIO DIR$ #EDMQIO ;Output message RETURN 50$: .BLKW 128. ; ; ** END OF EDMWRT ; .PAGE .SBTTL State tables for .TPARS ISTAT$ STATE1,KEYTBL STATE$ CMDLIN TRAN$ $STRNG ;Bypass program name 'VDC' STATE$ TRAN$ 'V,DCHK,CVDUN,DV.VDS,SWFLAG ;Check for VDn: entered TRAN$ '/,GETSW ;Not VDn:, better be a switch STATE$ DCHK TRAN$ 'D ;Check for D in VDn: STATE$ TRAN$ $NUMBR,CHKCOL,STVDUN ;Check for n in VDn: TRAN$ ':,CHKSW ;Check for VD: with implied n=0 STATE$ CHKCOL TRAN$ ': ;Check for : in VDn: STATE$ CHKSW TRAN$ '/,GETSW ;Check for switch TRAN$ $EOS,$EXIT ;Only exit from TPARS STATE$ GETSW TRAN$ "NQ",CHKSW,,DV.NQS,SWFLAG ;Check for /NQ TRAN$ !DEV,CHKSW,,DV.DEV,SWFLAG ;Check for /dev STATE$ DEV ;/dev subexpression TRAN$ $ALPHA,,MNEM1 ;Check for 1st letter of device name STATE$ TRAN$ $ALPHA,,MNEM2 ;Check for 2nd letter of device name STATE$ TRAN$ ':,$EXIT ;return if implied unit of 0 TRAN$ $NUMBR,CKCOL2,STUNIT ;Get unit number TRAN$ $LAMDA,$EXIT ;Return if implied unit 0 with no : STATE$ CKCOL2 TRAN$ ':,$EXIT ;Return if : entered TRAN$ $LAMDA,$EXIT ;Return if : not entered STATE$ ;End of state table ; ; TPARS Action routines ; CVDUN: CLR VDUNIT ;Assume VD is unit 0 RETURN STVDUN: MOV .PNUMB,VDUNIT ;Get VD unit to de-assign RETURN MNEM1: MOVB .PCHAR,DEVNAM ;1st char of device mnumonic from /dev MOVB .PCHAR,VDASW ;Set up VDA command line RETURN MNEM2: MOVB .PCHAR,DEVNAM+1 ;2nd char of device mnumonic from /dev MOVB .PCHAR,VDASW+1 ;Set up VDA command line CLR DEVUN ;Assume /dev is unit 0 RETURN STUNIT: MOV .PNUMB,DEVUN ;Device unit from /dev MOV .PSTPT,R0 ;Put ascii unit number in MOV .PSTCN,R1 ;.. VDA command line MOV #VDASW+2,R2 ; " 1$: MOVB (R0)+,(R2)+ ; " SOB R1,1$ ; " RETURN .END VDC