.TITLE VARY - Change availabilty of allocatable device .IDENT /1.01/ ;++ ; Title: ; VARY - Change availability of allocatable device ; ; Facility: ; System operation utility ; ; Abstract: ; This program is a quick hack to allow a device to be marked ; as unavailable for allocation. Doing this is desirable for ; such things as dual-ported tapes and disks since VMS provides ; no protection from simultaneous access by both ports. To mark the ; device as unallocatable, we make the device unavailable. ; This is done by clearing the DEV$V_AVL bit in UCB$L_DEVCHAR. This ; program can diagnose the three possible states of a device (OFF, ON, ; and IN USE). The program should be run from a foreign command ; with the following syntax. ; VARY ddxn: state ; where state is OFF or ON. ; ; Program must be assembled with DEV$SSG:[SSG.SOURCE.SMAC]SMAC.MLB ; and SYS$LIBRARY:LIB.MLB. Program must be linked with ; SYS$SYSTEM:SYS.STB ; ; Environment: ; Native Mode. Requires CMKRNL priv. ; ; Author: ; Gary L. Grebus, Creation date: 20-Jan-1982 ; Battelle Columbus Labs ; ; Modified by: ; Gary L. Grebus, 20-Jan-1982 ; 1.00 - Completed first version ; ; 1.01 - Gary L. Grebus, 12-Apr-1985 15:50:32 ; Modified under VMS V4 to use the AVL bit instead of ; the previous mechanism of using the ALL bit and the ; reference count. The old mechanism does not prevent ; MOUNT from getting to the device. MOUNT can then ; undo the pseudo-allocate leaving the device unprotected. ;-- .PAGE .SBTTL Symbol definitions ; System symbols $UCBDEF ; UCB fields $DIBDEF ; $GETDEV return fields $TPADEF ; LIB$TPARSE symbols $STSDEF ; Condition value symbols $DEVDEF ; Device characteristics .PAGE .SBTTL Read/write data .PSECT RWDATA RD,WRT,NOEXE,NOSHR,LONG ; Read/write data CMD_BUFFER: STRING 80 ; Desc and space for command line CMD_LINE_D: .LONG 0 ; Skeleton desc for command line .ADDRESS CMD_BUFFER+8 DEV_DESC: .LONG 0,0 ; Skeleton desc for device name string CHAR_BUF: .BLKB DIB$K_LENGTH ; Buffer for device characteristics CHAR_BUF_D: .LONG DIB$K_LENGTH .ADDRESS CHAR_BUF ; Descriptor for above DEV_CHAN: .BLKL 1 ; Buffer for channel number TPARSE_BLOCK: .LONG TPA$K_COUNT0 ; Parameter list for LIB$TPARSE .BLKL TPA$K_LENGTH0-4 K_PARM: .LONG 2 ; Parameter list for kernal mode call ON_FLAG: .BLKL 1 ; Flag that action is VARY ON .ADDRESS DEV_DESC ; Address of device name desc .PSECT RODATA RD,NOWRT,NOEXE,SHR,LONG ; TPARSE tables $INIT_STATE STATE_TBL, KEY_TBL $STATE $TRAN TPA$_SYMBOL,,,,DEV_DESC $STATE $TRAN ':' $TRAN TPA$_LAMBDA $STATE $TRAN 'ON',,,1,ON_FLAG $TRAN 'OFF',,,0,ON_FLAG $STATE $TRAN TPA$_EOS,TPA$_EXIT $END_STATE .PAGE .SBTTL VARY - Main program .PSECT CODE RD,NOWRT,EXE,SHR,LONG .ENTRY VARY,^M<> ; Register usage: ; R0-R1 - Scratch ;*************************************************************** ; Get the command line CALL G^LIB$GET_FOREIGN - CMD_BUFFER,#0,CMD_LINE_D ; Get command line IF THEN SIGNAL - CODE1=#VARY_CMDLINE RET ; Return error status ENDIF CALL G^STR$UPCASE - CMD_LINE_D, CMD_LINE_D ; Force command to upper case ; Parse the command setting DEV_DESC and ON_FLAG CLRL ON_FLAG ; Assume VARY OFF MOVZWL CMD_LINE_D,- TPARSE_BLOCK+TPA$L_STRINGCNT ; Point TPARSE at command MOVL CMD_LINE_D+4,- TPARSE_BLOCK+TPA$L_STRINGPTR CALL G^LIB$TPARSE - TPARSE_BLOCK, STATE_TBL, KEY_TBL ; Parse the command line ENB_LONG ;; Enable long branches for macros IF THEN IF THEN ; Bad syntax in command line SIGNAL - CODE1=#VARY_SYNTAXERR,- F1= ; Issue message ELSE ; Some other error with parsing SIGNAL - CODE1=#VARY_PARSERR,- CODE2=R0 ; Issue messages ENDIF BISL2 #STS$M_INHIB_MSG,R0 ; No message from return status RET ; Return with status ENDIF ;****************************************************************** ; Get device characteristics for device specified $GETDEV_S - DEVNAM=DEV_DESC,- PRIBUF=CHAR_BUF_D ; Get characteristics IF THEN SIGNAL - CODE1=#VARY_DEVERR,- F1= ; Issue error message RET ; Return with status ENDIF MOVAB CHAR_BUF,R1 ; Get pointer to characteristics buff IF - OR THEN ; Device has an owner. Can't do anything. MOVL #VARY_INUSE,R0 ; Return "in use" status RET ENDIF ; Device is unowned. Check current state. IF THEN ; Command is VARY ON. IF THEN MOVL #VARY_ALRDYON,R0 ; Device is already on RET ; Return with status ENDIF ELSE ; Command is VARY OFF IF THEN MOVL #VARY_ALRDYOFF,R0 ; Device is already off RET ; Return with status ENDIF ENDIF ; Device is in opposite of desired state and is not busy at this time. ; Proceed to VARY it. $CMKRNL_S - ROUTIN=VARY_K,- ARGLST=K_PARM ; Go VARY the device IF THEN IF THEN SIGNAL - CODE1=#VARY_VARYERR,- F1= ; If error, issue message ENDIF ENDIF RET ; Return with status DSB_LONG .PAGE .SBTTL VARY_K - Kernal mode routine to VARY device ;++ ; Functional Description: ; This routine performs the actual VARY operation on the device. ; It first locks the I/O database for write access, using the ; same synchronization mechanism (mutex) that device allocation uses. ; It then checks that the device is unowned. If there is no value for ; the owner PID and the ALL bit is cleared, change the AVL bit in the ; UCB to perform the requested command. The I/O database is unlocked ; following this operation. ; ; Calling Sequence: ; $CMKRNL_S ROUTIN=VARY_K, ARGLST=x ; ; Input Parameters: ; 4(AP) - Flag (0=VARY OFF, 1=VARY ON) ; 8(AP) - Address of descriptor for device name ; ; Output Parameters: NONE ; ; Implicit Inputs: NONE ; ; Implicit Outputs: NONE ; ; Procedures called: ; SCH$IOLOCKW, SCH$IOUNLOCK ; ; Completion Status: ; Returns SS$NORMAL if successful. ; Returns VARY_INUSE if device is busy. ; Returns SS$_IVDEVNAM, SS$_NONLOCAL, or SS$_NOSUCHDEV if error ; CMKRNL returns SS$_NOPRIV if no priv to get here ; ; Side Effects: ; Locks and unlocks the I/O database mutex. ; ;-- .PSECT CODE RD,NOWRT,EXE,SHR,LONG .ENTRY VARY_K,^M MOVL G^SCH$GL_CURPCB,R4 ; Our PCB address is parameter ; to SCH routines called JSB G^SCH$IOLOCKW ; Lock I/O database for write access MOVL 8(AP),R1 ; Get address of descriptor JSB G^IOC$SEARCHDEV ; Get UCB address for device into R1 ENB_LONG ;; Long branches for the macros IF THEN ; If we got UCB address okay. IF - OR THEN MOVL #VARY_INUSE,R0 ; Device is busy. Can't do anything ELSE IF THEN ; Command is VARY ON BISL2 #DEV$M_AVL,- UCB$L_DEVCHAR(R1) ; Set available bit ELSE ; Command is VARY OFF BICL2 #DEV$M_AVL,- UCB$L_DEVCHAR(R1) ; And set allocated bit ENDIF MOVZWL #SS$_NORMAL,R0 ; Return success ENDIF ENDIF DSB_LONG ;; Disable long branches for macros PUSHL R0 ; Save return status JSB G^SCH$IOUNLOCK ; Unlock database POPL R0 ; Restore return status RET .END VARY