PROC L; # TITLE L - LOW LEVEL REQUEST PROCESSOR DOCUMENTATION. # BEGIN # L # # **** LOW LEVEL REQUEST PROCESSORS. * * THE FOLLOWING PROCESSORS CONSTITUTE THE LOW LEVEL REQUEST * PROCESSORS: * CPY$DS * CPY$RS * CPY$SD * INIT$HW * LD$CAR * RD$LAB * TEST$YZ * UNL$CAR * WT$LAB * * THESE PROCESSORS ARE ALL CODED IN A SPECIAL WAY THAT IS TERMED * "PSEUDO-REENTRANT". * * WHEN A LOW LEVEL REQUEST PROCESSOR IS CALLED IT IS PASSED THE * ADDRESS OF AN *LLRQ* ENTRY (A REQUEST) WHICH IS READY FOR * FURTHER PROCESSING. ALL THE PARAMETERS THE PROCESSOR NEEDS FOR * ADVANCING THE REQUEST ARE CONTAINED IN THE *LLRQ* ENTRY. IN * PARTICULAR, THE PROCESS STATE FIELD (LLR$PS) TELLS THE PROCESSOR * WHERE IT LEFT OFF THE LAST TIME IT WAS PROCESSING THIS REQUEST, * AND THUS WHAT TO DO NEXT TO ADVANCE THE REQUEST. * * WHEN A LOW LEVEL REQUEST PROCESSOR REACHES A POINT WHERE IT * CANNOT CONTINUE ADVANCING THE REQUEST WITHOUT A LONG DELAY, IT * SETS UP SOME CONDITION THAT WILL EVENTUALLY GET THE REQUEST PUT * BACK ON THE *LLRQ* READY CHAIN, AND THEN DROPS OUT BY * 1) SETTING THE PROCESS STATE FIELD IN THE *LLRQ* ENTRY TO A * VALUE THAT WILL ALLOW THE PROCESSOR TO RESTART THE REQUEST * AT THE CORRECT POINT LATER, AND * 2) RETURNING CONTROL TO THE *LLRQ* MONITOR. * * WHEN A LOW LEVEL REQUEST PROCESSOR COMPLETES THE PROCESSING OF * A REQUEST, IT CAUSES THE ORIGINATOR OF THE REQUEST TO BE * NOTIFIED OF THE COMPLETION. IF THE REQUEST ORIGINATED FROM A * *UCP* THE NOTIFICATION IS DONE BY STORING THE RESPONSE CODE IN * THE LONG TERM CONNECT TABLE ENTRY FOR THE *UCP* AND THEN * CALLING *UCP$RES*. IF THE REQUEST ORIGINATED FROM A HIGH LEVEL * REQUEST PROCESSOR, THE NOTIFICATION IS DONE BY STORING THE * RESPONSE CODE IN THE *HLRQ* ENTRY FOR THE HIGH LEVEL REQUEST, * AND PUTTING THE *HLRQ* ENTRY ON THE *HLRQ* READY CHAIN. * * WHEN THE PROCESSOR HAS NOTIFIED THE ORIGINATOR, IT THEN SETS * PROCESS STATE FIELD IN THE *LLRQ* ENTRY TO "COMPLETE" AND * RETURNS CONTROL TO THE *LLRQ* MONITOR. THE MONITOR THEN ZEROES * OUT THE *LLRQ* ENTRY AND PUTS IT ON THE *LLRQ* FREE SPACE * CHAIN. # END # L # TERM PROC CPY$DS((LLRADR)); # TITLE CPY$DS - COPY DISK TO VOLUME. # BEGIN # CPY$DS # # ** CPY$DS - COPY DISK TO VOLUME. * * *CPY$DS* COPIES THE DISK FILE (FROM ITS CURRENT POSITION) TO THE * VOLUME, UNTIL END OF VOLUME OR END OF FILE IS ENCOUNTERED. * * PROC CPY$DS((LLRADR)) * * ENTRY (LLRADR) - ADDRESS OF *LLRQ* ENTRY FOR THE COPY * CONTAINING THE SMA-ID, YZ COORDINATES, * ADDRESS OF THE DISK AND M860 FET-S. THE * FET-S MUST BE INITIALIZED. * * EXIT THE PROCESS STATE FIELD IN THE *LLRQ* ENTRY HAS BEEN * ADVANCED TO INDICATE WHERE PROCESSING OF THIS REQUEST * LEFT OFF AND THUS WHAT TO DO NEXT TO ADVANCE THE * REQUEST. WHEN THE COPY IS COMPLETE AN ERROR RESPONSE * CODE IS RETURNED IN THE *HLRQ* ENTRY WHICH GENERATED * THE COPY REQUEST. * (HLR$RESP[0]) - ERROR RESPONSE CODE. * (VALUES DEFINED IN *COMBCPR*). * = RESPTYP4"OK4". * = RESPTYP4"UN$WRT$ERR". * = RESPTYP4"EX$WRT$ERR". * = RESPTYP4"M86$HDW$PR". * = RESPTYP4"RMS$FL$ERR". * * NOTES THIS MODULE IS A PSEUDO REENTRANT ROUTINE, CALLED ONLY * BY *DESTAGR* THRU THE *HLRQ* PROCESSOR. # ITEM LLRADR U; # *LLRQ* ENTRY ADDRESS # ITEM STRPCT U; # NUMBER OF STRIPES # # **** PROC CPY$DS - XREF LIST BEGIN. # XREF BEGIN PROC ADD$LNK; # ADD ENTRY TO CHAIN # PROC GETBUF; # GET LARGE BUFFER # PROC RLSBUF; # RELASE LARGE BUFFER # PROC READCW; # READ WITH CONTROL WORDS # PROC SETFET; # INITIALIZE LARGE BUFFER # END # **** PROC CPY$DS - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL COMBFAS *CALL COMBCDD *CALL COMBCHN *CALL COMBCPR *CALL COMBFET *CALL COMBLRQ *CALL COMBRCD *CALL COMXCCB *CALL COMXHLR *CALL COMXMSC ITEM FLAG B; # FLAG # SWITCH CDSENTR:PROCST # COPY DISK TO VOLUME ENTRIES # CDSINIT:INITIAL, # INITIAL ENTRY # CDS1:CONT1, # WAIT LARGE BUFFER # CDS2:CONT2, # DRIVER VOLUME RETURN # CDS3:CONT3; # DRIVER RETURN *REWIND/UNLOAD* # CONTROL EJECT; P = LLRADR; P = LLR$UCPRA[0]; GOTO CDSENTR[LLR$PRCST[0]]; # * "INITIAL" PROCESS STATE. # CDSINIT: # SET UP COPY CONTROL BLOCK # GETBUF(LLRADR,HLRQIND,FLAG); IF NOT FLAG THEN # NO BUFFER AVAILABLE # BEGIN LLR$PRCST[0] = PROCST"CONT1"; # WAIT BUFFER ASSIGNMENT # ADD$LNK(LLRADR,LCHN"LL$LGBUF",0); RETURN; END # * *CONT1* PROCESS STATE. # CDS1: SETFET(LLRADR); # INITIALIZE,LARGE BUFFER # P = LLR$UCPRA[0]; P = LLRADR; P = LLR$CCB[0]; P = LLR$DSKFET[0]; P = LLR$MSFET[0]; CCBOPCODE[0] = CPYC"DISKAU"; FET$RR[0] = HLR$PRU[0]; # * SET STRIPE INFORMATION IN LARGE BUFFER. # FHB$TIME[0] = PDATEV; FHB$SMIF[0] = LLR$SMIF[0]; FHB$CCSN[0] = HLR$CSNTCU[0]; FHB$SHDWD[0] = HLR$FETMT[0]; FHB$PCSN[0] = HLR$CSNTPS[0]; FHB$PFC[0] = HLR$PFC[0]; FHB$CODE[0] = FCCWW; # CONTROL WORD WRITE # READCW(FETSET[0],0,NRCL); LLR$RC[0] = REQCODE"SWRT$VOL"; # ISSUE WRITE VOLUME REQUEST # LLR$RS[0] = PROCST"INITIAL"; ADD$LNK(CCBLLRQ[0],LCHN"DRQUEUE",0); LLR$PRCST[0] = PROCST"CONT2"; RETURN; # * *CONT2* PROCESS STATE. * CPU DRIVER RETURN FROM VOLUME MOUNT. # CDS2: # PROCESS DRIVER RESPONSE # IF LLR$DR[0] NQ RESPTYP4"OK4" THEN BEGIN # PROCESS DRIVER ERROR RETURN CODE # IF LLR$DR[0] EQ RESPTYP4"UN$WRT$ERR" THEN BEGIN # UNRECOVERED WRITE ERROR # HLR$AUUD[0] = (LLR$ST$LW[0] - INFTST) / INSPAU + 1; HLR$HRDE[0] = HLR$HRDE[0] + 1; # SET WRITE ERROR # END # WRITE ERROR # GOTO CONT; END ADD$LNK(LLR$CCB[0],LCHN"KC$GOING",0); LLR$PRCST[0] = PROCST"CONT3"; RETURN; # * *CONT3* PROCESS STATE. * KEEP COPY GOING RETURN AFTER REWIND/UNLOAD COMMAND. # CDS3: P = LLR$CCB[0]; HLR$AUUD[0] = (LLR$LT$ST[0] - INFTST) / INSPAU + 1; STRPCT = LLR$LOG$ST[0] / INSPAU; IF CCBDERR[0] THEN BEGIN # DISK ERROR # LLR$DR[0] = RESPTYP4"RMS$FL$ERR"; GOTO CONT; END IF (CCBHDWPM[0]) OR (LLR$DR[0] NQ RESPTYP4"OK4") OR (HLR$AUUD[0] LS HLR$VOLAU[0]) OR (HLR$AUUD[0] GR (HLR$VOLAU[0] + HLR$VOLLN[0])) OR (STRPCT GR HLR$VOLLN[0]) THEN # HARDWARE ERROR # BEGIN LLR$DR[0] = RESPTYP4"M86$HDW$PR"; LLR$DRFUL[0] = TRUE; # FORCE UNLOAD OF CARTRIDGE # GOTO CONT; END IF CCBTAPPAR THEN BEGIN # WRITE PARITY ERROR # LLR$DR[0] = RESPTYP4"UN$WRT$ERR"; HLR$HRDE[0] = HLR$HRDE[0] + 1; # SET WRITE ERROR # GOTO CONT; END HLR$PRU[0] = LLR$LOG$ST[0] * INPRUS + HLR$PRU[0]; CONT: HLR$RESP[0] = LLR$DR[0]; # RETURN RESPONSE # ADD$LNK(LLR$UCPRA[0],LCHN"HL$READY",0); LLR$MSFET[0] = 0; LLR$DSKFET[0] = 0; RLSBUF(LLRADR); # RELEASE BUFFER # RETURN; END # CPY$DS # TERM PROC CPY$RS((LLRADR)); # TITLE CPY$RS - COPY RAW VOLUME. # BEGIN # CPY$RS # # ** CPY$RS - COPY RAW VOLUME. * * *CPY$RS* APPENDS A RAW VOLUME TO A FILE, STARTING WITH THE * CURRENT POSITION ON THE VOLUME TO THE END OF VOLUME. * * PROC CPY$RS((LLRADR)) * * ENTRY (LLRADR) - ADDRESS OF *LLRQ* ENTRY FOR THE COPY * CONTAINING THE SMA-ID, THE VOLUME * NUMBER, AND THE YZ COORDINATES. * * EXIT THE PROCESS STATE FIELD IN THE *LLRQ* ENTRY HAS BEEN * ADVANCED TO INDICATE WHERE PROCESSING OF THIS REQUEST * LEFT OFF AND THUS WHAT TO DO NEXT TO ADVANCE THE * REQUEST. WHEN THE COPY IS COMPLETE AN ERROR RESPONSE * CODE IS RETURNED VIA *LTC$RQR[LTCENTRY]*. * (LTC$RQR[LTCENTRY]) - ERROR RESPONSE CODE. * (VALUES DEFINED IN *COMBCPR*). * = RESPTYP4"OK4". * = RESPTYP4"M86$HDW$PR". * = RESPTYP4"RMS$FL$ERR". * = RESPTYP4"DISK$FULL". * * MESSAGES * EXEC ABNORMAL, CPY$RS.*. * * NOTES THIS MODULE IS A PSEUDO REENTRANT ROUTINE. A COPY RAW * VOLUME REQUEST ONLY COMES FROM *ASDEBUG* AND IS USED * TO SALVAGE INFORMATION FROM A VOLUME WITH READ ERRORS. # ITEM LLRADR U; # *LLRQ* ENTRY ADDRESS # # **** PROC CPY$RS - XREF LIST BEGIN. # XREF BEGIN PROC ABORT; # ABORT # PROC ADD$LNK; # ADD ENTRY TO CHAIN # PROC DELAY; # TIMED DELAY # PROC GETBUF; # GET LARGE BUFFERS # PROC MESSAGE; # ISSUE MESSAGE # PROC PFD; # PERMANENT FILE REQUEST DELAYS # PROC RETERN; # RETURN FILE # PROC RLSBUF; # RELEASE LARGE BUFFERS # PROC SETFET; # INITIALIZE LARGE BUFFER # PROC SETPFP; # SET PERMANENT FILE PARAMETERS # PROC SFCALL; # INTERFACE TO *SFCALL* MACRO # PROC SKIPEI; # SKIP TO *EOI* # PROC UCP$RESP; # UCP RESPONSE # PROC WRITE; # WRITE DATA FROM *CIO* BUFFER # PROC WRITER; # WRITE *EOR* # END # **** PROC CPY$RS - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL COMBFAS *CALL COMBCHN *CALL COMBCPR *CALL COMBFET *CALL COMBLBL *CALL COMBLRQ *CALL COMBPFP *CALL COMBPFS *CALL COMBRCD *CALL COMBUCR *CALL COMXBST *CALL COMXIPR *CALL COMXLTC *CALL COMXMSC *CALL COMSPFM ITEM FLAG B; # FLAG # SWITCH CRSENTR:PROCST # COPY RAW VOLUME ENTRIES # CRSINIT:INITIAL, # INITIAL ENTRY # CRS1:CONT1, # CONTINUATION 1 # CRS2:CONT2, # CONTINUATION 2 # CRS3:CONT3, # CONTINUATION 3 # CRS4:CONT4; # CONTINUATION 4 # CONTROL EJECT; P = LLRADR; LLR$DR[0] = RESPTYP4"OK4"; GOTO CRSENTR[LLR$PRCST[0]]; # PROCESS REQUEST # # * "INITIAL" PROCESS STATE. # CRSINIT: GETBUF(LLRADR,HLRQIND,FLAG); IF NOT FLAG THEN # NO BUFFER AVAILABLE # BEGIN LLR$PRCST[0] = PROCST"CONT1"; #WAIT BUFFER ASSIGNMENT# ADD$LNK(LLRADR,LCHN"LL$LGBUF",0); RETURN; END CRS1: SETFET(LLRADR); # * "CONT1" PROCESS STATE. * * REREAD THE UCP REQUEST BLOCK TO GET THE FAMILY, USER INDEX, * AND FILE NAME. # CRS2: IF LLR$UCPABT[0] THEN BEGIN GOTO CRSCOMP; END P = LLR$DSKFET[0]; LTCENTRY = LLR$LTCT[0]; LTC$SFUCPA[LTCENTRY] = LLR$UCPRA[0]; LTC$SFSCPA[LTCENTRY] = FET$IN[0]; LTC$SFFP[LTCENTRY] = TYP4$WC + 1; LTC$SFFC[LTCENTRY] = SFREAD; SFCALL(LOC(LTC$WORD0[LTCENTRY]),RCL); IF LTC$SFRC[LTCENTRY] NQ 0 THEN BEGIN # PROCESS ERROR RESPONSE # IF LTC$SFRC[LTCENTRY] EQ SFRCSWPOUT THEN BEGIN # SWAP IN UCP # LTC$SFUCPA[LTCENTRY] = 0; LTC$SFSCPA[LTCENTRY] = 0; LTC$SFFC[LTCENTRY] = SFSWPI; SFCALL(LOC(LTC$WORD0[LTCENTRY]),NRCL); # * "CONT3" PROCESS STATE. # CRS3: LTCENTRY = LLR$LTCT[0]; IF LTC$SFFCC[LTCENTRY] THEN # RETRY *SFREAD* # BEGIN LLR$PRCST[0] = PROCST"CONT2"; END ELSE # DELAY FOR REQUEST COMPLETION # BEGIN LLR$PRCST[0] = PROCST"CONT3"; DELAY(UCP$INTV,LLRADR,LLRQIND); END RETURN; END # SWAP IN UCP # ELSE # FATAL ERROR # BEGIN GOTO CRSFERR; END END # PROCESS ERROR RESPONSE # P = FET$IN[0]; FET$LFN[0] = CPR$PFN[0]; PFP$WRD0[0] = 0; # SET FAMILY AND USER INDEX # PFP$FAM[0] = CPR$FAM[0]; PFP$UI[0] = CPR$UI[0]; PFP$FG1[0] = TRUE; PFP$FG4[0] = TRUE; SETPFP(PFP); IF PFP$STAT[0] NQ 0 THEN BEGIN GOTO CRSFERR; END PFD("ATTACH",FET$LFN[0],0,"M","W","RC",PFSTAT,"NA",0,"UP",0,0); PFP$FAM[0] = DEF$FAM; # RETURN TO DEFAULT FAMILY # PFP$UI[0] = DEF$UI; SETPFP(PFP); IF PFP$STAT[0] NQ 0 THEN BEGIN GOTO CRSFERR; END IF PFSTAT NQ 0 THEN # IF *ATTACH* ERROR # BEGIN LLR$DR[0] = RESPTYP4"ATTACH$ERR"; GOTO CRSCOMP; END SKIPEI(FETSET[0],RCL); # * SET READ ONE STRIPE AT A TIME. # LLR$SAV$HI[0] = LLR$ST$HI[0]; # SAVE LAST STRIPE TO READ # LLR$ST$HI[0] = LLR$ST$LW[0] + 1; # * ISSUE A READ RAW STRIPE REQUEST TO THE DRIVER. WHEN IT IS * COMPLETED, WRITE THE RAW STRIPE TO THE DISK FILE. THEN LOOP * BACK TO READ THE NEXT RAW STRIPE. CONTINUE THIS LOOP UNTIL * THE LAST STRIPE IS READ. # LLR$RC[0] = REQCODE"SRDRAW$STP"; LLR$PRCST[0] = PROCST"CONT4"; RDRAWSTP: # ISSUE READ RAW STRIPE REQUEST # IF LLR$UCPABT[0] THEN BEGIN GOTO CRSCOMP; END LLR$DR[0] = 0; LLR$RS[0] = PROCST"INITIAL"; ADD$LNK(LLRADR,LCHN"DRQUEUE",0); RETURN; # * "CONT4" PROCESS STATE. # CRS4: IF LLR$DR[0] NQ RESPTYP4"OK4" ## THEN BEGIN # PROCESS ERROR # GOTO CRSCOMP; END P = LLR$MSFET[0]; P = LLR$DSKFET[0]; FET$IN[0] = FHB$IN[0]; WRITER(FETSET[0],RCL); IF FET$AT[0] NQ 0 THEN BEGIN # WRITE ERROR # IF FET$AT[0] EQ ATCODE AND FET$DEC[0] EQ DISKFULL THEN # DISK FULL # BEGIN LLR$DR[0] = RESPTYP4"DISK$FULL"; END ELSE # FILE WRITE ERROR # BEGIN LLR$DR[0] = RESPTYP4"RMS$FL$ERR"; END GOTO CRSCOMP; END # WRITE ERROR # LLR$ST$LW[0] = LLR$ST$LW[0] + 1; LLR$ST$HI[0] = LLR$ST$LW[0] + 1; IF LLR$ST$LW[0] LQ LLR$SAV$HI[0] THEN # IF NOT END OF VOLUME # BEGIN FHB$IN[0] = FET$FRST[0]; FHB$OUT[0] = FET$FRST[0]; FET$IN[0] = FET$FRST[0]; FET$OUT[0] = FET$FRST[0]; GOTO RDRAWSTP; # CONTINUE READING STRIPES # END LLR$DR[0] = RESPTYP4"OK4"; CRSCOMP: P = LLR$DSKFET[0]; IF FET$LFN[0] NQ 0 THEN BEGIN RETERN(FETSET[0],RCL); END LLR$MSFET[0] = 0; LLR$DSKFET[0] =0; RLSBUF(LLRADR); # RELEASE BUFFERS # P = LLRADR; IF NOT LLR$UCPABT[0] THEN # ISSUE RESPONSE TO THE UCP # BEGIN LTCENTRY = LLR$LTCT[0]; LTC$RQR[LTCENTRY] = LLR$DR[0]; UCP$RESP; END ELSE BEGIN # FORCE UNLOAD OF CARTRIDGE # LLR$PRCNME[0] = REQTYP4"UNLD$CART"; LLR$PRCST[0] = PROCST"INITIAL"; LLR$RQI[0] = REQNAME"RQIAUCP"; ADD$LNK(LLRADR,LCHN"LL$READY",0); END # UNLOAD CARTRIDGE # RETURN; CRSFERR: # FATAL ERROR # FE$RTN[0] = "CPY$RS."; MESSAGE(FEMSG,UDFL1); ABORT; END # CPY$RS # TERM PROC CPY$SD((LLRADR)); # TITLE CPY$SD - COPY VOLUME TO DISK. # BEGIN # CPY$SD # # ** CPY$SD - COPY VOLUME TO DISK. * * *CPY$SD* COPIES A VOLUME TO A DISK FILE. * * PROC CPY$SD((LLRADR)) * * ENTRY (LLRADR) - ADDRESS OF *LLRQ* ENTRY FOR THE COPY * CONTAINING THE SMA-ID, YZ COORDINATES, * ADDRESS OF THE DISK AND M860 FET-S. THE * FET-S MUST BE INITIALIZED. * * EXIT THE PROCESS STATE FIELD IN THE *LLRQ* ENTRY HAS BEEN * ADVANCED TO INDICATE WHERE PROCESSING OF THIS REQUEST * LEFT OFF AND THUS WHAT TO DO NEXT TO ADVANCE THE * REQUEST. WHEN THE COPY IS COMPLETE AN ERROR RESPONSE * CODE IS RETURNED IN THE *HLRQ* ENTRY WHICH GENERATED * THE COPY REQUEST. * (HLR$RESP[0]) - ERROR RESPONSE CODE. * (VALUES DEFINED IN *COMBCPR*). * = RESPTYP4"OK4". * = RESPTYP4"UNR$RD$ERR". * = RESPTYP4"M86SYS$ERR". * = RESPTYP4"M86$HDW$PR". * = RESPTYP4"RMS$FL$ERR". * = RESPTYP4"DISK$FULL". * * NOTES THIS MODULE IS A PSEUDO REENTRANT ROUTINE, CALLED ONLY * BY *STAGER* THRU THE *HLRQ* PROCESSOR. # ITEM LLRADR U; # *LLRQ* ENTRY ADDRESS # # **** PROC CPY$SD - XREF LIST BEGIN. # XREF BEGIN PROC ADD$LNK; # ADD ENTRY TO CHAIN # PROC GETBUF; # GET LARGE BUFFER # PROC RLSBUF; # RELEASE LARGE BUFFER # PROC SETFET; # INITIALIZE LARGE BUFFER # END # **** PROC CPY$SD - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL COMBFAS *CALL COMBCDD *CALL COMBCHN *CALL COMBCPR *CALL COMBFET *CALL COMBLRQ *CALL COMBRCD *CALL COMXCCB *CALL COMXHLR *CALL COMXMSC ITEM FLAG B; # FLAG # SWITCH CSDENTR:PROCST # COPY VOLUME TO DISK ENTRIES # CSDINIT:INITIAL, # INITIAL ENTRY # CSD1:CONT1, # WAIT LARGE BUFFER # CSD2:CONT2, # DRIVER VOLUME RETURN # CSD3:CONT3; # DRIVER RETURN *REWIND/UNLOAD* # CONTROL EJECT; P = LLRADR; P = LLR$UCPRA[0]; GOTO CSDENTR[LLR$PRCST[0]]; # * "INITIAL" PROCESS STATE. # CSDINIT: # SET UP COPY CONTROL BLOCK # GETBUF(LLRADR,HLRQIND,FLAG); IF NOT FLAG THEN # NO BUFFER AVAILABLE # BEGIN LLR$PRCST[0] = PROCST"CONT1"; # WAIT BUFFER ASSIGNMENT # ADD$LNK(LLRADR,LCHN"LL$LGBUF",0); RETURN; END # * *CONT1* PROCESS STATE. # CSD1: SETFET(LLRADR); # INITIALIZE LARGE BUFFER # P = LLRADR; P = LLR$CCB[0]; P = LLR$DSKFET[0]; P = LLR$MSFET[0]; CCBOPCODE[0] = CPYC"AUDISK"; FHB$CODE[0] = FCCWR; LLR$RC[0] = REQCODE"SREAD$VOL"; # ISSUE READ VOLUME REQUEST # LLR$RS[0] = PROCST"INITIAL"; ADD$LNK(CCBLLRQ[0],LCHN"DRQUEUE",0); LLR$PRCST[0] = PROCST"CONT2"; RETURN; # * *CONT2* PROCESS STATE. * CPU DRIVER MOUNT VOLUME RETURN. # CSD2: # PROCESS DRIVER RETURN # IF LLR$DR[0] NQ RESPTYP4"OK4" THEN BEGIN # PROCESS DRIVER ERROR RETURN CODE # GOTO CONT; END ADD$LNK(LLR$CCB[0],LCHN"KC$GOING",0); LLR$PRCST[0] = PROCST"CONT3"; RETURN; # * *CONT3* PROCESS STATE. * CPU DRIVER RETURN FROM REWIND/UNLOAD COMMAND. # CSD3: P = LLR$CCB[0]; P = LLR$DSKFET[0]; P = LLR$MSFET[0]; IF CCBDERR[0] THEN # DISK ERROR # BEGIN LLR$DR[0] = RESPTYP4"RMS$FL$ERR"; GOTO CONT; END IF CCBDFULL[0] THEN # DISK FULL ERROR # BEGIN LLR$DR[0] = RESPTYP4"DISK$FULL"; GOTO CONT; END IF CCBHDWPM[0] OR LLR$DR[0] NQ RESPTYP4"OK4" THEN # IF HARDWARE ERROR # BEGIN LLR$DR[0] = RESPTYP4"M86$HDW$PR"; LLR$DRFUL[0] = TRUE; # FORCE UNLOAD OF CARTRIDGE # GOTO CONT; END IF CCBTAPPAR THEN BEGIN # READ PARITY ERROR # LLR$DR[0] = RESPTYP4"UN$RD$ERR"; IF NOT HLR$RETRY[0] # FIRST PARITY ERROR # THEN BEGIN # FORCE UNLOAD AND DELINK OF CARTRIDGE # LLR$DRFUL[0] = TRUE; END GOTO CONT; END IF CCPPUDCK THEN BEGIN # PPU FOUND DATA TRANSFER ERROR # LLR$DR[0]= RESPTYP4"PPU$D$PROB"; IF NOT HLR$RETRY[0] # FIRST DATA ERROR # THEN BEGIN # FORCE UNLOAD AND DELINK OF CARTRIDGE # LLR$DRFUL[0] = TRUE; END GOTO CONT; END IF FHB$PVLN[0] NQ HLR$VOLLNP[0] # PREVIOUS VOLUME LENGTH # OR FHB$PVSN[0] NQ HLR$VOLAUP[0] # PREVIOUS VOLUME NUMBER # OR FHB$CVSN[0] NQ HLR$VOLAU[0] # VOLUME NUMBER # OR FHB$PCSN[0] NQ HLR$CSNTPS # CSN OR PREVIOUS VOLUME # OR FHB$PFC$UI[0] NQ HLR$TDAMUI[0] # USER INDEX # OR FHB$PFC$DT[0] NQ HLR$TDAMCD[0] # CREATION DATE / TIME # THEN BEGIN # SET VOLUME HEADER ERROR # LLR$DR[0] = RESPTYP4"VOL$HD$ERR"; GOTO CONT; END HLR$PRU[0] = FET$CRI[0] + HLR$PRU[0]; IF CCBTPMARK THEN BEGIN HLR$EOI[0] = TRUE; END CONT: HLR$RESP[0] = LLR$DR[0]; # RETURN RESPONSE # ADD$LNK(LLR$UCPRA[0],LCHN"HL$READY",0); LLR$MSFET[0] = 0; LLR$DSKFET[0] = 0; RLSBUF(LLRADR); # RELEASE BUFFER # RETURN; END # CPY$SD # TERM PROC INIT$HW((LLRADR)); # TITLE INIT$HW - INITIALIZE M860 HARDWARE. # BEGIN # INIT$HW # # ** INIT$HW - INITIALIZE M860 HARDWARE. * * *INIT$HW* PASSES M860 HARDWARE INITIALIZATION * REQUESTS TO THE MSAS DRIVER. IT CLEARS THE * *INITIALIZE* FLAG TO INDICATE THAT FULL * INITIALIZATION HAS COMPLETED WHEN IT FINDS THE * *LLRQ* READY CHAIN AND *DRQUEUE* BOTH INACTIVE, WHILE * PROCESSING A REQUEST JUST RETURNED FROM THE DRIVER. * * PROC INIT$HW((LLRADR)) * * ENTRY (LLRADR) - *LLRQ* ENTRY ADDRESS CONTAINING * CONTROLLER ORDINAL FROM WHICH HARDWARE * INITIALIZATION IS TO BE BASED. * * EXIT THE *LLRQ* ENTRY PROCESS STATE FIELD HAS BEEN * ADVANCED TO INDICATE WHERE SUBSEQUENT PROCESSING OF * THIS REQUEST IS TO CONTINUE. * * NOTES THIS MODULE IS A PSEUDO-REENTRANT ROUTINE. # ITEM BYNR U; # OFF SET BIT ADDRESS # ITEM LLRADR U; # *LLRQ* ENTRY ADDRESS # ITEM STAT U; # STATUS BIT # # **** PROC INIT$HW - XREF LIST BEGIN. # XREF BEGIN PROC ABORT; # ABORT # PROC ADD$LNK; # ADD ENTRY TO END OF CHAIN # PROC MESSAGE; # ISSUE MESSAGE # PROC UCP$RES; # RETURN RESPONSE TO UCP # END # **** PROC INIT$HW - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL,COMBFAS *CALL,COMBCHN *CALL,COMBCPR *CALL,COMBLRQ *CALL,COMBRCD *CALL,COMBUCR *CALL COMBUDT *CALL,COMXCTF *CALL,COMXLTC *CALL,COMXMSC BASED ARRAY UDTBIT [0:0] P(1); # CHECK *UDT* AREA # BEGIN ITEM UDT$BIT U(00,00,60); END # * GENERAL MESSAGE BUFFER. # ARRAY GMSB [0:0] S(5); BEGIN # INIT MSGS # ITEM MSG$LINE C(00,00,40); # MESSAGE LINE # ITEM MSG$ZERO U(04,00,12) = [0]; # ZERO-BYTE TERMINATOR # END # INIT MSGS # SWITCH INITIALS:PROCST # INITIALIZATION ENTRIES # INIT1:INITIAL, # INITIAL ENTRY # INIT2:CONT1; # FINAL ENTRY # CONTROL EJECT; P = LLRADR; GOTO INITIALS[LLR$PRCST[0]]; # * "INITIAL" PROCESS STATE. # INIT1: LLR$RC[0] = RESTART$CU; # ASSUME DRIVER RESTART REQUEST # IF NOT INITIALIZE ## THEN # NO CU RESTART REQUIRED # BEGIN # RESET # LLR$RC[0] = INIT$SM; END # RESET # LLR$PRCST[0] = PROCST"CONT1"; ADD$LNK(LLRADR,LCHN"DRQUEUE",0); RETURN; # * "COMPLETE" PROCESS STATE. # INIT2: IF CHN$BOC[LCHN"LL$READY"] EQ 0 ## AND CHN$BOC[LCHN"DRQUEUE"] EQ 0 ## AND INITIALIZE THEN # FULL INITIALIZATION COMPLETED # BEGIN # INIT DONE # IF UDT$HWOFF[0] EQ 0 THEN # INITIALIZATION WAS SUCCESSFUL # BEGIN # OK # INITIALIZE = FALSE; MSG$LINE[0] = " INITIALIZATION COMPLETE."; MESSAGE(GMSB,SYSUDF1); END # OK # ELSE # NO 7990 HARDWARE ACCESS # BEGIN # EXIT # MSG$LINE[0] = " INITIALIZATION HALTED."; MESSAGE(GMSB,SYSUDF1); MSG$LINE[0] = "$INITIALIZATION HALTED."; MESSAGE(GMSB,LINE2); END # EXIT # END # INIT DONE # IF LLR$RQI[0] EQ REQNAME"RQIALTER" # SSALTER WORKING # AND NOT LLR$UCPABT[0] THEN # REQUEST FROM UCP # BEGIN # RETURN # BYNR = LLR$BYNR[0]; P = LLR$UDTQ[0]; STAT = B UDT$BIT[0]; LTCENTRY = LLR$LTCT[0]; LTC$RQR[LTCENTRY] = RESPTYP5"OK5"; IF STAT NQ LLR$PMMR[0] # STATUS UNCHANGED # OR LLR$DR[0] EQ RESPTYP4"M86$HDW$PR" # HARDWARE PROBLEM # THEN BEGIN # STATUS REMAINED # LTC$RQR[LTCENTRY] = RESPTYP5"SSA$ERROR"; END # STATUS REMAINED # LTC$LLRQA[LTCENTRY] = 0; UCP$RES; # RETURN RESPONSE TO UCP # END # RETURN # LLR$PRCST[0] = PROCST"COMPLETE"; RETURN; END # INIT$HW # TERM PROC KCG; # TITLE KCG - KEEP COPY GOING. # BEGIN # KCG # # ** KCG - KEEP COPY GOING. * * *KCG* MONITORS THE PROGRESS OF COPIES BETWEEN DISK AND A * CARTRIDGE VOLUME, MOVES *IN* AND *OUT* POINTERS BETWEEN THE *CIO* * AND *1SS* FET AND RESTARTS *CIO* OR *1SS* AS NECESSARY TO * KEEP THE COPY PROCESS GOING. * * PROC KCG * * EXIT ALL COPY REQUESTS WHICH HAVE BEEN COMPLETED ARE * DELETED FROM THE KEEP COPY GOING CHAIN AND ADDED BACK * ON THE *LLRQ* READY CHAIN. * * SENSE SWITCH 2 IS USED TO SET READ AND WRITE 1MS * CALLS IN THE DAYFILE. THE NUMBER OF TIMES 1MS IS CALLED * IN A VOLUME CAN BE TRACED BY SETTING SENSE SWITCHS 1 AND 2. * * THE STRIPES ARE READ OR WRITTEN IN 13 PRU BLOCKS. * THE BUFFER HAS BEEN SET FOR 4 PLUS BLOCKS. * THE BUFFER SIZE IS CHANGED BY *DATABL* IN COMXBST. * * * THE CODE IS SET TO CALL 1MS WHEN A BUFFER IS 1/2 FULL. * * THE BUFFER SIZE CAN BE VARIED, BUT 1/3 OF A BUFFER MUST BE * OVER 13 PRU-S OR A LOCK WILL HAPPEN BETWEEN 1SS AND 1MS. * DATABL (BUFFER SIZE) HAS BEEN INCREASED FROM 3700 TO * 6501. * * TO CHANGE FROM 1/2 TO 2/3 BUFFER FULL CALLS TO *1MS* - * ((DATABL-1) / 2) TO ((DATABL-1) / 3) * 2 * # DEF BUFSTART #((DATABL-1) / 2)#; # SETS HALF BUFFER START # DEF EOI$IWRD #O"2000 0000 0000 0000 0000"#; # *EOI* WORD # # **** PROC KCG - XREF LIST BEGIN. # XREF BEGIN PROC ADD$LNK; # ADD ENTRY TO CHAIN # PROC CALLPPU; # CALL PPU # PROC DEL$LNK; # DELETE ENTRY FROM CHAIN # PROC READCW; # READ WITH CONTROL WORDS # PROC WRITECW; # WRITE WITH CONTROL WORDS # PROC K8G; # KEEP M860 GOING # PROC MESSAGE; # ISSUE MESSAGE # END # **** PROC KCG - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL COMBFAS *CALL COMBCDD *CALL COMBCHN *CALL COMBFET *CALL COMBLRQ *CALL COMXBST *CALL COMXCCB *CALL COMXCTF *CALL COMXJCA *CALL COMXMSC ITEM ENTADR U; # *CCB* ENTRY ADDRESS # ITEM NEXTADDR U; # NEXT ENTRY ADDRESS # ITEM TEMP U; # TEMPORARY STORAGE # ITEM RD$READY B; # READ BUFFER READY # ITEM WRT$READY B; # WRITE BUFFER READY # ARRAY WRITEMG [0:0] S(2); BEGIN ITEM WRITEMSG C(00,00,12) = [" 1MS WRITE."]; ITEM TERMA U(01,48,12) = [0]; # TERMINATOR # END ARRAY READMG [0:0] S(2) ; BEGIN ITEM READMSG C(00,00,12) = [" 1MS READ."]; ITEM TERMB U(01,48,12) = [0]; # TERMINATOR # END CONTROL EJECT; ENTADR = CHN$BOC[LCHN"KC$GOING"]; REPEAT WHILE ENTADR NQ 0 DO BEGIN # MONITOR ENTRIES ON KEEP COPY GOING CHAIN # P = ENTADR; P = CCBLLRQ[0]; NEXTADDR = CCBLINK[0]; P = CCBDKFET[0]; P = CCBM86FET[0]; IF CCBOPCODE[0] EQ CPYC"DISKAU" THEN BEGIN # COPY DISK TO M860 # FHB$IN[0] = FET$IN[0]; FET$OUT[0] = FHB$OUT[0]; END ELSE BEGIN # COPY M860 TO DISK # FET$IN[0] = FHB$IN[0]; FHB$OUT[0] = FET$OUT[0]; END IF FET$LOCK[0] ## AND NOT (CCBDERR[0] OR CCBDFULL[0]) THEN # IF MEDIA NOT EMPTY, NO DISK ERRORS AND *CIO* NOT RUNNING # BEGIN IF FET$AT[0] NQ 0 THEN BEGIN # SET DISK ERROR FLAG # IF FET$AT[0] EQ 1 THEN BEGIN # DISK FULL # CCBDFULL[0] = TRUE; END ELSE BEGIN # DISK ERROR # CCBDERR[0] = TRUE; END END ELSE BEGIN # START COPY # IF CCBOPCODE[0] EQ CPYC"DISKAU" THEN BEGIN # DISK INPUT # IF FET$EOI[0] THEN BEGIN # WRITE *EOI* WORD # RA$WORD[FET$IN[0]] = EOI$IWRD; IF FET$IN[0] EQ FET$LIM[0] - 1 THEN BEGIN FET$IN[0] = FET$FRST[0]; END ELSE BEGIN FET$IN[0] = FET$IN[0] + 1; END CCBDEOI[0] = TRUE; END # END OF *EOI* WRITE # RD$READY = ((FET$OUT[0] GR FET$IN[0]) ## AND ((FET$OUT[0] - FET$IN[0]) GR BUFSTART)) ## OR ((FET$OUT[0] LQ FET$IN[0]) ## AND (((FET$OUT[0]-FET$FRST[0]) + (FET$LIM[0]-FET$IN[0])) GR BUFSTART)); IF RD$READY ## AND (CCBRWCT[0] EQ 0) ## AND (NOT CCBDEOI[0]) THEN BEGIN READCW(FETSET[0],0,NRCL); IF RA$SW2 THEN BEGIN MESSAGE(READMSG,UDFL1); END END END # END OF DISK INPUT # ELSE BEGIN # WRITE DISK # WRT$READY = ((FET$IN[0] GR FET$OUT[0]) ## AND ((FET$IN[0] - FET$OUT[0]) GR BUFSTART)) OR ((FET$IN[0] LQ FET$OUT[0]) ## AND ((FET$LIM[0] - FET$OUT[0]) ## + (FET$IN[0] - FET$FRST[0]) GR BUFSTART)); IF (WRT$READY OR CCBRWDULD[0] OR (CCBRWCT[0] NQ 0)) ## AND (NOT FET$IN[0] EQ FET$OUT[0]) THEN BEGIN WRITECW(FETSET[0],NRCL); IF RA$SW2 THEN BEGIN MESSAGE(WRITEMSG,UDFL1); END END END # END OF WRITE DISK # END # END OF COPY # IF CCBDERR[0] OR CCBDFULL[0] THEN # STOP *1SS* # BEGIN FHB$ST$SS[0] = TRUE; END END IF FHB$LOCK[0] AND NOT CCBRWDULD[0] THEN # IF *1SS* RUNNING # BEGIN K8G(ENTADR); # M860 SIDE OF COPY # P = ENTADR; P = CCBM86FET[0]; END # * IF THE INPUT COULD NOT BE RESTARTED (BECAUSE THE BUFFER WAS * FULL OR THE INPUT MEDIA WAS EMPTY OR THERE WAS AN UNRECOVERABLE * READ ERROR), AND THE OUTPUT COULD NOT BE RESTARTED (BECAUSE THE * BUFFER WAS EMPTY OR THE OUTPUT MEDIA WAS FULL OR THERE WAS AN * UNRECOVERABLE WRITE ERROR), THEN THE COPY OPERATION IS COMPLETE. # IF FET$LOCK[0] ## AND ((CCBOPCODE[0] EQ CPYC"DISKAU" AND CCBRWDULD[0]) ## OR (CCBOPCODE[0] EQ CPYC"AUDISK" AND CCBRWDULD[0] ## AND FET$IN[0] EQ FHB$IN[0] AND FET$IN[0] EQ FET$OUT[0]) ## OR (CCBRWDULD[0] AND (CCBDERR[0] OR CCBDFULL[0]))) THEN # INDICATE COPY COMPLETE # BEGIN DEL$LNK(ENTADR,LCHN"KC$GOING",0); LLR$CCF[0] = TRUE; LLR$RS[0] = PROCST"CONT3"; DRVRRECALL = TRUE; # INSURE DRIVER ACTIVE # ADD$LNK(CCBLLRQ[0],LCHN"DRQUEUE",0); IF CCBHDWPM THEN BEGIN # DELINK 1SS, NO REWIND/UNLOAD MESSAGE # LLR$DRFUL[0] = TRUE; # FORCE UNLOAD OF CARTRIDGE # END # RETURN OF COPY # END ENTADR = NEXTADDR; END # MONITOR ENTRIES ON KEEP COPY GOING CHAIN # RETURN; END # KCG # TERM PROC K8G((CCBADR)); # TITLE K8G - KEEP M860 COPY GOING. # BEGIN # K8G # # ** K8G - KEEP M860 COPY GOING. * * *K8G* KEEPS THE M860 COPY SIDE OF A VOLUME OPERATION GOING. * FLAGS IN THE *CCB* ARE UPDATED TO INDICATE THE STATE OF THE COPY * OPERATION AND A *1SS* CALL IS ISSUED IF NECESSARY. * * PROC K8G((CCBADR)) * * ENTRY (CCBADR) - ADDRESS OF THE COPY CONTROL BLOCK. # ITEM CCBADR U; # COPY CONTROL BLOCK ADDRESS # # **** PROC K8G - XREF LIST BEGIN. # XREF BEGIN PROC ABORT; # ABORT # PROC FSCLOG; # LOG FSC ERROR MESSAGE # PROC MESSAGE; # ISSUE MESSAGE # END # **** PROC K8G - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL COMBFAS *CALL COMBCDD *CALL COMBCHN *CALL COMBFET *CALL COMBRCD *CALL COMXCCB *CALL COMXCTF *CALL COMXMSC CONTROL EJECT; # * SET FLAGS TO INDICATE WHY *1SS* HAS STOPPED. # P = CCBADR; P = CCBM86FET[0]; IF CCBRWCT[0] NQ 0 THEN # FIRST REWIND/UNLOAD EXECUTED # BEGIN IF FHB$AT[0] EQ 0 THEN BEGIN # REWIND/UNLOAD COMPLETED # CCBRWDULD[0] = TRUE; RETURN; END ELSE BEGIN # SET FOR ANOTHER TRY # IF CCBRWCT[0] LQ 5 THEN BEGIN # TRY AN OTHER REWIND/UNLOAD # GOTO RWDAUND; END ELSE BEGIN # HARDWARE PROBLEM - REWIND/UNLOAD # CCBHDWPM[0] = TRUE; CCBRWDULD[0] = TRUE; # FORCE COMPLETE # RETURN; END END # END OF REWIND/UNLOAD SET UP # END # IF REWIND/UNLOAD COMPLETED # IF FHB$EOI[0] THEN BEGIN # SET TAPE MARK # CCBTPMARK[0] = TRUE; END IF FHB$AT[0] EQ RCENDV # # OR FHB$AT[0] EQ RCTBRT THEN # *TAPE MARK* OR *END OF VOLUME* # BEGIN CCBENDVOL[0] = TRUE; GOTO RWDAUND; END IF FHB$AT[0] EQ 0 THEN BEGIN # NO ERROR # GOTO RWDAUND; END IF FHB$AT[0] EQ RCTERF THEN BEGIN FHB$ST$SS[0] = FALSE; GOTO RWDAUND; END IF FHB$AT[0] EQ RCBFTO THEN BEGIN CCBHDWPM[0] = TRUE; GOTO BMLRWUL; END IF FHB$AT[0] EQ RCSTER # # AND FHB$ERRCD[0] EQ 0 # # AND FHB$PYERR[0] EQ 1 THEN BEGIN # TAPE PARITY ERROR # CCBTAPPAR[0] = TRUE; GOTO BMLRWUL; END IF FHB$AT[0] EQ RCILLF OR FHB$AT[0] EQ RCBARG OR FHB$AT[0] EQ RCILLU THEN # ABORT ON ERRORS # BEGIN FE$RTN[0] = "K8G."; MESSAGE(FEMSG,UDFL1); ABORT; END IF (FHB$AT[0] EQ RCDLER) OR (FHB$AT[0] EQ RCCWER) OR (FHB$AT[0] EQ RCHDER) THEN BEGIN # PPU FOUND DATA TRANSFER ERROR # CCPPUDCK[0] = TRUE; GOTO BMLRWUL; END FSCLOG(DFET); # ERROR LOG MESSAGE # CCBHDWPM[0] = TRUE; # REMAINING ERRORS # CCBRWDULD[0] = TRUE; RETURN; # * SEND A *BML* MESSAGE BEFORE REWIND/UNLOAD. # BMLRWUL: FSCLOG(DFET); # ERROR LOG MESSAGE # # * RELEASE THE HARDWARE WITH A REWIND/UNLOAD FUNCTION. # RWDAUND: DRVRRECALL = TRUE; # INSURE CPUDRIVER ACTIVE # FHB$CODE[0] = FCRUN; # SET REWIND/UNLOAD # CCBRWCT[0] = CCBRWCT[0] + 1; RETURN; END # KDG # TERM PROC LD$CAR((LLRADR)); # TITLE LD$CAR - LOAD CARTRIDGE. # BEGIN # LD$CAR # # ** LD$CAR - LOAD CARTRIDGE. * * LOAD CARTRIDGE GETS THE SPECIFIED CARTRIDGE LOADED ON A * DRD AND THE LABEL VERIFIED BY *SSDRIVER*. * * PROC LD$CAR((LLRADR)) * * ENTRY (LLRADR) - ADDRESS OF *LLRQ* ENTRY FOR THE REQUEST * CONTAINING THE SMA-ID AND THE YZ * COORDINATES. * * EXIT THE PROCESS STATE FIELD IN THE *LLRQ* ENTRY HAS BEEN * ADVANCED TO INDICATE WHERE PROCESSING OF THIS REQUEST * LEFT OFF, AND THUS WHAT TO DO NEXT TO ADVANCE THE * REQUEST. IF THE MOUNT IS COMPLETE AN ERROR RESPONSE * CODE IS RETURNED VIA *HLR$RESP[0]* FOR INTERNAL * REQUESTOR OR *LTC$RQR[LTCENTRY]* FOR EXTERNAL * REQUESTORS. * ERROR RESPONSE CODES (VALUES DEFINED IN *COMBCPR*). * = RESPTYP4"OK4". * = RESPTYP4"NO$CART". * = RESPTYP4"M86$HDW$PR". * * NOTES THIS MODULE IS A PSEUDO REENTRANT ROUTINE. * # ITEM DRDCOUNT I; # *DRD-S* ACTIVE # ITEM LLRADR U; # *LLRQ* ENTRY ADDRESS # ITEM I U; # COUNTER # ITEM MUCPRA U; # *UCP* OR *HLRQ* ADDRESS # ITEM RQIID B; # INTERIAL REQUEST # ITEM SMAO U; # REQUEST SM-ID # ITEM YZO U; # Y AND Z COORDINATE # # **** PROC LD$CAR - XREF LIST BEGIN. # XREF BEGIN PROC ABORT; # INTERFACE TO *ABORT* MACRO # PROC ADD$LNK; # ADD ENTRY TO END OF CHAIN # PROC DELAY; # TIMED DELAY # PROC KILL$UC; # ABORT A UCP # PROC MESSAGE; # INTERFACE TO *MESSAGE* MACRO # PROC SFCALL; # INTERFACE TO *SFCALL* MACRO # PROC UCP$RES; # SEND RESPONSE TO UCP # END # **** PROC LD$CAR - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL COMBFAS *CALL COMBCHN *CALL COMBCPR *CALL COMBLRQ *CALL COMBLBL *CALL COMBMAT *CALL COMBRCD *CALL COMBUCR *CALL COMXHLR *CALL COMXCTF *CALL COMBUDT *CALL COMXIPR *CALL COMXLTC *CALL COMXMSC DEF SKELLAB #" E CSN=CCCCCCCC, SM=A, SF=X, FFFFFFF. "#; ARRAY MSGS [0:0] S(4); BEGIN ITEM MSGS$SKEL C(00,00,36); # TEXT # ITEM MSGS$TYPE C(00,06,01); # TYPE # ITEM MSGS$CSN C(00,42,08); # CCCCCCCC # ITEM MSGS$SM C(02,00,01); # A # ITEM MSGS$SF C(02,36,01); # SUB FAMILY # ITEM MSGS$FAM C(02,54,07); # FAMILY # ITEM MSGS$FI U(03,36,24); # ZERO FILL # END BASED ARRAY CLEAR [0:0] S(1); BEGIN ITEM CLN U(00,36,24); # CLEAR DRD ASSIGNMENT # END SWITCH LDENTR:PROCST # LOAD CARTRIDGE ENTRIES # LDINIT:INITIAL, # INITIAL ENTRY INTO PROCESS # LDCONT:CONT1, # CONTINUE PROCESS # LDWAIT1:CONT2; # AFTER A SWAPIN DELAY # CONTROL EJECT; P = LLRADR; GOTO LDENTR[LLR$PRCST[0]]; # * "INITIAL" PROCESS STATE. # LDINIT: # INITIAL ENTRY # # * SEARCH THE *LLRQ* FOR AN MATCHING *CSN*. IF AN INTERNAL * REQUEST, LINK THE NEW REQUEST AT THE END OF THE DUPLICATE * *CSN* REQUEST. IF THE REQUEST IS FROM A *UCP* RETURN AN * *CSN$IN$USE* RESPONSE. # SMAO = LLR$SMA[0]; YZO = LLR$YZ[0]; RQIID = LLR$RQI[0] EQ REQNAME"RQIINT"; P = MAT$FWA[MAT$ENTRY"LLRQ"]; SLOWFOR I=0 STEP LLRQENTL WHILE I LS MAT$SPACE[MAT$ENTRY"LLRQ"] DO BEGIN # CHECK IF CALL FROM *UCP* # IF SMAO EQ LLR$SMA[0] ## AND YZO EQ LLR$YZ[0] ## AND (LLR$DRDL[0] OR LLR$UNLD[0]) THEN BEGIN # CHECK FOR *UCP* OR *INTERNAL* CALL # IF LLR$UNLD[0] THEN # DUPLICATE CARTRIDGE IN UNLOAD STATE # BEGIN P = LLRADR; DELAY(UCP$INTV,LLRADR,LLRQIND); RETURN; END IF NOT RQIID THEN BEGIN # *UCP* DUPLICATE CARTRIDGE REQUEST # P = LLRADR; LTCENTRY = LLR$LTCT[0]; LTC$RQR[LTCENTRY] = RESPTYP4"CSN$IN$USE"; UCP$RES; END # END *UCP* DUPLICATE CARTRIDGE # ELSE BEGIN # *INTERNAL* DUPLICATE CARTRIDGE REQUEST # P = LLRADR; P = LLR$UCPRA[0]; HLR$RESP[0] = RESPTYP4"CSN$IN$USE"; P = HLR$DRDRA[0]; CLN = 0; HLR$DRDRA[0] = 0; HLR$LRQADR[0] = 0; ADD$LNK(LLR$UCPRA[0],LCHN"HL$READY",0); END LLR$PRCST[0] = PROCST"COMPLETE"; RETURN; END # END OF *DUPLICATE* CARTRIDGE FOUND # P = P + LLRQENTL; END # END OF DUPLICATE CARTRIDGE SEARCH # P = LLRADR; IF NOT RQIID THEN # ASSIGN *DRD* TO EXTERNAL REQUEST # BEGIN SLOWFOR I=1 STEP 1 UNTIL MAXSMUNIT DO BEGIN # UNTIL *SM* FOUND # IF SMAO EQ SM$ID[I] THEN BEGIN # *SM* FOUND # GOTO SMFOUND; END END SMFOUND: DRDCOUNT = 0; IF D0$ON[I] THEN BEGIN DRDCOUNT = 1; END IF D1$ON[I] THEN BEGIN DRDCOUNT = DRDCOUNT + 1; END IF SM$REQRES1[I] NQ 0 ## AND SM$REQRES2[I] NQ 0 THEN # NO *DRD-S* AVAILABLE # BEGIN DELAY(UCP$INTV,LLRADR,LLRQIND); RETURN; END IF DRDCOUNT EQ 1 THEN # ONLY ONE *DRD* ACTIVE # BEGIN IF (SM$REQRES1[I] NQ 0) ## OR (SM$REQRES2[I] NQ 0) THEN # NO *DRD* AVAILABLE # BEGIN DELAY(UCP$INTV,LLRADR,LLRQIND); RETURN; END END # *DRD* = 1 # IF SM$REQRES1[I] EQ 0 THEN # RESERVE A *DRD* # BEGIN SM$REQRES1[I] = LLRADR; SM$LLRQ1[I] = TRUE; LLR$DRDRA[0] = LOC(SM$REQRES1[I]); END ELSE BEGIN SM$REQRES2[I] = LLRADR; SM$LLRQ2[I] = TRUE; LLR$DRDRA[0] = LOC(SM$REQRES2[I]); END END # EXTERNAL *DRD*ASSIGNMENT # LLR$RC[0] = REQCODE"SMOUNT"; # ISSUE MOUNT REQUEST TO DRIVER # LLR$DRDL[0] = TRUE; ADD$LNK(LLRADR,LCHN"DRQUEUE",0); LLR$PRCST[0] = PROCST"CONT1"; RETURN; # * "CONT1" PROCESS STATE. * * RETURN RESPONSE FROM *SSDRVR* TO THE REQUESTOR. # LDCONT: # CONTINUE PROCESSING # LTCENTRY = LLR$LTCT[0]; IF LLR$RQI[0] LQ REQNAME"RQITEST" THEN BEGIN # REQUEST IS FROM A UCP # IF LLR$UCPABT[0] THEN BEGIN # UCP HAS ABORTED # IF LLR$DR[0] EQ RESPTYP4"OK4" OR (LLR$DR[0] EQ RESPTYP4"M86$HDW$PR" AND NOT LLR$LDERR[0]) THEN BEGIN # MOUNT WAS OK SO DISMOUNT CARTRIDGE # GOTO UNLCART; END # MOUNT WAS OK SO DISMOUNT CARTRIDGE # ELSE BEGIN # CLEAR LLRQ # GOTO CL$EX$UDT; END END # UCP HAS ABORTED # ELSE BEGIN # UCP IS STILL RUNNING # IF LLR$DR[0] EQ RESPTYP4"OK4" OR LLR$DR[0] EQ RESPTYP4"CART$LB$ERR" # # OR LLR$DR[0] EQ RESPTYP4"UNK$CART" THEN BEGIN # MOUNT OK, SET UP *LTC* # LTC$CART[LTCENTRY] = TRUE; LTC$DRD[LTCENTRY] = LLR$DRD[0]; LTC$YP[LTCENTRY] = LLR$Y[0]; LTC$ZP[LTCENTRY] = LLR$Z[0]; # * RETURN THE LABEL TO THE UCP. IF THE UCP IS SWAPPED OUT, * DELAY THE REQUEST AND TRY AGAIN LATER. # WRTLOOP: LTCENTRY = LLR$LTCT[0]; LTC$SFUCPA[LTCENTRY] = LLR$ADDR2[0]; LTC$SFSCPA[LTCENTRY] = MAT$FWA[MAT$ENTRY"LABBUF"]; LTC$SFFP[LTCENTRY] = LABLEN; LTC$SFFC[LTCENTRY] = SFWRIT; SFCALL(LOC(LTC$WORD0[LTCENTRY]),RCL); IF LTC$SFRC[LTCENTRY] EQ SFRCUCPGON THEN BEGIN GOTO UNLCART; END IF LTC$SFRC[LTCENTRY] EQ SFRCBDUCPA THEN BEGIN KILL$UC(KILLCODE"INVADDR"); GOTO UNLCART; END IF LTC$SFRC[LTCENTRY] EQ SFRCSWPOUT THEN BEGIN LTC$SFUCPA[LTCENTRY] = 0; LTC$SFSCPA[LTCENTRY] = 0; LTC$SFFC[LTCENTRY] = SFSWPI; SFCALL(LOC(LTC$WORD0[LTCENTRY]),RCL); # * "CONT2" PROCESS STATE. # LDWAIT1: LTCENTRY = LLR$LTCT[0]; IF LTC$SFFCC[LTCENTRY] THEN BEGIN GOTO WRTLOOP; END LLR$PRCST[0] = PROCST"CONT2"; DELAY(UCP$INTV,LLRADR,LLRQIND); RETURN; END LTC$RQR[LTCENTRY] = LLR$DR[0]; LABELBUSY = FALSE; UCP$RES; RETURN; END # MOUNT WAS OK SO BUILD UTC # # * ERROR - CLEAN UP *LTCT*. # LLR$RQR[0] = LLR$DR[0]; LTC$LLRQA[LTCENTRY] = 0; # CLEAR *LLRQ* ENTRY # LTC$RQR[LTCENTRY] = LLR$DR[0]; UCP$RES; END # UCP IS STILL RUNNING # LABELBUSY = FALSE; CL$EX$UDT: P = LLR$DRDRA[0]; # CLEAR *DRD* RESERVATION # CLN = 0; LLR$PRCST[0] = PROCST"COMPLETE"; RETURN; END # REQUEST IS FROM A UCP # IF LLR$RQI[0] EQ REQNAME"RQIINT" THEN # IF REQUEST IS INTERNAL # BEGIN # * ADD REQUESTING *HLRQ* ENTRY TO THE READY CHAIN. # P = LLR$UCPRA[0]; HLR$RESP[0] = LLR$DR[0]; HLR$ADRD[0] = LLR$DRD[0]; IF LLR$DR[0] NQ RESPTYP4"OK4" THEN BEGIN # RETURN THE *LLRQ* # MSGS$SKEL[0] = SKELLAB; MSGS$CSN[0] = HLR$CSND[0]; MSGS$SM[0] = HLR$SM[0]; MSGS$SF[0] = O"33" + HLR$SBF[0]; MSGS$FAM[0] = HLR$FAM[0]; MESSAGE(MSGS,SYSUDF1); IF (LLR$DR[0] NQ RESPTYP4"CELL$EMP") ## AND (LLR$DR[0] NQ RESPTYP4"SMA$OFF") ## AND (LLR$DR[0] NQ RESPTYP4"M86$HDW$PR") THEN BEGIN # OUTPUT DRIVER LABEL BUFFER # MSGS$TYPE[0] = "R"; MSGS$CSN[0] = LAB$CSND[0]; MSGS$SM[0] = LAB$SMID; MSGS$SF[0] = O"33" + LAB$SF; MSGS$FAM[0] = LAB$FMLY; MESSAGE(MSGS,SYSUDF1); END # DRIVER LABEL BUFFER # IF LLR$DR[0] EQ RESPTYP4"M86$HDW$PR" AND NOT LLR$LDERR[0] THEN BEGIN # UNLOAD OF CARTRIDGE # GOTO INTIALUNL; # LET EXEC UNLOAD CARTRIDGE # END # * DELINK LLRQ FROM HLRQ. * RELEASE LLRQ. # HLR$LRQADR[0] = 0; LLR$PRCST[0] = PROCST"COMPLETE"; P = HLR$DRDRA[0]; # CLEAR *DRD* RESERVATION # CLN = 0; HLR$DRDRA[0] = 0; IF LLR$DR[0] EQ RESPTYP4"CELL$EMP" ## OR LLR$DR[0] EQ RESPTYP4"SMA$OFF" ## OR LLR$DR[0] EQ RESPTYP4"M86$HDW$PR" THEN BEGIN # DO NOT RELEASE LABEL BUFFER # GOTO NOLABREL; END # RETURNED # END INTIALUNL: LABELBUSY = FALSE; NOLABREL: ADD$LNK(LLR$UCPRA[0],LCHN"HL$READY",0); RETURN; END # * UNLOAD A CARTRIDGE. # UNLCART: LLR$PRCNME[0] = REQTYP4"UNLD$CART"; LLR$PRCST[0] = PROCST"INITIAL"; LABELBUSY = FALSE; ADD$LNK(LLRADR,LCHN"LL$READY",0); RETURN; END # LD$CAR # TERM PROC LLRQENQ(ADDR); # TITLE LLRQENQ - LOW LEVEL REQUEST QUEUE ENQUEUER. # BEGIN # LLRQENQ # # ** LLRQENQ - LOW LEVEL REQUEST QUEUE ENQUEUER. * * *LLRQENQ* DELETES AN ENTRY FROM THE FREE SPACE CHAIN AND * LINKS IT INTO THE *LLRQ* READY CHAIN. * *LLRQENQ* IS CALLED ONLY IF THE *LLRQ* IS NOT FULL. * * PROC LLRQENQ(ADDR) * * EXIT (ADDR) - ADDRESS OF ENTRY ADDED TO QUEUE. * * MESSAGES * EXEC ABNORMAL, LLRQENQ.* # ITEM ADDR U; # ADDRESS OF *LLRQ* ENTRY # # **** PROC LLRQENQ - XREF LIST BEGIN. # XREF BEGIN PROC ABORT; # ABORT # PROC ADD$LNK; # ADD ENTRY TO END OF CHAIN # PROC DEL$LNK; # DELETE ENTRY FROM CHAIN # PROC MESSAGE; # ISSUE MESSAGE # END # **** PROC LLRQENQ - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL COMBFAS *CALL COMBCHN *CALL,COMBKDD *CALL COMBLRQ *CALL COMXMSC CONTROL EJECT; # * CHECK FOR NO FREE SPACE. # ADDR = CHN$BOC[LCHN"LL$FRSPC"]; IF ADDR EQ 0 # IF NO FREE ENTRIES # THEN BEGIN FE$RTN[0] = "LLRQENQ."; MESSAGE(FEMSG,UDFL1); ABORT; END DEL$LNK(ADDR,LCHN"LL$FRSPC",0); # DELETE ENTRY FROM FREE SPACE CHAIN # P = ADDR; P = LOC(LLR$KWORDS[0]); # PRESET K-DISPLAY WORDS # KW$COMP[0] = TRUE; ADD$LNK(ADDR,LCHN"LL$READY",0); # ADD ENTRY TO READY CHAIN # RETURN; END # LLRQENQ # TERM PROC LLRQMTR; # TITLE LLRQMTR - LOW LEVEL REQUEST QUEUE MONITOR. # BEGIN # LLRQMTR # # ** LLRQMTR - LOW LEVEL REQUEST QUEUE MONITOR. * * THE LOW LEVEL REQUEST QUEUE MONITOR CONTROLS THE ACTIVATION * OF *LLRQ* PROCESSORS. EACH *LLRQ* ENTRY ON THE READY CHAIN IS * ACTIVATED BY CALLING THE APPROPRIATE PROCESSOR. * * PROC LLRQMTR * * EXIT IF THE PROCESS STATE FIELD OF AN *LLRQ* ENTRY IS SET * TO "COMPLETE" AFTER ITS PROCESSOR IS CALLED, THE ENTRY * IS CLEARED AND LINKED INTO THE FREE SPACE CHAIN. * OTHERWISE, THE PROCESSOR HAS SET UP SOME CONDITION * THAT WILL EVENTUALLY CAUSE THE *LLRQ* ENTRY TO BE * RELINKED INTO THE *LLRQ* READY CHAIN. # # **** PROC LLRQMTR - XREF LIST BEGIN. # XREF BEGIN PROC ADD$LNK; # ADD ENTRY TO END OF CHAIN # PROC CPY$DS; # COPY DISK TO VOLUME # PROC CPY$RS; # COPY RAW VOLUME # PROC CPY$SD; # COPY VOLUME TO DISK # PROC DEL$LNK; # DELETE ENTRY FROM CHAIN # PROC INIT$HW; # INITIALIZE M860 HARDWARE # PROC LD$CAR; # LOAD CARTRIDGE # PROC SSDRVR; # SS DRIVER # PROC UNL$CAR; # UNLOAD CARTRIDGE # PROC WT$LAB; # WRITE LABEL # PROC ZFILL; # ZERO FILL BUFFER # END # **** PROC LLRQMTR - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL COMBFAS *CALL COMBCHN *CALL COMBCPR *CALL COMBLRQ *CALL COMXMSC ITEM LLRENT U; # *LLRQ* ENTRY ADDRESS # SWITCH LLPROC:REQTYP4 # *LLRQ* PROCESSOR CALLS # LL1:LOAD$CART, # # LL2:UNLD$CART, # # LL3:WRT$LAB, # # LL4:CPY$AD, # # LL5:CPY$DA, # # LL6:CP$RAW$AU, # # LL7:INITHW, # # ENDLLP:LSTREQTYP4; # END OF *LLRQ* PROCESSOR CALLS # CONTROL EJECT; # * *LLRQMTR* IS CALLED WHEN THERE IS WORK FOR *SSDRVR* TO DO OR * WHEN THERE ARE ENTRIES ON THE *LLRQ* READY CHAIN TO BE PROCESSED. * PROCESSING OF ENTRIES ON THE *LLRQ* READY CHAIN CAN CREATE WORK * FOR *SSDRVR*, AND EXECUTION OF *SSDRVR* CAN PUT ENTRIES BACK * ON THE *LLRQ* READY CHAIN. # IF CHN$BOC[LCHN"LL$READY"] EQ 0 THEN # IF READY CHAIN IS EMPTY # BEGIN SSDRVR; END # * TRAVERSE THE *LLRQ* READY CHAIN. # REPEAT WHILE CHN$BOC[LCHN"LL$READY"] NQ 0 DO BEGIN # PROCESS READY *LLRQ* ENTRIES # LLRENT = CHN$BOC[LCHN"LL$READY"]; DEL$LNK(LLRENT,LCHN"LL$READY",0); P = LLRENT; # * SIMULATED CASE STATEMENT FOR *LLRQ* PROCESSOR CALLS. # GOTO LLPROC[LLR$PRCNME[0]]; LL1: # LOAD CARTRIDGE # LD$CAR(LLRENT); GOTO ENDLLP; LL2: # UNLOAD CARTRIDGE # UNL$CAR(LLRENT); GOTO ENDLLP; LL3: # WRITE LABEL # WT$LAB(LLRENT); GOTO ENDLLP; LL4: # COPY VOLUME TO DISK # CPY$SD(LLRENT); GOTO ENDLLP; LL5: # COPY DISK TO VOLUME # CPY$DS(LLRENT); GOTO ENDLLP; LL6: # COPY RAW VOLUME # CPY$RS(LLRENT); GOTO ENDLLP; LL7: # INITIALIZE M860 HARDWARE # INIT$HW(LLRENT); GOTO ENDLLP; ENDLLP: # CONTINUE # # * END SIMULATED CASE STATEMENT FOR *LLRQ* PROCESSOR CALLS. # # * IF A PROCESSOR CREATED WORK FOR THE DRIVER, CALL *SSDRVR*. # IF CHN$BOC[LCHN"DRQUEUE"] NQ 0 THEN # IF DRIVER QUEUE NOT EMPTY # BEGIN SSDRVR; END # * ADD *LLRQ* ENTRY TO THE FREE SPACE CHAIN IF PROCESS IS COMPLETE. # P = LLRENT; IF LLR$PRCST[0] EQ PROCST"COMPLETE" THEN # IF PROCESS IS COMPLETE # BEGIN ZFILL(LLRQ,LLRQENTL); # CLEAR *LLRQ* ENTRY # ADD$LNK(LLRENT,LCHN"LL$FRSPC",0); END END # PROCESS READY *LLRQ* ENTRIES # RETURN; END # LLRQMTR # TERM PROC UNL$CAR((LLRENT)); # TITLE UNL$CAR - RETURN CARTRIDGE TO MATRIX. # BEGIN # UNL$CAR # # ** UNL$CAR - RETURN CARTRIDGE TO MATRIX. * * *UNL$CAR* RETURNS THE CARTRIDGE FROM THE DRD TO THE * DESIGNATED MATRIX POSITION. IF THE CARTRIDGE IS ASSIGNED TO THE * INPUT TRAY ON ENTRY, THE ASSIGNMENT WILL BE CHANGED TO THE * OUTPUT TRAY PRIOR TO DISMOUNTING THE CARTRIDGE. * * PROC UNL$CAR((LLRENT)) * * ENTRY (LLRENT) - ADDRESS OF *LLRQ* ENTRY FOR THE REQUEST * CONTAINING THE SMA-ID AND THE YZ * COORDINATES. * * EXIT THE PROCESS STATE FIELD IN THE *LLRQ* ENTRY HAS BEEN * ADVANCED TO INDICATE WHERE PROCESSING OF THIS REQUEST * LEFT OFF, AND THUS WHAT TO DO NEXT TO ADVANCE THE * REQUEST. * * WHEN THE PROCESS IS COMPLETED AN ERROR RESPONSE CODE * IS RETURNED VIA *LTC$RQR[LTCENTRY]* FOR EXTERNAL * REQUESTORS OR *HLR$RESP[0]* FOR INTERNAL REQUESTORS. * RESPONSE CODE (VALUES ARE DEFINED IN *COMBCPR*). * = RESPTYP4"OK4". * * THE CARTRIDGE LOAD, PASS, AND ERROR COUNTS ARE * ALSO RETURNED WHEN THE REQUEST IS COMPLETED. * * NOTES THIS MODULE IS A PSEUDO REENTRANT ROUTINE. # ITEM LLRENT U; # *LLRQ* ENTRY TO PROCESS # ITEM LLRENTI U; # WAITTING *LLRQ* ADDRESS # ITEM SCR1 U; # SCRATCH WORD # ITEM SCR2 U; # SCRATCH WORD # ITEM SCR3 U; # SCRATCH WORD # # **** PROC UNL$CAR - XREF LIST BEGIN. # XREF BEGIN PROC ADD$LNK; # ADD ENTRY TO END OF CHAIN # PROC UCP$RES; # NOTIFY UCP OF REQUEST COMPLETE # END # **** PROC UNL$CAR - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMMON DECKS # *CALL COMBFAS *CALL COMBCHN *CALL COMBCPR *CALL COMBLRQ *CALL COMBRCD *CALL COMBUCR *CALL COMXHLR *CALL COMXLTC *CALL COMXMSC BASED ARRAY CLEAR [0:0] S(1); BEGIN ITEM CLN U(00,36,24); # CLEAR *DRD* ASSIGNMENT # END SWITCH UNLENTR:PROCST # UNLOAD CARTRIDGE ENTRIES # UNLINIT:INITIAL, # INITIAL ENTRY POINT # UNLC1:CONT1; # CONTINUE AFTER DISMOUNT REQUEST # CONTROL EJECT; P = LLRENT; GOTO UNLENTR[LLR$PRCST[0]]; # * "INITIAL" PROCESS STATE. * * ASSIGN THE CARTRIDGE TO THE EXIT TRAY IF THE ORIGINAL * ASSIGNMENT WAS TH ENTRY TRAY. # UNLINIT: IF LLR$Y[0] EQ SM$ENT$TY ## AND LLR$Z[0] EQ SM$TY$Z THEN BEGIN LLR$Y[0] = SM$EXIT$TY; LLR$Z[0] = SM$TY$Z; END # * DISMOUNT THE CARTRIDGE. # LLR$RC[0] = REQCODE"SDISMOUNT"; LLR$PRCST[0] = PROCST"CONT1"; LLR$DRDL[0] = FALSE; LLR$UNLD[0] = TRUE; # UNLOAD STARTED # LLR$RS[0] = PROCST"INITIAL"; ADD$LNK(LLRENT,LCHN"DRQUEUE",0); RETURN; # * "CONT1" PROCESS STATE. * * UPDATE THE APPROPRIATE DATA FIELDS OF THE REQUEST AND PASS * THE REQUEST ON TO THE NEXT PROCESS. # UNLC1: IF LLR$RQI[0] EQ REQNAME"RQIINT" THEN BEGIN # INTERNAL REQUEST # P = LLR$UCPRA[0]; HLR$LRQADR[0] = 0; # DELINK *LLRA* FROM *HLRA* # HLR$RESP[0] = RESPTYP4"OK4"; ADD$LNK(LLR$UCPRA[0],LCHN"HL$READY",0); END # INTERNAL REQUEST # ELSE BEGIN # EXTERNAL REQUEST # P = LLR$DRDRA[0]; # CLEAR *DRD* RESERVE # CLN = 0; IF NOT LLR$UCPABT[0] THEN # RETURN RESPONSE TO UCP # BEGIN LTCENTRY = LLR$LTCT[0]; LTC$LLRQA[LTCENTRY] = 0; LTC$CART[LTCENTRY] = FALSE; LTC$RQR[LTCENTRY] = RESPTYP4"OK4"; UCP$RES; END END # EXTERNAL REQUEST # # * MARK THE REQUEST COMPLETE AND RETURN TO *LLRQ* MONITOR. # LLR$UNLD[0] = FALSE; # UNLOAD COMPLETE # LLR$PRCST[0] = PROCST"COMPLETE"; RETURN; END # UNL$CAR # TERM PROC SETFET(LLRADR); # TITLE SETFET - SETS LARGE BUFFER POINTERS # BEGIN # SETFET # # ** SETFET - SETS LARGE BUFFER POINTERS. * * *SETFET* SETS FET POINTERS FOR CIO AND *1SS*. * * PROC SETFET * * ENTRY (LLRADR) - ADDRESS OF THE *LLRQ* ENTRY THAT * CONTAINS THE ADDRESS OF THE DISK * AND *M860* FET AND BUFFER ADDRESSES. * (LARGE BUFFER MUST ALREADY EXIST.) * * EXIT FETS ARE COMPLETE FOR BOTH CIO AND *1SS* * PROCESSING. STRIPE HIGH AND LOW SET INTO THE * *LLRQ*. * * NOTES THIS MODULE IS CALLED ONLY BY THE COP$XX ROUTINES. # ITEM LLRADR; # *LLRQ* ADDRESS # # **** PROC SETFET - XREF LIST BEGIN. # XREF BEGIN PROC ZFILL; # ZERO FILL BUFFER # PROC ZSETFET; # INITIALIZE A FET # END # **** PROC SETFET - XFET LIST END. # DEF LISTCON #0#; # DO NOT LIST COMDECKS # *CALL COMBFAS *CALL COMBCPR *CALL COMBFET *CALL COMBLRQ *CALL COMXBST *CALL COMXCCB *CALL COMXHLR # * SET *LLRQ* STIPE LOW AND HIGH POINTERS. # P = LLRADR; P = LLR$UCPRA[0]; P = LLR$CCB[0]; IF LLR$PRCNME[0] NQ REQTYP4"CP$RAW$AU" THEN BEGIN LLR$ST$LW[0] = INSPAU*HLR$VOLAU[0]+(INFTST-INSPAU); LLR$ST$HI[0] = INSPAU*HLR$VOLLN[0]+LLR$ST$LW[0]-1; END # * INITIALIZE CIO AND *1SS* FETS. # CCBDKFET[0] = LLR$DSKFET[0]; CCBM86FET[0] = LLR$MSFET[0]; CCBLLRQ[0] = LLRADR; CCBCLFG[0] = 0; CCBRWCT[0] = 0; # CLEAR COUNTER # ZSETFET(LLR$DSKFET[0],HLR$FLNM[0],LLR$DA[0],DATABL,(RFETL+RFHBL)); P = LLR$MSFET[0]; P = LLR$DSKFET[0]; FET$EP[0] = TRUE; FET$R[0] = TRUE; FET$UP[0] = TRUE; FHB$FRST[0] = FET$FRST[0]; FHB$IN[0] = FET$IN[0]; FHB$OUT[0] = FET$OUT[0]; FHB$LIM[0] = FET$LIM[0]; END TERM PROC WT$LAB((LLRENT)); # TITLE WT$LAB - WRITE CARTRIDGE LABEL. # BEGIN # WT$LAB # # ** WT$LAB - WRITE CARTRIDGE LABEL. * * *WT$LAB* WRITES THE CARTRIDGE LABEL. * * PROC WT$LAB((LLRENT)) * * ENTRY (LLRENT) - ADDRESS OF *LLRQ* ENTRY FOR THE REQUEST * CONTAINING THE SMA-ID, THE VOLUME NUMBER, * AND THE YZ COORDINATES. * * EXIT THE PROCESS STATE FIELD IN THE *LLRQ* ENTRY HAS BEEN * ADVANCED TO INDICATE WHERE PROCESSING OF THIS REQUEST * LEFT OFF, AND THUS WHAT TO DO NEXT TO ADVANCE THE * REQUEST. * * WHEN THE PROCESS IS COMPLETED AN ERROR RESPONSE CODE * IS RETURNED VIA LTC$RQR[LTCENTRY] FOR EXTERNAL * REQUESTORS OR HLR$RESP[0] FOR INTERNAL REQUESTORS. * IS RETURNED VIA *LTC$RQR[LTCENTRY]* FOR EXTERNAL * REQUESTORS OR *HLR$RESP[0]* FOR INTERNAL REQUESTORS. * RESPONSE CODE (VALUES ARE DEFINED IN *COMBCPR*). * = RESPTYP4"OK4". * = RESPTYP4"UN$WRT$ERR". * = RESPTYP4"EX$WRT$ERR". * = RESPTYP4"MSFHDW$ERR". * * MESSAGES * EXEC ABNORMAL, WT$LAB.* * * NOTES THIS MODULE IS A PSEUDO REENTRANT ROUTINE. * * COMMON BUFFER *LABBUF* WILL BE USED TO TRANSFER * THE LABEL FROM THE *UCP* TO THE *SSDRIVER*. # ITEM LLRENT U; # ADDRESS OF *LLRQ* ENTRY # # **** PROC WT$LAB - XREF LIST BEGIN. # XREF BEGIN PROC ABORT; # INTERFACE TO *ABORT* MACRO # PROC ADD$LNK; # ADD ENTRY TO END OF CHAIN # PROC DELAY; # TIMED DELAY # PROC KILL$UC; # ABORT A UCP # PROC MESSAGE; # CALLS *MESSAGE* MACRO # PROC SFCALL; # INTERFACE TO *SFCALL* MACRO # PROC UCP$RES; # NOTIFY UCP OF REQUEST COMPLETE # END # **** PROC WT$LAB - XREF LIST END. # DEF LISTCON #0#; # DO NOT LIST COMMON DECKS # *CALL COMBFAS *CALL COMBCHN *CALL COMBCPR *CALL COMBFET *CALL COMBLBL *CALL COMBLRQ *CALL COMBMAT *CALL COMBRCD *CALL COMBUCR *CALL COMXCTF *CALL COMXHLR *CALL COMXIPR *CALL COMXLTC *CALL COMXMSC ITEM REQTYP B=FALSE; # *LLRQ* ID FOR *GET$SB* # BASED ARRAY CLEAR [0:0] S(1); BEGIN ITEM CLN U(00,36,24); # CLEAR *DRD* ASSIGNMENT # END SWITCH WTENTR:PROCST # WRITE LABEL ENTRIES # WTINIT:INITIAL, # INITIAL ENTRY POINT # WTC1:CONT1, # AFTER A SWAPIN DELAY # WTC2:CONT2; # AFTER WRITE LABEL # CONTROL EJECT; P = LLRENT; LLR$DR[0] = 0; LTCENTRY = LLR$LTCT[0]; GOTO WTENTR[LLR$PRCST[0]]; # * "INITIAL" PROCESS STATE. # WTINIT: # * CHECK LABEL BUFFER FOR BUSY. IF BUSY, RETURN *LLRQ* * TO THE DELAY CHAIN. # IF LABELBUSY THEN BEGIN # EXIT TO DELAY CHAIN # DELAY(UCP$INTV,LLRENT,LLRQIND); RETURN; END # RETURNED TO DELAY CHAIN # LABELBUSY = TRUE; # RESERVE LABEL BUFFER # # * READ THE LABEL FROM THE UCP. IF THE UCP IS SWAPPED OUT, DELAY * THE REQUEST AND TRY AGAIN LATER. # SFLOOP: LTC$SFUCPA[LTCENTRY] = LLR$ADDR2[0]; LTC$SFSCPA[LTCENTRY] = MAT$FWA[MAT$ENTRY"LABBUF"]; LTC$SFFP[LTCENTRY] = LABLEN; LTC$SFFC[LTCENTRY] = SFREAD; SFCALL(LOC(LTC$WORD0[LTCENTRY]),RCL); IF LTC$SFRC[LTCENTRY] EQ SFRCUCPGON THEN BEGIN GOTO COMPLUCP; END IF LTC$SFRC[LTCENTRY] EQ SFRCBDUCPA THEN BEGIN KILL$UC(KILLCODE"INVADDR"); GOTO COMPLUCP; END IF LTC$SFRC[LTCENTRY] EQ SFRCSWPOUT THEN BEGIN LTC$SFUCPA[LTCENTRY] = 0; LTC$SFSCPA[LTCENTRY] = 0; LTC$SFFC[LTCENTRY] = SFSWPI; SFCALL(LOC(LTC$WORD0[LTCENTRY]),RCL); # * "CONT1" PROCESS STATE. # WTC1: LTCENTRY = LLR$LTCT[0]; IF LTC$SFFCC[LTCENTRY] THEN BEGIN GOTO SFLOOP; END LLR$PRCST[0] = PROCST"CONT1"; DELAY(UCP$INTV,LLRENT,LLRQIND); RETURN; END IF LTC$SFRC[LTCENTRY] NQ 0 THEN BEGIN FE$RTN[0] = "WT$LAB."; MESSAGE(FEMSG[0],UDFL1); ABORT; END LLR$PRCST[0] = PROCST"CONT2"; LLR$RC[0] = REQCODE"SWRT$LABEL"; LLR$RS[0] = PROCST"INITIAL"; ADD$LNK(LLRENT,LCHN"DRQUEUE",0); RETURN; # * RETURN THE RESPONSE CODE TO THE *UCP*. # COMPLUCP: LABELBUSY = FALSE; LLR$DR[0] = 0; LLR$UCPABT[0] = FALSE; LLR$Y[0] = SM$EXIT$TY; LLR$Z[0] = SM$TY$Z; LLR$PRCNME[0] = REQTYP4"UNLD$CART"; LLR$PRCST[0] = PROCST"INITIAL"; ADD$LNK(LLRENT,LCHN"LL$READY",0); RETURN; # * "CONT2" PROCESS STATE. # WTC2: # * MARK THE REQUEST COMPLETE AND RETURN TO *LLRQ* MONITOR. # IF NOT LLR$UCPABT[0] THEN BEGIN # SEND REQUEST BACK TO UCP # LTC$CART[LTCENTRY] = FALSE; LTC$LLRQA[LTCENTRY] = 0; LTC$RQR[LTCENTRY] = LLR$DR[0]; UCP$RES; END # COMPLETED RETURN REQUEST # P = LLR$DRDRA[0]; # CLEAR *DRD* RESERVE # CLN = 0; LLR$PRCST[0] = PROCST"COMPLETE"; RETURN; END # WT$LAB # TERM