.TITLE QADRV DR-11W DEVICE DRIVER .IDENT /02/ ; ; change to version 2, add set time out subfunction code ; ; ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,SCBDF$,UCBDF$,DEVDF$ HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS SCBDF$ ;DEFINE SCB OFFSETS UCBDF$ DEVDF$ ; ; ; ; ; DRIVER DISPATCH TABLE ; GENERATES THE DRIVER DISPATCH TABLE FOR A M-PLUS SYSTEM. ; INCLUDES POWER FAIL, CONTROLLER ONLINE AND UNIT ONLINE ; ENTRY POINTS. ; .list meb DDT$ QA,Q$$A11,,,,NEW=y ;GENERATE DISPATCH TABLE ; .even .ENABL LSB QAKRB:: ;CONTROLLER ENTRY POINT ; Entry will be for controller online/offline transitions ; execute return on controller on line ; clear unit on offline ; c=1 online to offline transition ; c=0 offline to online transition ; r3=ctb address ; r2=krb address ; bcs qaaofl ;if c set take controller offline return qaaofl: mov k.csr(r2),r0 ;get csr clr drcsr(r0) ;clear csr return ; ; QAucb: ; unit status change ; similar to device controller ; for online, reset ; for offline, clear csr ; r5=ucb address ; r4=scb address ; r3=controller index ; c=1 online to offline ; c=0 offline to online ; bcs QAofl ;if c set, take device offline bicb #us.ofl,u.st2(r5) ;set device online mov s.csr(r4),r2 ;get csr base reset ;reset dr11-w return ; QAofl: mov s.csr(r4),r2 ;get csr dsabl pr5 ;;;disable interrupt clr drcsr(r2) ;;;clear csr delay 5 ;;;let settle enabl ;enable interrupt return ; ; i/o initiation point ; QAINI: ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ; ; 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. ; ; DR11-W I/O PACKET STRUCTURE ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB, IO.WLB, IO.STC, OR IO.SEC) ; 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 (DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; Start of parameter 6 word block ; WD. 12 -- MEMORY EXTENSION BITS (BITS 4 AND 5) OF I/O TRANSFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- if io.sft subfunction, function bits ; WD. 16 -- if io.sto subfunction, time out in seconds ; WD. 17 -- ; WD. 20 -- Attachment descriptors, used by system for io ; WD. 21 -- locking ; ; DETERMINE FUNCTION ; GTPKT$ QA,Q$$A11,,,SUC ;GET NEXT PACKET cmpb #5,i.fcn+1(r1) ;we doing set or sense beq 5$ jmp 25$ ;must be someting else 5$: cmp #io.stc,i.fcn(r1) ;set or sense characterisitcs beq 8$ ;set characteristics cmp #io.sec,i.fcn(r1) ;sense characteristics beq 12$ 6$: mov #ie.bad,r0 ;flag bad parameter call $iodon ;tell him about it jmp qaini ;go do some work ;++ ; set characteristics function ; ;-- 8$: mov s.csr(r4),r2 ;get csr address mov i.prm(r1),r0 ;get bits bic #177770,r0 ;clear trash asl r0 ;shift left dsabl pr5 ;don't bother me mov drcsr(r2),r1 ;;;get csr into r1 bic #qaerr!qafnt!qago,r1 ;;;clear function and go bits bis r0,r1 ;;;set function bits mov r1,drcsr(r2) ;;;reset reg enabl ;back ;++ ; sense characteristics function ;-- 12$: mov s.csr(r4),r2 ;get csr address mov drcsr(r2),r1 ;put csr in r1 mov #is.suc&377,r0 ;flag we got the data call $iodon ;finish i/o jmp QAini ;go see if more to do ;++ ; ; read or write logical function at this point ; must be a data transfer ; ; get here with ; r1=iopkt ; r5=scb ; r4=ucb ; ;-- 25$: cmpb #,i.fcn+1(r1) ;read ? beq 27$ cmpb #,i.fcn+1(r1) ;write beq 27$ jmp 6$ ;bad params 27$: bit #1,u.cnt(r5) ;test for odd word count beq 28$ ;eq 0, must be even jmp 6$ 28$: bit #io.res,i.fcn(r1) ;reset needed beq 30$ ;eq 0, no mov s.csr(r4),r2 ; get csr base , r2 had unit # reset ;reset dr11-w ; ; we set up to do transfer ; 30$: CALL $STMAP ;GET UNIBUS MAPPING SET UP CALL $MPUBM ;MAP UNIBUS TO MEM ;R3 PRESERVED ACCROSS CALL MOV s.pkt(r4),R1 ;RESTORE PACKET MOV s.csr(R4),R2 ;POINT R2 TO CSR actually base ;READ/WRITE DMA FUNCTION ; convert byte to word count and load wcr MOV U.CNT(R5),R3 ;POINT R3 TO BYTE COUNT CLC ;CLEAR CARRY ROR R3 ;BYTE*2=WORD CNT NEG R3 ;- WORD COUNT dsabl pr5 ;don't bother me mov r3,drwcr(r2) ;;;load wcr for dma operation ; ;may differ for word mode ; ; ; first we must set up csr image in r0 mov drcsr(r2),r0 ;;;get csr bic #^c,r0 ;;;clear all but function bits bit #io.sft,i.fcn(r1) ;;;set function ? beq 50$ ;;;eq 0, no bic #QAfnt,r0 ;;;clear old bits mov i.prm+6(r1),r3 ;;;get new function bits ? bic #177770,r3 ;;;clear all but lower three asl r3 ;;;shift to control position bis r3,r0 ;;;set into csr image 50$: mov u.buf+2(r5),drbar(r2) ;;;set buffer address reg bis u.buf(r5),r0 ;;;set address exentsion bits ; ; r0 now has interrupt enable, function bits, address extension bits ; attention bits all set bis #qaie,r0 ;;;interrupt enable mov r0,drcsr(r2) ;;;set bits, let settle bis #QAgo,r0 ;;;set go and interrupt bits, bitb #io.sto,i.fcn(r1) ;;;new time out ? /02/ bne 55$ ;;; ne yes /02/ movb s.itm(r4),s.ctm(r4) ;;;set timeout to initial value br 60$ ;;;go on 55$: movb i.prm+10(r1),s.ctm(r4) ;;; set time out /02/ 60$: mov #qaexp,u.exp(r5) ;;;flag interrupt expected mov r0,drcsr(r2) ;;;set bits + go bit enabl ; QACAN: ;CANCEL ENTRY ; QAPWF: ;POWER FAIL IS RETURN QARET: RETURN ;go back to caller ; ; INTERRUPT ENTRY POINT $QAINT:: intsv$ QA,pr5,Q$$A11,, ;;;load r5 with ucb address mov r4,-(sp) ;;;save r4 mov u.scb(r5),r4 ;;;get scb mov s.csr(r4),r4 ;;;get register base for csr ;;; we now get all register into ucb before clean up .if ne okdma mov drwcr(r4),u.wcr(r5) ;;;save wcr .iif df deb,mov drbar(r4),u.bar(r5) ;;;save bar .iff mov dridr(r4),u.idr(r5) ;;;idr .endc tst drcsr(r4) ;;;error bit set bmi errqa ;;;minus yes mov drcsr(r4),u.csr(r5) ;;;save csr br qafork ;;;don't need eir errqa:: mov drcsr(r4),u.eir(r5) ;;;save eir bic #qaerr,drcsr(r4) ;;;clear error bit mov drcsr(r4),u.csr(r5) ;;;save csr qafork: mov (sp)+,r4 ;;;restore r4 tst u.exp(r5) ;;;interrupt expected? bne qaok ;;;if ne, yes return qaok: clr u.exp(r5) ;;;clear expected interrupt call $fork ;lower priority mov u.cnt(r5),r1 ;get byte count clc ;set up for word count ror r1 ;word count in r1 add u.wcr(r5),r1 ;compute actuall transfer ;count asl r1 ;back to byte count mov #is.suc&377,r0 ;indicate success QAdone: call $iodon ;indicate completion JMP QAINI ;get next operation ; miscellaneous entry points ; QAout: ;timeout entry mov s.csr(r4),r2 ;;; mov drcsr(r2),u.csr(r5) ;;;get csr clr drcsr(r2) ;;;clear csr clr u.exp(r5) ;;;clear interrupt expected mtps #0 ;enable intterupts QAdnr: mov #ie.tmo,r0 ;set not ready code mov u.csr(r5),r1 ;csr as iosb+2 br QAdone ;go back to caller .end