.TITLE IRF -- "FIX" I/O RUNDOWN FAILURE .IDENT -010000- .ENABL LC ;+ ; ABSTRACT: IRF ; ; THIS TASK WILL SEARCH THE ATL FOR A TASK MATCHING THE ; SPECIFIED TASK NAME AND TERMINAL-ID WHICH IS IN I/O ; RUNDOWN FAILURE. IF FOUND, IT WILL UNDO THE I/O RUNDOWN ; FAILURE (IF IT IS ABLE TO DO SO). IF IT IS NOT ABLE TO ; UNDO THE I/O RUNDOWN FAILURE, IT WILL PRINT OUT AN ; APPROPRIATE ERROR MESSAGE. ; ; Operating procedures: ; ; MCR>IRF taskname/TI=ddn: ; MCR>IRF taskname/TERMINAL:ddn: ; ; PDS> IRF taskname/TI=ddn: ; PDS> IRF taskname/TERMINAL:ddn: ; ; taskname is the name of the task whose I/O pending is to ; be fixed. The length must be less than or equal ; to six RAD50 characters. ; ddn is the device name and unit number of the device on ; which the task is running. The ':' is optional. ; The /TI switch can be specified as either ; /TI=ddn: or /TI:ddn:, and is equivalent to the ; /TERMINAL switch. The /TERMINAL switch can be ; abbreviated to as few as one character (/T:). ; ; SUBROUTINES: ; ; $CAT5 CONVERT ASCII TO RADIX-50 ; ..ENB0 RE-ENABLE CONTEXT SWITCHING WHEN TURNED OFF. ; .DIRDL EXECUTE DIRECTIVE AND WAIT IF NO NODES. ; .TPARS FINITE-STATE PARSER ; ; NONSTANDARD FEATURES: ; ; This is a very unusual function to want to do. It is ; useful at times because the alternative is to reboot ; the operating system. It can be slightly dangerous, ; if some user-written device driver or other software ; uses the I/O Pending field to mean something other ; than the standard IAS/RSX-11D meaning. It does not ; attempt to clean up all possible I/O rundown failures, ; only those which it can clean up in relative safety. ; Note that since this may clear out the I/O pending ; count which might have been used to indicate the ; absence of pending detach's, close's, etc., it is ; possible to wind up with locked terminals/files, and ; the system should probably be rebooted as soon as ; possible in any event. This task can be useful to ; free up enough memory to allow user tasks to terminate ; gracefully before rebooting the system, if there is ; insufficient memory to quiesce the system otherwise. ; ; LIMITATIONS: ; ; This will work on either IAS or RSX-11D. A symbol ; (R$$11D) must be defined for RSX-11D V6.2 or IAS V2.2 ; or earlier; IAS V3.0 and later must not have the ; symbol defined. This will work on both IAS V3.0 and ; IAS V3.1. ; ; WRITTEN: 31-MAY-79, -0.0.0-, BRUCE C. WRIGHT ; MODIFIED: 06-Mar-1981, -1.0.0-, Bruce C. Wright ; Cleanups to put into production ; VERIFIED: 06-Mar-1981, -1.0.0-, Bruce C. Wright ;- ; ; Define the following symbol to generate a version of IRF which ; will work on RSX-11D V6.2 or earlier or IAS V2.2 or earlier. ; Leave the symbol out for IAS V3.0 or later. ; ;R$$11D = 1 ; .MCALL QIOW$,GMCR$,DIR$,EXIT$S,DECL$S ; .MACRO ERROR STRING .NCHR $$$, JSR R0,$ERROR .WORD $$$ .ASCII "STRING" .EVEN .ENDM BEGIN:: DIR$ #GMCR ; TRY TO GET AN MCR COMMAND LINE. BCC 10$ ; GOT IT, CONTINUE. ERROR 10$: MOV .CRTSK,R0 ; GET OUR ATL NODE. MOV A.TI(R0),R0 ; GET OUR TERMINAL ADDRESS. BITB #UT.PR,U.TF(R0) ; ARE WE ON A PRIVILEGED TERMINAL? BNE 20$ ; YES, CONTINUE. ERROR 20$: MOV #401,R1 ; GET .TPARS OPTION WORD ; KEYWORDS MAY BE ABBREVIATED TO 1 CHAR ; BLANKS ARE SIGNIFICANT MOV #KEYTBL,R2 ; GET KEYWORD TABLE MOV @#$DSW,R3 ; GET LENGTH MOV #GMCR+G.MCRB,R4 ; GET BEGINNING OF BUFFER MOV #START,R5 ; GET INITIAL STATE. CALL .TPARS ; ATTEMPT TO PARSE COMMAND LINE. BCC 30$ ; SKIP IF OK ERROR ; ; Check various syntax errors which .TPARS can't find ; 30$: MOV .CRTSK,R0 ; GET OUR ATL NODE. MOV A.TI(R0),PUDPTR ; DEFAULT TI ADDRESS TO THIS TERMINAL. BIT #SW.TI,SWORD ; WAS A /TI SWITCH SPECIFIED? BEQ 80$ ; NO, SKIP THE TEST. CMP DEVUNT,#77 ; LEGAL DEVICE UNIT NUMBER? BLOS 35$ ; YES, TRY TO FIND IT. ERROR 35$: MOV .PUDBA,R1 ; GET BEGINNING OF PUD. 40$: CMP U.DN(R1),DEVNAM ; CORRECT DEVICE NAME? BNE 50$ ; NO, NEXT DEVICE. CMPB U.UN(R1),DEVUNT ; CORRECT UNIT NUMBER? BEQ 60$ ; YES, PROCESS IT. 50$: ADD #U.SZ,R1 ; INCREMENT PUD POINTER. CMP R1,.PUDEA ; AT END OF PUD? BLO 40$ ; NO, NEXT DEVICE. ERROR 60$: MOV R1,PUDPTR ; REMEMBER TI ADDRESS OF TASK. 80$: MOV TSKPTR,R0 ; GET THE TASK NAME ADDRESS. CMP TSKLEN,#6. ; IS THE TASK NAME > 6 CHARACTERS? BLOS 90$ ; NO, CONTINUE. ERROR 90$: CALL $CAT5 ; CONVERT FIRST PART TO RAD50 MOV R1,TSK1 ; GET FIRST TASK NAME WORD BCS 100$ ; SKIP IF DIDN'T TERMINATE ON RAD50 CHAR. CALL $CAT5 ; CONVERT SECOND PART TO RAD50 MOV R1,TSK2 ; SAVE IT. ; ; Scan the ATL looking for the appropriate task name running on ; the appropriate device name. ; 100$: MOV #.ATLLH,R1 ; GET THE ATL LISTHEAD. MOV @#PS.EXP,-(SP) ; SAVE THE PSW BIS #140,@#PS.EXP ;;; SET THE PRIORITY TO 3 (INHIBIT CONTEXT SW) 110$: MOV (R1),R1 ;;; GET TO NEXT ELEMENT ON ATL. CMP R1,#.ATLLH ;;; TO END OF THE ATL? BNE 115$ ;;; NO -- LOOK FOR SOMETHING ELSE. JMP 160$ ;;; YES -- GO TO THE EXIT CODE. 115$: CMP PUDPTR,A.TI(R1) ;;; DOES THE PUD POINTER MATCH? BNE 110$ ;;; NO, NOT RIGHT TI: MOV A.TD(R1),R2 ;;; GET THE STD ADDRESS. CMP S.TN(R2),TSK1 ;;; GET FIRST PART OF TASK NAME. BNE 110$ ;;; NOT RIGHT, NEXT ENTRY. CMP S.TN+2(R2),TSK2 ;;; GET SECOND PART OF TASK NAME. BNE 110$ ;;; NOT RIGHT, NEXT ENTRY. INC FOUND ;;; SIGNAL THAT A TASK FOUND BUT NOT IN IRF CMPB A.TS(R1),#TS.IR4 ;;; I/O RUNDOWN FAILURE? BNE 110$ ;;; NO, NEXT ENTRY. TSTB A.IR(R1) ;;; IS THERE I/O IN PROGRESS? BEQ 120$ ;;; NO, WE CAN CONTINUE. CALL @#..ENB0 ;;; ENABLE CONTEXT SWITCHING AGAIN. ERROR 120$: TSTB A.IN(R1) ;;; IS THERE I/O PENDING? BNE 130$ ;;; YES CALL @#..ENB0 ;;; RE-ENABLE CONTEXT SWITCHING. ERROR .IF NDF R$$11D ; IF IN IAS V3.0 130$: TSTB A.QI(R1) ;;; ANY I/O QUEUED? BEQ 140$ ;;; NO CALL @#..ENB0 ;;; RE-ENABLE CONTEXT SWITCHING. ERROR 140$: TSTB A.SW(R1) ;;; ANY I/O RELEASED FOR SWAPPING? BEQ 150$ ;;; NO CALL @#..ENB0 ;;; RE-ENABLE CONTEXT SWITCHING. ERROR .IFF ; OR ELSE IF IN RSX-11D 130$: .ENDC ; R$$11D 150$: CLRB A.IN(R1) ;;; CLEAR THE I/O PENDING COUNT. CALL @#..ENB0 ;;; RE-ENABLE CONTEXT SWITCHING. DECL$S ; DECLARE A SIGNIFICANT EVENT ; (AND WHAT A SIGNIFICANT EVENT!!!) EXIT$S ; AND GET OUT. 160$: CALL @#..ENB0 ;;; RE-ENABLE CONTEXT SWITCHING. TST FOUND ; WAS A TASK FOUND? BNE 170$ ; YES, BUT NOT IN 'IRF' ERROR 170$: ERROR $ERROR: MOV (R0)+,QIOW+Q.IOPL+2 ; GET THE LENGTH OF REQUEST MOV R0,QIOW+Q.IOPL ; GET ADDRESS OF REQUEST MOV #QIOW,-(SP) ; DPB TO STACK CALL .DIRDL ; DO THE I/O EXIT$S ; AND GET OUT. ; GMCR: GMCR$ ; MCR COMMAND LINE. QIOW: QIOW$ IO.WVB,1,1,,,,<0,0,40> ; QI/O ; SWORD: .WORD 0 ; SWITCH WORD SW.TI = 1 ; /TI: SWITCH ; PUDPTR: .WORD 0 ; PUD ADDRESS OF VICTIM TASK DEVNAM: .WORD 0 ; DEVICE NAME OF VICTIM TASK DEVUNT: .WORD 0 ; DEVICE UNIT OF VICTIM TASK TSK1: .WORD 0 ; TASK NAME OF VICTIM TASK (WD 1) TSK2: .WORD 0 ; TASK NAME OF VICTIM TASK (WD 2) TSKPTR: .WORD 0 ; POINTER TO TASK NAME IN CMD STRING TSKLEN: .WORD 0 ; LENGTH OF TASK NAME IN CMD STRING FOUND: .WORD 0 ; FLAG FOR TASK BEING IN I/O RUNDOWN ; ; .TPARS VARIABLES ; .MCALL ISTAT$,STATE$,TRAN$ ; ; INITIALISE STATE TABLES ; ISTAT$ STATBL,KEYTBL ; ; PICK UP COMMAND NAME ; STATE$ START TRAN$ "IRF" ; STATE$ TRAN$ $BLANK,TSTTER TRAN$ $LAMDA ; STATE$ TSTTER TRAN$ !GETTER,GETTSK TRAN$ $LAMDA ; STATE$ GETTSK TRAN$ $BLANK,GETTS1 TRAN$ $LAMDA ; STATE$ GETTS1 TRAN$ $RAD50,,SETTSK ; STATE$ TRAN$ $BLANK,TSTTE1 TRAN$ $LAMDA ; STATE$ TSTTE1 TRAN$ $EOS,$EXIT TRAN$ !GETTER ; STATE$ TRAN$ $BLANK,GETEOS TRAN$ $LAMDA ; STATE$ GETEOS TRAN$ $EOS,$EXIT ; ; SUBEXPRESSION TO READ /TERMINAL:TT0 OR /TI=TT0 ; STATE$ GETTER TRAN$ '/ ; STATE$ TRAN$ "TI",GETCOL TRAN$ "TERMINAL" ; STATE$ GETCOL TRAN$ ':,GETDEV TRAN$ '= ; STATE$ GETDEV TRAN$ $ANY,,SETDV1 ; STATE$ TRAN$ $ANY,,SETDV2 ; STATE$ TRAN$ $NUMBR,GETEND,SETUNT TRAN$ $LAMDA ; STATE$ GETEND TRAN$ $EOS,$EXIT TRAN$ ':,$EXIT TRAN$ $LAMDA,$EXIT ; STATE$ .EVEN ; ; THE ACTION ROUTINES ; ; SET FIRST CHARACTER IN DEVICE NAME ; SETDV1: MOVB .PCHAR,DEVNAM ; SET FIRST CHARACTER IN DEVICE NAME BIS #SW.TI,SWORD ; SIGNAL THAT /TI IS SPECIFIED. RETURN ; AND RETURN FROM ACTION ROUTINE ; ; SET SECOND CHARACTER IN DEVICE NAME ; SETDV2: MOVB .PCHAR,DEVNAM+1 ; SET SECOND CHARACTER IN DEVICE NAME RETURN ; AND RETURN FROM ACTION ROUTINE ; ; SET DEVICE NUMBER ; SETUNT: MOV .PNUMB,DEVUNT ; SET DEVICE UNIT NUMBER. TST .PNUMH ; ENSURE NOTHING IN HI ORDER BEQ 10$ ; SKIP IF NOTHING ADD #2,(SP) ; REJECT TRANSITION IF SO 10$: RETURN ; AND RETURN FROM ACTION ROUTINE. ; ; SET TASK NAME STRING ; SETTSK: MOV .PSTPT,TSKPTR ; RETURN THE TASKNAME POINTER MOV .PSTCN,TSKLEN ; RETURN THE TASKNAME LENGTH RETURN ; AND RETURN FROM ACTION ROUTINE .END BEGIN