.TITLE XXDRV .IDENT /00/ ;+ ; XXDRV.SMC ; ; ; ; ** SKELETON RSX-11M I/O DRIVER ** ; ** SUPERMAC VERSION ** ; ; INSTRUCTIONS FOR USE: ; ; THIS IS A SKELETON I/O DRIVER FOR RSX-11M. IT ; CONTAINS ALL THE NECESSARY BOILERPLATE THAT IS ; REQUIRED TO BE IN EVERY RSX-11M I/O DRIVER. ; ; THE USER MUST INSERT ALL THE DEVICE-SPECIFIC ; PROCESSING FOR THE INTENDED DEVICE. REFER TO ; THE "GUIDE TO WRITING AN I/O DRIVER" MANUAL ; FOR INTIMATE DETAILS. ; ; OTHER FILES FOR SKELETON DEVICE DRIVER: ; ; XXDF.MAC SYMBOL DEFINITIONS, MACROS ; XXTAB.MAC SKELETON DATA BASE ; XXMAKE.CMD COMMAND FILE FOR ASSEMBLING/TASK-BUILDING ; ; ; ; ; REMEMBER TO CHANGE ALL REFERENCES TO X$$X11 TO THE ; PARTICULAR LABEL USED TO DEFINE THE ; NUMBER OF DEVICE CONTROLLERS FOR THE ACTUAL DEVICE ; YOU'RE CONFIGURING INTO THE SYSTEM. ; ; ; ;;; COMMENTS INDICATE CODE EXECUTED WITH ; PROCESSOR INTERRUPTS DISABLED. ; ; ; ; *** REQURES SUPERMAC VERSION 46 OR LATER *** ; ; ; ; SEE ALSO OTHER INSTRUCTIONS IN XXTAB.MAC ; ; COMMAND LINE FOR ASSEMBLY: ; PIP>XXDRV.SRC/NV=LB:[11,10]RSXMC,SY:[]XXDF,XXDRV ; MAC>XXDRV,XXDRV=LB:[1,1]EXEMC/ML,SUPERMAC/ML,SY:[]XXDRV.SRC ; PIP>XXDRV.SRC;*/DE ; ; ; J. MCGLINCHEY VERSION 00 15-APR-80 ;- .PAGE ; ; MACRO LIBRARY CALLS (DELETE THE ONES NOT USED) ; .MCALL ABODF$,HWDDF$,PKTDF$ .MCALL SCBDF$,UCBDF$,DCBDF$ ABODF$ ;DEFINE TASK ABORT CODES HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS SCBDF$ ;DEFINE SCB OFFSETS UCBDF$ ;DEFINE UCB OFFSETS DCBDF$ ;DEFINE DCB OFFSETS .MCALL SMACIT ;INVOKE SUPERMAC SMACIT .PAGE .SBTTL LOCAL DATA, DISPATCH TABLE ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER NUMBER) ; CNTBL: .BLKW X$$X11 ;ADDRESS OF UNIT CONTROL BLOCK .IF GT X$$X11-1 TEMP: .BLKW 1 ;TEMPORARY STORAGE FOR CONTROLLER NUMBER .ENDC ; ; DRIVER DISPATCH TABLE ; $XXTBL::.WORD XXINI ;DEVICE INITIATOR ENTRY POINT .WORD XXCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD XXOUT ;DEVICE TIMEOUT ENTRY POINT .WORD XXPWF ;POWERFAIL ENTRY POINT .PAGE .SBTTL INTERRUPT SERVICE ; $XXINT CONTROLLER INTERRUPT SERVICE ROUTINE PROCEDURE $XXINT,GLOBAL BEGIN INTERRUPT DEBUG 1 ;;; DEBUGGING BREAKPOINT INTSV$ XX,XXPRI,X$$X11 ;;; GENERATE INTERRUPT SAVE CODE DEBUG 1 ;;; DEBUGGING BREAKPOINT PUSH R0,R1,R2,R3 ;;; SAVE REGS (R4, R5 ALREADY SAVED) LET R4 := U.SCB(R5) ;;; GET ADDRESS OF STATUS CONTROL BLOCK LET @S.CSR(R4) := @S.CSR(R4) OFF.BY #IE ;;; DISABLE DEVICE INTERRUPTS ; . ; . *** DEVICE-SPECIFIC INTERRUPT SERVICE CODE *** ; . POP R3,R2,R1,R0 ;;; RESTORE REGISTERS END INTERRUPT ;;; $CALL $FORK ;;; CREATE A SYSTEM PROCESS BEGIN FORKPROCESS ; IF #ERR SET.IN @S.CSR(R4) ; WAS THERE AN ERROR? DEBUG 1 ; DEBUGGING BREAKPOINT ; ; DEVICE SPECIFIC FORK LEVEL CODE ; GOES HERE ; ; POSSIBLE THINGS TO DO: ; DECODE ERRORS ; CALCULATE RETURN BYTE COUNT ; LOG ERRORS ; RETRY OPERATION ELSE LET R1 := S.PKT(R4) ; FIND THE I/O PACKET LET R1 := I.PRM+4(R1) ; SET RETURN BYTE COUNT LET R0 := #IS.SUC ; SET RETURN STATUS LET R2 := #0 ; SET RETRY COUNT PUSH R4 $CALL $IODON ; AND TERMINATE I/O OPERATION POP R4 END LET @S.CSR(R4) := @S.CSR(R4) SET.BY #IE ; ENABLE DEVICE INTERRUPTS END FORKPROCESS ; *** NOTE: FALLS THROUGH INTO INITIALIZATION CODE *** .PAGE .SBTTL CONTROLLER INITIATOR ;+ ; XXINI CONTROLLER INITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. ; ; IF (SPECIFIED CONTROLLER IS NOT BUSY) ; THEN (TRY TO DEQUEUE NEXT I/O REQUEST) ; IF (DEQUEUE SUCCESSFUL) ; THEN (INITIATE NEXT I/O OPERATION) ; RETURN TO CALLER. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF (SPECIFIED CONTROLLER NOT BUSY) ; THEN IF (I/O REQUEST WAITING) ; THEN (DEQUEUE REQUEST; ; INITIATE I/O OPERATION) ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; I/O REQUEST PACKET FORMAT: ; ; I.LNK WD. 00 -- I/O QUEUE THREAD WORD. ; I.PRI,I.EFN WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; I.TCB WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTER TASK. ; I.LN2 WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTER TASK HEADER. ; I.UCB WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTER TASK HEADER (UCB). ; I.FCN WD. 05 -- I/O FUNCTION CODE ; I.IOSB WD. 06 -- VIRTUAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; I.AST WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; I.PRM WD. 12 -- RELOCATION BIAS OF I/O BUFFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERRED. ; WD. 15 -- NOT USED. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ;- .PAGE ; ; AT THIS POINT: ; IF UC.QUE=1 ; R5 - UCB ADDRESS ; R4 - SCB ADDRESS ; R1 - ADDR OF I/O PACKET ; IF UC.QUE=0 ; R5 - UCB ADDRESS ; PROCEDURE XXINI,GLOBAL BEGIN INITIATE DEBUG 1 ; DEBUGGING BREAKPOINT $CALL $GTPKT ; GET AN I/O PACKET ON.ERROR LEAVE INITIATE ; NONE LEFT. LET CNTBL(R3) := R5 ; SAVE UCB ADDR ; . ; . ; ; DEVICE-SPECIFIC INITIATION CODE GOES HERE ; ; . ; . LET S.CTM(R4) :B= S.ITM(R4) ; SET TIMEOUT LET @S.CSR(R4) := @S.CSR(R4) SET.BY #IE ; ENABLE CONTROLLER INTERRUPT DEBUG 1 ; DEBUGGING BREAKPOINT END INITIATE $RETURN .PAGE .SBTTL POWERFAIL RECOVERY ;+ ; ; POWERFAIL IS HANDLED VIA THE DEVICE TIMEOUT FACILITY AND ; THEREFORE CAUSES NO IMMEDIATE ACTION ON THE DEVICE. ; A RACE CONDITION IS THUS AVOIDED THAT COULD EXIST IN ; RESTARTING THE OPERATION. ; ; POWER FAIL CAN BE USED TO INITIALIZE THE CONTROLLER ; AND DRIVER WHEN THE DRIVER IS LOADED. ; THIS IS ENABLED BY SETTING BIT UC.PWF IN BYTE U.CTL OF THE UCB. ; AT THIS POINT: ; R5 - UCB ADDRESS ; R4 - SCB ADDRESS ; R3 - CONTROLLER INDEX ; ;- PROCEDURE XXPWF,GLOBAL BEGIN POWERFAIL DEBUG 2 ; DEBUGGING BREAKPOINT IF S.PKT(R4) EQ #0 ; 1ST TIME CALLED? ; . ; . ; FIRST-TIME CODE GOES HERE ; MAY WANT TO INITIALIZE DRIVER AND/OR ; CONTROLLER HERE ; . ; . ELSE ; . ; . ; POWERFAIL RECOVERY CODE, IF ANY ; . ; . END END POWERFAIL $RETURN .PAGE .SBTTL TIMEOUT PROCESSING ;+ ; DEVICE TIMEOUT ; ; THIS SKELETON JUST CALLS $IODON TO TERMINATE THE I/O OPERATION ; AND RETURN 'DEVICE NOT READY' STATUS. ; ; AT THIS POINT: ; R5 - UCB ADDRESS ; R4 - SCB ADDRESS ; R3 - CONTROLLER INDEX ; R2 - ADDRESS OF DEVICE CSR ; R0 - I/O STATUS CODE IE.DNR ; ;- PROCEDURE XXOUT,GLOBAL BEGIN TIMEOUT DEBUG 1 ;;; DEBUGGING BREAKPOINT LET @S.CSR(R4) := @S.CSR(R4) OFF.BY #IE ;;; DISABLE CONTROLLER INTERRUPT MTPS #0 ;;; ALLOW PROCESSOR INTERRUPTS ; . ; . ; DEVICE-SPECIFIC TIMEOUT CODE GOES HERE ; MIGHT WANT TO RETRY OPERATION OR JUST ; CALL $IODON TO TERMINATE THIS OPERATION, AS ; BELOW: ; ; . ; . ; . LET R1 := S.PKT(R4) LET R1 := I.PRM+4(R1) + BCR(R2) ; COMPUTE RETURN BYTE COUNT LET R2 := #0 ; RETRY COUNT PUSH R4 $CALL $IODON POP R4 END TIMEOUT $RETURN .PAGE .SBTTL I/O CANCEL ;+ ; CANCEL I/O OPERATION-FORCE I/O TO COMPLETE IF DEVICE IS NOT READY ; ; AT THIS POINT: ; R5 - UCB ADDRESS ; R4 - SCB ADDRESS ; R3 - CONTROLLER INDEX ; R1 - TCB ADDRESS OF CURRENT TASK ; R0 - ADDRESS OF ACTIVE I/O PACKET (ALL OTHERS HAVE BEEN PURGED) ; ;- PROCEDURE XXCAN,GLOBAL BEGIN CANCEL DEBUG 1 ;;; DEBUGGING BREAKPOINT IF R1 EQ I.TCB(R0) ;;; THIS TASK? ; . ;;; YES. ; . ; . ELSE ; . ;;; NO. ; . ; . END END CANCEL $RETURN ;;; .END