.IDENT 'X-01' ; ;**************************************************************************** ;* * ;* COPYRIGHT (c) 1990 BY * ;* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. * ;* ALL RIGHTS RESERVED. * ;* * ;* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED * ;* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE * ;* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER * ;* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY * ;* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY * ;* TRANSFERRED. * ;* * ;* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE * ;* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT * ;* CORPORATION. * ;* * ;* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS * ;* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. * ;* * ;* * ;**************************************************************************** ; ;++ ; ; FACILITY: ; ; VAX/VMS Executive, I/O Drivers ; ; ABSTRACT: ; ; This module contains the driver to map VME memory. ; ; ENVIRONMENT: ; ; Kernel Mode, Non-paged ; ; AUTHOR: ; ; Stanley Russell 01-DEC-1990 ; ; ;-- .SBTTL External and local symbol definitions ; External symbols $ACBDEF ; AST control block $ADPDEF ; Adapter control block $CRBDEF ; Channel request block $DCDEF ; Device types $DDBDEF ; Device data block $DEVDEF ; Device characteristics $DPTDEF ; Driver prolog table $DYNDEF ; Dynamic data structure types $EMBDEF ; EMB offsets $IDBDEF ; Interrupt data block $IO9CCDEF ; Define Calypso/CVAX memory layout $IO9RRDEF ; Define Calypso/Rigel memory layout $IO1202DEF ; Define Mariah memory layout $IO1302DEF ; Define Neptune memory layout $IODEF ; I/O function codes $IPLDEF ; Hardware IPL definitions $IRPDEF ; I/O request packet $PRDEF ; Internal processor registers $PRIDEF ; Scheduler priority increments $PTEDEF ; PTE definitions $SSDEF ; System status codes $UCBDEF ; Unit control block $VECDEF ; Interrupt vector block $XADEF ; Define device specific characteristics ; $XVIBDEF ; VME definitions ; Local symbols ; Argument list (AP) offsets for device-dependent QIO parameters P1 = 0 ; First QIO parameter P2 = 4 ; Second QIO parameter P3 = 8 ; Third QIO parameter P4 = 12 ; Fourth QIO parameter P5 = 16 ; Fifth QIO parameter P6 = 20 ; Sixth QIO parameter ; Other constants ; DATEL DVME definitions that follow the standard UCB fields $DEFINI UCB .=UCB$L_DPC+4 $DEF UCB$L_MAPDESCR,.LONG UCB$K_SIZE = . $DEFEND UCB .SBTTL Device Driver Tables ; Driver prologue table DPTAB - ; DPT-creation macro END=QS_END,- ; End of driver label ADAPTER=VME,- ; Adapter type FLAGS=,- ; Allocate system page table UCBSIZE=UCB$K_SIZE,- ; UCB size NAME=QSDRIVER ; Driver name DPT_STORE INIT ; Start of load ; initialization table DPT_STORE UCB,UCB$B_FLCK,B,SPL$C_IOLOCK8 ; Device fork IPL DPT_STORE UCB,UCB$B_DIPL,B,20 ; Device interrupt IPL DPT_STORE UCB,UCB$L_DEVCHAR,L,<- ; Device characteristics DEV$M_AVL> ; Available DPT_STORE UCB,UCB$B_DEVCLASS,B,DC$_REALTIME ; Device class DPT_STORE UCB,UCB$B_DEVTYPE,B,DT$_XVIB ; Device Type DPT_STORE REINIT ; Start of reload ; initialization table DPT_STORE DDB,DDB$L_DDT,D,QS$DDT ; Address of DDT DPT_STORE CRB,CRB$L_INTD+4,D,- ; Address of interrupt QS_INTERRUPT ; service routine DPT_STORE CRB,CRB$L_INTD+VEC$L_UNITINIT,-; Unit init. D,QS_UNIT_INIT ; DPT_STORE CRB,CRB$L_INTD+VEC$L_INITIAL,-; Address of controller D,QS_CONTROL_INIT ; initialization routine DPT_STORE END ; End of initialization ; tables ; Driver dispatch table DDTAB - ; DDT-creation macro DEVNAM=QS,- ; Name of device START=QS_START,- ; Start I/O routine FUNCTB=QS_FUNCTABLE,- ; FDT address CANCEL=QS_CANCEL ; Cancel I/O routine ; ; Function dispatch table ; QS_FUNCTABLE: ; FDT for driver FUNCTAB ,- ; Valid I/O functions FUNCTAB , ; No buffered functions FUNCTAB QS_FDT_DEACCESS, FUNCTAB QS_FDT_INITIALIZE, .SBTTL QS_CONTROL_INIT, Controller initialization ;++ ; QS_CONTROL_INIT, Called when driver is loaded, system is booted, or ; power failure recovery. ; ; Functional Description: ; ; Inputs: ; ; R4 = address of CSR ; R5 = address of IDB ; R6 = address of DDB ; R8 = address of CRB ; ; Outputs: ; ; ;-- QS_CONTROL_INIT:: MOVL IDB$L_UCBLST(R5),R0 ; Address of UCB MOVL R0,IDB$L_OWNER(R5) ; Make permanent owner BISW #UCB$M_ONLINE,UCB$W_STS(R0) RSB ; Done QS_UNIT_INIT: BISW #UCB$M_ONLINE,UCB$W_STS(R5) MOVZBL #SS$_NORMAL,R0 RSB .SBTTL DT_FDT_DEACCESS, FDT for Release PIO map regs. ;++ ; QS_FDT_DEACCESS FDT for DEACCESS ; ; Functional description: ; ; 1) This routine will release the current PIO mapping registers that ; have been allocated. ; ; Inputs: ; ; R3 = Address of IRP ; R4 = Address of PCB ; R5 = Address of UCB ; R6 = Address of CCB ; R8 = Address of FDT routine ; AP = Address of P1 ; ; Outputs: ; ; Queued to start IO routine ; ;-- QS_FDT_DEACCESS: JMP G^EXE$QIODRVPKT .SBTTL QS_FDT_INITIALIZE, FDT to allocate the PIO map registers. ;++ ; QS_FDT_INITIALIZE FDT for INITIALIZE ; ; Functional description: ; ; Inputs: ; ; P1 = VME address to map. ; P2 = # of bytes to map. ; P3 = VME access modes. ; R3 = Address of IRP ; R4 = Address of PCB ; R5 = Address of UCB ; R6 = Address of CCB ; R8 = Address of FDT routine ; AP = Address of P1 ; ; Outputs: ; ; Queued to start IO routine ;-- QS_FDT_INITIALIZE: MOVL P1(AP),IRP$L_IOST1(R3) ; Get the VME address. MOVL P3(AP),IRP$L_IOST2(R3) ; Get the Access modes. JMP G^EXE$QIODRVPKT .SBTTL QS_START, Start I/O routines QS_START: MOVW IRP$W_FUNC(R3),- ; Save function code & modifier UCB$W_FUNC(R5) ;+ ; Do final set up and dispatch to the routine which performs the function. ;- EXTZV #IRP$V_FCODE,#IRP$S_FCODE,- ; Extract I/O function code... IRP$W_FUNC(R3),R1 ; ...without function modifiers CMPL #IO$_WRITEPBLK,R1 ; Allocate and load PIO map registers BEQL 10$ ; Branch if allocate CMPL #IO$_DEACCESS,R1 ; Deallocate PIO map registers BEQL 20$ ; Branch if deallocate ; ; If we fall through then we were passed an illegal function code ; MOVZBL #SS$_ILLIOFUNC,R0 ; Specify the error type REQCOM ; ; Come here to allocate and load the PIO mapping registers. We will pass back the ; IO space PFN that corresponds to the first PIO map register allocated. This will ; allow the user to PFN map the mapped VME space into their P0 space ; 10$: PUSHL R3 MOVZBL #1,R3 ; We want 1 PIO map register. BSBW IOC$ALOVMEMAP_PIO ; Allocate a mapping register. BLBC R0,15$ ; Branch if error. MOVL (SP),R2 ; Get a pointer to the IRP MOVL IRP$L_IOST1(R2),R0 ; Get the VME address. MOVL IRP$L_IOST2(R2),R1 ; Get the Access modes. BSBW IOC$LOADVMEMAP_PIO ; Load the mapping registers. BLBC R0,15$ MOVL UCB$L_CRB(R5),R2 ; Get the CRB. MOVW CRB$L_INTD+VEC$W_MAPALT(R2),R1 ; Get the starting map reg #. MOVL CRB$L_INTD+VEC$L_ADP(R2),R2 ; Get our ADP MOVZWL ADP$W_TR(R2),R0 ; Get our node nexus number ASHL #-4,R0,R0 ; Turn into a node id DECL R0 ; Account for node zero MULL3 R0,#IO9CC$C_PERXBI,R0 ; Offset to window space ADDL2 #IO9CC$AL_IOADAP1,R0 ; Now we point to start of PIO map reg IO space MULL #1024*1024,R1 ; Get offset for this map register ADDL R0,R1 ; IO space address mapped to the VME ASHL #-9,R1,R1 ; Determine PFN of this node. BICL #^C,R1 ; Mask only PFN MOVZBL #SS$_NORMAL,R0 ; Set succus status 11$: POPL R3 ; Restore IRP REQCOM ; Return to user 15$: CLRL R0 BRB 11$ ; ; Deallocate the PIO mapping registers ; 20$: BSBW IOC$RELVMEMAP_PIO ; Release the VME PIO map regs. CLRL R1 ; Set return to not released. MOVZWL #SS$_NORMAL,R0 ; Init return to success. REQCOM ; Return to user .SBTTL QS_INTERRUPT, Interrupt service routine. QS_INTERRUPT: JSB G^INI$BRK REI ; Return from interrupt .SBTTL QS_CANCEL, Cancel I/O routine QS_CANCEL: ; Cancel I/O DEVICELOCK - LOCKADDR=UCB$L_DLCK(R5),- ; Lock device access SAVIPL=-(SP),- ; Save current IPL PRESERVE=NO ; Don't preserve R0 ; Check to see if a data transfer request is in progress ; for this process on this channel JSB G^IOC$CANCELIO ; Check if transfer going BBC #UCB$V_CANCEL,- UCB$W_STS(R5),30$ ; Branch if not for this guy ; ; Release resources ; MOVAB UCB$L_MAPDESCR(R5),R2 ; Which ones to deallocate BSBW IOC$RELVMEMAP_PIO ; Release any map registers 30$: DEVICEUNLOCK - LOCKADDR=UCB$L_DLCK(R5),- ; Unlock device access NEWIPL=(SP)+,- ; Enable interrupts PRESERVE=NO RSB ; Return QS_END: ; End of driver label .END