*DECK DB$ATCH*                                                         HCTA$BD K
USETEXT CDCSCTX 
      PROC DB$ATCH(LFN,PFINFO,QUEUE); 
      BEGIN 
 #
* *   DB$ATCH--NOS ATTACH PROCESSOR              PAGE  1
* *   J E ESLER                                  DATE  02/02/77 
* *   M L BRANDENBURG - ADD DEVICE AND FAMILY    DATE 06/08/81
* 
* DC  PURPOSE 
* 
*     ATTACH PERMANENT FILES FOR NOS. 
* 
* DC  ENTRY CONDITIONS
* 
*     PARAMETERS
# 
      ITEM LFN;              #LFN FOR FILE# 
      ARRAY PFINFO; 
        BEGIN 
        ITEM PFN C(0,0,7);   #PERMANENT FILE NAME (MAX OF 7 CHARS)# 
        ITEM PFID C(1,0,7);  #PERMANENT FILE ID (MAX OF 7 CHARS)# 
        ITEM PFPW C(2,0,7);  #PASSOWRD (MAX OF 7 CHARS)#
        ITEM PFPN C(7,0,7);  #PACKNAME (MAX OF 7 CHARS)#
        ITEM PFFN   I(7,0,60);     # FAMILY NAME, 7 CHARACTERS, 0 FILL #
        ITEM PFFMF  B(7,59,1);     # TRUE IF FAMILY NAME               #
        ITEM PFDT   C(8,36,2);     # DEVICE TYPE MNEMONIC              #
        ITEM PFUNIT U(8,48,6);     # AUXILIARY UNIT                    #
        END 
      ITEM QUEUE B;          #TRUE IF ATTACH TO BE QUEUED#
# 
*     ASSUMPTIONS 
* 
*     ARRAY ITEM PFID - MUST BE ZERO-FILLED.
*     ARRAY ITEM PFN  - MUST BE ZERO-FILLED.
*     ARRAY ITEM PFPN - MUST BE ZERO-FILLED.
*     ARRAY ITEM PFPW - MUST BE ZERO-FILLED.
* 
* DC  EXIT CONDITIONS 
* 
*     CDCS COMMON CELL ATTACHSTATUS 
*       = 0 IF PERMANENT FILE ATTACHED
*       = -PF ATTACHSTATUS IF FILE NOT AVAILABLE. 
*       OTHERWISE PF ERROR CODE.
* 
* DC  CALLING ROUTINES
* 
*     DB$ACAI                ATTACH FILE DURING AUTOMATIC RECOVERY
*     DB$ADAX                ATTACH DATA BASES AND INDEX FILES
*     DB$DFIN                ATTACH DBP FILE
*     DB$JFIN                ATTACH JOURNAL LOG FILES 
*     DB$JRPT                JOURNAL LOG RECOVERY POINT 
*     DB$QFIN                ATTACH QUICK RECOVERY FILE 
*     DB$RFIN                ATTACH RESTART ID FILE 
*     DB$TFIN                ATTACH TRANSACTION FILE
* 
* DC  CALLED ROUTINES 
# 
      XREF PROC DB$ATCM;     #ISSUE ATTACH MACRO FOR NOS# 
      XREF PROC DB$FAM;      #CALL ENFAM MACRO                         #
      XREF PROC DB$FLOP;     #FLOW TRACER                              #
      XREF PROC DB$MBA;      #ALLOCATE TEMPORARY BUFFER#
      XREF PROC DB$MBF;      #FREE TEMPORARY BUFFER#
      XREF PROC DB$MSGB;     #ISSUE B DISPLAY MESSAGE                  #
      XREF PROC DB$POP;      #POP AN ENTRY FROM THE PUSH DOWN STACK    #
      XREF PROC DB$POP2;     #POP TWO ENTRIES FROM THE PUSH DOWN STACK #
      XREF PROC DB$PUSH;     #PUSH ENTRY INTO PUSH DOWN STACK#
      XREF FUNC DB$ROLB B;   #ROLL OUT CDCSBTF (DUMMY IN CDCS2)#
      XREF PROC DB$RSDC;     #RESET DELAY COUNTS OF OTHER RUN-UNITS    #
      XREF PROC DB$SCHD;     #CDCS SCHEDULER# 
      XREF PROC DB$SWPI;     #SWAP IN USER TABLES#
      XREF PROC DB$SWPO;     #SWAP OUT USER TABLES# 
# 
* DC  NON-LOCAL VARIABLES MODIFIED
* 
# 
      XDEF ITEM ATCHOFT I = 0;     # LOCATION OF OFT FROM DB$ADAX      #
      XDEF ITEM DB$NOS B=TRUE;     # ON NOS, DB$NOS IS TRUE            #
  
      XREF ARRAY DB$ROAF; 
        BEGIN 
        ITEM ROATFLAG I(00,00,60);  # DB$ROLL ATTACH FLAG              #
        ITEM ROFTWORD I(01,00,60);  # DB$ROLL PF FET WORD              #
        END 
 #
*     LOCAL VARIABLES.
# 
      ITEM FAMNAME;          # FAMILY NAME, DB$FAM PARAMETER WORD      #
      ITEM INDEX;            #LOOP INDEX# 
      ITEM INDX2;           #LOOP INDEX#
      ITEM MOUNTMSG C(20) = "$MOUNT PACK XXXXXXX:"; 
      BASED ARRAY PFMFET;          #PERMANENT FILE MANAGER FET# 
        BEGIN 
        ITEM ATFTWD  U(0,0,60); 
        ITEM ATFTLFN U(0,0,60);    #LFN FOR FILE# 
        ITEM ATFTEC  U(0,42,8);    #PF ERROR CODE#
        ITEM ATFTDT  C(1,0,02);    #DEVICE TYPE                        #
        ITEM ATFTCOMP U(0,59,1);   #COMPLETE BIT# 
        ITEM ATFTLEN U(1,36,6);    #LENGTH - 5 OF FET#
        ITEM ATFTUP U(1,14,1);     #USER PROCESSING BIT                #
        ITEM ATFTEP  U(1,15,1);    #ERROR PROCESSING BIT# 
        ITEM ATFTPFN C(8,0,7);     #PFN FOR FILE# 
        ITEM ATFTUN C(9,0,7);      #USER NUMBER#
        ITEM ATFTPW  C(10,0,7);    #PF PASSWORD#
        ITEM ATFTPN  C(12,0,7);    #PF PACK NAME# 
        ITEM ATFTUNIT U(12,48,12); #AUXILIARY UNIT                     #
  
        #  ATF EXTENSION.  CONTAINS CONTROL VARIABLES USED BY DB$ATCH* #
  
        ITEM ATFCOUNT I(13,00,60); #COUNT ATTACH TRIES FOR INTERLOCK   #
        ITEM ATFFAM   I(14,00,60); # FAMILY NAME                       #
        ITEM ATFQUEUE B(15,00,01); # QUEUE PARAMETER STORAGE           #
        ITEM ATFOFT   I(15,42,18); # OFT LOCATION STORAGE              #
        END 
  
      DEF DFATFXL #03#;            #LENGTH OF THE ATF EXTENSION        #
  
  
  
#**********************************************************************#
#                                                                      #
#     I N T E R N A L   P R O C E D U R E   -   A T T A C H            #
#                                                                      #
#**********************************************************************#
  
 #
* DC  INTERNAL PROCEDURES 
* 
*     ATTACH - ISSUE ATTACH REQUEST AND SAVE RETURN CODE. 
* 
*     IF A FAMILY NAME IS SPECIFIED, CALL DB$FAM TO ENTER THE FAMILY
*     NAME INTO THE CONTROL POINT AREA. 
*     CALL IT AGAIN AFTER THE ATTACH, TO RESTORE THE DEFAULT NAME.
* 
*     IF THE ERROR CODE INDICATES FILE BUSY OR ANY OTHER TEMPORARY
*     INTERLOCK, RETURN THE NEGATIVE OF THE ERROR CODE IN ATTACHSTATUS. 
* 
*       IF EXECUTING CDCS2, THE DELAY IS ACCOMPLISHED BY A SERIES OF
*         CALLS TO DB$SCHD
*       IF EXECUTING CDCSBTF THERE IS A CALL TO DB$ROLB TO ROLL OUT 
*         THE BATCH JOB.
* 
*     ISSUE OPERATOR MESSAGE IF PACK IS NOT MOUNTED.
* 
 #
      PROC ATTACH;
      BEGIN 
      IF ATFFAM[0] NQ 0 
      THEN
        BEGIN 
        FAMNAME = ATFFAM[0];
        DB$FAM(FAMNAME);           # SET ALTERNATE FAMILY NAME         #
        DB$ATCM(P<PFMFET>);        # ATTACH THE PERMANENT FILE         #
        DB$FAM(FAMNAME);           # RESTORE DEFAULT FAMILY NAME       #
        END 
      ELSE
        BEGIN 
        DB$ATCM(P<PFMFET>);        # ATTACH THE PERMANENT FILE         #
        END 
  
      ATTACHSTATUS = ATFTEC[0]; 
      ATFTEC[0] = 0;               # CLEAR ERROR CODE                  #
  
      IF ATFOFT[0] GR 0            # IF AN OFT IS IN USE,              #
      THEN                         # SEND THE ERROR CODE BACK TO ANY   #
                                   # OTHER USER THAT MIGHT BE WAITING. #
        BEGIN 
        P<OFT> = ATFOFT[0]; 
        OFPFAERR[0] = ATTACHSTATUS; 
        END 
  
      IF ATTACHSTATUS EQ O"001"    # FILE BUSY                         #
        OR ATTACHSTATUS EQ O"016"  # PF UTILITY ACTIVE                 #
        OR ATTACHSTATUS EQ O"104"  # INTERLOCK NOT AVAILABLE           #
        OR ATTACHSTATUS EQ O"107"  # FNT FULL                          #
        OR ATTACHSTATUS EQ O"111"  # PFM EXCESS ACTIVITY               #
      THEN
        BEGIN 
        ATTACHSTATUS = -ATTACHSTATUS; 
        END 
      IF ATTACHSTATUS EQ O"14"     # UNMOUNTED PACK                    #
      THEN
        BEGIN 
        ATTACHSTATUS = -ATTACHSTATUS; 
        C<12,7>MOUNTMSG = PFPN[0];
        DB$MSGB(MOUNTMSG);
        END 
 #
* 
*     SET UP THE FLAG IN DB$ROAF (ROLL-OUT ATTACH FLAG - ROATFLAG). 
*     WHEN THERE ARE NO JOBS WAITING TO ATTACH A FILE, THE FLAG IS ZERO.
*     WHEN ONLY ONE JOB IS WAITING, THE FLAG CONTAINS THE RCB ADDRESS.
*       DB$MTR WILL INITIATE A CDCS ROLL-OUT.  WHILE CDCS IS ROLLED OUT 
*       DB$ROLL ATTEMPTS THE ATTACH PERIODICALLY AND WILL ROLL IN TO
*       CONTINUE PROCESSING WHEN THE FILE IS AVAILABLE. 
*     WHEN MORE THAN ONE JOB IS WAITING, THE FLAG CONTAINS THE NEGATIVE 
*       RCB ADDRESS OF THE LAST JOB THAT ATTEMPTED THE ATTACH.
*       DB$MTR WILL NOT INITIATE A CDCS ROLL-OUT. 
*     THIS LOGIC DEPENDS ON THE FACT THAT TWO JOBS WILL BOTH DELAY FOR
*     'DFATCHDELAY' SCHEDULER CYCLES. 
*     THIS CAUSES THEIR DB$ATCH EXECUTIONS TO ALTERNATE WITH EACH OTHER.
*     EACH WILL FIND ROATFLAG (DB$ROAF) SET TO THE COMPLEMENT OF THE
*     OTHERS RCB LOCATION AND RECOGNIZE THAT THERE IS ANOTHER RCB 
*     WAITING.
*     ROATFLAG IS SET TO THE COMPLEMENT OF ITS OWN RCB LOCATION TO
*     CONTINUE THIS COMMUNICATION UNTIL ONE OR THE OTHER IS DISPOSED
*     OF BY COMPLETING THE ATTACH OR BEING DROPPED. 
* 
 #
      IF ATTACHSTATUS LS 0
      THEN
        BEGIN 
        IF ROATFLAG[0] EQ 0 
          OR ROATFLAG[0] EQ -LOC(RCB) 
        THEN
          BEGIN              # MAKE A COPY OF THE FET FOR DB$ROLL      #
          FOR INDEX = DFNOSATFETSZ-1 STEP -1 UNTIL  0 
          DO
            BEGIN 
            ROFTWORD[INDEX] = ATFTWD[INDEX];
            END 
          ROATFLAG[0] = LOC(RCB); 
          END 
        ELSE
          BEGIN 
          IF ROATFLAG[0] NQ LOC(RCB)
          THEN
            BEGIN 
            ROATFLAG[0] = -LOC(RCB);
            END 
          END 
        END 
      ELSE
        BEGIN 
                             # FILE IS ATTACHED OR HAS A FATAL ERROR   #
        IF ABS(ROATFLAG[0]) EQ LOC(RCB) 
        THEN
          BEGIN 
            ROATFLAG[0] = 0;
          END 
        END 
      END 
  
  
  
  
#     B E G I N   D B $ A T C H   E X E C U T A B L E   C O D E .      #
  
  
 #
* 
* DC  DESCRIPTION 
* 
*     SAVE ENTRY POINT
 #
      CONTROL IFGR DFFLOP,0;
        DB$FLOP("ATCH   "); 
      CONTROL ENDIF;
  
      DB$PUSH(DB$ATCH); 
      $BEGIN                       #DEBUG TRACE#
      XREF PROC DB$TRCT;
      DB$TRCT("ATTACH:",0,0); 
      DB$TRCT(PFINFO[0],"  UN AS",7);  # TRACE THE PFN                 #
      DB$TRCT(PFINFO[1],"  AS",4);     # TRACE THE UN                  #
      DB$TRCT(":",C<3,7>LFN,7); 
      $END
 #
*     GENERATE FET FOR PF ATTACH IN MANAGED MEMORY. 
 #
      DB$MBA(DFNOSATFETSZ + DFATFXL,P<PFMFET>); 
      FOR INDEX = DFNOSATFETSZ-1 STEP -1 UNTIL 0 DO 
        ATFTWD[INDEX] = 0;
      ATFTLFN[0] = LFN * 2**18; 
      ATFTCOMP[0] = 1;
      ATFTLEN[0] = DFNOSATFETSZ - 5;
      ATFTUP[0] = 1;
      ATFTEP[0] = 1;
      ATFTPFN[0] = PFN[0];
      ATFTPW[0] = PFPW[0];
      ATFTUN[0] = PFID[0];
  
#     THE FOLLOWING TEST IS MADE TO SEE IF THE VALUE STORED            #
#     IN ARRAY ITEM PFPN[0] IS THE PACKNAME OR THE FAMILY NAME.        #
#     IF THE ARRAY ITEM PFFMF[0] IS TRUE THEN THE VALUE IS THE         #
#     FAMILY NAME AND THE FAMILY NAME IS SAVED IN THE FET EXTENSION.   #
#     IF PFFMF[0] IS FALSE THEN THE PACK NAME HAS BEEN STORED AND      #
#     THE VALUE WILL BE STORED IN THE PACKNAME FIELD OF THE FET.       #
  
      IF PFFMF[0]                  # SEE IF FAMILY OR PACK NAME        #
      THEN
        BEGIN                      # FAMILY NAME                       #
        ATFFAM[0] = PFFN[0];       # SAVE IT ACROSS DB$SCHD CALLS      #
        B<42,18>ATFFAM[0] = 0;     # ZERO-FILL THE REST OF THE WORD    #
                                   # WHICH CONTAINS THE VALUE OF       #
                                   # FAMNAME TO ELIMINATE ANY GARBAGE. #
        END 
      ELSE
        BEGIN 
        ATFTPN[0] = PFPN[0];       # SET PACK NAME                     #
        ATFFAM[0] = 0;             # ZERO OUT THE FAMILY NAME FIELD    #
        END 
  
      ATFTDT[0] = PFDT[0];         # STORE DEVICE TYPE                 #
      ATFTUNIT[0] = PFUNIT[0];     # AUXILIARY UNIT NUMBER             #
  
      ATFQUEUE[0] = QUEUE;
      ATFOFT[0] = ATCHOFT;
      ATCHOFT = 0;
      IF ATFOFT[0] GR 0 
      THEN
        BEGIN 
        P<OFT> = ATFOFT[0]; 
        OFPFABUSY[0] = FALSE; 
        END 
 #
*     TRY AN INITIAL ATTACH.
 #
      ATTACH; 
  
      IF ATTACHSTATUS GQ 0
      THEN
        BEGIN 
 #
*       ISSUE ONE SCHEDULER CALL TO INTERRUPT THE ATTACHING OF
*       MULTIPLE FILES. 
*       THIS WILL PERMIT OTHER REQUESTS TO ADVANCE DURING AN INVOKE.
* 
 #
        DB$PUSH(ATTACHSTATUS);
        DB$SCHD(LOC(STATCOMP),DFWAITINV); 
  
        CONTROL IFGR DFFLOP,0;
          DB$FLOP("ATCH-S0"); 
        CONTROL ENDIF;
  
        DB$POP2(ATTACHSTATUS,DB$ATCH);
        DB$MBF(P<PFMFET>);
        RETURN; 
  
        END 
 #
*     IF WAITING FOR A NOS SYSTEM INTERLOCK, MAKE A FEW MORE TRIES. 
*       ATFCOUNT DETERMINES THE NUMBER OF ADDITIONAL TRIES. 
 #
      ATFCOUNT[0] = 10; 
      FOR INDEX = INDEX WHILE 
        (  ATTACHSTATUS EQ -O"104"
        OR ATTACHSTATUS EQ -O"111" )
        AND ATFCOUNT[0] GR 0
      DO
        BEGIN 
        DB$PUSH(DFATCHIND);  # TRY AGAIN, JUST BEFORE CDCS ROLLOUT     #
                             # DB$SCHD POPS THE COUNT AND USES IT      #
        DB$SCHD(LOC(STATCOMP),DFWAITCOUNT); 
  
        CONTROL IFGR DFFLOP,0;
          DB$FLOP("ATCH-S1"); 
        CONTROL ENDIF;
  
        ATFCOUNT[0] = ATFCOUNT[0] - 1;
        ATTACH; 
        END 
  
      IF ATFOFT[0] GR 0 
      THEN
        BEGIN 
        P<OFT> = ATFOFT[0]; 
        OFPFABUSY[0] = TRUE;
        END 
 #
* 
*     DURING THE INITIAL ATTACH ATTEMPTS THE DELAY PERIODS ARE MUCH 
*     SHORTER THAN DURING THE EXTENDED WAITING PHASE. 
*     IT IS THEN POSSIBLE THAT DB$ROAF (ROATFLAG) INDICATES ONLY ONE
*     JOB IS WAITING WHEN IN FACT THERE ARE OTHERS. 
*     IN ORDER TO ESTABLISH THE EXISTENCE OF THE OTHERS, CALL DB$RSDC 
*     SO THE OTHERS WILL ENTER DB$ATCH AGAIN BEFORE CDCS IS ROLLED OUT. 
 #
      DB$RSDC;
 #
*     IF THE FILE IS BUSY AND QUEUEING IS REQUESTED, WAIT.
* 
 #
      IF ATFQUEUE[0]
      THEN
        BEGIN 
        FOR INDEX = INDEX WHILE 
          ATTACHSTATUS LS 0 
        DO
          BEGIN 
          IF NOT DB$ROLB           #IF BTF, ROLLOUT WHILE WAITING      #
          THEN
            BEGIN 
            IF NOT RCSFSWP[0] 
              AND LOC(TQT) NQ TQTMTR
            THEN
              BEGIN 
              DB$SWPO(TRUE);
              END 
            SCHDCOUNT = SCHDCOUNT -1; 
            DB$PUSH(DFATCHDELAY);  # PUT DELAY COUNT IN RCB STACK      #
                                   # DB$SCHD POPS THE COUNT AND USES IT#
            DB$SCHD(LOC(STATCOMP),DFWAITCOUNT); 
  
            CONTROL IFGR DFFLOP,0;
              DB$FLOP("ATCH-S2"); 
            CONTROL ENDIF;
  
            END 
          ATTACH; 
          END 
        END 
      IF TQRSB[0] LS 0
      THEN
        BEGIN 
        DB$SWPI;
        SETRSARBLK; 
        END 
      DB$POP(DB$ATCH);
      DB$MBF(P<PFMFET>);
      RETURN; 
  
      END 
      TERM
