From:	SMTP%"turion@research.ptt.nl" 21-MAR-1994 16:09:17.90
To:	EVERHART
CC:	
Subj:	part 4 status tool

X-Newsgroups: comp.os.vms
From: turion_s@dnlts0research.ptt.nl. (Paul Turion)
Subject: part 4 status tool
Message-ID: <1994Mar21.144054.957@news.research.ptt.nl>
Sender: turion_s@research.ptt.nl (Paul Turion)
Nntp-Posting-Host: dnlts0.research.ptt.nl
Reply-To: turion@research.ptt.nl
Organization: PTT Research
X-Newsreader: mxrn 6.18-4
Date: Mon, 21 Mar 1994 14:40:54 GMT
Lines: 558
To: Info-VAX@CRVAX.SRI.COM
X-Gateway-Source-Info: USENET


-- 
 ------- --------------------  			Paul Turion 
| p t t |  r e s e a r c h   |			The Netherlands
|      _|                    | 			e-mail address
|    _|_|   .  .  .  .  .    |			P.Turion@research.ptt.nl
|___|_|      
My interest is in the future because
I am going to spend the rest of my life there.
-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+
X`009`009`009UCBSIZE=UCB$C_Length,  -;UNIT CONTROL BLOCK LENGTH
X`009`009`009MAXUNITS=1,`009       -;ONLY ONE LAV0 DEVICE
X`009`009`009UNLOAD=LAV_UNLOAD,     -;UNLOAD ROUTINE
X`009`009`009NAME=LAVDRIVER,        -;DRIVER NAME
X`009`009`009FLAGS=DPT$M_SNAPSHOT,  -;SNAPSHOT SYSTEM OK
X`009`009`009SMP=YES,-`009`009;Works under SMP
X`009`009`009STEP=1`009`009`009;Step 1 Alpha driver
X.ENDC
X;+ ---
X;
X; INITIALIZATION INFORMATION
X;
X;- ---
X`009DPT_STORE`009INIT
X.IF`009DF,VMS_V4
X`009DPT_STORE`009UCB,UCB$B_FIPL,B,8`009;FORK IPL LEVEL
X.IFF
X`009DPT_STORE`009UCB,UCB$B_FLCK,B,SPL$C_IOLOCK8 ;FORK SPINLOCK
X.ENDC
X`009DPT_STORE`009UCB,UCB$B_DIPL,B,21`009;DEVICE IPL LEVEL (BR5 = 21)
X`009DPT_STORE`009UCB,UCB$L_DEVCHAR,L,   -;DEVICE CHARACTERISTICS:
X`009`009       <-
X`009`009`009DEV$M_AVL!`009       -;   DEVICE AVAILABLE
X`009`009`009DEV$M_REC!`009       -;   RECORD ORIENTED
X`009`009`009DEV$M_IDV!`009       -;   INPUT DEVICE
X`009`009`009DEV$M_SHR`009       -;   SHARED
X`009`009       >
X`009DPT_STORE`009UCB,UCB$W_DEVBUFSIZ,   -;DEVICE BUFFER SIZE
X`009`009`009`009W,36`009`009;    (36 bytes)
X.IF`009NDF,VMS_V4
X`009DPT_STORE`009ORB,ORB$L_OWNER,L,<`094x10004> ;Owner UIC = `0911,4`093
X.ENDC
X;+ ---
X;
X; RE-INITIALIZATION INFORMATION
X;
X;- ---
X`009DPT_STORE`009REINIT
X`009DPT_STORE`009DDB,DDB$L_DDT,D,LAV$DDT ;DRIVER DISPATCH TABLE
X.If`009NDF,EVAX
X`009DPT_STORE`009CRB,`009`009       -;CONTROLLER INITIALIZATION ROUTINE
X`009`009`009 CRB$L_INTD+VEC$L_INITIAL,D,-
X`009`009`009`009LAV_CONTROLLER_INIT
X`009DPT_STORE`009CRB,`009`009       -;UNIT INITIALIZATION ROUTINE
X`009`009`009 CRB$L_INTD+VEC$L_UNITINIT,D,-
X`009`009`009`009LAV_UNIT_INIT
X.Endc
X`009DPT_STORE`009END
X;
X
X`009.SBTTL`009DRIVER DISPATCH TABLE
X;+ ---
X;
X; ADDRESSES OF VARIOUS DRIVER ENTRY POINTS
X;
X;- ---
X
X.If`009DF,EVAX
X`009DDTAB`009-
X`009`009 DEVNAM=LAV,-`009`009`009;DEVICE NAME
X`009`009 FUNCTB=LAV_FUNCTABLE,-`009`009;ADDRESS OF FUNCTION DECISION TABLE
X`009`009 UNITINIT=LAV_UNIT_INIT,-`009;Unit initialization
X`009`009 CTRLINIT=LAV_CONTROLLER_INIT`009;Controller initialization
X.Iff
X`009DDTAB`009-
X`009`009 DEVNAM=LAV,-`009`009`009;DEVICE NAME
X`009`009 FUNCTB=LAV_FUNCTABLE`009`009;ADDRESS OF FUNCTION DECISION TABLE
X.Endc
X;
X
X`009.SBTTL`009FUNCTION DECISION TABLE
XLAV_FUNCTABLE:
X;+ ---
X;
X; SPECIFY LEGAL FUNCTION CODES
X;
X;- ---
X`009FUNCTAB ,`009       -;LEGAL FUNCTION CODE ENTRY
X`009`009<`009       -;
X`009`009 READVBLK,     -;READ VIRTUAL BLOCK
X`009`009 READLBLK,     -;READ LOGICAL BLOCK
X`009`009 READPBLK,     -;READ PHYSICAL BLOCK
X`009`009 WRITEVBLK,    -;WRITE VIRTUAL BLOCK
X`009`009 WRITELBLK,    -;WRITE LOGICAL BLOCK
X`009`009 WRITEPBLK,    -;WRITE PHYSICAL BLOCK
X`009`009>
X;+ ---
X;
X; SPECIFY BUFFERED I/O FUNCTION CODES
X;
X;- ---
X`009FUNCTAB ,`009       -;BUFFERED FUNCTION CODE ENTRY
X`009`009<>`009`009;NONE
X;+ ---
X;
X; SPECIFY 1ST FDT ROUTINE
X;
X;- ---
X`009FUNCTAB GET_LOAD_AVE,  -;GET THE CURRENT LOAD AVERAGES
X`009`009<`009       -;USED BY:
X`009`009 READVBLK,     -;READ VIRTUAL BLOCK
X`009`009 READLBLK,     -;READ LOGICAL BLOCK
X`009`009 READPBLK      -;READ PHYSICAL BLOCK
X`009`009>`009`009;
X;+ ---
X;
X; SPECIFY 2ND FDT ROUTINE
X;
X;- ---
X`009FUNCTAB SET_PRIORITIES, -;SET WHICH PRIORITIES ARE SCANNED
X`009`009<`009`009-;USED BY:
X`009`009 WRITEVBLK,`009-;WRITE VIRTUAL BLOCK
X`009`009 WRITELBLK,`009-;WRITE LOGICAL BLOCK
X`009`009 WRITEPBLK`009-;WRITE PHYSICAL BLOCK
X`009`009>`009`009;
X;
X`009.SBTTL`009LOCAL DATA
X;+ ---
X; Local Data for the Load Average Watcher
X;- ---
XSCALE_FACTOR_FLOAT:
X`009.FLOAT`00965536.0
XSCALE_FACTOR_SHIFT=16
X
XM1:`009.LONG`0090`009`009`009`009;1  Min. Load Ave.
XM5:`009.LONG`0090`009`009`009`009;5  Min. Load Ave.
XM15:`009.LONG`0090`009`009`009`009;15 Min. Load Ave.
X
XP1:`009.LONG`0090`009`009`009`009;1  Min. Priority Ave.
XP5:`009.LONG`0090`009`009`009`009;5  Min. Priority Ave.
XP15:`009.LONG`0090`009`009`009`009;15 Min. Priority Ave.
X
XQ1:`009.LONG`0090`009`009`009`009;1  Min. Ave disk queue len
XQ5:`009.LONG`0090`009`009`009`009;5  Min. Ave disk queue len
XQ15:`009.LONG`0090`009`009`009`009;15 Min. Ave disk queue len
X
XF1:`009.LONG`00964453`009    ;`009    0.983471453 ;1 min. load ave. constant
Vs
XF11:`009.LONG`009 1083`009    ;`009    0.016528547
X
XF2:`009.LONG`00965318`009    ;`009    0.996672213 ;5 min. load ave. constant
Vs
XF12:`009.LONG`009  218`009    ;`009    0.003327787
X
XF3:`009.LONG`00965463`009    ;`009    0.998889506 ;15 min. load ave. constan
Vts
XF13:`009.LONG`009   73`009    ;`009    0.001110494
X
X
X.If`009DF,EVAX
X`009.Align`009Quad
X.Endc
X
XTQE:`009.BLKB`009TQE$K_LENGTH
X.=TQE+TQE$W_SIZE`009`009`009`009;Define Size
X`009.WORD`009TQE$K_LENGTH`009`009`009;Size
X.=TQE+TQE$B_TYPE`009`009`009`009;Define Type
X`009.BYTE`009DYN$C_TQE`009`009`009;Type = DYN$C_TQE
X.=TQE+TQE$B_RQTYPE`009`009`009`009;Define RQTYPE
X`009.BYTE`009TQE$C_SSREPT`009`009`009; REQUEST=REPEAT
X.=TQE+TQE$Q_DELTA`009`009`009`009;Define Repeat Time
X`009.LONG`009100000*100,0`009`009`009;Repeat time (1 Sec.)
X.=TQE+TQE$K_LENGTH
X
XHAVEINITED:
X`009.LONG`0090`009`009`009`009; Set if alread initied
XRUNNING:
X`009.LONG`0090`009`009`009`009; True if TQE entry is in queue.
XSTOPPING:
X`009.LONG`0090`009`009`009`009; SET TO REQUEST TQE TO ABORT
X
X`009.Align`009Long
X
XPRIORITY_MASK:
X`009.LONG`0090`009`009`009`009; Check all priorities
X
X.If`009DF,EVAX
X`009.Align`009Quad
X.Endc
X
XFKB:`009.LONG`0090`009`009`009`009; FQFL
X`009.LONG`0090`009`009`009`009; FQBL
X`009.WORD`0090`009`009`009`009; SIZE
X`009.BYTE`009DYN$C_FRK`009`009`009; TYPE
X`009.BYTE`009SPL$C_TIMER`009`009`009; IPL LOW ENOUGH TO LOCK TIMER
XFKB_PC: .LONG`0090`009`009`009`009; PC
X.If`009DF,EVAX
X`009.QUAD`0090`009`009`009`009; R3
X`009.QUAD`0090`009`009`009`009; R4
X.Iff
X`009.LONG`0090`009`009`009`009; R3
X`009.LONG`0090`009`009`009`009; R4
X.Endc
X
X`009.SBTTL`009READ FDT ROUTINE
X
X.If`009DF,EVAX
X
X`009DRIVER_CODE`009`009`009`009;To the driver code psect
X
X.Endc
X;+ ---
X;
X; GET_LOAD_AVE`009`009READ FDT ROUTINE
X;
X; FUNCTIONAL DESCRIPTION:
X;
X;`009All this routine does is verify the read arguments and return M1->M15
X;
X; INPUTS:
X;
X;`009R3 = I/O Packet address
X;`009R4 = Current Process Control Block address
X;`009R5 = Unit Control Block Address
X;`009R6 = Channel Control Block Address
X;`009R7 = Function Code
X;`009R8 = Scratch
X;`009R9 = Scratch
X;
X;`0090(AP) --> Read Size
X;`0094(AP) --> Read Buffer
X;
X; OUTPUTS:
X;
X;`009none
X;
X;- ---
XGET_LOAD_AVE:
X.If`009DF,EVAX
X
X`009.JSB_Entry Preserve=<R2,R3,R4,R5>,-
X`009`009   Output=R0
X.Endc
X;+ ---
X; Get Read Size (limited to 36 bytes)
X;- ---
X.If`009DF,EVAX
X`009MOVZWL`009IRP$L_QIO_P2(R3),R0`009`009;Get Read Size
X.Iff
X`009MOVZWL`0094(AP),R0`009`009`009;Get Read Size
X.Endc
X`009CMPL`009R0,#36`009`009`009`009;Bigger than 36??
X`009BLEQU`00910$`009`009`009`009;No:
X`009MOVL`009#36,R0`009`009`009`009;Yes: Truncate to 36 bytes
X10$:
X;+ ---
X; Make sure that the buffer is writeable
X;- ---
X.If`009DF,EVAX
X`009IFWRT R0,@IRP$L_QIO_P1(R3),20$`009`009;Return SS$_ACCVIO if no write
X.Iff
X`009IFWRT R0,@(AP),20$`009`009`009;Return SS$_ACCVIO if no write
X.Endc
X`009MOVZWL`009#SS$_ACCVIO,R0`009`009`009;Set return code
X`009CLRL`009R1
X`009JSB`009G`094EXE$ABORTIO`009`009`009;Abort the I/O request
X`009RSB
X20$:
X;+ ---
X; Move the data; converting the scaled integers into the floats onto the
X; stack.
X;- ---
X
X`009CVTLF`009W`094Q15,R2
X`009DIVF3`009W`094SCALE_FACTOR_FLOAT,R2,-(SP)
X`009CVTLF`009W`094Q5,R2
X`009DIVF3`009W`094SCALE_FACTOR_FLOAT,R2,-(SP)
X`009CVTLF`009W`094Q1,R2
X`009DIVF3`009W`094SCALE_FACTOR_FLOAT,R2,-(SP)
X
X`009CVTLF`009W`094P15,R2
X`009DIVF3`009W`094SCALE_FACTOR_FLOAT,R2,-(SP)
X`009CVTLF`009W`094P5,R2
X`009DIVF3`009W`094SCALE_FACTOR_FLOAT,R2,-(SP)
X`009CVTLF`009W`094P1,R2
X`009DIVF3`009W`094SCALE_FACTOR_FLOAT,R2,-(SP)
X
X`009CVTLF`009W`094M15,R2
X`009DIVF3`009W`094SCALE_FACTOR_FLOAT,R2,-(SP)
X`009CVTLF`009W`094M5,R2
X`009DIVF3`009W`094SCALE_FACTOR_FLOAT,R2,-(SP)
X`009CVTLF`009W`094M1,R2
X`009DIVF3`009W`094SCALE_FACTOR_FLOAT,R2,-(SP)
X;+ ---
X; Move the data
X;- ---
X`009PUSHR`009#`094M<R0,R1,R2,R3,R4,R5>`009`009;Be conservative!!!
X.If`009DF,EVAX
X`009MOVC3`009R0,<4*6>(SP),@IRP$L_QIO_P1(R3)`009;Move the data
X.Iff
X`009MOVC3`009R0,<4*6>(SP),@(AP)`009`009;Move the Data
X.Endc
X`009POPR`009#`094M<R0,R1,R2,R3,R4,R5>`009`009;Restore registers
X;+ ---
X; Remove the extra crap from the stack
X;- ---
X`009ADDL2`009#36,SP
X;+ ---
X; Complete the I/O request
X;- ---
X`009ASHL`009#16,R0,R0`009`009`009;Set transfer size
X`009BISW2`009#SS$_NORMAL,R0`009`009`009;Set Completion code
X`009JSB`009G`094EXE$FINISHIOC`009`009`009;Complete the request
X`009RSB
X
X
X`009.SBTTL`009WRITE FDT ROUTINE
X;+ ---
X;
X; SET_PRIORITIES`009WRITE FDT ROUTINE
X;
X; FUNCTIONAL DESCRIPTION:
X;
X;`009All this routine does is verify the write arguments and change the
X;`009priorities mask.
X;
X; INPUTS:
X;
X;`009R3 = I/O Packet address
X;`009R4 = Current Process Control Block address
X;`009R5 = Unit Control Block Address
X;`009R6 = Channel Control Block Address
X;`009R7 = Function Code
X;`009R8 = Scratch
X;`009R9 = Scratch
X;
X;`0090(AP) --> Write Size
X;`0094(AP) --> Write Buffer
X;
X; OUTPUTS:
X;
X;`009none
X;
X;- ---
XSET_PRIORITIES:
X.If`009DF,EVAX
X
X`009.JSB_Entry Preserve=<R2,R3,R4,R5>,-
X`009`009   Output=R0
X.Endc
X;+ ---
X; Check privs (must have CMKRNL)
X;- ---
X
X`009ASSUME`009PHD$Q_PRIVMSK EQ 0
X`009BBC`009#PRV$V_CMKRNL,@PCB$L_PHD(R4),NOPRIV
X
X;+ ---
X; Get Write Size (limited to 4 bytes)
X;- ---
X.If`009DF,EVAX
X`009MOVZWL`009IRP$L_QIO_P2(R3),R0`009`009;Get Write Size
X.Iff
X`009MOVZWL`0094(AP),R0`009`009`009;Get Write Size
X.Endc
X`009CMPL`009R0,#4`009`009`009`009;Bigger than 4??
X`009BLEQU`00910$`009`009`009`009;No:
X`009MOVL`009#4,R0`009`009`009`009;Yes: Truncate to 4 bytes
X10$:
X;+ ---
X; Make sure that the buffer is readable
X;- ---
X.If`009DF,EVAX
X`009IFNORD`009R0,@IRP$L_QIO_P1(R3),ACCVIO2`009;Return SS$_ACCVIO if no write
X.Iff
X`009IFNORD`009R0,@(AP),ACCVIO2`009`009;Return SS$_ACCVIO if no write
X.Endc
X;+ ---
X; Move the data
X;- ---
X.If`009DF,EVAX
X`009MOVL`009@IRP$L_QIO_P1(R3),PRIORITY_MASK
X.Iff
X`009MOVL`009@(AP),PRIORITY_MASK
X.Endc
X;+ ---
X; Complete the I/O request
X;- ---
X`009ASHL`009#16,R0,R0`009`009`009;Set transfer size
X`009BISW2`009#SS$_NORMAL,R0`009`009`009;Set Completion code
X`009JSB`009G`094EXE$FINISHIOC`009`009`009;Complete the request
X`009RSB
X
X;+ ---
X; Return an access violation
X;- ---
XACCVIO2:
X`009MOVZWL`009#SS$_ACCVIO,R0`009`009`009;Set return code
X`009CLRL`009R1
X`009JSB`009G`094EXE$ABORTIO`009`009`009;Abort the I/O request
X`009RSB
X
X;+ ---
X; Return an NOPRIV error
X;- ---
XNOPRIV:
X`009MOVZWL`009#SS$_NOPRIV,R0`009`009`009;Set return code
X`009CLRL`009R1
X`009JSB`009G`094EXE$ABORTIO`009`009`009;Abort the I/O request
X`009RSB
X
X
X`009.SBTTL`009CONTROLLER INITIALIZATION ROUTINE
X;+ ---
X;
X; ROUTINE CALLED WHEN THE LOADING PROCEDURE SETS UP THE CONTROLLER
X;
X; INPUT REGISTERS:
X;`009R0 = SCRATCH
X;`009R5 = ADDRESS OF UNIT CONTROL BLOCK
X;
X; REGISTERS MODIFIED:
X;`009R0 = SCRATCH
X;
X; SIDE EFFECTS:
X;`009LOAD AVERAGE WATCHER IS SET UP
X;
X;- ---
XLAV_CONTROLLER_INIT:
X.If`009DF,EVAX
X
X`009.JSB_Entry Preserve=<R2,R3,R4,R5>,-
X`009`009   Output=R0
X.Endc
X`009TSTL`009HAVEINITED`009`009; If power failure recovery,
X`009BEQL`0091$`009`009       ; don't reenter the TQE block.
X`009RSB
X1$:`009MOVL`009#1,HAVEINITED
X
X; SET LOAD AVES TO ZERO
X
X`009CLRL`009M1
X`009CLRL`009M5
X`009CLRL`009M15
X`009CLRL`009P1
X`009CLRL`009P5
X`009CLRL`009P15
X`009CLRL`009Q1
X`009CLRL`009Q5
X`009CLRL`009Q15
X
X; SET UP THE LOAD AVERAGE WATCHING CODE (INSERT THE TIMER QUEUE ENTRY)
X;
X; Fork to a lower IPL
X;
X`009MOVQ`009R4,-(SP)`009    ; Not allowed to modify R4 or R5
X`009MOVAQ`009FKB,R5
X.If`009DF,EVAX
X`009FORK`009ROUTINE=20$,-`009    ; Create a fork process here
X`009`009CONTINUE=10$`009    ; Return to here
X.Iff
X`009PUSHAB`00910$`009`009    ; Trick EXE$FORK into returning to us.
X`009PUSHAB`00920$`009`009    ; Address to fork to
X`009JMP`009G`094EXE$FORK
X.Endc
X10$:
X`009MOVQ`009(SP)+,R4`009    ; Restore R4, R5
X`009MOVL`009#SS$_NORMAL,R0`009    ; Return success.
X15$:`009RSB`009`009`009    ; Return from unit init routine
X;
X; Now running at IPL 6
X;
X20$:
X.If`009DF,EVAX
X`009.JSB_Entry Input=<R3,R4,R5>,-
X`009`009   Scratch=<R0,R1,R2>
X.Endc
X`009MOVAB`009UPDATE_LOAD_AVERAGE,TQE+TQE$L_FPC
X`009MOVAL`009TQE,R5
X`009MOVL`009#1,RUNNING`009    ; CURRENTLY RUNNING
X`009CLRL`009STOPPING`009    ; AND NOT STOPPING
X.IF`009DF,VMS_V4
X`009MOVQ`009@#EXE$GQ_SYSTIME,TQE+TQE$Q_TIME
X`009INSQUE`009TQE,@#EXE$GL_TQFL
X.IFF
X`009READ_SYSTIME R0
X`009JSB`009G`094EXE$INSTIMQ
X.ENDC
X30$:`009RSB`009`009`009`009`009;AND RETURN
X;
X
X`009.SBTTL`009CONTROLLER UNLOAD ROUTINE
X;+ ---
X;
X; ROUTINE CALLED WHEN THE DRIVER IS RELOADED
X;
X; INPUT REGISTERS:
X;`009R0 = SCRATCH
X;`009R5 = ADDRESS OF UNIT CONTROL BLOCK
X;
X; REGISTERS MODIFIED:
X;`009R0 = SCRATCH
X;
X; SIDE EFFECTS:
X;`0091st call TQE entry is removed
X;`0092nd call driver is unloaded
X;- ---
XLAV_UNLOAD:
X.If`009DF,EVAX
X
X`009.JSB_Entry Output=R0
X
X.Endc
X`009TSTL`009RUNNING`009`009    ; If not running, unload
X`009BNEQ`00910$
X`009MOVL`009#SS$_NORMAL,R0`009    ; If not running, ok to unload driver
X`009RSB
X10$:`009MOVL`009#1,STOPPING`009    ; SET THE STOPPING FLAG
X`009CLRL`009R0
X`009RSB
X;
X
X`009.SBTTL`009UNIT INITIALIZATION ROUTINE
X;+ ---
X;
X; ROUTINE CALLED WHEN THE LOADING PROCEDURE SETS UP THE UNIT.
X;  THE DEVICE ONLINE BIT IS SET IN THE UCB.
X;
X; INPUT REGISTERS:
X;`009R0 = SCRATCH
X;`009R5 = ADDRESS OF UNIT CONTROL BLOCK
X;
X; REGISTERS MODIFIED:
X;`009R0 = SCRATCH
X;
X; SIDE EFFECTS:
X;`009UNIT ONLINE BIT IS SET IN UCB
X;
X;- ---
XLAV_UNIT_INIT:
X
X.If`009DF,EVAX
X
X`009.JSB_Entry Output=R0
X
X`009BISL`009#UCB$M_ONLINE,UCB$L_STS(R5)`009;SET STATUS = ONLINE
X.Iff
X`009BISW`009#UCB$M_ONLINE,UCB$W_STS(R5)`009;SET STATUS = ONLINE
X.Endc
X`009MOVL`009#SS$_NORMAL,R0`009`009`009;Success
X`009RSB
X;
X
X
X`009.SBTTL`009Load Average Watching Code
X
XUPDATE_LOAD_AVERAGE:`009`009`009`009;We link into the
+-+-+-+-+-+-+-+-  END  OF PART 4 +-+-+-+-+-+-+-+-

