Specifications

Writing a Start-I/O Routine
6.3 Functions of a Start-I/O Routine
If the channel is available, IOC_STD$PRIMITIVE_REQCHANL locates the
interrupt dispatch block (IDB) for the channel with a pointer in the UCB:
UCB CRB IDB
The driver for a unit attached to a dedicated controller must contain the code
needed to load the IDB address into R4.
IOC_STD$PRIMITIVE_REQCHANL also writes the address of the new channel-
owner’s UCB in the owner field of the IDB (IDB$L_OWNER). The drivers
interrupt service routine later reads this IDB field to determine which device unit
owns the controllers data channel. A driver for a single-unit controller must fill
the IDB$L_OWNER field in its controller or unit initialization routines.
6.3.2 Obtaining and Converting the I/O Function Code and Its Modifiers
The start-I/O routine extracts the I/O function code and function modifiers from
the field IRP$_FUNC and translates them into device-specific function codes,
which it loads into the device’s CSR or other control registers. The start-I/O
routine creates and modifies a bit mask that is to be loaded into the CSR when
the driver starts the device. To accomplish this, the start-I/O routine converts the
function modifiers contained in IRP$_FUNC into device-specific bit settings in the
general register.
6.3.3 Preparing the Device Activation Bit Mask
For a typical device, the start-I/O routine prepares the device-activation bit mask
by setting the interrupt-enable bit and the go bit in the general purpose register
that also contains the high-order bits of the bus address and the device-function
bits. At this point, the general register contains a complete command for starting
the transfer, also known as the control mask.
When the start-I/O routine copies the contents of the register into the device’s
CSR, the device starts the transfer. Before activating the device, however, the
start-I/O routine should perform the steps described in Sections 6.3.4 and 6.3.5.
6.3.4 Synchronizing Access to the Device Database
The start-I/O routine invokes the system macro DEVICELOCK to synchronize
its access to device registers with the interrupt service routine. This macro
invocation is doubly important, for it establishes the context wherein the driver
can later issue the wait-for-interrupt macro (WFIKPCH or WFIRLCH). The wait-
for-interrupt macros expect the drivers fork IPL to be on the stack, as placed
there by the DEVICELOCK macro. In addition, the wait-for-interrupt macros
issue the DEVICEUNLOCK macro to release ownership of the device lock and
restore the previous IPL.
6.3.5 Checking for a Local Processor Power Failure
After synchronizing access to device registers, the start-I/O routine invokes the
system macro SETIPL to raise IPL to IPL$_POWER to block all interrupts on the
local processor.
The start-I/O routine then examines the power failure bit in the UCB’s status
longword (UCB$V_POWER in UCB$L_STS) to determine whether a local power
failure has occurred since the start-I/O routine gained control. If the bit is not
set, the transfer can proceed.
6–3