        .TITLE  ACP_PROCS - Common procedures for ACP

;++
; ACP_PROCS - Common procedures for ACP
;
; Abstract:
;
;       This module contains various procedures used by ACP images.
;
;       Note that the procedures herein cannot be used by the ACP
;       device driver, due to .psect name issues.
;--

        .LIBRARY \SYS$LIBRARY:LIB\
        $AQBDEF
        $PRDEF
        $SSDEF

        .PSECT  CODE            SHR, NOWRT, PIC, LONG

        .PAGE
        .SBTTL  LOCK_IODB - lock I/O database via mutex

;++
; LOCK_IODB - lock I/O database via mutex
;
; Inputs:  
;
;       None
;
; Implicit inputs:  
;
;       CTL$GL_PCB - address of current process's PCB
;
; Side effects:
;
;       This procedure returns at IPL ASTDEL.
;       If the mutex is not available, the process will be put into
;        MWAIT state until the mutex becomes available.  
;--

        .ENTRY  LOCK_IODB, ^M<R4>               ; lock I/O database 
        MOVL    G^CTL$GL_PCB, R4                ; get our PCB address
        JSB     G^SCH$IOLOCKW                   ; lock database for write
        RET

        .PAGE
        .SBTTL  LOCKR_IODB - lock I/O database via mutex for reading

;++
; LOCKR_IODB - lock I/O database via mutex for reading
;
; Inputs:  
;
;       None
;
; Implicit inputs:  
;
;       CTL$GL_PCB - address of current process's PCB
;
; Side effects:
;
;       This procedure returns at IPL ASTDEL.
;       If the mutex is not available, the process will be put into
;        MWAIT state until the mutex becomes available.  
;--

        .ENTRY  LOCKR_IODB, ^M<R4>              ; lock I/O database 
        MOVL    G^CTL$GL_PCB, R4                ; get our PCB address
        JSB     G^SCH$IOLOCKR                   ; lock database for write
        RET

        .PAGE
        .SBTTL  UNLOCK_IODB - unlock I/O database 

;++
; UNLOCK_IODB - unlock I/O database 
;
; Inputs:
;
;       None
;
; Implicit inputs:
;
;       CTL$GL_PCB - address of current process's PCB
;--

        .ENTRY  UNLOCK_IODB, ^M<R2,R3,R4>       ; unlock I/O database 
        MOVL    G^CTL$GL_PCB, R4                ; get our PCB address
        JSB     G^SCH$IOUNLOCK                  ; unlock mutex
        SETIPL  #0, ENVIRON=UNIPROCESSOR        ; lower IPL
        RET

        .PAGE
        .SBTTL  UNLINK_AQB - find AQB and remove it from the system AQB list

;++
; UNLINK_AQB - find AQB and remove it from the system AQB list
;
;       Should be called with the I/O database mutex locked for writing.
;
; Inputs:
;
;       4(SP)   - AQB address
;
;--

        .ENTRY  UNLINK_AQB, ^M<R2>
        MOVL    4(AP), R2                       ; get AQB address
        MOVAB   G^IOC$GL_AQBLIST, R1            ; get list address
        MOVL    (R1), R0                        ; get AQB listhead
        CMPL    R2, R0                          ; got the right one?
        BNEQ    20$                             ;  br if no
        MOVL    AQB$L_LINK(R2), (R1)            ; we're the first in the
                                                ;  list; make listhead point
                                                ;  to the next one
        BRB     40$                             ; unlink done

20$:    CMPL    AQB$L_LINK(R0), R2              ; is the next one ours?
        BEQL    30$                             ;  br if yes
        MOVL    AQB$L_LINK(R0), R0              ; else get its address
        BNEQ    20$                             ;  and loop, unless not there
        MOVL    #SS$_NOAQB, R0                  ;  and return bad status
        RET                                     ;  (AQB not found)

30$:    MOVL    AQB$L_LINK(R2), AQB$L_LINK(R0)  ; take our AQB out of list

40$:    MOVZWL  #SS$_NORMAL, R0                 ; set completion status
        RET                                     ;  and return

        .END

