CONTENTS Title Page Copyright Page Preface Part I The VMS Device Driver Environment 1 Introduction to Device Drivers 1.1 Driver Functions 1.2 Driver Components 1.2.1 Driver Tables 1.2.2 Driver Routines 1.3 The I/O Database 1.3.1 Driver Tables 1.3.2 Data Structures 1.3.3 I/O Request Packets 1.4 Synchronization of Driver Activity 1.5 Driver Context 1.5.1 Example of Driver Context-Switching 1.6 Hardware Considerations 1.6.1 Driver Dependency on VAX Processing Systems 1.6.1.1 VAX-11/780, VAX-11/785, and VAX 8600/8650 Systems 1.6.1.2 The VAX-11/750 System 1.6.1.3 The VAX-11/730 System 1.6.1.4 VAX 82 x 0/83 x 0, VAX 85 x 0/8700/88 x 0, and VAX 6000-Series Systems 1.6.1.5 The VAX 9000 Series System 1.6.1.6 The MicroVAX 3400/3600/3900 Series, MicroVAX/VAXstation II, and VAX 4000 Series Systems 1.6.1.7 The MicroVAX/VAXstation 3100 and VAXstation 3520/3540 Systems 1.7 Programmed-I/O and Direct-Memory-Access Transfers 1.7.1 Programmed I/O 1.7.2 Direct-Memory-Access I/O 1.8 Buffered and Direct I/O 1.9 Example of an I/O Request 2 Discussion of a $QIO Request 2.1 Driver Code for the LP11 Write Function 2.2 A User Process I/O Request 2.3 Device-Independent I/O Preprocessing by VMS 2.4 Device-Dependent I/O Preprocessing by the Driver 2.5 Queuing the I/O Request Packet to the Driver 2.6 Activating the Printer 2.7 Waiting for a Device Interrupt 2.8 Handling Interrupts 2.9 I/O Postprocessing by the Driver 2.10 I/O Postprocessing by VMS 3 Synchronization of I/O Request Processing 3.1 Interrupt Priority Levels 3.1.1 Interrupt Service Routines 3.1.2 IPL Use During I/O Processing 3.1.2.1 IPL 2 (IPL$_ASTDEL) 3.1.2.2 IPL 4 (IPL$_IOPOST) 3.1.2.3 IPL 8 to IPL 11 (Fork IPLs) 3.1.2.4 IPL 20 to IPL 23 (Device IPLs) 3.1.2.5 IPL 31 (IPL$_POWER) 3.1.3 Additional IPLs 3.1.3.1 IPL 3 (IPL$_RESCHED) 3.1.3.2 IPL 6 (IPL$_QUEUEAST) 3.1.3.3 IPL 7 (IPL$_TIMERFORK) 3.1.3.4 IPL 8 (IPL$_SYNCH) 3.1.3.5 IPL 11 (IPL$_MAILBOX) 3.1.3.6 IPL 14 (XDELTA Entry IPL) 3.1.3.7 IPL 22 or IPL 24 (Interval Clock IPLs) 3.1.4 Modifying IPL in Driver Code 3.1.4.1 Raising IPL 3.1.4.2 Lowering IPL 3.2 Spin Locks 3.2.1 Fork Locks 3.2.2 Device Locks 3.3 Device Driver Synchronization 3.3.1 Overview of the Synchronization of an I/O Operation 3.3.2 Synchronizing the Device Database 3.3.3 Synchronizing at Driver Fork Level 3.3.3.1 Forking and the VMS Fork Dispatcher 3.3.3.2 Restrictions on Fork Processes 3.4 Resource Wait Queues 3.4.1 Competing for a Controller's Data Channel 4 Overview of I/O Processing 4.1 Preprocessing an I/O Request 4.1.1 Process I/O Channel Assignment 4.1.2 Locating a Device Driver in the I/O Database 4.1.2.1 Channel Request Block 4.1.2.2 Interrupt Dispatch Block 4.1.2.3 Device Data Block 4.1.3 Validating the I/O Function 4.1.4 Checking Process I/O Request Quotas 4.1.5 Validating the I/O Status Block 4.1.6 Allocating and Setting Up an I/O Request Packet 4.1.7 FDT Processing 4.2 Handling Device Activity 4.2.1 Creating a Driver Fork Process to Start I/O 4.2.2 Activating a Device and Waiting for an Interrupt 4.2.3 Handling a Device Interrupt 4.2.4 Switching from Interrupt to Fork Process Context 4.2.5 Activating a Fork Process from a Fork Queue 4.3 Completing an I/O Request 4.3.1 I/O Postprocessing Part II Writing a Device Driver 5 Device Driver Coding Format 5.1 Coding Conventions 5.2 Restrictions on the Use of Device-Register I/O Space 5.3 Implementing Conditional Code in a Driver 6 Writing Device-Driver Tables 6.1 Driver Prologue Table 6.2 Driver Dispatch Table 6.3 Function Decision Table 6.3.1 Defining Buffered-I/O Functions 6.3.2 Defining Device-Specific Function Codes 7 Writing FDT Routines 7.1 Context of FDT Routine Execution 7.2 FDT Routines and Their Exit Paths 7.2.1 FDT Exit Paths 7.2.1.1 RSB 7.2.1.2 JMP G^EXE$QIODRVPKT 7.2.1.3 JMP G^EXE$FINISHIO or JMP G^EXE$FINISHIOC 7.2.1.4 JMP G^EXE$ABORTIO 7.2.1.5 JSB G^EXE$ALTQUEPKT 7.3 FDT Routines for VMS Direct I/O 7.4 FDT Routines for VMS Buffered I/O 7.4.1 Checking Accessibility of the User's Buffer 7.4.2 Allocating the System Buffer 7.4.3 Buffered-I/O Postprocessing 7.5 FDT Routines Provided by VMS 8 Writing a Start-I/O Routine 8.1 Transferring Control to the Start-I/O Routine 8.2 Context of a Driver Fork Process 8.3 Functions of a Start-I/O Routine 8.3.1 Obtaining Controller Access 8.3.2 Obtaining and Converting the I/O Function Code and Its Modifiers 8.3.3 Preparing the Device Activation Bit Mask 8.3.4 Synchronizing Access to the Device Database 8.3.5 Checking for a Local Processor Power Failure 8.3.6 Activating the Device 8.4 Waiting for an Interrupt or Timeout 8.4.1 Expansion of WFIKPCH Macro 8.4.2 IOC$WFIKPCH Routine 9 Writing an Interrupt Service Routine 9.1 Interrupt Context 9.2 Servicing a Solicited Interrupt 9.3 Servicing an Unsolicited Interrupt 9.3.1 Examples of Unsolicited Interrupts 10 Completing an I/O Request and Handling Timeouts 10.1 I/O Postprocessing 10.1.1 EXE$IOFORK 10.1.2 Completing an I/O Request 10.1.2.1 Releasing the Controller 10.1.2.2 Saving Status, Count, and Device-Dependent Status 10.1.2.3 Returning Control to the Operating System 10.2 Timeout Handling Routines 10.2.1 Retrying an I/O Operation 10.2.2 Aborting an I/O Request 10.2.3 Sending a Message to the Operator 11 Other Driver Routines 11.1 Initialization Routines 11.1.1 Controller Initialization Routine 11.1.2 Unit Initialization Routine 11.1.3 Initialization During Driver Loading 11.1.4 Initialization During Recovery from a Power Failure 11.1.5 Forking from a Driver Initialization Routine 11.2 Cancel-I/O Routine 11.2.1 Context of a Cancel-I/O Routine 11.2.2 Drivers That Need No Cancel-I/O Routine 11.2.3 Device-Independent Cancel-I/O Routine 11.2.4 Device-Dependent Cancel-I/O Routine 11.3 Error Logging Routines 11.3.1 Error Logging Routines Supplied by VMS 11.3.2 Register Dumping Routine 11.3.3 Interpreting Error Log Entries 11.4 Cloned UCB Routine Part III Loading and Debugging a Driver 12 Loading a Device Driver 12.1 Preparing a Driver for Loading into the Operating System 12.2 Loading a Driver 12.2.1 LOAD Command 12.2.2 CONNECT Command 12.2.3 RELOAD Command 12.2.4 SHOW/ADAPTER Command 12.2.5 SHOW/BI Command 12.2.6 SHOW/BUS Command 12.2.7 SHOW/XMI Command 12.2.8 SHOW/CONFIGURATION Command 12.2.9 SHOW/DEVICE Command 12.3 Loading Uniprocessing and Multiprocessing Drivers 12.4 The SYSGEN Autoconfiguration Facility 12.4.1 SYSGEN Device Table 12.4.2 Device Driver Control of Autoconfiguration 12.4.3 Floating-Vector Address Calculation 12.4.4 Floating-CSR Address Calculation 12.4.5 Rules for Configuration 13 Debugging a Device Driver 13.1 Bootstrapping the System with XDELTA 13.2 Proceeding from the Initial Breakpoints 13.3 Loading the Driver 13.4 Inserting Breakpoints in Driver Source Code 13.5 Calculating the Base of Driver Code 13.6 Requesting an XDELTA Software Interrupt 13.7 Examining the Vector-Jump Table 13.8 Setting an XDELTA Base Register 13.9 Examining the UCB, IRP, or PSL 13.10 XDELTA Commands 13.10.1 Values and Expressions 13.10.2 Special Symbols 13.10.2.1 Stored Base Registers 13.10.2.2 Stored Command Strings 13.10.2.3 Setting Base Registers 13.10.3 Display Names and Locations of Loaded Executive Images 13.10.4 Set Display Mode 13.10.5 Open, Examine, and Close Location 13.10.5.1 Open and Display Value Command 13.10.5.2 Display Instruction Command 13.10.5.3 Close and Display Next Location Command 13.10.5.4 Display Range Command 13.10.5.5 Indirect Command 13.10.5.6 Display Previous Location Command 13.10.6 Breakpoints 13.10.6.1 Setting Breakpoints 13.10.6.2 Clearing Breakpoints 13.10.6.3 Displaying Breakpoint List 13.10.6.4 Proceeding from Breakpoints 13.10.6.5 Setting Complex Breakpoints 13.10.7 Step, Set Location, and Execute Instruction Commands 13.10.7.1 Loading PC and Continuing 13.10.7.2 Execute Instruction and Step Command 13.10.7.3 Step Instruction over Subroutine Command 13.10.8 Execute String Command 13.10.8.1 Locating Nonpaged System Patch Space 13.11 Guidelines for Debugging Device Drivers 13.11.1 Opening Device Registers in XDELTA 13.11.2 Adjusting the Device Timeout Value 13.11.3 XDELTA and System Failures 13.12 Common Driver Errors 13.12.1 References to System Addresses 13.12.2 Incorrect References to Device Registers 13.12.3 Destroying Register Contents 13.13 Pool Checking Mechanism 13.14 Detecting Driver Problems in a Multiprocessing System Part IV Bus Specifics and Advanced Topics 14 UNIBUS and Q22 Bus Device Support 14.1 Functions of the UNIBUS Adapter and Q22 Bus Interface 14.1.1 Reading and Writing Device Registers 14.1.2 Map Registers 14.1.3 UNIBUS Adapter Data Transfer Paths 14.1.3.1 Direct Data Path 14.1.3.2 Buffered Data Paths 14.1.3.3 Byte-Offset Data Transfers 14.1.3.4 Purging a Buffered Data Path 14.1.3.5 Longword-Aligned, 32-Bit, Random-Access Mode 14.2 Writing Driver Code for UNIBUS/Q22 Bus DMA Transfers 14.2.1 Selecting and Requesting a Data Path 14.2.1.1 Requesting a Buffered Data Path 14.2.1.2 Requesting a Permanent Buffered Data Path 14.2.1.3 Requesting the Direct Data Path 14.2.1.4 Mixed Use of Direct and Buffered Data Paths 14.2.2 Requesting Map Registers 14.2.2.1 Allocating Map Registers 14.2.2.2 Permanently Allocating Map Registers 14.2.3 Loading Map Registers 14.2.4 Computing the Starting Address of a Transfer 14.2.5 Computing the Transfer Length 14.2.6 Activating the Device 14.2.7 Completing a DMA Transfer 14.2.7.1 Purging the Data Path 14.2.7.2 Releasing a Buffered Data Path 14.2.7.3 Releasing Map Registers 14.3 Interrupt Dispatching in a UNIBUS/Q22 Bus System 14.3.1 Direct-Vector and Non-Direct-Vector Interrupt Dispatching 14.3.2 Adapter Dispatch Table 14.3.3 Interrupt Transfer Vector and Interrupt Transfer Routine 14.3.4 Multilevel Device Interrupt Dispatching for Q22 Bus Devices 14.3.4.1 Ensuring That the Q22 Bus Is Properly Configured 14.3.4.2 Effects of Enabling Multilevel Device Interrupt Dispatching 15 MASSBUS Device Support 15.1 MASSBUS Adapter Registers 15.1.1 Loading MASSBUS Adapter Registers 15.1.2 MASSBUS Adapter Registers and Offsets 15.1.3 Modifying MASSBUS Adapter Registers 15.2 I/O Database for MASSBUS Devices 15.3 MASSBUS Adapter Operations 15.4 MASSBUS Adapter's Interrupt Dispatching 15.4.1 Checking for MASSBUS Adapter Ownership 15.4.2 Dispatching a Device Interrupt 15.5 Special Considerations for MASSBUS Device Drivers 15.5.1 Unit Initialization Routine 15.5.2 The MASSBUS Adapter and the I/O Database 15.5.3 Start-I/O Routine 15.5.3.1 Requesting Controller Data Channels 15.5.3.2 Loading Map Registers 15.5.3.3 Releasing Controller Data Channels 15.5.4 DPTAB Macro 15.6 Interrupt Service Routines for MASSBUS Devices 15.6.1 Transferring Control to the Interrupt Service Routine 15.6.2 Returning Control to MBA$INT 15.6.3 Considerations for Interrupt Service Routines 16 Generic VAXBI Device Support 16.1 Overview 16.2 VAXBI Concepts 16.2.1 VAXBI Address Space 16.2.2 Backplane Interconnect Interface Chip (BIIC) 16.3 SCU/XMI Concepts 16.4 Initialization Performed by VMS 16.4.1 Data Structures 16.4.2 System Control Block 16.5 Initialization Performed by the VAXBI Device Driver 16.5.1 Examining BIIC Self-Test Status 16.5.2 Clearing BIIC Errors, Setting Interrupts, and Enabling Interrupts 16.5.2.1 Clearing the Bus Error Register 16.5.2.2 Loading the Interrupt Destination Register 16.5.2.3 Setting Interrupt Vectors 16.5.2.4 Enabling Error Interrupts 16.5.2.5 Enabling BIIC Options 16.5.3 Mapping Window Space 16.6 DMA Transfers 16.6.1 Example: DMB32 Asynchronous/Synchronous Multiplexer 16.7 Unit Initialization Routine 16.8 Register Dumping Routine 16.9 Loading a VAXBI Device Driver 16.10 BIIC Register Definitions 17 SCSI Class Driver Support 17.1 VAX Systems with SCSI Bus Concepts 17.2 SCSI Class/Port Architecture 17.2.1 SCSI Port Interface 17.2.2 SCSI-Specific Data Structures 17.2.3 SCSI Class Driver Template 17.3 Connecting to a SCSI Device 17.4 Setting Up a SCSI Command 17.4.1 Preparing a SCSI Command Descriptor Block 17.4.2 Setting Command Timeouts 17.4.3 Disabling Command Retry 17.5 Performing a SCSI Data Transfer 17.5.1 Setting the Data Transfer Mode 17.5.2 Enabling Disconnection and Reselection 17.5.3 Determining the Maximum Data Transfer Size 17.5.4 Initializing the SCDRP to Reflect Class Driver Data Buffering Mechanisms 17.5.5 Making a Class Driver Data Buffer Accessible to the Port 17.5.6 Examining Port and SCSI Status 17.5.6.1 Examining Port Status 17.5.6.2 Examining the SCSI Status Byte 17.5.6.3 Testing for Incomplete Transfers 17.6 Other SCSI Class Driver Issues 17.6.1 Preserving Local Context 17.6.2 Error Logging 17.7 Flow of a Read I/O Request Through the SCSI Class and Port Drivers 17.8 Components of a SCSI Class Driver 17.8.1 Data Definitions 17.8.2 Driver Prologue Table 17.8.3 Driver Dispatch Table 17.8.4 Function Decision Table and FDT Routines 17.8.5 Controller Initialization Routine 17.8.6 Unit Initialization Routine 17.8.7 Start-I/O Routine 17.8.8 Cancel-I/O Routine 17.8.9 Register Dumping Routine 17.9 Servicing Asynchronous Events from a SCSI Device 17.10 Configuring a SCSI Third-Party Device 17.10.1 Disabling the Autoconfiguration of a SCSI Device 17.11 Debugging a SCSI Class Driver 17.11.1 Selecting a SCSI Bus Analyzer 17.11.2 Interpreting SCSI Error Log Entries 17.11.2.1 SCSI Port Driver Error Log Entries 17.11.2.2 SCSI Class Driver Error Log Entries 17.12 Resolving SCSI Class Driver Problems Using Error Logs 18 Terminal Class and Port Drivers 18.1 Overview 18.2 Data Structures 18.2.1 Terminal UCB 18.2.2 Port Driver Vector Table 18.2.3 Class Driver Vector Table 18.2.4 Vector Table Generation Macros 18.2.4.1 $VECINI Macro 18.2.4.2 $VEC Macro 18.2.4.3 $VECEND Macro 18.3 Structure of Port and Class Drivers 18.3.1 Binding Class and Port Drivers 18.4 Port Driver Routines 18.4.1 Port Startup Routines 18.4.1.1 Controller Initialization Routine 18.4.1.2 Unit Initialization Routine 18.4.2 Port Initiate Routines 18.4.2.1 PORT_DISCONNECT 18.4.2.2 PORT_DS_SET 18.4.2.3 PORT_FDT 18.4.2.4 PORT_FORKRET 18.4.2.5 PORT_MAINT 18.4.2.6 PORT_SET_LINE 18.4.2.7 PORT_SET_MODEM 18.4.2.8 PORT_STARTIO 18.4.3 Port Service Routines 18.4.3.1 PORT_ABORT 18.4.3.2 PORT_CANCEL 18.4.3.3 PORT_RESUME 18.4.3.4 PORT_STOP 18.4.3.5 PORT_XOFF 18.4.3.6 PORT_XON 18.4.3.7 Port Interrupt Service Routines 18.5 Class Driver Routines 18.5.1 CLASS_DDT 18.5.2 CLASS_DISCONNECT 18.5.3 CLASS_DS_TRANS 18.5.4 CLASS_FORK 18.5.5 CLASS_GETNXT 18.5.6 CLASS_PUTNXT 18.5.7 CLASS_SETUP_UCB 18.5.8 CLASS_POWERFAIL 18.5.9 CLASS_READERROR 19 VMEbus Device Driver Support 19.1 Hardware Environment 19.2 Selecting VMEbus Protocol Parameters 19.3 Considering Byte Order Transfer Differences 19.4 Handling Interrupts 19.5 DMA Operations 19.6 Programmed I/O Operations and I/O Mapping 19.7 Coding a VMEbus Device Driver 19.7.1 Porting from UNIX System-Based Drivers 19.8 Assembling and Linking a VMEbus Driver 19.9 Loading a VME Device Driver 20 Mapping to I/O Space and the Connect-to-Interrupt Facility 20.1 I/O Address Space 20.2 PFN Mapping 20.2.1 Notes on PFN Mapping 20.3 Connecting to an Interrupt Vector 20.3.1 Performing the Connect-to-Interrupt 20.3.2 $QIO Connect-to-Interrupt Request to Driver 20.3.3 The Connect-to-Interrupt Driver (CONINTERR.EXE) 20.3.4 Process-Specified Routines 20.3.4.1 Unit Initialization Routine 20.3.4.2 Start-I/O Routine 20.3.4.3 Interrupt Service Routine 20.3.4.4 Cancel-I/O Routine 20.3.5 AST Procedure 20.4 Real-Time Applications Examples 20.4.1 Example 1: KW11-W Watchdog Timer 20.4.2 Example 2: AD11-K, AM11-K A/D Converter with Multiplexer Connected to the UNIBUS 20.4.3 Example 3: KW11-P Real-Time Clock and AD11-K Converter Connected to the UNIBUS Part V Driver Templates and Examples A VMS Driver Template B VMS SCSI Class Driver Template C Sample Driver for the RL11, RL01, and RL02 Disk Drives D Sample Driver for the DR11-W and DRV11-WA Interfaces E Sample Driver for a VMEbus DR11-W Interface F Multiprocessing Requirements on Kernel-Mode Code F.1 Uniprocessor and Multiprocessor Device Drivers F.1.1 MULTIPROCESSING System Parameter F.1.2 Device Driver Loading F.1.3 VMS Synchronization Macros F.2 Changes Required to Drivers Written Before VMS Version 5.0 F.2.1 Address of the Driver's Interrupt Service Routine in the DPT F.2.2 Checking, Debiting, and Crediting a Process's Byte Count Quota F.2.3 Referring to the Current PCB F.2.4 Allocating System Page-Table Entries F.2.5 Referring to a System Process Mailbox F.2.6 Reassembling and Relinking the Driver F.3 Adapting Device Drivers to Run on a VMS Multiprocessing System F.3.1 Specifying the Fork Lock Index F.3.2 Synchronizing Access to the Device Database with the Interrupt Service Routine F.3.2.1 Synchronizing at Device IPL F.3.2.2 Raising IPL to IPL$_POWER F.3.2.3 Synchronization Within the Interrupt Service Routine F.3.3 Controller and Unit Initialization Routines F.3.3.1 Permanently Allocating Map Registers and Buffered Data Paths F.3.4 Timeout Handling Routine F.3.5 General Methods for Synchronizing Kernel-Mode Code F.3.5.1 Using the Spin Lock Synchronization Macros F.3.5.2 Interlocking Access to Data Cells and Queues F.3.6 Miscellaneous Conversion Tasks F.3.6.1 Reading the System Time F.3.6.2 Calling the Driver Fork Process from a TQE F.3.6.3 Invalidating Translation Buffer Entries F.3.6.4 Unsupported Use of the IRP F.3.6.5 Poor Man's Lockdown F.3.7 Troubleshooting a Device Driver in a Multiprocessing System F.3.7.1 Multiprocessing Bugchecks F.3.7.2 Analyzing a Multiprocessing System Failure F.3.7.2.1 Investigating the Status of Spin Locks F.3.7.3 Using XDELTA on SMP Systems Glossary ACF . . . AST ASTLVL . . . bugcheck busy wait . . . connection connect-to-interrupt . . . DDT device affinity . . . direct-memory-access (DMA) transfer DPT . . . FDT routines fork block . . . IDB Initiator . . . I/O function code I/O function modifier . . . load balancing locking a page in memory . . . multiprogramming nexus . . . PID port . . . process priority program section (psect) . . . SCSI SCSI class driver . . . Small Computer System Interface small process . . . symmetric multiprocessing (SMP) synchronous backplane interconnect (SBI) . . . unit initialization routine urgent interrupt . . . XQP EXAMPLES 9-1 Example of an Unsolicited Interrupt 13-1 Loading a Driver 17-1 SCSI Bus Phase Error Port Driver Error Log Entry 17-2 SCSI Bus Reset Port Driver Error Log Entry 17-3 SCSI Bus Reset Class Driver Error Log Entry 19-1 Using the SHOW/ADAPTER Command 19-2 Using the SHOW/BUS Command 19-3 Loading a Driver with the CONNECT Command 20-1 Locating the Adapter Address Space of a UNIBUS Adapter on a VAXBI Bus FIGURES 1-1 The I/O Database 1-2 SBI-Based System Configurations 1-3 VAXBI-Based System Configurations 1-4 SCU/XMI-Based Systems Architecture 1-5 Q22 Bus Based Systems 1-6 MicroVAX/VAXstation 3100 System Architecture 1-7 VAXstation 3520/3540 System Architecture 1-8 Example of I/O Request Processing 2-1 A Printer Write Function 3-1 Synchronizing I/O Request Processing 3-2 Synchronizing I/O Request Completion 3-3 Processor-Specific Fork Queue Structure 4-1 Sequence of Driver Execution 4-2 Detailed Sequence of VMS I/O Processing 4-3 Data Structures for Three Devices on One Controller 4-4 I/O Database for Two Controllers 4-5 Layout of a Function Decision Table 4-6 FDT Routines and I/O Preprocessing 4-7 Creating a Fork Process After an Interrupt 4-8 Reactivation of a Driver Fork Process 5-1 Driver Organization 7-1 $QIO Scan of a Function Decision Table 7-2 Format of System Buffer for a Buffered-I/O Read Function 8-1 Inserting a UCB into the Channel Wait Queue 9-1 Flow of Interrupt Servicing 13-1 Format of the POOLCHECK System Parameter 13-2 Poisoned Pool Packet 14-1 UNIBUS and Q22 Bus Map Registers 14-2 Mapping a UNIBUS Address to a Physical Address 14-3 Mapping a Q22 Bus Address to a Physical Address 14-4 UNIBUS Data Path Registers 14-5 Direct-Vector Interrupt Dispatching 14-6 Non-Direct-Vector Interrupt Dispatching 14-7 VEC Structures Within a CRB 14-8 Interrupt Transfer Vector Block (VEC) 15-1 MASSBUS Configuration 15-2 MASSBUS External-Register Longword 15-3 Location of MASSBUS Registers in Physical Address Space 15-4 I/O Database for MASSBUS Disk Unit 15-5 I/O Database for MASSBUS Disk and Tape Units 15-6 I/O Data Structures Used in Dispatching a MASSBUS Device Interrupt 16-1 VAXBI Address Space 16-2 Description of VAXBI I/O Address Space 16-3 Physical Addresses in VAXBI I/O Address Space 16-4 SCU/XMI Systems I/O Address Space 16-5 VAXBI Device Vectors 16-6 Backplane Interconnect Interface Chip (BIIC) Registers 17-1 VMS SCSI Class/Port Interface 17-2 VMS SCSI Port Driver Configuration 17-3 VMS SCSI Class Driver Configuration 17-4 SCSI Class/Port Data Structures 17-5 SCSI_NOAUTO System Parameter 18-1 UCB Structure for Terminal Class/Port Drivers 18-2 Port Driver Vector Table 18-3 Class Driver Vector Table 18-4 Port Driver Structure 18-5 Class Driver Structure 18-6 Terminal Class/Port Driver Binding 19-1 XMI/VME Bus-Based System 19-2 Little-Endian Versus Big-Endian Byte Alignment 19-3 VMEbus DMA to and from VAX Host 19-4 VMEbus Map Register 19-5 Mapping of Programmed I/O Access from User Space 20-1 Format of a Physical Address TABLES 3-1 IPLs Defined by VMS 3-2 VMS Macros That Change a Processor IPL 3-3 Static Spin Locks 4-1 IRP Data Fields 6-1 I/O Function Codes 7-1 Registers Loaded by the $QIO System Service 7-2 FDT Routines Provided by VMS 11-1 Input for Cloned UCB Routine 12-1 Conventional Nexus Assignments 12-2 SYSGEN Device Table 13-1 Boot Flags That Control the Loading of XDELTA 13-2 Recommended Methods for Bootstrapping with XDELTA 13-3 Requesting an XDELTA Software Interrupt 13-4 XDELTA Command Summary 13-5 POOLCHECK Parameter Flag Bit Definitions 13-6 POOLCHECK Bugcheck Longword Reasons 13-7 Relevant Registers to a Corrupt Packet Bugcheck 13-8 Settings of MULTIPROCESSING System Parameter 13-9 Bugchecks Produced by Full-Checking Multiprocessing 14-1 Features of the UNIBUS Adapters/Q22 Bus Interfaces of VAX Systems 14-2 VAX System UNIBUS/Q22 Bus Interrupt Dispatching 15-1 Major Offsets Defined by $MBADEF 16-1 Contents of the BIIC Registers 17-1 SCSI Port Interface (SPI) Macros 17-2 Data Structures 17-3 Initialized SCDRP Fields for a Process Buffer 17-4 Initialized SCDRP Fields for a System Buffer 17-5 Initialized SCDRP Fields from SPI$MAP_BUFFER 17-6 Port Driver Return Status in R0 17-7 SCSI Status Byte Format 17-8 Error Message Buffer Extension for SCSI Class Drivers 17-9 SPI Extension Macros Supporting Asynchronous Event Notification 17-10 Key to Port Driver Error Log Entries 17-11 Key to Class Driver Error Log Entries 18-1 Initialized UCB Fields from CLASS_UNIT_INIT Routine 18-2 Port Driver Routines 18-3 Class Driver Routines 19-1 Mapped defaults for XMI and VME Interrupt Request Levels 19-2 Driver Entry Point Routines 19-3 Driver Notions Porting from UNIX to VMS 20-1 Symbols Defined by the $IO xxx DEF Macros 20-2 UNIBUS and Q22 Bus Adapter Address Space 20-3 Section Type Flag Bits E-1 DR11-W VME Driver Code Contents F-1 VMS Synchronization Images F-2 Settings of MULTIPROCESSING System Parameter F-3 Converting IPL Synchronization to Spin Lock Synchronization