.TITLE XXDRV .IDENT /00/ ;+ ; ; XXDRVMPL.MAC ; ; ** RSX-11M-PLUS ** ; ** SKELETON I/O DRIVER ** ; ; INSTRUCTIONS FOR USE: ; ; THIS IS A SKELETON I/O DRIVER FOR RSX-11M-PLUS. ; IT CONTAINS ALL THE NECESSARY BOILERPLATE THAT IS ; REQUIRED TO BE IN EVERY M-PLUS 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. ; ; SEE ALSO OTHER INSTRUCTIONS IN XXTAB.MAC ; ; COMMAND LINE FOR ASSEMBLY: ; ; MAC>XXDRV,XXDRV=LB:[1,1]EXEMC/ML,[11,10]RSXMC/PA:1,SY:[]XXDRV ; ; ; J. MCGLINCHEY ; ; VERSION 00 15-APR-80 ; VERSION 01 5-MAR-85 ;- .PAGE ; ; MACRO LIBRARY CALLS (DELETE THE ONES NOT USED) ; .MCALL ABODF$,HWDDF$,PKTDF$ .MCALL SCBDF$,UCBDF$,DCBDF$ .MCALL KRBDF$,INTSV$ ABODF$ ;DEFINE TASK ABORT CODES DCBDF$ ;DEFINE DCB OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS KRBDF$ ;DEFINE KRB OFFSETS PKTDF$ ;DEFINE I/O PACKET OFFSETS SCBDF$ ;DEFINE SCB OFFSETS UCBDF$ ;DEFINE UCB OFFSETS .PAGE .SBTTL DISPATCH TABLE $XXTBL:: .WORD XXINI ; INITIATOR .WORD XXCAN ; I/O CANCEL .WORD XXOUT ; TIMEOUT .WORD XX5$ ; POWER FAIL .WORD XX7$ ; CTRLR STATUS CHANGE .WORD XXKRB ; UNIT STATUS CHANGE .ASCII /XX/ ; 2-CHARACTER GENERIC DEVICE NAME .WORD $XXINT ; INTERRUPT ENTRY .WORD 0 ; (TERMINATOR) XXCTB: .WORD 0 ; PTR TO KRB TBL (FILLED IN BY LOA) $XXTBE:: .WORD 0 ; END OF DISPATCH TABLE XX5$: BCS XX7$ ; BRANCH IF UNIT, ELSE CONTROLLER XX6$: JMP XXPWF ; POWER FAIL ENTRY POINT XX7$: RETURN .PAGE .SBTTL INTERRUPT SERVICE ; $XXINT CONTROLLER INTERRUPT SERVICE ROUTINE ; $XXINT:: ;;; REF LABEL DEBUG 1 ;;; DEBUGGING BREAKPOINT BIC #IE,@#CSR0 ;;; DISABLE DEVICE INTERRUPTS INTSV$ XX,XXPRI,X$$X11 ;;; GENERATE INTERRUPT SAVE CODE DEBUG 1 ;;; DEBUGGING BREAKPOINT ;;; SAVE REGS (R4, R5 ALREADY SAVED) MOV R0,-(SP) ;;; SAVE R0 MOV R1,-(SP) ;;; SAVE R1 MOV R2,-(SP) ;;; SAVE R2 MOV R3,-(SP) ;;; SAVE R3 MOV U.SCB(R5),R4 ;;; GET ADDRESS OF STATUS CONTROL BLOCK ; . ; . *** DEVICE-SPECIFIC INTERRUPT SERVICE CODE *** ; . MOV (SP)+,R3 ;;; RESTORE R3 MOV (SP)+,R2 ;;; RESTORE R2 MOV (SP)+,R1 ;;; RESTORE R1 MOV (SP)+,R0 ;;; RESTORE R0 CALL $FORK ;;; CREATE A SYSTEM PROCESS DEBUG 1 ; DEBUGGING BREAKPOINT TST @S.CSR(R4) ; DEVICE ERROR? BPL 65$ ; IF PL NO ; ; DEVICE SPECIFIC FORK LEVEL CODE ; GOES HERE ; ; POSSIBLE THINGS TO DO: ; DECODE ERRORS ; CALCULATE RETURN BYTE COUNT ; LOG ERRORS ; RETRY OPERATION 50$: MOV S.PKT(R4),R1 ; GET ADDRESS OF I/O PACKET MOV I.PRM+4(R1),R1 ; SET NUMBER OF BYTES PROCESSED MOV #,R0 ; SET RETURN STATUS 60$: ; REF LABEL: COME HERE WITH STATUS IN R1 CLR R2 ; RETRY COUNT MOV R4,-(SP) ; SAVE R4 FROM $IODON CALL $IODON ; FINISH I/O OPERATION MOV (SP)+,R4 65$: ; REF LABEL BIS #IE,@S.CSR(R4) ; ENABLE DEVICE INTERRUPTS ; *** NOTE: FALLS THROUGH INTO INITIATION 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. (1 IF EMPTY) ; 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 .ENABL LSB ; ; 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 ; XXINI:: DEBUG 1 ; DEBUGGING BREAKPOINT CALL $GTPKT ; GET AN I/O PACKET TO PROCESS BCS 49$ ; IF CS CONTROLLER BUSY OR NO REQUEST ; ; ;DEVICE-SPECIFIC INITIATION ; ;CODE GOES HERE ; 40$: MOVB S.ITM(R4),S.CTM(R4) ; RESET DEVICE TIMEOUT BISB #IE,@S.CSR(R4) ; ENABLE DEVICE INTERRUPT DEBUG 1 ; DEBUGGING BREAKPOINT 49$: 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. ; ; AT THIS POINT: ; R5 - UCB ADDRESS ; R4 - SCB ADDRESS ; R3 - CONTROLLER INDEX ;- XXPWF:: DEBUG 2 ; DEBUGGING BREAKPOINT 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 ; ;- XXOUT:: DEBUG 1 ;;; DEBUGGING BREAKPOINT BIC #IE,@S.CSR(R4) ;;; DISABLE CONTROLLER INTERRUPT ; ; ; ; DEVICE-SPECIFIC TIMEOUT ; ; PROCESSING GOES HERE ; ; MIGHT WANT TO RETRY OPERATION ; ; OR JUST CALL $IODON TO TERMINATE ; ; THIS OPERATION, AS BELOW: ; MOV S.PKT(R4),R1 ; FIND THE PACKET MOV I.PRM+4(R1),R1 ; CALCULATE RETURN BYTE COUNT CLR R2 ; RETRY COUNT MOV R4,-(SP) ; SAVE R4 CALL $IODON ; END THIS I/O MOV (SP)+,R4 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) ; ;- XXCAN:: DEBUG 1 ;;; DEBUGGING BREAKPOINT CMP R1,I.TCB(R0) ;;; REQUEST FOR CURRENT TASK? BNE 10$ ;;; IF NE NO ; BIS #ABRT,U.CW2(R5) ;;; SET FOR ABORT IF DEVICE NOT READY ; ;;; (SUGGESTED) 10$: RETURN ;;; .PAGE ;+ ; UNIT CHANGE ENTRIES (CON OFFLINE/ONLINE) ; ; CALLED WITH CS IF CHANGE TO OFFLINE, CC IF CHANGE TO ONLINE ; ; INPUTS: ; R5 - UCB ADDRESS ; R4 - SCB ADDRESS ; R3 - CONTROLLER INDEX ; ;- XXKRB:: BCC 100$ ; . ; CON OFFLINE ; . ; MIGHT WANT TO RESET THE WHOLE CONTROLLER ; . JMP 199$ 100$: ; CON ONLINE CLRB S.STS(R4) ; SET CONTROLLER UNBUSY BICB #US.BSY,U.STS(R5) ; AND UNIT TOO MOV R3,-(SP) ; PLUG OWNER UCB INTO KRB. MOV XXCTB,R3 ADD (SP)+,R3 MOV (R3),R3 ; GOT KRB ADDR MOV R5,K.OWN(R3) ; AND PLUG IT. ; . ; . ; ALSO MIGHT WANT TO: ; . ; RESET CONTROLLER ; . ; SET UP UCB EXTSNSION WORDS, ; ; LOCAL BUFFERS, ETC. 199$: RETURN ;+ ; ANCILLARY ENTRY POINTS ;- $QJLOA:: ; DRIVER LOAD $QJUNL:: ; DRIVER UNLOAD QJUCB:: ; UCB CHANGE RETURN .END