.TITLE ZFDRIVER - Driver for example "File System" ACP .IDENT 'X01-000' ;++ ; ZFDRIVER - Driver for example "File System" ACP ; ; ABSTRACT: ; ; This driver, in conjunction with ZFACP, implements file create, ; write, and file close functions on a mythical file-structured device. ; The driver also supports the IO$_MOUNT and IO$_ACPCONTROL (dismount) ; $QIO functions. ;-- .PAGE .SBTTL External and local symbol definitions ; standard VMS data structures .LIBRARY \SYS$LIBRARY:LIB\ $AQBDEF ; ACP queue block $CANDEF ; Cancel reason codes $CCBDEF ; Channel control block $CRBDEF ; Controller request block $DCDEF ; Device classes and types $DDBDEF ; Device data block $DDTDEF ; Driver dispatch table $DEVDEF ; Device characteristics $DYNDEF ; Data structure ID codes $IDBDEF ; Interrupt data block $IODEF ; I/O function codes $IPLDEF ; Hardware IPL definitions $IRPDEF ; I/O request packet $JIBDEF ; Job information block $PCBDEF ; Process control block $PRDEF ; Processor register names $PRVDEF ; Privilege bits $PSLDEF ; Processor status longword $SPLDEF ; Spinlock definitions $SSDEF ; System status codes $UCBDEF ; Unit control block $VCBDEF ; Volume control block $VECDEF ; Interrupt vector block ; bits in UCB$L_DEVDEPEND $DEFINI UCB _VIELD ZF,0,<> ; file is open $DEFEND UCB ; 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 ; driver/ACP-specific values ZF_K_ACPTYPE = 250 ZF_K_ACPCLASS = 251 .PAGE .SBTTL Standard tables and local storage ; Driver prologue table DPTAB - ; DPT-creation macro END=ZF_END,- ; End of driver label ADAPTER=NULL,- ; Adapter type UCBSIZE=,- ; Length of UCB MAXUNITS=1,- ; Length of UCB vector in IDB NAME=ZFDRIVER,- ; Driver name FLAGS=DPT$M_SMPMOD ; Ok to run in SMP environment DPT_STORE INIT ; load initialization table DPT_STORE DDB,DDB$L_ACPD,L,<^A\ZF\> ; default ACP name DPT_STORE DDB,DDB$B_ACPCLASS,B,- ; ACP class ZF_K_ACPCLASS ; field DPT_STORE UCB,UCB$B_FLCK,B,SPL$C_IOLOCK8; Device fork lock index DPT_STORE UCB,UCB$B_DIPL,B,20 ; Dvc IPL (not really used) DPT_STORE UCB,UCB$L_DEVCHAR,L,<- ; Device characteristics DEV$M_SQD!- ; sequential DEV$M_AVL!- ; available DEV$M_IDV!- ; input device DEV$M_ODV> ; output device DPT_STORE UCB,UCB$B_DEVCLASS,B,255 ; device class DPT_STORE UCB,UCB$B_DEVTYPE,B,255 ; and type DPT_STORE UCB,UCB$L_DEVDEPEND,L,0 ; flags DPT_STORE UCB,UCB$W_DEVBUFSIZ,W,0 ; Default buffer size DPT_STORE REINIT ; reload initialization table DPT_STORE DDB,DDB$L_DDT,D,ZF$DDT ; Address of DDT DPT_STORE CRB,- ; Address of controller CRB$L_INTD+VEC$L_INITIAL,- ; initialization routine D,ZF_CONTROL_INIT DPT_STORE CRB,- ; Address of unit CRB$L_INTD+VEC$L_UNITINIT,- ; initialization routine D,ZF_UNIT_INIT ; routine DPT_STORE END ; End of initialization ; tables ; Driver dispatch table DDTAB - DEVNAM=ZF,- ; Name of device START=ZF_START,- ; Start I/O routine FUNCTB=ZF_FUNCTABLE ; FDT address .PAGE .SBTTL Function Decision Table ZF_FUNCTABLE: FUNCTAB ,- ; Valid I/O functions ; mount and dismount ACP FUNCTAB ,<> ; Buffered I/O functions - none ; function selection masks FUNCTAB FDT_CHECK_LOCK_BUFFER,- ; writes FUNCTAB FDT_QUEUE_TO_DRIVER,- ; writes FUNCTAB FDT_MOUNT, ; mount ACP FUNCTAB FDT_MNTDMT,- ; common for mount and ; dismount funcs FUNCTAB FDT_QUEUE_TO_ACP,- ; mount and dismount ACP .PAGE .SBTTL FDT routines for mount and dismount ;++ ; FDT_MOUNT, FDT routine for mount requests ; ; This routine performs the `mounting' consistency check for the ; MOUNT function. ;-- FDT_MOUNT: MOVZWL #SS$_DEVNOTMOUNT, R0 ; assume sync error BBCCI #UCB$V_MOUNTING, UCB$W_STS(R5),-; br if so ACP_REQ_ERR RSB ;++ ; FDT_MNTDMT, FDT routine for ACP mount and dismount requests ; ; This routine ensures proper context for ACP mount and control requests. ;-- FDT_MNTDMT: MOVZWL #SS$_NOPRIV, R0 ; assume insuff. priv. IFNPRIV MOUNT, ACP_REQ_ERR ; check for MOUNT IFNPRIV OPER, ACP_REQ_ERR ; and OPER privs RSB ;++ ; FDT_QUEUE_TO_ACP, FDT routine to queue IRP to ACP ; ; This routine checks for the existence of a VCB, then queues the IRP to ; the ACP. ;-- FDT_QUEUE_TO_ACP: MOVZWL #SS$_DEVNOTMOUNT, R0 ; assume sync error MOVL UCB$L_VCB(R5), R1 ; get VCB address BEQL ACP_REQ_ERR ; should never happen, but... ADAWI #1, VCB$W_TRANS(R1) ; bump VCB transaction count JMP G^EXE$QIOACPPKT ; queue IRP to ACP ACP_REQ_ERR: JMP G^EXE$ABORTIO .PAGE .SBTTL FDT Routines for data transfer requests ;++ ; FDT_CHECK_LOCK_BUFFER, check user buffer for readability ; (ie for writes to the device) and lock it into physical memory ;-- FDT_CHECK_LOCK_BUFFER: MOVL P1(AP), R0 ; get address of user buffer MOVZWL P2(AP), R1 ; and length JSB G^EXE$WRITELOCK ; probe and lock buffer RSB ;++ ; FDT_QUEUE_TO_DRIVER, queue IRP to driver's start I/O routine ;-- FDT_QUEUE_TO_DRIVER: JMP G^EXE$QIODRVPKT .PAGE .SBTTL ZF_START, Start I/O routine ;++ ; ZF_START - Do a write transfer on the device ; ; Functional description: ; ; Simulates starting and completion of a write transfer on the device. ;-- ZF_START: EXTZV S^#IO$V_FCODE, S^#IO$S_FCODE,- ; get function code from IRP, IRP$W_FUNC(R3), R0 ; ignoring modifier bits CMPL R0, #IO$_CREATE ; is it a "file open" function? BNEQ 10$ ; br if no BBCS #ZF_V_FOPEN,- ; set the file open bit, UCB$L_DEVDEPEND(R5), 100$ ; br if was clear MOVZWL #SS$_FILALRACC, R0 ; trying to open file, but CLRL R1 ; it's already open REQCOM ; if we get here the IRP is a write request, either from the user or ; the ACP (the latter on behalf of a user's file close request). 10$: BBS #ZF_V_FOPEN,- ; br if file UCB$L_DEVDEPEND(R5), 100$ ; is "open" MOVZWL #SS$_FILNOTACC, R0 ; else complete the request CLRL R1 ; with a "file not open" REQCOM ; status 100$: ; (if we were talking to a real device, this is where we ; would start the transfer, WFIKPCH, IOFORK, etc.) CLRL R1 MOVW #SS$_NORMAL, R0 INSV IRP$W_BCNT(R3), #16, #16, R0 REQCOM .PAGE .SBTTL ZF_CONTROL_INIT, Controller initialization routine ;++ ; ZF_CONTROL_INIT, Readies controller for I/O operations ; ; Functional description: ; ; The operating system calls this routine in 2 places: ; during driver loading and reloading ; during recovery from a power failure ; ; Inputs: ; ; R4 - address of the CSR (controller status register) ; R5 - address of the IDB (interrupt data block) ; R6 - address of the DDB (device data block) ; R8 - address of the CRB (channel request block) ; ; Outputs: ; ; The routine must preserve all registers except R0-R3. ; ;-- ZF_CONTROL_INIT: MOVL #SS$_NORMAL, R0 RSB ; return .PAGE .SBTTL ZF_UNIT_INIT, Unit initialization routine ;++ ; ZF_UNIT_INIT, Readies unit for I/O operations ; ; Functional description: ; ; The operating system calls this routine after calling the ; controller initialization routine: ; ; during driver loading (but not reloading) ; during recovery from a power failure ; ; Inputs: ; ; R4 - address of the CSR (controller status register) ; R5 - address of the UCB (unit control block) ; ; Outputs: ; ; Sets the ONLINE bit in the UCB status longword. ; The routine must preserve all registers except R0-R3. ; ;-- ZF_UNIT_INIT: BBSS #UCB$V_ONLINE,UCB$L_STS(R5),10$ ; Set unit online ; if first time, do other initializations 10$: MOVL #SS$_NORMAL, R0 RSB ; Return .PAGE .SBTTL ZF_END, End of driver ;++ ; Label that marks the end of the driver ;-- ZF_END: ; Last location in driver .END