.ident 'V02-01E' ; ; Facility: ; ; VAX/VMS V5. Executive, I/O Drivers ; ; Abstract: ; ; This module contains the Kinetic 3922-2922 Crate controller driver: ; ; Table for loding and dispatching ; Unit-initialization routine ; FDT-routine ; Start CAMAC I/O routine (DMA mode) ; Error-logging, register dump routine ; Interrupt-servicing routine ; Deliver AST routine after interupt ; ; This module supports Block mode DMA transfer and Interupt handling. ; For a single CAMAC operation, another program C2922.MAR exsis. ; ; Enviroment: ; ; VAX/VMS V5.x Kernel mode, non paged. ; ; This version supports symmetric multi-processor enviroment together ; with uni-processor and asymmetric multi-processor enviroment. ; ; Author ; ; Takashi Ichihara RIKEN, Hirosawa, Wako, 351-01, Japan ; ; 12 September 1987 ; ; History ; ; 10 December 1987 Modified resistor load sequence ; 21 February 1989 Modified for VAX/VMS V5.0 ; 2 May 1990 Modified for Symmetric Multi-CPU support ; .sbttl External and local symbol definitions ; External symbols $ACBDEF ; AST control block $ADPDEF ; Adapter control block $CRBDEF ; Channel request block $DCDEF ; Divice type $DDBDEF ; Device data block $DEVDEF ; Device characteristic $DPTDEF ; Driver prolog table $DYNDEF ; Dynamic data structure type $EMBDEF ; EMB offset $IDBDEF ; Interupt data block $IODEF ; I/O function code $IPLDEF ; Hardware IPL definition $IRPDEF ; I/O request package $PRDEF ; Internal processor resister $PRIDEF ; Scheduler priority increments $SSDEF ; System status code $UCBDEF ; unit contoll block $VECDEF ; Interupt vecter block $XADEF ; Define device specific characteristic ; Local symbols ; Argument list (AP) offset for devide-dependent QIO paramters P1 = 0 ; First QIO parameter P2 = 4 ; Second QIO patameter P3 = 8 ; QIO patameter P4 = 12 ; QIO patameter P5 = 16 ; QIO patameter P6 = 20 ; QIO patameter CB_RESET_DELAY = 1000 ; Reset time delay (10 mill sec.) CB_DEF_TIMEOUT = 5 ; Defalt timeout ( 5 sec. ) ;CB_DEF_BUFSIZE =65535 ; Defalt buffer size CB_DEF_BUFSIZE =0 ; Defalt buffer size $EQU CB$M_DATAPATH 1 $EQU CB$M_LINK 2 $EQU CB$S_CBDEF 1 $EQU CB$V_DATAPATH 0 $EQU CB$V_LINK 1 ; ; 3922-2922 definition ; $DEFINI UCB .=UCB$L_DPC+4 $DEF UCB$L_CB_ATTN ; Attention AST listhead .BLKL 1 $DEF UCB$W_CB_CSRTMP ; Temporary storage of CSR image .BLKW 1 $DEF UCB$W_CB_NAFTMP ; Temporary storage of NAF image .BLKW 1 $DEF UCB$W_CB_MCRTMP ; Temporary storage of MCR image .BLKW 1 $DEF UCB$W_CB_CCRTMP ; Temporary storage of CCR image .BLKW 1 $DEF UCB$W_CB_WCRTMP ; Temporary storage of WCR image .BLKW 1 $DEF UCB$W_CB_MARTMP ; Temporary storage of MAR image .BLKW 1 $DEF UCB$W_CB_EMATMP ; Temporary storage of EMA image .BLKW 1 $DEF UCB$W_CB_CSR ; Saved CSR on interrupt .BLKW 1 $DEF UCB$W_CB_ERS ; Saved ERS on interrupt .BLKW 1 $DEF UCB$W_CB_MCR ; Saved MCR on interrupt .BLKW 1 $DEF UCB$W_CB_CCR ; Saved CCR on interrupt .BLKW 1 $DEF UCB$W_CB_NAF ; Saved NAF on interrupt .BLKW 1 $DEF UCB$W_CB_DLR ; Saved DLR on interrupt .BLKW 1 $DEF UCB$W_CB_DHR ; Saved DHR on interrupt .BLKW 1 $DEF UCB$W_CB_SRR ; Saved SRR on interrupt .BLKW 1 $DEF UCB$W_CB_WCR ; Saved WCR on interrupt .BLKW 1 $DEF UCB$W_CB_MAR ; Saved MAR on interrupt .BLKW 1 $DEF UCB$W_CB_EMA ; Saved EMA on interrupt .BLKW 1 $DEF UCB$W_CB_ERROR ; Saved Device status error flag .BLKW 1 $DEF UCB$L_CB_DPR ; Data-path register's number .BLKL 1 $DEF UCB$L_CB_FMPR ; Final map resister's content .BLKL 1 $DEF UCB$L_CB_PMPR ; Previous map resister's content .BLKL 1 $DEF UCB$W_CB_DPRN ; Saved Data-path register's number .BLKL 1 ; Bit positions for device-dependent status field in UCB $VIELD UCB,0,<- ; UCB device-specific bit definitions ,- ; ATTN AST requested ,- ; Unexpected interrupt received > UCB$K_SIZE=. $DEFEND UCB ; Bit position for device conrol/status ersister $EQULST CB_CSR_,,0,1,<- ; - ;Go bit - ;Done interupt inable - ;Done bit - ;Request for service interupt inable - ;Request for service interupt pending - ;Non exsisting memory - ;Reset interface - ;Bus timeout - ;Abort bit - ;Error bit > ; Bit position for error status rersister ERS $EQULST CB_ERS_,,0,1,<- ; - ;No Q - ;NO X - ;N > 23 > ; Bit position for mode control rersister MCR $EQULST CB_MCR_,,0,1,<- ; - ;Abort disable - ;Word size 1 - ;Word size 2 - ;Transfer mode 1 - ;Transfer mode 2 - ;Block mode > ; Bit position for CAMAC command rersister $EQULST CB_NAF_,,0,1,<- ; - ;funttion bit - ;funttion bit - ;funttion bit - ;funttion bit - ;funttion bit (Controll) - ;funttion bit (Write) - ;Sub address bit - ;Station number bit > ; ; Device register offset from CSR address ; $DEFINI CB ; Start of 3922 definitions $DEF CB_CSR ; Control/Status register .blkw 1 ; $DEF CB_ERS ; Error/Status register .blkw 1 ; $DEF CB_MCR ; Mode control register register .blkw 1 ; $DEF CB_CCR ; CAMAC crete register .blkw 1 ; $DEF CB_NAF ; CAMAC command resister .blkw 1 ; $DEF CB_DLR ; Data low register .blkw 1 ; $DEF CB_DHR ; Data high register .blkw 1 ; $DEF CB_SRR ; Service Request register .blkw 1 ; $DEF CB_WCR ; World count register .blkw 1 ; $DEF CB_MAR ; Memory address register .blkw 1 ; $DEF CB_EMA ; Extended memory address register .blkw 1 ; $DEFEND CB ; End of 3920 definition .sbttl Device prologue table ; Driver prologue table DPTAB - ; DPT-creation macro end=CB_END,- ; End of driver label adapter=UBA,- ; Adapter type flags=DPT$M_SVP,- ; Allocate system page table ucbsize=UCB$K_SIZE,- ; UCB size name=CBDRIVER ; Driver name DPT_STORE INIT ; Start of load ; initialization table ; DPT_STORE UCB,UCB$B_FIPL,B,8 ; Device fork ipl (old) DPT_STORE UCB,UCB$B_FLCK,B,SPL$C_IOLOCK8 ; Device fork loc (new) DPT_STORE UCB,UCB$B_DIPL,B,22 ; Device interrupt IPL DPT_STORE UCB,UCB$L_DEVCHAR,L,< - ; Device characteristic DEV$M_RTM!- ; Real time device DEV$M_ELG!- ; Error loging enabled DEV$M_IDV!- ; input device DEV$M_ODV!- ; output device DEV$M_AVL> ; available for user DPT_STORE UCB,UCB$B_DEVCLASS,B,DC$_REALTIME ; Device class ; DPT_STORE UCB,UCB$B_DEVTYPE,B,DT$_CC3922 ; Device Type DPT_STORE UCB,UCB$W_DEVBUFSIZ,W,- ; Defalt buffer size CB_DEF_BUFSIZE ; DPT_STORE REINIT ; Start of reload ; initialization table DPT_STORE DDB,DDB$L_DDT,D,CB$DDT ; Address of DDT ; DPT_STORE CRB,CRB$L_INTD+4,D,- ; Address of first Interupt(V4) ; CB_INTERUPT_1 ; service routine ; DPT_STORE CRB,CRB$L_INTD2+4,D,- ; Address of second Interupt ; CB_INTERUPT_2 ; service routine DPT_STORE CRB,CRB$L_INTD+VEC$L_ISR,D,- ; Address of first Interupt(V5) CB_INTERUPT_1 ; service routine DPT_STORE CRB,CRB$L_INTD2+VEC$L_ISR,D,- ; Address of second Interupt CB_INTERUPT_2 ; service routine DPT_STORE CRB,CRB$L_INTD+VEC$L_INITIAL,-; Address of controller D,CB_CONTROL_INIT ; initialization routine DPT_STORE END ; End of initialization tables ; Driver dispatch table DDTAB - ; DDT-creation macro devnam=CB,- ; Name of device start=CB_START,- ; Start I/O routine functb=CB_FUNCTABLE,- ; FDT address cancel=CB_CANCEL,- ; Cancel I/O ruotine regdmp=CB_REGDUMP,- ; Resister dump routine diagbf=<<23*4>+<<3+5+1>*4>>,- ; Diagnostic buffer size erlgbf=<<23*4>+<1*4>+> ;Error log buffer size ; ; Function dispatch table ; CB_FUNCTABLE: FUNCTAB,- ; FDT Driver ; FUNCTAB , ; No buffered function FUNCTAB CB_READ_WRITE- ; Device specfic FDT ; FUNCTAB CB_SETMODE, ; Set mode .sbttl CB_Control_init, Conroller initialization ;++ ; CB_CONTROL_INIT , Called when driver is loaded, system is booted, or ; power failure recovery. ; ; Functional Description: ; ; 1) Allocate the direct data path permanebtly ; 2) Assigns the controller data channel permanebtly ; 3) Clear the Control and Status resister ; ; Input: ; ; R4 = Address of CSR ; R5 = address pf IDB ; R6 = address of DDB ; r8 = address of CRB ; ; Outputs: ; ; ;-- CB_CONTROL_INIT: movl IDB$L_UCBLST(r5),r0 ; Address of UCB movl r0,IDB$L_OWNER(r5) ; Make permanent controller owner bisw #UCB$M_ONLINE,UCB$W_STS(R0) ; Set Device status "on-line" ADPDISP SELECT=ADAP_MAPPING,- ; Check for adapter mapping ADDRLIST=<>,- CRBADDR=R8,- SCRATCH=R1 BUG_CHECK UNSUPRTCPU,FATAL ; not supported on non-mapping adapter 1$: ADPDISP SELECT=QBUS,- ; Check for QBUS machine ADDRLIST=<>,- ADPADDR=R1 BLBC g^SGN$GB_QBUS_MULT_INTR,2$ ; protect against ILLQBUSCFG MOVB #^x14,UCB$B_DIPL(R5) ; This is correct DIPL for Q-bus dev. 2$: ;MOVB #DT$_XA_DRV11WA,- ; This is a Q-bus. ; UCB$B_DEVTYPE(R0) ; bisw #UCB$M_INT,UCB$W_STS(R0) ; Set Device status inturrupt expected 9$: bbs #UCB$V_POWER,UCB$W_STS(R0),10$ ; Branch if powerfail bisb #VEC$M_PATHLOCK,CRB$L_INTD+VEC$B_DATAPATH(r8) ; permanebtly allocate direct datapath 10$: pushl r5 ; save R5 movl r0,r5 ; copy ucbaddress to R5 SETIPL #20,- ; set IPL to 20 ENVIRON=UNIPROCESSOR ; Avaid assembly-time warning bsbw CB_DEV_RESET ; Reset 3920 Crate controller popl r5 ; Restore R5 rsb ; Done ;++ ; CB_READ_WRITE, FDT routin for READPBLK,WRITEPBLK ; ; Function description: ; ; 1) Reject QUEUE I/O's with odd transfer count ; 2) Reject QUEUE I/O's for Block mode (DMA) request to UBA(QBA) ; data path on odd byte boundary ; 3) Store defalt timeout count specified in P3 into IPR ; 4) Check the range of the F,N,A,Mode parameters ; 5) Stores F,N,A,Mode code into IRP ; 6) Check block mode transters for memory modufy access ; ; Context: ; ; User process mapping ; Kernel mode ; IPL is set at IPL$_ASTDEL ; Kernel stack ; ; Inputs: ; ; r0 = Address of the FDT routine being called ; r3 = Address of IRP ; r4 = Address of PCB ; r5 = Address of UCB ; r6 = Address of CCB ; r7 = Bit number of the user-specified I/O function code ; r8 = Address of FDT routines ; ap = Address of P1 ; ; p1 = Address of buffer ; p2 = Byte count to be transterd ; p3 = CAMAC Crate number (0-7) (CCR image) ; p4 = CAMAC NAF (N*512 + A*32 + F) code (NAFR image) ; p5 = CAMAC Access mode (TM*64+WS*16+256) (MCR image) ; TM 0 Q-STOP WS 0 24 BIT ; TM 1 IGNORE Q WS 1 16 BIT ; TM 2 Q-REPEAT WS 2 8 BIT ; TM 3 Q-SCAN WS 3 Reserved ; p6 = Reserved ; ; Outputs: ; ; r0 = Error status if odd stransfer address ; IRP$L_MEDIA = Timeout count for this request ; IRP$L_SEGVBN = NAF and mode bit for Kinetic 3920-2920Z2B ; CAMAC Crate controller ; ; ; CB_READ_WRITE: blbc p2(ap),10$ ; Branch if transfer count is odd blbc p1(ap),10$ ; Branch if transfer address is odd 2$: movzwl #SS$_BADPARAM,r0 ; Set error status code 5$: jmp G^EXE$ABORTIO ; Abort request 10$: movzwl IRP$W_FUNC(r3),r1 ; Set request specified timeout count movl #CB_DEF_TIMEOUT,IRP$L_MEDIA(r3) ; Set defalu timeout value 15$: movzwl p3(ap),r9 ; Fetch CCR (CAMAC Crate number) movzwl p4(ap),r10 ; Fetch NAF (CAMAC NAF code) movzwl p5(ap),r11 ; Fetch MCR (CAMAC Access mode) ; ; Check input parameters and pack them into IRP registers ; bitw #^XFFF8,r9 ; CCR (Crate address) bneq 2$ ; Out of range (C > 7) bitw #^XC000,r10 ; NAF bneq 2$ ; Out of range bIcW #^XFE00,r11 ; Clear high 7 bit of MCR ashl #10,r9,r9 ; shft CCR to 10 bit up addl r9,r11 ; MCR + CCR(shifted) => MCR movw r10,IRP$L_SEGVBN(r3) ; Save NAFR to IRP reggister 1 movw r11,IRP$L_SEGVBN+2(r3) ; Save MCR+CCR(shifted)to IRP register 2 ; ; This is a block mode (DMA) transfer, check buffer for ; modify accdess whether of not the function is read of write. ; ; bitl #CB_NAF_F8,r9 ; Camac controll ; bneq 2$ ; Yes, but this is invarid parameter 25$: jmp G^EXE$MODIFY ; Check buffer for modify access and ; Locck in Physcal memory for DMA ; ; This is word-mode transter ; 30$: rsb ;++ ; CB_SETMODE FDT routine to process SET MODE ; ; Function description: ; ; If IO$M_ATTNAST modifier is set, queue attentins AST for device ; If IO$M_DATAPATH modifier is set, queue packet ; Else, finish I/O ; ; Inputs: ; ; r3 = I/O packet address ; r4 = PCB address ; r5 = UCB address ; r6 = CCB address ; r7 = Function code ; ap = QIO parameter list address ; ; Output: ; ; If IO$M_ATTNAST is specified, queue AST on UCB attention AST list ; If IO$M_DATAPATH is specified, queue packet to driver ; Else, use exec routine to update device characterritics ; ; ;-- CB_SETMODE: movzwl IRP$W_FUNC(r3),r0 ; Get entire function code bbc #IO$V_ATTNAST,r0,20$ ; Branch if not an ATTN AST ; Attention AST request pushr #^M movab UCB$L_CB_ATTN(r5),r7 ; Address of ATTN AST control block list jsb G^COM$SETATTNAST ; Setup attention AST popr #^M blbc r0,50$ ; Branch if error bisw #UCB$M_ATTNAST,UCB$W_DEVSTS(r5) ; Flag ATTN AST expected. bbc #UCB$V_UNEXPT,UCB$W_DEVSTS(r5),10$ ; Deliver AST if unsoliciated interrupt bsbw DEL_ATTNAST 10$: movzbl #SS$_NORMAL,r0 ; set status jmp G^EXE$FINISHIOC ; That's all for now (clears r1) 20$: movzwl #SS$_BADPARAM,r0 ; Set error status code 50$: clrl r1 jmp G^EXE$ABORTIO ; Abort IO on error ;++ ; CB_START - Start a data transfer, set characterristics ; 1) Start an i/o transfer. This transfer can be in either CAMAC ; single function or DMA mode. ; ; Context: ; ; System mapping ; Kernel mode ; High IPL (between driver fork level and IPL$_POWER) ; Kernel or interrupt stack ; ; Inputs: ; ; r3 = Address of the I/O request packet ; r5 = Address of the UCB ; ; Output: ; ; r0 = final status and number of bytes transferred ; r1 = value of CSR STATUS bits and value of input data buffer register ; Device error are logged ; CB_START: ; ; Retrive the address of the device CSR ; assume IDB$L_CSR EQ 0 movl UCB$L_CRB(r5),r4 ; Address of CRB movl @CRB$L_INTD+VEC$L_IDB(r4),r4 ; Address of CSR ; ; Reset interface ; bisw #CB_CSR_RST,CB_CSR(r4) ; Initialize camac crate interface ; ; Fetch the I/O function code ; movl IRP$L_SEGVBN(r3),r1 ; get MCR+CCR + NAFR movw r1,UCB$W_FUNC(r5) ; Save Func in UCB for error logging ; 4$: ; check device status brb 5$ ; ok available bsbw CB_REGISTER ; Error detected. fech device registers jsb G^IOC$DIAGBUFILL ; Fill diagnostic buffer if specified. jsb G^ERL$DEVICERR ; Log a devaice error movl UCB$W_CB_CSR(r5),r1 ; Return CSR movl UCB$W_CB_ERROR(r5),r0 ; REQCOM ; Request done 5$: movl IRP$L_SEGVBN(r3),r1 ; get MCR+CCR + NAFR movw r1,UCB$W_CB_NAFTMP(r5) ; Set CAMAC NAF temp register ashl #-16,r1,r0 ; obtain MCR + (CCR)shifted => r0 ashl #-10,r0,r1 ; CCR => R1 movw r1,UCB$W_CB_CCRTMP(r5) ; Set CCR temp bicw #^XFE00,r0 ; obtain mcr movw r0,UCB$W_CB_MCRTMP(r5) ; set MCR temp bitl #CB_MCR_BM,r0 ; DMA mode transfer ? bneq BLOCK_MODE ; Yes, CAMAC DMA blockmode transter brw SINGLE_MODE ; CAMAC single function ;++ ; BLOCK MODE --- Process block mode (DMA) transfer request ; ; Functional Description: ; ; This routine calculate the UNIBUS address, allcate the UBA ; map registers, load the Kinetic 3920-2920Z2B device resisters ; and starts the request. ; ; BLOCK_MODE: reqdpr ; Request UBA data path reqmpr ; Request UBA loaduba ; Load UBA map resisters ; ; Calculate the UNIBUS transfer address for the 2922-3922 from ; the UBA map register address and byte offset ; ; ; Memory Address ; movzwl UCB$W_BOFF(r5),r1 ; Byte offset in first page of transfer movl UCB$L_CRB(r5),r2 ; Address of CRB insv CRB$L_INTD+VEC$W_MAPREG(r2),#9,#9,r1 ; Insert page number movw r1,UCB$W_CB_MARTMP(r5) ; MAR ; ; Calculate transfer Word length and counts ; movzwl IRP$W_BCNT(r3),r2 ; Transfer byte cont movzbl UCB$W_CB_MCRTMP(r5),r0 ; Restore MCR temp bitw #CB_MCR_WS1,r0 ; 16 bit mode ? beql 5$ ; no ashl #-1,r2,r2 ; devide by 2 (because 16 bit mode) brb 6$ ; 5$: bitw #CB_MCR_WS2,r0 ; 8 bit mode ? bneq 6$ ; yes 8 bit mode ashl #-2,r2,r2 ; devide by 4 (because 24/32 bit mode) 6$: mnegw r2,UCB$W_CB_WCRTMP(r5) ; WCR (transfer word count) extzv #16,#2,r1,r2 ; Extract bits 22:16 of bus address movw r2,UCB$W_CB_EMATMP(r5) ; save ; ; Disable all interruput ; ; DSBINT,ENVIRON=UNIPROCESSOR ; Diasble all interrupt ; 90/04/28 for symm. multi CPU support DEVICELOCK - ; Secure device lock LOCKADDR=UCB$L_DLCK(r5),- ; (also raised IPL to device IPL) SAVIPL=-(SP),- ; Save current IPL PRESERVE=NO ; Don't preserver R0 SETIPL #31,- ; Rraize IPL to 31 to disable power- ENVIRON=UNIPROCESSOR ; failuer interrupt. ; ; Write into device registers ; movw UCB$W_CB_CCRTMP(r5),CB_CCR(r4) ; Write CAMAC Crate reg. movw UCB$W_CB_NAFTMP(r5),CB_NAF(r4) ; Write CAMAC Command reg. movw UCB$W_CB_MCRTMP(r5),CB_MCR(r4) ; Write Mode Control reg. movw UCB$W_CB_MARTMP(r5),CB_MAR(r4) ; Write Memory Address reg. movw UCB$W_CB_EMATMP(r5),CB_EMA(r4) ; Write Extended M. A. reg. movw UCB$W_CB_WCRTMP(r5),CB_WCR(r4) ; Write Word count reg. ; ; Start DMA transfer ; bisw #CB_CSR_DIE,CB_CSR(r4) ; Set done interupt inable bit bisw #CB_CSR_GO,CB_CSR(r4) ; Set go bit ; ; Wait Done Interupt or timeout ; wfikpch CB_TIME_OUT,IRP$L_MEDIA(r3) ; Wait for interrupt/timeout ; ; Device has interrupted, FORK ; iofork ; Fork to lower IPL movzwl #SS$_NORMAL,-(sp) ; Assume success clrw UCB$W_CB_DPRN(r5) ; Clear DPR number purdpr ; pur UBA data path blbs r0,27$ ; Branch if no data-path error movzwl #SS$_PARITY,(sp) ; Flag parity error incb UCB$W_CB_DPRN+1(r5) ; Flag PDR error for log 27$: movl r1,UCB$L_CB_DPR(r5) ; Save data pass register extzv #VEC$V_DATAPATH,- ; Get data-path register number #VEC$S_DATAPATH,- ; For error log CRB$L_INTD+VEC$B_DATAPATH(r3),r0 movb r0,UCB$W_CB_DPRN(r5) ; Save for later in UCB extzv #9,#7,UCB$W_CB_MAR(r5),r0 ; Low bits of map-register number extzv #0,#2,UCB$W_CB_EMA(r5),r1 ; High bits of map-register number insv r1,#7,#2,r0 ; Entire map-register number cmpw r0,#496 ; Is map register in range ? bgtr 28$ ; No, forge it, compound error movl (r2)[r0],UCB$L_CB_FMPR(r5) ; Save map-register contents clrl UCB$L_CB_PMPR(r5) ; Assume no privious map register decl r0 ; Was there a previous map register cmpv #VEC$V_MAPREG,#VEC$S_MAPREG,- CRB$L_INTD+VEC$W_MAPREG(r3),r0 bgtr 28$ ; if GRR , no movl (r2)[r0],UCB$L_CB_FMPR(r5) ; Save previous map register contens 28$: relmpr ; Release UBA mapping resister reldpr ; Release UBA DPR ; ; Check for error and return status ; movw CB_CSR(r4),UCB$W_CB_CSR(r5) ;CSR bgeq 35$ ; no error movzwl UCB$W_CB_ERROR(r5),(sp) ; Flag for controller/driver error stat ; bsbw CB_DEV_RESET ; Reset device 35$: blbs (sp),40$ ; Any error after this jsb G^IOC$DIAGBUFILL ; Fill diagnostic buffer 40$: movl (sp)+,r0 ; Get final device status mulw3 #2,UCB$W_CB_WCR(r5),r1 ; Calculate final transfer count addw UCB$W_BCNT(r5),r1 insv r1,#16,#16,r0 ; Insert into high byte of IOSB movl UCB$W_CB_CSR(r5),r1 ; return DMACSR and EIR in IOSB reqcom ; Finish request SINGLE_MODE: MOVl #12345,r0 reqcom rsb RETURN_STATUS: rsb ;++ ; Kinetic 2922-3922 CAMAC Cratecontroler time out ; ; If a DMA transfer was in progress, release UBA resources. ; DElever ATTN AST's, log a device timeout error, ; and do a hard reset on the controller. ; ;-- CB_TIME_OUT: ; timeout for DMA transfer ; setipl UCB$B_FIPL(r5),ENVIRON=UNIPROCESSOR ; Lower to FORK transfer iofork ; Fork to complete requesst 90/04/28 purdpr ; purge buffered data path in UBA relmpr ; Relese UBA map resister reldpr ; Relese UBA data path 10$: movl UCB$L_CRB(r5),r4 ; Retch address of CSR movl @CRB$L_INTD+VEC$L_IDB(r4),r4 ; bsbw CB_REGISTER ; Read 3920-2020z2b resisters jsb G^IOC$DIAGBUFILL ; Fill diagnostic buffer jsb G^ERL$DEVICTMO ; Log device timeout bsbw DEL_ATTNAST ; and deliver the AST's bsbw CB_DEV_RESET ; and deliver the AST's movzwl #SS$_TIMEOUT,r0 ; set time-out error code clrl r1 ; clrw UCB$W_DEVSTS(r5) ; Clear ATTN AST flags bicw #,- UCB$W_STS(r5) ; Clear unit statsu flag reqcom ; Complete I/O in exec ;++ ; CB_INTERUPT_1, Handles interupt_1 (DMA Done) genarated by 3922 Interface ; ; Function descriptions: ; ;-- CB_INTERUPT_1: movl @(sp)+,r4 ; Address of IDB and pop sp movq (r4),r4 ; CSR and UCB address from IDB DEVICELOCK - ; add 90/04/28 LOCKADDR=UCB$L_DLCK(r5),- ; Lock Device access CONDITION=NOSETIPL,- ; Don't change IPL PRESERVE=NO ; Don't change R0 ; ; Check to see if device transfer request active or not ; If so, call driver back at wait-for-interrupt point and ; Clear unexpected interupt flag ; bicw #CB_CSR_DIE,CB_CSR(r4) ; Disable interupt bsbw CB_REGISTER ; Read all the device-registers ;20$: bbcc #UCB$V_INT,UCB$W_STS(r5),25$ ; if clear, no interrupt expected ; ; Interrupt expected, clear unexpected interupt flag and call driver ; back ; bicw #UCB$M_UNEXPT,UCB$W_DEVSTS(R5) ; clear unexpected interupt flag movl UCB$L_FR3(r5),r3 ; restore drivers r3 pushl r4 jsb @UCB$L_FPC(r5) ; Call diver back popl r4 brb 30$ ; ; ; Delever ATTN ASTs if no interrupt expected and set unexpected ; interrupt flag. ; 25$: ; ; Unlock device and restoe resisters and return form interupt ; 30$: DEVICEUNLOCK - ; Relese Device lock LOCKADDR=UCB$L_DLCK(R5),- ; PRESERVE=no ; Don't preserve R0 popr #^M ;restore resisters rei ;return from interupt ;++ ; CB_INTERUPT_2, Handles interupt_2 (LAM) genarated by 3920 ; ; Function descriptions: ; ;-- CB_INTERUPT_2: movl @(sp)+,r4 ; Address of IDB and pop sp movq (r4),r4 ; CSR and UCB address from IDB DEVICELOCK - ; add 90/04/28 LOCKADDR=UCB$L_DLCK(r5),- ; Lock Device access CONDITION=NOSETIPL,- ; Don't change IPL PRESERVE=NO ; Don't change R0 ; ; Delever ATTN ASTs if no interrupt expected and set unexpected ; interrupt flag. ; bisw #UCB$M_UNEXPT,UCB$W_DEVSTS(r5) ; set unexpected interrupt flag bicw #CB_CSR_RIE,CB_CSR(r4) ; Disable device interrupt ; ; ; bisw #CB_CSR_IE,CB_CSR(r4) ; Enable device interrupt bsbw DEL_ATTNAST ; Deliver ATTN ASTs ; ; Restoe resisters and return form interupt ; DEVICEUNLOCK - ; Relese Device lock LOCKADDR=UCB$L_DLCK(R5),- ; PRESERVE=no ; Don't preserve R0 30$: popr #^M ;restore resisters rei ;++ ; CB_CANCEL, Cancel an I/O operation in progress ;-- CB_CANCEL: rsb ;++ ; CB_ATTNAST, Delver all outstanding ATTN ASTs ; ; Functional description: ; ; This routine is uset by the cc3920 driver to deliver all of the ; outstanding attentions ASTs. It is copied from COM$DELETTNAST in ; the exec. In addition, it place the slaved value of the cc3920 ; CSR in the AST parameters. ; ; Inputs: ; ; r5 - UCB of Kinetic 3922 unit ; ; Output: ; ; r0,r1,r2 Destroyed ; r3,r4,r5 Preserved ;-- DEL_ATTNAST: ; dsbint UCB$B_DIPL(r5),ENVIRON=UNIPROCESSOR ; Device ipl ; 90/04/28 for symm. multi CPU support DEVICELOCK - ; Secure device lock LOCKADDR=UCB$L_DLCK(r5),- ; (also raised IPL to device IPL) SAVIPL=-(SP),- ; Save current IPL PRESERVE=NO ; Don't Preserve R0 bbcc #UCB$V_ATTNAST,UCB$W_DEVSTS(r5),30$ ; Any ATTN ASTs expected? pushr #^M ; Save r3,r4,r5 10$: movl 8(sp),r1 ; Get address of UCB movab UCB$L_CB_ATTN(r1),r2 ; address of attn AST listed movl (r2),r5 ; Address of next entry on list beql 20$ ; No next entry, end of loop bicw #UCB$M_UNEXPT,UCB$W_DEVSTS(r1) ; Clear unexpected interuupt flag movl (r5),(r2) ; Close list ;movw UCB$W_CB_IDR(r1),ACB$L_KAST+6(r5) ; ; Store IDR in AST parameter movw UCB$W_CB_CSR(r1),ACB$L_KAST+4(r5) ; Store CSR in AST parameter pushab B^10$ ; Set return address for FORK FORK ; fork for this ast ; AST fork procedure movq ACB$L_KAST(r5),ACB$L_AST(r5) ; Re-arrange entries movb ACB$L_KAST+8(r5),ACB$B_RMOD(r5) movl ACB$L_KAST+12(r5),ACB$L_PID(r5) clrl ACB$L_KAST(r5) movzbl #pri$_iocom,r2 ; Set up priority incriment jmp G^SCH$QAST ; queue the AST 20$: popr #^M ; restoe resisters 30$: ;enbint ; Enable interrupt ; 90/04/28 sym muti-cpu support DEVICEUNLOCK - ; Relese Device lock LOCKADDR=UCB$L_DLCK(R5),- ; NEWIPL=(sp)+,- ; Enable interrupt PRESERVE=no,- ; Don't preserve R0 CONDITION=RESTORE ; rsb ; return ;++ ; CB_REGISTER - Routine to handle Kinetic 3920-2920Z2B Crate controller ; register transfers ; ; Inputs: ; ; r4 - CC3922 CSR address ; r5 - UCB address of unit ; ; Output: ; ; All 11 registers of 3922 will be stored into UCB. ; ; r0,r1 - destroyed. all other registers preserved. ;-- CB_REGISTER: movzwl #SS$_NORMAL,R0 ; ASSUME SUCCESS movzwl CB_CSR(r4),r1 ; Read CSR movw r1,UCB$W_CB_CSR(r5) ; Save CSR into UCB movw CB_ERS(r4),UCB$W_CB_ERS(r5) ; Save ERS register movw CB_MCR(r4),UCB$W_CB_MCR(r5) ; Save MCR register movw CB_CCR(r4),UCB$W_CB_CCR(r5) ; Save CCR register movw CB_NAF(r4),UCB$W_CB_NAF(r5) ; Save NAF register movw CB_DLR(r4),UCB$W_CB_DLR(r5) ; Save DLR register movw CB_DHR(r4),UCB$W_CB_DHR(r5) ; Save DHR register movw CB_SRR(r4),UCB$W_CB_SRR(r5) ; Save SRR register movw CB_WCR(r4),UCB$W_CB_WCR(r5) ; Save WCR register movw CB_MAR(r4),UCB$W_CB_MAR(r5) ; Save MAR register movw CB_EMA(r4),UCB$W_CB_EMA(r5) ; Save EMA register tstw r1 ; TEST error bit bgtr 56$ ; No DMA error movzwl #SS$_DRVERR,r0 ; Assume deiver error 56$: movw r0,UCB$W_CB_ERROR(r5) ; Save status in UCB rsb ;++ ; CB_ REGDUMP - 3922 resister dump routine ; ; This routine is called to save the controller register in a specified ; buffer. It is called form the device error logging routine and from the ; diagnostic buffer fill routine ; ; Inputs: ; ; r0 - Address of the resister save buffer ; r4 - Address of the Control and Statsu register ; r5 - Address of UCB ; ; Output: ; ; The Controller registers are saved in the specified buffer. ; ; CSRTMP - The last CSR image ; FNATMP - The last FNA image ; CSR - The last CSR image at the last interrupt ; ; ERROR - The system statsu at request completion ; PDRN - UBA dat-path-register nimber ; DPR - The content of the UBA data-path register ; FMPR - The content of the last UBA Map register ; PMPR - The content of the previous UBA map register ; DPRF - Flag for purge-data-path error ; 0 = no purge-date-path error ; 1 = parity error during ehen data path was purged ; ; Note that the values stored are from the last completed transfer ; operation. ;-- CB_REGDUMP: movzbl #23,(r0)+ ; 17 resisgers movab UCB$W_CB_CSRTMP(r5),r1 ; saved CSR movzbl #19,r2 ; 13 resistes 10$: movzwl (r1)+,(r0)+ ; copy image of the register sobgtr r2,10$ ; movzbl UCB$W_CB_DPRN(r5),(r0)+ ; Save data-path register number movzbl #3,r2 ; and three more here 20$: movl (r1)+,(r0)+ ; sobgtr r2,20$ ; movzbl UCB$W_CB_DPRN+1(r5),(r0)+ ; Save data-path-parity error flag rsb .page .sbttl CB_DEV_RESET ;++ ; CB_DEV_RESET - Kinetic 3922 (CAMAC) Reset routine ; ; This routine reset the 3922 interface ; ; Input: ; ; R4 - Address of the control and status resister ; R5 - Address of UCB ; ; Output ; ; controller is reset, controller interupt are disabled. ; --------- ;-- ; .list me CB_DEV_RESET: pushr #^M ; save some resister ; DSBINT,ENVIRON=UNIPROCESSOR ; Raise IPL to lock all interupts ; 90/04/28 for symm. multi CPU support DEVICELOCK- ; Secure device lock LOCKADDR=UCB$L_DLCK(r5),- ; (also raised IPL to device IPL) SAVIPL=-(SP),- ; Save Current IPL PRESERVE=NO ; Don't Preserver R0 clrw CB_CSR(r4) ; Clear 3920-2920 Control/status reg. bisw #CB_CSR_RST,CB_CSR(r4) ; Initialize camac crate interface timedwait time=#CB_RESET_DELAY ; Reset time delay ; enbint ; Reenable devce interupts ; 90/04/28 sym muti-cpu support DEVICEUNLOCK - ; Relese Device lock LOCKADDR=UCB$L_DLCK(R5),- ; NEWIPL=(SP)+,- ; PRESERVE=NO ; Don't Preserver R0 popr #^M ; Restore resisters rsb ; CB_END: ; END of driver label .end