From:	MERC::"uunet!WKUVX1.BITNET!MacroMan" 14-APR-1992 14:40:29.69
To:	MACRO32@WKUVX1.BITNET, YATES@WCTDPV.GD.COM
CC:	
Subj:	RE: HELP - Device allocated/mounted to non-existant process

Date sent:  14-APR-1992 08:34:01


>  Does anyone have or know where I can obtain a utility which will deallocate
>  and dismount a device that is in such a state to a non-existant process.

        Ehud

--
Ehud Gavron        (EG76)
gavron@vesta.sunquest.com
"The world bores you when you're cool."

        .TITLE  CLRREF  -        Clear Device Reference count
        .IDENT  /002-0/

;++
;
; CLRREF.MAR            16-Sep-1991             Ehud Gavron
; So you want to clear a device that someone has left allocated and gone
; away, huh?  Be vewy vewy caweful.  We'we huntin' wabbits.
;
;       Ehud Gavron             gavron@Spades.ACES.COM
;
;--
; V1.0.0        Created because I'm not getting enough interesting
;               kernel-coding to do in my regular job.
;
; V2.0.0        Made it $ASSIGN, set reference count to 1, $DASSGN
;               19-Sep-1991     Ehud Gavron
;
; V2.0.1        Added clearing of mount bit so I can use this to
;               release tapes owned by nonexistent processes.
;
;
; Definitions
;
        .library        "sys$Library:lib.mlb"                   ; find $xxxdefs
        .link           "sys$system:sys.stb"/selective_search   ; find xxx$x_xs

        $ccbdef         ; Channel Control Block offsets (to get UCB)
        $pcbdef         ; Process Control Block offsets (to get PID)
        $prvdef         ; Privilege definitions (to get BYPASS and _IO)
        $orbdef         ; Object Resource Block offsets (to clear owner)
        $ssdef          ; System Service status values (for normal status)
        $ucbdef         ; Unit Control Block offsets (miscellaneous)
;
; Macros
;
        .macro  check ?l1
        blbs    r0,l1
        $exit_s r0
l1:
        .endm   check

;
; Variables
;
Channel:        .blkl   1               ; channel number
Device:         .ascid "$all$ddcuuuu:"  ; the device (max size I expect)
Privmsk:        .blkl   2               ; privilege mask
Prompt:         .ascid "Device: "       ; the prompt if someone didn't enter it
Ucb:            .blkl   1               ; address of UCB
Clrref_arg:     .long   1               ; The argument list to give the UCB
                .address        ucb     ; address to the kernel-mode routine
;
; Start of user-mode code
;
        .entry  clrref,^m<>

;
; Get the device name from the command line
;
        pushl   #0                      ; flags
        pushal  Device                  ; resultant-length
        pushal  Prompt                  ; prompt-string
        pushal  Device                  ; resultant-string
        calls   #4,g^lib$get_foreign
        check
;
; Enable privileges
;
        movl    #<prv$m_bypass+prv$m_phy_io+prv$m_log_io>,privmsk
        $setprv_s       enbflg=#1,prvadr=privmsk
        check
;
; Assign channel to the device
;
        $assign_s       devnam=device,chan=channel
        check
;
; Get UCB address from CCB
;
        movl    @#ctl$gl_ccbbase,r0     ; Get CCB table base address
        movzwl  channel,r1              ; Get channel number (byte offset)
        subl    r1,r0                   ; Get address of CCB for this channel
        movl    ccb$l_ucb(r0),ucb       ; Get UCB address
;
; Call the kernel-mode routine to set the reference count and owner
;
        $cmkrnl_s routin=clrref_k,arglst=clrref_arg
        check
;
; Deassign the channel
;
        $dassgn_s       chan=channel
        $exit_s r0

;
; The kernel-mode code
;
        .entry clrref_k,^m<>

;
; Get the Unit Control Block (UCB) address
;
        movl    4(ap),r1                ; Address of Ucb variable
        movl    (r1),r1                 ; Address of device UCB
;
; Get PCB address into R4       (really we already have this from $cmkrnl)
;
        movl    ctl$gl_pcb,r4
;
; Raise IPL, acquire Mutex, and set the reference count
;
        lock    lockname=iolock8        ; Raise IPL, acquire lock
        movw    #1,ucb$w_refc(r1)       ; Set reference count to 1
        bicl    #dev$m_all,ucb$l_devchar(r1)    ; Clear the allocated bit
        bicl    #dev$m_mnt,ucb$l_devchar(r1)    ; Clear the mount bit (tapes)
        movl    pcb$l_pid(r4),ucb$l_pid(r1)     ; Set us as the owner in UCB
;
; Get the Object Resource Block (ORB) address
;
        movl    ucb$l_orb(r1),r1        ; Object Resource Block offset from UCB
        movl    pcb$l_pid(r4),orb$l_owner(r1)   ; Set us as the owner in ORB
;
; Return to user mode
;
        unlock  lockname=iolock8,newipl=#0 ; Release lock (lower IPL)
        movl    #ss$_normal,r0          ; Status ok
        ret                             ; G'bye

        .end    clrref
