device_driver(3K) SDK R4.11 device_driver(3K)
NAME
devicedriver: devxxxinit, devxxxconfigure, devxxxdeconfigure,
devxxxdevicetoname, devxxxnametodevice, devxxxopen,
devxxxclose, devxxxserviceinterrupt, devxxxreadwrite,
devxxxstartio, devxxxselect, devxxxioctl, devxxxopendump,
devxxxwritedump, devxxxreaddump, devxxxclosedump,
devxxxmaddmap, devxxxmmap, devxxxmunmap, devxxxpowerfail -
implement a device driver
SYNOPSIS
#include "/usr/src/uts/aviion/ii/iio.h"
statustype devxxxclose (
iodevicehandletype devicehandle, READONLY
iochannelflagstype channelflags READONLY )
statustype devxxxclosedump (
iodevicehandletype devicehandle READONLY )
statustype devxxxconfigure (
charptrtype devicenameptr, READONLY
iomajordevicenumbertype majornumber READONLY )
statustype devxxxdeconfigure (
charptrtype devicenameptr READONLY )
statustype devxxxdevicetoname (
iodevicenumbertype devicenumber, READONLY
charptrtype nameptr, WRITEONLY
uint32type size READONLY )
void devxxxinit ()
statustype devxxxioctl (
iodevicehandletype devicehandle, READONLY
bit32etype command, READONLY
bit32etype parameter, READWRITE
int32eptrtype returnvalueptr WRITEONLY )
void devxxxmaddmap (
iodevicehandletype devicehandle, READONLY
opaqueptrtype fileid, READONLY
int32type mmapcountdelta READONLY )
statustype devxxxmmap (
iodevicehandletype devicehandle, READONLY
opaqueptrtype fileid, READONLY
iommaprequestptrtype requestptr, READONLY
iochannelflagstype ioflags, READONLY
byteaddressptrtype startaddressptr WRITEONLY )
statustype devxxxmunmap (
iodevicehandletype devicehandle, READONLY
opaqueptrtype fileid, READONLY
iommaprequestptrtype requestptr, READONLY
byteaddresstype startphysaddr READONLY )
statustype devxxxnametodevice (
charptrtype devicenameptr, READONLY
iodevicenumberptrtype numberptr WRITEONLY )
statustype devxxxopen (
iodevicenumbertype devicenumber, READONLY
iochannelflagstype channelflags, READONLY
iodevicehandleptrtype devicehandleptr WRITEONLY )
statustype devxxxopendump (
charptrtype devicename, READONLY
iodevicehandleptrtype devicehandleptr READONLY )
statustype devxxxpowerfail ()
statustype devxxxreaddump (
iodumprequestinfoptrtype dumprbptr READONLY )
statustype devxxxreadwrite (
iorequestinfoptrtype requestinfoptr READONLY )
void devxxxselect (
iodevicehandletype devicehandle, READONLY
booleantype selectmode, READONLY
vpecptrtype ecptr, READONLY
ioselectintentptrtype intentptr READWRITE )
void devxxxserviceinterrupt (
devxxxdeviceinfoptrtype deviceinfoptr READONLY )
statustype devxxxstartio (
iooperationrecordptrtype oprecordptr READONLY )
statustype devxxxwritedump (
iodumprequestinfoptrtype dumprbptr READONLY )
void kernelcompleteio (
iooperationrecordptrtype oprecordptr, READONLY
statustype status READONLY )
where:
channelflags Flags indicating how the device was or will be
opened (read, write, or read/write) and whether the
open is for block or character special operation.
These flags are listed below under Constants and
Data Structures, iochannelflagstype. (See also
iio.h for a listing of the channel flags.) The
driver does not need to validate this argument.
command A command to the device. The driver must validate
the command because commands are driver-specific.
devicehandle The device handle that was returned by the driver's
devxxxopen routine. The driver does not need to
validate this argument.
devicehandleptr A pointer to the location where the device handle
is to be returned. If the routine does not return
an OK status, this value is undefined. The driver
does not need to validate this pointer.
deviceinfoptr A pointer to the device information structure for
the interrupting device. A pointer to the
devxxxserviceinterrupt routine is the first
field in this structure. The driver does not need
to validate this pointer.
devicename A pointer to the null-terminated string identifying
the device to be opened as a dump device.
devicenameptr A pointer to a null-terminated string specifying
the name of the device to be configured,
deconfigured, or translated.
devicenumber The major and minor device numbers of a particular
device.
dumprbptr A pointer to the dump request information
structure. This structure contains the
iobuffervector, the devicehandle, the
deviceoffset, and the deviceoffsetextender
fields. The devicehandle field is returned from
the devxxxopendump routine.
ecptr A pointer to the eventcounter to be advanced by the
driver when the particular type of select is
satisfied. The driver does not need to validate
this pointer.
fileid A file identifier associated with the character
special file that was initially opened to gain
access to the device.
intentptr A pointer to an intent variable consisting of a set
of intent flags. The kernel calls the driver with
the intent flags showing whether the device is
being selected for read, write, or exceptional
conditions or any combination of these. When the
driver returns, it sets the intent flags to show
which input conditions are currently TRUE. The
driver does not need to validate this argument.
The possible intent flags are described under
Constants and Data Structures below.
ioflags The channel flags for the descriptor passed to
mmap(2).
majornumber The major number of the device to be configured.
mmapcountdelta The amount to increment or decrement the mmap use
count for the device.
nameptr A pointer to the location where the device name is
to be written as a null-terminated string.
numberptr A pointer to where the corresponding device number
is to be written. The device number consists of a
major and minor device number.
oprecordptr A pointer to the operation record for an
asynchronous request. The operation record
contains the following fields:
· The device handle that is the target of the
operation.
· The operation to be performed; for example,
read, write, or both.
· The offset indicating where the read/write
operation should begin. The offset is a file
pointer maintained by the kernel. For example,
on a disk the offset might indicate where to
start reading after the start of the sector.
The interpretation of the offset is driver-
dependent.
· The address of the kernel's I/O completion
routine that is to be called by the driver's
complete_io routine when the operation
completes. The Kernel I/O completion routine
follows the interface shown under
kernelcompleteio below. Note that you pass
the oprecord and a completion status back as
parameters to the kernelcompleteio routine.
· An iobuffervector structure that holds the
transfer size and the address of the memory
buffers.
parameter An argument to the command. The interpretation of
the parameter is specific to the driver and the
command. The parameter is often used to transfer
information between the caller and the device, in
both direction. For example one might use it to
send a pointer to a buffer supplied by the caller.
requestinfoptr A pointer to a request information structure.
requestptr Information indicating which memory is to be memory
mapped (and in what mode) or unmapped. The members
of this structure correspond directly to mmap(2)
arguments as follows:
Member name mmap Argument
start_address addr
file_offset_extender set to 0 by mmap()
file_offset off
byte_count len
protection_flags prot
control_flags flags
requestptr Additional information indicating which memory is
requested to be unmapped.
returnvalueptr A pointer to a value that the routine defines and
returns. This additional return value increases
the flexibility of your ioctl operation by
providing variations on the generic return value
specified in the "Return Value" subsection.
selectmode If selectmode is TRUE, this is the start of a
select operation. If selectmode is FALSE, this is
the end of a select operation.
size The maximum number of bytes, including the
terminating null, that is to be written to
nameptr.
startaddressptr Location used to return the start address in the
user address space of the newly mapped region.
startphysaddr The physical memory address of the beginning of the
region to be unmapped.
status The completion status of the request.
DESCRIPTION
This man page gives the detailed interface specifications for the
following device driver routines:
devxxxinit Perform pre-configuration initialization
devxxxconfigure Configure a device
devxxxdeconfigure Deconfigure a device
devxxxdevicetoname Return name associated with device number
devxxxnametodevice Return device number for device name
devxxxopen Open a device
devxxxclose Close a device
devxxxserviceinterrupt Handle device interrupts
devxxxreadwrite Synchronously read from or write to device
devxxxstartio Start asynchronous I/O operation
kernelcompleteio Clean up after asynchronous I/O operation
devxxxselect Check whether device ready for I/O
devxxxioctl Performs control operation on device
devxxxopendump Open a dump device
devxxxwritedump Write system dump data to dump destination
devxxxreaddump Read a system dump device
devxxxclosedump Close a dump device
devxxxmaddmap Modify device memory map reference count
devxxxmmap Implement the mmap system call
devxxxmunmap Determine whether to unmap memory
devxxxpowerfail* Restart devices after power failure
__________
*Not currently supported
Each routine specification includes a "Return Value" subsection that
lists specific return values that the kernel can process when the
routine returns. When no return value is specified, the routine must
not fail (the kernel will not process any returns or exceptions). If
the driver routine experiences an exception other than those
specified in the "Return Value" subsection, it can proceed in one of
the following three ways:
1. It can return an exception by returning a value other than one
of the specified values. The kernel will filter this value
back to the user as a standard errno. You can either define
your own values for this errno or use values already defined
by the system. Check /usr/include/sys/errno.h for a listing
of the existing errnos and their definitions.
2. It can use the error server to log an error.
3. It can halt the system. Some driver routines are not allowed
to halt. The "Return Value" subsection of the interface
description indicates whether or not a routine can halt.
The statuscodemacros(3K) man page describes how to define an error
status and how to log an error to the error server. The scpanic(3K)
man page describes how to use the routine that halts the system.
Constants and Data Structures
This subsection describes constants and data structures defined in
the include files cited in the SYNOPSIS section and used by the
routines documented in this man page.
Try to avoid dependencies on the specifics of these structures, such
as size or location of fields, because these specifics may change in
later releases of the software. You can verify exact variable
definitions in the appropriate include file. The best way to avoid
such dependencies is to use kernel-supplied routines to manipulate
these structures.
iodriverroutinesvectortype
typedef struct
{
uint16type version;
bit16type flags;
statustype (*open)();
void (*close)();
statustype (*readwrite)();
void (*select)();
statustype (*ioctl)();
statustype (*startio)();
void (*init)();
statustype (*configure)();
statustype (*deconfigure)();
statustype (*devicetoname)();
statustype (*nametodevice)();
statustype (*opendump)();
statustype (*writedump)();
statustype (*readdump)();
statustype (*closedump)();
statustype (*powerfail)();
statustype (*mmap)();
statustype (*munmap)();
statustype (*maddmap)();
} iodriverroutinesvectortype ;
The kernel must have a pointer to each of your routines that it
calls. You provide a vector of pointers to your driver's routines in
a routines vector of iodriverroutinesvectortype. You must
allocate a variable of this type for your driver in
devxxxglobaldata.c.
The structure contains a version field that the kernel uses to
support compatibility with device drivers if the routines vector
changes between releases. This field is also used to flag the
difference between a device driver and an adapter driver. Adapter
drivers have two routines vectors, one of ioroutinesvectortype
type and one of devscsiadapterroutinesvectortype type. The
version field is used to signal the kernel that the driver is an
adapter driver and has another routines vector.
If the driver was written prior to release 5.4.2, you should set the
version field to one (1) for device drivers and to
IODRIVERROUTINESVECTORSCSIADAPTERVERSION for adapter drivers.
For drivers using the new wire/unwire memory calls for release 5.4.2
[see the iobuffervector(3K) and memoryallocation(3K) man pages],
the version field should be IODRIVERROUTINESVECTORVERSION2 for
device drivers and IODRIVERROUTINESVECTORSCSIADAPTERVERSION2
for adapter drivers.
iodevicenumbertype
typedef struct
{
iomajordevicenumbertype major;
iominordevicenumbertype minor;
} iodevicenumbertype ;
A device number is a composite of the device's major and minor device
numbers. During configuration, the kernel calls your
devxxxconfigure routine with the device's major number. Your
devxxxconfigure routine gets the device's minor number and creates
the device number variable for the unit by calling the kernel's
ioallocatedevicenumber routine. devxxxconfigure then uses the
device number to create the special file (node) for the specific
units. After devxxxconfigure creates the device number, the kernel
uses it as an device identifier when calling your devxxxopen
routine. devxxxopen returns a file descriptor that the kernel uses
to identify the unit to the user and a device handle that the kernel
uses to identify the unit to other driver routines.
iodevicehandletype
typedef opaque32type iodevicehandletype ;
A device handle identifies an open device to other calls to the
device driver. Your devxxxopen routine defines and returns the
device handle when the device is opened. The device handle becomes
invalid when the device is closed.
The kernel does not interpret the device handle. Thus, you are free
to define the device handle as you want. A common strategy is to use
a pointer to the unit-specific portion of the device information
structure as the device handle.
iorequestinfotype
typedef struct
{
iooperationtype op;
iochannelflagstype flags;
iodevicehandletype devicehandle;
uint32type deviceoffsetextender;
uint32type deviceoffset;
iobuffervectortype buffervector;
dfselfidtype selfid;
} iorequestinfotype;
The kernel uses a variable of this type to supply information to your
driver's routines about an I/O request made to your driver. The
request information package groups several related I/O request
parameters. The request information package fields are as follows:
op This field indicates the requested operation. See
iooperationtype for a list of the operation types. The op
request is modified by the flags field below.
flags This field holds an additional set of flags that modifies the
operation indicated by the op field. See
iochannelflagstype described later in this subsection for a
list of the flags.
devicehandle
This field holds the device handle of the device to which the
request is to be directed. It must be the device handle
returned by the driver's open routine.
deviceoffsetextender
This field exists for device offsets needing more than 32
bits. This field should be zero if the request does not use
large offsets (for example, nondisk devices). Disk drivers
should check this field. If your disk does not support
offsets needing the extender, you should reject requests where
this offset is non-zero.
deviceoffset
This field holds the offset in bytes on the device where the
transfer is to begin. The interpretation of this field is
defined by the driver to which the request is directed.
buffervector
This field holds a buffer vector describing the main memory
area that is to be used in the I/O operation. The addresses
may be logical or physical depending upon the operation
specified in the op field.
selfid
The home system identification against which read data is to
be checked if the IOCHECKSELFID flag is TRUE.
iooperationtype
typedef bit16type iooperationtype ;
#define IOOPERATIONREAD
#define IOOPERATIONWRITE
#define IOOPERATIONCHECKSELFID
#define IOOPERATIONPHYSICALBUFFER
#define IOOPERATIONUSERBUFFER
This type defines a bit field used to modify the I/O operation
specified in the op field of iorequestinfotype. The READ or WRITE
bits are exclusive, only one can be on at a time. The
PHYSICAL_BUFFER flag indicates that the buffer address supplied with
the operation is a physical memory address not a logical memory
address. The USER_BUFFER flag indicates that the buffer address
supplied with the operation is a user memory address rather than a
kernel memory address. The PHYSICAL_BUFFER flag and the USER_BUFFER
flag may be present only on a READ or WRITE. The CHECK_SELF_ID flag
may be present only on a READ operation.
iochannelflagstype
typedef bit32type iochannelflagstype ;
#define IOCHANNELNOFLAGS
#define IOCHANNELREADINTENT
#define IOCHANNELWRITEINTENT
#define IOCHANNELEXCLUDEWRITERSINTENT
#define IOCHANNELAPPENDINTENT
#define IOCHANNELSYNCIO
#define IOCHANNELNOWAIT
#define IOCHANNELASYNCIO
#define IOCHANNELNONBLOCK
#define IOCHANNELNDELAY
#define IOCHANNELBLOCKSPECIAL
#define IOCHANNELNORETRIES
#define IOCHANNELNOTIFYIFMANDATORY
#define IOCHANNELNOCTTY
This type defines a set of literals that modify the open operation.
The channel flags specify the open conditions that the user requested
and are passed in the flags field of the iorequestinfotype. These
conditions are passed to the devxxxopen routine. See devxxxopen
for more information about the conditions. The open options are as
follows:
IOCHANNELNOFLAGS
This flag indicates that none of the conditions described
below applies.
IOCHANNELREADINTENT
This flag indicates that the channel is opened with read
intent. This flag corresponds to the O_RDONLY or O_RDWR
option on the open system call.
IOCHANNELWRITEINTENT
This flag indicates that the channel is opened with write
intent. This flag corresponds to the O_WRONLY or O_RDWR
option on the open system call.
IOCHANNELEXCLUDEWRITERSINTENT
This flag indicates that the channel is opened only if there
are currently no writers, and future attempts to open with
write intent are disallowed. This flag is used internally by
the file system to prevent other processes from writing to a
disk it is managing.
IOCHANNELAPPENDINTENT
This flag indicates that the channel is opened with append
intent. This flag corresponds to the O_APPEND option on the
open system call.
IOCHANNELSYNCIO
This flag indicates that the channel is opened with the
synchronous I/O option. This flag corresponds to the O_SYNC
option on the open system call.
IOCHANNELNOWAIT
This flag indicates that the channel is opened with the no-
wait I/O option. This flag corresponds to the O_NDELAY or to
the O_NONBLOCK option on the open system call.
IOCHANNELASYNCIO
This flag indicates that the channel is opened with the
asynchronous I/O option. This flag corresponds to setting the
FASYNC option with the fcntl system call.
IOCHANNELNONBLOCK
This flag indicates that the channel is opened with the
O_NONBLOCK option.
IOCHANNELNDELAY
This flag indicates that the channel is opened with the
O_NDELAY option. The driver should not look at this flag.
IOCHANNELBLOCKSPECIAL
This flag indicates that the driver is being opened as a block
special device. This flag is used only internally.
IOCHANNELNORETRIES
This flag indicates that the I/O performed via this channel
should not be retried if errors occur; all errors are treated
as hard errors. This flag may or may not be supported by a
given device driver.
IOCHANNELNOTIFYIFMANDATORY
This flag indicates that the kernel uses this option
internally to avoid deadlock on mandatory locks. Drivers
should not use this option.
IOCHANNELNOCTTY
This flag indicates that the driver is being opened with the
O_NOCTTY open flag set. The kernel uses this option to
prevent the controlling terminal from being set.
iooperationrecordtype
typedef struct
{
miscqueuelinkstype links;
iorequestinfotype ri;
iocompletionroutineptrtype completionroutine;
} iooperationrecordtype;
You use the operation record when starting an asynchronous I/O
request using your driver's devxxxstartio function. The structure
is basically an extension of the iorequestinfotype that you use
for synchronous requests. This extension supplies extra information
needed to service the request in an asynchronous manner. The
operation record's fields are as follows:
links A pointer to a space that the driver can use to link this
operation record into a queue with other operation records.
The driver determines the actual use of this space.
ri The request information structure that specifies the request.
completionroutine
A pointer to the address of the function that should be called
when the operation denoted by this operation record is
complete. This function must conform to the I/O completion
routine interface described below under kernelcompleteio.
ioselectintenttype
typedef bit16type ioselectintenttype ;
IOSELECTINTENTREAD
IOSELECTINTENTWRITE
IOSELECTINTENTEXCEPTION
IOSELECTINTENTPOLLIN
IOSELECTINTENTPOLLPRI
IOSELECTINTENTPOLLOUT
IOSELECTINTENTPOLLERR
IOSELECTINTENTPOLLHUP
IOSELECTINTENTPOLLNVAL
IOSELECTINTENTNONE
IOSELECTINTENTPOLLWRBAND
IOSELECTINTENTPOLLRDBAND
IOSELECTINTENTPOLLRDNORM
This type describes the select options that may be specified to a
device driver's devxxxselect routine. The READ, WRITE, and
EXCEPTION options start a select for the corresponding operation.
Any combination of these three options may be sent in a single
devxxxselect call. IO_SELECT_INTENT_NONE is used as a return value
from ioselectcancel when no intent has been satisfied.
iobuffervectortype
typedef struct
{
union
{
iobuffervectorcontroltype many;
iobufferdescriptortype one;
} u;
uint16type descriptorcount;
uint16type currentdescriptor;
uint32type currentoffset;
uint32type totalremaining;
} iobuffervectortype ;
This structure defines a buffer vector, which is a collection of
individual buffer descriptors plus an associated state. A buffer
vector may be the source or destination of a single read or write
operation; the individual buffer descriptors define the locations
from which the data is being read or into which the data is being
written.
The current position indicates where the next byte of data will be
read from or written to. The current position is initialized to the
first byte of the first buffer descriptor. The current position
within the buffer vector is maintained by the associated state.
The fields in this structure are as follows:
many This field contains a pointer to the array of buffer
descriptors and the total of the sizes of all the elements of
the array. This field is used only when descriptorcount is
non-zero. See also iobuffervectorcontroltype later in
this subsection.
one This field contains the single buffer descriptor when the
buffer vector consists of a single descriptor. This field is
used only when descriptorcount is zero. See also
iobufferdescriptortype later in this subsection.
descriptorcount
This field indicates the number of entries in the many array
of the iobuffervectorcontroltype and is used to determine
the actual amount of memory allocated to the array. If this
field is zero, then there is no memory allocated to the array
and a single descriptor is stored in the one field. The
totalsize field of iobuffervectorcontroltype controls the
number of entries that are actually used, which may be less
than the amount specified by descriptorcount.
currentdescriptor
This field contains the index of the descriptor that contains
the current position.
currentoffset
This field contains the offset of the current position in the
buffer descriptor indexed by currentdescriptor.
totalremaining
This field indicates the total number of bytes remaining to be
moved to or from this buffer vector since it was initialized.
iobufferdescriptortype
typedef struct
{
pointertoanytype bufferptr;
uint32type size;
} iobufferdescriptortype ;
This structure describes the buffer from which data is to be read or
to which data is to be written. The fields in this structure are as
follows:
bufferptr A pointer to the start of the buffer.
size The size of the buffer, in bytes.
iobuffervectorcontroltype
typedef struct
{
iobufferdescriptorptrtype descriptorsptr;
uint32type totalsize;
} iobuffervectorcontroltype;
This structure is used in the many field of iobuffervectortype.
The fields in this structure are as follows:
descriptorsptr
A pointer to an array of buffer descriptors. The array may
contain as many as UINT16MAX entries. (For the definition of
UINT16MAX, see /usr/src/uts/aviion/ext/cgenerics.h.)
totalsize
The sum of the size fields in all the elements of the array
buffer descriptors.
DEVICE DRIVER ROUTINE DESCRIPTIONS
devxxxclose
This routine removes a specified device from the set of devices on
which this driver can perform I/O. You should invoke one
devxxxclose for each successful devxxxopen. devxxxclose should
always get the same intents supplied to the open and the same device
handle returned by the open. However, if a device is opened multiple
times, it will not necessarily be closed in the same or reverse order
of the opens.
Typically, devxxxclose performs any necessary exit operations such
as flushing any buffers that may be present and releasing previously
allocated storage. Some devices will also have special exit
requirements. For example, a tape close would probably rewind the
tape. Most drivers also use devxxxclose in coordination with
devxxxopen to manage the number of outstanding opens.
devxxxclosedump
The routine closes the dump device previously opened by
devxxxopendump.
The devxxxclosedump routine is called by the system dump code when
all of the data has been written to the dump destination.
devxxxclosedump should perform all the standard exit operations
(for example, write End-of-file or rewind the tape). In particular,
it should close the completed volume and inform the operator that the
dump has completed.
devxxxconfigure
This routine configures a single device of the type supported by this
driver.
The routine performs operations that make a physical device of the
driver's type supported accessible to the system. The
devxxxconfigure routine can be called anytime. If your device has
system and master file entries, it will be called by system
initialization code during system boot. It is called once for each
system file entry in the system.
The devxxxconfigure routine receives a devicenameptr variable
that points to a device name. The name string is terminated by a
null character and has the following form:
devicemnemonic [@devicecode]([parameters])
Because each devxxxconfigure is called for all system file entries,
your devxxxconfigure should verify that the name string for the
current call contains its device's name. If the name is not for one
of its devices, devxxxconfigure should exit with a return value of
IOENXIODEVICENAMENOTRECOGNIZED.
devxxxconfigure must initialize the device and must make the device
accessible to the kernel. Device initialization is unique to the
device and to the driver. The devxxxconfigure routine should
perform the following functions:
· Allocate a device information structure. The driver uses the
device information structure to hold information relating to a
specific device (status, permissions, and so on). While the
driver can define most of this structure's internal specifics,
the structure must contain a pointer to the driver's interrupt
service routine (if it has one) in the first field. In
addition, if you want to use the kernel's routines for managing
a select list [see the ioselect(3K) man page], you should
allocate a select list header in the device information
structure. The select list header type is defined in iio.h.
You will also have to initialize this list by calling the
kernel's ioinitselect routine.
· Register the device information structure. If the device
handles interrupts, you must register the device information
structure using the ioregisterdeviceinfo routine.
Registering the device information links the device code and
device class of the driver with the interrupt service routine
given in the device information structure.
· Define a device handle and device number. You do this by
calling ioallocatedevicenumber. ioallocatedevicenumber
allocates a minor number for the device specified and links the
device number and device handle in the kernel's internal tables.
Later you can retrieve this information by using kernel routines
for accessing device information [see the
systemconfiguration(3K) man page]. The kernel will pass the
device number to your driver's devxxxopen routine, but
thereafter it will identify a device to all driver routines by
passing the device handle. If the device has a controller with
accessible units, you should establish a device number and
device handle for all units that users will access.
· Create device special files. As with device numbers, you should
create special files for all the units that users will access.
We recommend that you create the special files after registering
your device information structure, because it is possible for
the register operation to fail. The systemconfiguration(3K)
man page describes kernel routines that create device special
files.
If the device has a controller, the driver usually performs any
initialization needed to bring the controller on-line in
devxxxconfigure. The driver can then initialize the controller's
units at open time.
If a failure occurs in any phase of the operation, devxxxconfigure
must return the system to the state it was in before the
devxxxconfigure routine was called. Data structures must be
deallocated and the device interrupt table slot freed.
You should write your devxxxconfigure routine such that it can be
called any time during the life of the system.
devxxxdeconfigure
This routine deconfigures the specified device if it is of the device
type supported by this driver.
The devxxxdeconfigure routine does the opposite of the configure
routine (see devxxxconfigure). It releases all system resources
obtained to configure the device. After devxxxdeconfigure has
completed, the system should be in the state it was in before the
device configure routine was executed. devxxxdeconfigure performs
the following functions:
· Deallocates a device information structure
· Frees the minor number
· Deregisters device information and removes the device from the
system dump list
· Releases all memory
· Releases Generic and I/O Server messages and timeout space, [see
iounspecifymaxdemonmessages(3K),
iounspecifymaxgenericdemonmessages(3K), and
vpunspecifymaxtimeouts(3K)].
· Removes /dev entries.
devxxxdeconfigure receives a pointer to a device specification of
the following form:
devicemnemonic [@devicecode]([parameters])
The pointer is terminated by a null character.
devxxxdevicetoname
This routine returns the device name associated with the specified
device number. The name is returned as a null-terminated string.
The devxxxdevicetoname routine is called by various file system
utilities to translate a device number into a device name. It
returns the name in a string of the following form:
devicemnemonic [@devicecode]([parameters])
If an earlier driver routine (for example, the configuration routine)
stored the device code and unit number in its unit tables, the
devxxxdevicetoname may call the kernel's iomapdevicenumber to
retrieve the device code and unit number for the given device number.
devxxxinit
This routine performs any pre-configuration initialization your
driver might need. It should not initialize the hardware device
itself, however.
The kernel calls the devxxxinit routine as part of system
initialization. devxxxinit gives the driver an opportunity to
perform any initialization needed before any of the driver's devices
are configured into the system. devxxxinit is invoked once in the
life of the system. No devices controlled by the driver will be
configured until after the devxxxinit routine completes.
The devxxxinit routine operates in a restricted environment. It
may not await or take a page fault.
devxxxioctl
This routine performs a control operation on the specified device.
The devxxxioctl routine performs an ioctl control operation on the
specified device based on the values of command and parameter. It is
invoked in response to a user or kernel ioctl call for one of the
driver's devices. However, not all user ioctl calls go to
devxxxioctl. Some ioctl calls are actually file descriptor
operations. These are intercepted and handled by the kernel. The
FIONCLEX operation, for example, would not reach devxxxioctl.
Multiple ioctl operations on the same or different minor devices may
be in progress simultaneously.
The kernel calls devxxxioctl with the command and parameter
arguments as specified by the ioctl system call. The kernel does not
interpret these arguments. Thus, you can define your driver's
command and parameter arguments as you wish.
Because ioctl operations are so specific to each driver, the kernel
validates only the device handle argument.
devxxxmaddmap
This routine modifies the reference count for memory-mapped sections
for the device. The reference count is called the "mmap use" count.
This routine maintains the mmap use count for the device. The count
indicates to the driver whether there are any outstanding memory
mappings of the device. If the count is positive, there are some
mappings. Otherwise, the count must be zero, indicating there are no
mappings.
This routine may assume that the device is either open or memory
mapped at the time it is called. That is, if the mmap count for the
device is zero when this routine is called, then the device's open
count and mmapcountdelta must both be positive. Typically, you can
maintain the mmap count and open count for a device as a single
unsigned integer (the use count), which must be at least 32 bits in
size and protected by the device's open lock. devxxxmaddmap
adjusts the device's use count by the (signed) amount specified by
mmapcountdelta. The use count must be positive prior to the call.
If the mmap count becomes zero and the open count is already zero as
a result of this call, then devxxxmaddmap should perform the
actions associated with the last system-wide close of the device (for
example, freeing resources). This means that the driver's close
routine must not perform the last close actions for a device unless
both the open count and mmap count are zero. If the use count
becomes zero, then devxxxmaddmap must perform the last close
actions for the device.
devxxxmmap
This routine implements the mmap system call. It maps a physical
address region controlled by the xxx character special device into
the user address space.
This routine validates and translates the caller's mmap request based
on the mapping of device offsets to physical address regions defined
by devicehandle, requestptr, and ioflags. If the request is valid
and all required resources are available, then devxxxmmap maps the
appropriate physical address region controlled by the device into
user memory at the address returned in startaddressptr.
The required steps are as follows:
1. Verify that the device offset range corresponds to a range of
physical addresses controlled by the device and is safely
accessible by the caller. The device offset range is defined
by the fileoffsetextender, fileoffset, and bytecount
fields of requestptr. If the range is not valid, return
IOENXIOILLEGALDEVICEADDRESS.
NOTE: fileoffsetextender denotes the high 32 bits of the 64-bit
device offset. A driver that supports only 32-bit offsets
should return an error if fileoffsetextender is non-zero.
2. Translate the beginning of the request's device offset range
to its corresponding physical address.
3. Compute the maximum access to the physical memory that the
mapping should allow. Generally, you should allow read and
execute access to the memory if the caller's channel flags
indicate that the device is open for reading. Similarly, you
should allow write access to the memory if the device is open
for writing.
4. Determine the appropriate memory cache control for the mapped
memory. Most memory mapped devices require caching to be
disabled.
After successfully completing these steps, devxxxmmap calls
vmmmapphysicalmemory to complete the request and returns the
status from vmmmapphysicalmemory's to the caller. To prevent
deadlock, avoid holding any locks when calling
vmmmapphysicalmemory as vmmmapphysicalmemory calls the driver's
maddmap routine one or more times.
devxxxmunmap
This routine determines whether to allow an unmap of a previously
memory-mapped region of physical memory.
This routine has no side effects beyond returning a status.
Presently, all character special devices which support memory mapping
must also allow subsequent unmapping on arbitrary page boundaries.
Thus, this routine must return OK.
devxxxnametodevice
This routine returns the device number for the specified device name.
This routine is called by various file system utilities to translate
a device name into the major and minor device numbers that are
required to access the device. The device name specified by
devicenameptr is of the following form:
devicemnemonic [@devicecode]([parameters])
To simplify its processing, devxxxnametodevice can call the
kernel's iogetdeviceinfo, which returns a pointer to the device
information structure that will contain the device's device number.
The driver should verify that the device mnemonic given in the name
matches its own mnemonic (xxx).
devxxxopen
This routine prepares a specified device for future I/O operations.
It also adds the device to the set of devices on which I/O can be
performed by this driver.
The kernel calls the routine whenever one of the driver's devices is
opened by a user or by the kernel. The kernel will not call
devxxxopen until both devxxxinit and devxxxconfigure have
completed.
The DG/UX system allows multiple opens on a device, and devxxxopen
should manage this feature as appropriate to its device.
devxxxopen controls the number of outstanding opens. For example,
devxxxopen may impose restrictions such as requiring an exclusive
open of a particular minor device. To implement this, devxxxopen
might return an error status if the minor device has already been
opened but not closed. Multiple devxxxopen processes may be in
progress simultaneously on the same or different minor device
numbers.
The devxxxopen routine must also control the type of open
requested. The kernel passes devxxxopen a set of channel flags
that specify the intents given in the higher level open call (for
example, read, write or both). devxxxopen may reject the open
because of conflicts between the current open intent and open intents
that have already taken place or because of conflicts with the
device's capabilities. For example, a write intent on a read-only
device must fail.
devxxxopen typically performs other operations to prepare the
device and ensure that it is ready for I/O. For example, it may
allocate storage for and initialize databases to hold information
describing the I/O operation on the specific unit. If the device is
a real hardware device, devxxxopen may query the device to verify
that it is on-line and ready for the type of I/O specified in the
open intent. For example, it may check that there is a write ring in
the tape if write intent is specified.
devxxxopen must establish the device handle that the kernel will
use as a parameter in all future driver operations. It can retrieve
the handle that devxxxconfigure stored by calling
iomapdevicenumber with the device number. If devxxxopen returns
an OK, it must return the device handle in devicehandleptr. If it
returns a status other than OK, the kernel presumes that the open
failed and it will disregard the returned devicehandleptr argument.
devxxxopendump
This routine prepares one of the driver's devices for use as the
destination of a system dump.
A master file entry specifies the default device for a system dump,
but during the dump procedure the user is allowed to specify an
alternative dump destination. If your device is selected as the dump
destination, the system will call your devxxxopendump routine if
the system halts.
The devxxxopendump routine initializes the device as a dump
destination. To do this, it must reinitialize the device's
controller (and/or units). Because the system is in an undefined
state as a result of the halt, the standard kernel facilities will
not be available for the initialization procedure. In particular,
this means that devxxxopendump must run in physical memory since
dynamically allocated memory cannot be accessed. devxxxopendump
should statically allocate its data structures in
devxxxglobaldata.c.
The devxxxopendump routine should also use device polling when
interacting with the controller, because the standard interrupt
mechanism will not be available.
Because the dump procedure is a single-threaded process, you do not
need and should not use the kernel locking mechanisms.
The devxxxopendump routine receives a device name specified by
devicename. It should verify that the device specified is of the
driver's type. The device name is of the following form:
devicemnemonic [@devicecode]([parameters])
Finally, as with any open routine, devxxxopendump should perform
any operations necessary to ensure that the device is on-line and
ready for a write operation. For example, if the device is a tape,
the tape should be on-line and write-enabled.
NOTE: This routine must not halt because it is invoked as part of
the halt sequence.
devxxxpowerfail
This routine restarts all devices managed by this driver when power
has been restored after a power failure.
The DG/UX system does not support this operation at this time. You
should use the appropriate ionodevice stub for this routine.
devxxxreaddump
This routine handles reading a system dump device.
This routine may be called during a halt to read one or more blocks
from the system dump device. Because it will be called during halt
processing, the normal kernel facilities may not be available. In
particular this routine should not use locks or interrupts. It
should implement the read operation by polling the device for the
read operation to complete.
devxxxreadwrite
This routine performs a synchronous read or write of the specified
device.
You can assume the request information structure has a valid
operation code and device handle. The driver must validate the
device offset and transfer count as being appropriate for the device.
The driver must also be prepared to handle errors in referencing the
memory address as specified in the buffer vector.
The transfer count specifies the maximum number of bytes that should
be transferred. The driver determines how much data to actually
transfer before it returns. If there is an error, the amount may be
less than the transfer count. However, under no circumstances may
the amount of data transferred exceed the specified maximum.
The offset specified is a file pointer maintained by the kernel; it
indicates where the read/write operation should begin. For example,
on a disk, the offset might specify where, after the start of the
sector, the desired data is located. The driver may ignore this
parameter if it is not applicable to its device for example, if the
device is character special.
The request information structure can be accessed only when the
requesting process is running; it can not be accessed from the
interrupt level.
The devxxxreadwrite routine performs a synchronous read or write
of the specified device, transferring data between the device and the
specified buffer. It is invoked whenever a user or kernel read or
write is performed on a device supported by this driver. This
routine is usually used for character special I/O, but it may also be
used for block special I/O.
Multiple reads/writes of the same or different minor devices may be
in progress simultaneously. Therefore the driver should take steps
to serialize requests as needed. This usually means using locks on
important data structures.
The devxxxreadwrite routine should also handle any special
transfer constraints for its device. For example, a disk device
might allow only those transfer counts that are multiples of 512
bytes. devxxxreadwrite should be prepared to handle a kernel-
requested self-identification check as indicated in the self-id field
in the request information structure. The flag indicates that the
driver should verify that this self-id matches the device's self-id
as stored in data blocks read from that device. You can use the
kernel's fscheckselfid routine to retrieve the self-id stored in
the data (see the fscheckselfid(3K) man page).
Because the devxxxreadwrite routine is synchronous, any data that
is going to be transferred to or from the buffer must already be
transferred when it completes. Because it must wait for the I/O to
complete, devxxxreadwrite will need to set up await mechanisms
such as a timeout, a signal, or an I/O completion event. The
eventcounters(3K) man page describes kernel routines that the driver
can use to implement these await mechanisms.
The buffer can only be accessed only when the requesting process is
running. Be sure to check the buffer's access status before reading
or writing to it. You should check write access to the buffer for
read operations and read access to the buffer for write operations.
Many transfer operations must be done to wired buffers. The
specified buffer is wired unless the IOOPERATIONUSERBUFFER
operation flag is set in the request block operation field. If the
buffer is unwired and the transfer requires a wired buffer, the
driver must explicitly wire the buffer and unwire it before
returning. The memoryallocation(3K) man page describes kernel
routines that the driver can use to wire and unwire memory.
After the read/write, the driver should update the buffer vector
pointers to reflect the actual data transferred (which may be less
than the transfer count in cases of error). You must use kernel
utilities for all references and updates to data contained in the
iobuffervector structure. The iobuffervector(3K) man page
describes the kernel routines used to manipulate buffer vectors.
devxxxselect
This routine supplies information about whether the specified device
is ready to perform an I/O operation.
The kernel calls the devxxxselect routine in response to user-level
select system calls. devxxxselect operates as follows:
· If the user is selecting a device (selectmode argument is
TRUE), and the device is ready for at least one of the
incoming intents, the driver should set the intent flags to
match the device's current state and return. It should set
the flags to FALSE for all intents that are not currently
ready. It should set the intent flag to TRUE if that flag was
TRUE on input and the intent is currently ready. If none of
the conditions the caller was interested in are TRUE, the
driver should add the eventcounter pointed to by ecptr to a
list of events maintained by the driver. Later, when one of
the specified intents becomes TRUE, the driver must advance
this eventcounter. Usually, drivers have the
devxxxserviceinterrupt routine complete select processing
via a message to the Driver or Generic Server.
· If the user is unselecting the device (the selectmode
argument is FALSE), the driver should discard the previously
saved ecptr and report any intents that have become TRUE.
Multiple selects of the same or different minor devices may be in
progress simultaneously. The devxxxselect routine must be able to
store multiple eventcounter pointers for each of the read, write, and
exception selects and advance them all when the intent becomes TRUE.
Kernel routines for managing select lists (adding and removing
entries and satisfying selects) are described in the ioselect(3K)
man page. The driver should have allocated and initialized the
select list structure before select operations begin, usually in the
devxxxconfigure routine.
For many devices, such as disks and tapes, devxxxselect always
returns TRUE because the I/O operations are quick. devxxxselect is
more meaningful on character devices that depend upon external
intervention. For example, the kernel might send a select FALSE for
writing to a terminal when its output is being held with Ctrl-S.
Similarly, it would select FALSE for reading when the driver is
waiting for the user to type something.
devxxxserviceinterrupt
This routine handles interrupts from devices under the control of
this driver. It is called by the system interrupt handler.
The devxxxserviceinterrupt routine performs any steps needed to
service the device at interrupt level. It operates in a restricted
environment: interrupts are disabled; no page faults may be taken;
and the process must not wait. Because of these restrictions,
devxxxserviceinterrupt should defer as much device service as
possible to a base-level process.
The devxxxserviceinterrupt must avoid calling any routine that may
pend. Therefore, it must forgo virtually all the kernel-supplied
utilities. You should use the Driver or Generic Server to signal or
send information back to other processes. You send a message to the
appropriate server (daemon) by queuing a message with a completion
routine to the server's queue. [To queue messages, see
ioqueuemessagetodriverdemon(3K) and
ioqueuemessagetogenericdemon(3K).] The server will dequeue the
message and execute the completion routine in the server's context
rather than the interrupt service routine's limited context.
Typically, devxxxserviceinterrupt might do any of the following:
read the device's status registers; advance an eventcounter for
synchronous events; send a message to the Driver or Generic Server
for an asynchronous event; or do a select satisfy for a select
operation. If the interrupt is not cleared automatically by reading
the status register, devxxxserviceinterrupt must clear the
interrupt before exiting.
The pointer to the device information structure allows
devxxxserviceinterrupt to access the device database associated
with the I/O request.
NOTE: If the device does not generate hardware interrupts, you do
not need to create this routine.
devxxxstartio
This routine starts an asynchronous I/O operation on the specified
device.
When a user initiates a read or write operation on a block special
device, the kernel will invoke devxxxstartio to process the
request asynchronously. The devxxxstartio routine is used only on
block special devices. Multiple devxxxstartio routines on the
same or different minor devices may be in progress simultaneously.
devxxxstartio should start the operation and then exit, leaving
the completion to be handled by another routine. If devxxxstartio
cannot initiate the operation (for example, if the device is busy),
it should queue the request to be handled later and exit. This
routine should not pend.
The operation record must reside in global kernel memory, so it may
be accessed by any process, not just the requester. The driver need
not validate most of the fields of the operation record. The
exceptions are the device offset and transfer size fields. The
driver may need to check these fields to ensure that they are
meaningful for the device.
The devxxxstartio routine returns before the data transfer is
complete. The driver must therefore decide how to finish processing
once the operation does complete. The driver is relatively free to
handle completion as necessary for its own device.
The only thing the driver is required to do during completion is to
call the kernel completion routine supplied in the operation record.
The kernel waits until its I/O completion routine is called before
expecting new data in the buffer, modifying data in a buffer that was
written, or modifying the operation record that was passed in as an
argument. Until the driver calls the kernel's I/O completion
routine, the kernel does not consider the operation complete.
The driver decides when to call the kernel's I/O completion routine.
Typically, when the operation completes, the
devxxxserviceinterrupt routine queues a message to the Driver or
Generic Server. The message contains a pointer to a routine which
the server will execute. This routine might be either the kernel's
I/O completion routine or a driver-supplied completeio routine that
in turn calls the kernel's I/O completion routine. The
servermessages(3K) man page describes the kernel routines for
interacting with the Driver or Generic Server.
The information below under kernelcompleteio describes the
interface the kernel's I/O completion routine uses. You do not need
to the kernel-specified interface in your driver's completeio
routine.
The following implementation notes are relevant regardless of how
completion is implemented:
· The driver must transfer the exact amount of data specified in
the request unless there is an I/O error (in which case less
data is acceptable). Under no circumstances may the amount of
data transferred exceed the amount specified.
· You must not call the kernel's I/O completion routine in the
same process from which the devxxxstartio routine is called
lest the kernel's I/O completion routine be called before
devxxxstartio finishes.
· The buffer to receive the data is wired in memory. The driver
may perform logical-to-physical address translations without
having to explicitly wire the buffer. Further, the buffer must
reside in global kernel memory, so any process may access the
buffer or perform the logical-to-physical translation.
devxxxwritedump
This routine writes system dump data to the dump destination device
previously opened by devxxxopendump.
During a dump, the system's halt code path calls devxxxwritedump
to write the data specified in the iobuffervector. The halt code
will call the devxxxwritedump routine as many times as necessary
to transfer all of the dump data. You will not need to wire buffer
memory or verify parameters for this routine.
If the dump destination must use multiple volumes to hold the entire
system dump, the devxxxwritedump routine should close the
completed volume, request that the operator mount a new volume, and
open the new volume.
NOTE: Because the normal kernel facilities are not available, this
routine should busy-wait for the write operations to complete.
The normal system interrupt handler is not available. Also,
this routine must not halt because it is invoked as part of
the halt sequence.
kernelcompleteio
This routine defines the kernel I/O completion routine interface.
The kernel supplies a routine that adheres to this interface to
perform work necessary when an asynchronous I/O operation completes.
The kernel's I/O completion routine performs the cleanup the kernel
must do to complete the asynchronous I/O. The driver calls it to
indicate that the operation is complete.
The status argument indicates the result of the asynchronous I/O
operation.
The kernel's I/O completion routine must always succeed. Therefore
it does not have a return value.
DIAGNOSTICS
Return Value
The devxxxinit routine does not return a status; any errors that it
encounters must result in a halt or in some method of flagging the
error to devxxxconfigure for further processing.
For devxxxconfigure:
OK The device was successfully configured.
IOENXIODEVICENAMENOTRECOGNIZED
devicenameptr does not specify a device of the type
supported by this driver.
IOENXIODEVICENOTSUPPORTED
devicenameptr specifies a device of the type
supported by this driver, but the particular model is
not supported.
IOEIOPHYSICALUNITFAILURE
A request issued to the device controller failed with
an error status.
IOEIODEVICETIMEDOUT
The controller did not respond to a request within a
reasonable length of time.
IOENXIODEVICEISALREADYCONFIGURED
A device is already registered at the location
specified by devicenameptr.
For devxxxdeconfigure:
OK The device was successfully deconfigured.
IOENXIODEVICENAMENOTRECOGNIZED
devicenameptr does not specify a device of the type
supported by this driver. This error is returned when
the device mnemonic does not match the mnemonic
associated with the driver.
IOEBUSYDEVICEHASOPENUNITS
The specified device currently has one or more units
that are open.
For devxxxdevicetoname:
OK The translation was performed successfully.
IOENXIODEVICEISNOTCONFIGURED
The specified device number is not configured.
For devxxxnametodevice:
OK The device name was successfully translated.
IOENXIODEVICENAMENOTRECOGNIZED
The specified device is not supported by this driver.
This error is returned when the device mnemonic does
not match the mnemonic associated with the driver.
IOENXIODEVICEISNOTCONFIGURED
The specified device is supported by this driver but is
not currently configured in the system.
For devxxxopen:
OK The devxxxopen routine was successful in preparing
the device for further operations.
IOENXIOUNITNOTREADY
The unit is not ready or on-line.
IOENXIODEVICEISNOTCONFIGURED
The specified device number cannot be mapped to a
configured device.
IOENXIOOPENINTENTCONFLICTS
The unit is already open and can only be opened
exclusively.
IOENXIONOWRITERING
The tape was opened with write intent, but the tape did
not have a write ring (only applicable to tape
devices).
IOENXIOTAPEDENSITYNOTSUPPORTED
The requested density is not supported by the tape
controller (only applicable to tape devices).
IOENXIOCANNOTCHANGETAPEDENSITY
The requested density is not compatible with the
current density setting of the unit, and the tape is
not at the beginning of the tape (BOT) (only applicable
to tape devices).
For devxxxclose:
OK The close was successful.
IOSTATUSERRORONEARLIERREQUEST
An error occurred on the last asynchronous request made
to the device. Since the last request was
asynchronous, this is the first opportunity to notify
the interested process.
The devxxxreadwrite routine must return a status indicating the
success or failure of the transfer. The definition of success or
failure is determined by the driver and need not be related to the
number of bytes actually transferred.
OK The devxxxreadwrite routine was successful.
IOEINVALILLEGALREQUESTSIZE
The requested count is not valid for the device type.
IOEINVALILLEGALBUFFERADDRESS
The buffer was not aligned as required by the device.
IOENXIOILLEGALDEVICEADDRESS
The location specification for reading/writing is
invalid for the device.
IOEIODEVICETIMEDOUT
The device controller did not respond to a request in a
reasonable length of time.
IOEIOHARDIOERROR
An unrecoverable I/O error occurred, resulting from a
media failure.
IOEIOPHYSICALUNITFAILURE
An uncorrectable error occurred that presumably affects
I/O operations to the entire physical unit.
IOEINTRINTERRUPTEDBYSIGNAL
A signal was received while waiting for the I/O to
complete.
IOEINVALREQUESTSIZETOOLARGE
The requested count exceeds the limit of this device.
The devxxxstartio routine must return a status indicating the
success or failure of the start of a transfer. All errors other than
IO_EINVAL_REQUEST_SIZE_TOO_LARGE are reported via the completion
routine.
OK The request was successfully started.
IOEINVALREQUESTSIZETOOLARGE
The requested count exceeds the limit of this device.
The devxxxioctl routine should return a status indicating the
success or failure of the control operation. The definition of
success or failure is determined by the driver.
OK The devxxxioctl routine was successful. No errors
should be indicated to the caller.
IOEINVALCOMMANDNOTSUPPORTEDBYDEVICE
The command was not supported by the driver.
For devxxxopendump:
OK The open completed successfully.
IOSTATUSDUMPNOTSUPPORTED
The device identified by the devicename string is not
supported as a dump device by this driver. Either the
device mnemonic does not match the mnemonic associated
with your driver; the device name is in an
unrecognizable format; or the device specified by
devicenameptr is supported by the driver but the
device type is not a valid dump destination device.
IOEIOHARDIOERROR
A request to the dump destination device has resulted
in an error condition.
For devxxxwritedump:
OK The write operation completed normally.
IOSTATUSTAKECHECKPOINT
The write operation completed normally but was written
as the first record on a volume. The system dump code
should checkpoint its current state.
IOEIOHARDIOERROR
An unrecoverable I/O error occurred. The system dump
code should restore its state from the last checkpoint
and begin writing again from there. This error does
not occur on the first record of the volume.
For devxxxreaddump:
OK The volume was successfully read.
IOEIOHARDIOERROR
An unrecoverable error occurred during the read
operation.
For devxxxclosedump:
OK The volume was successfully closed.
IOEIOHARDIOERROR
An unrecoverable error occurred in closing the volume.
The operator is prompted to mount another volume, and
the system dump utility should resume operation at its
last checkpoint.
For devxxxmmap:
OK The call successfully created a mapping at the user
address returned in startaddressptr.
IOENXIOILLEGALDEVICEADDRESS
The requested device offset range did not fall entirely
within a range of mappable device offsets.
other error status from vmmmapphysicalmemory
The mmap request failed due to a problem detected by
the vmmmapphysicalmemory routine.
vmmmapphysicalmemory will pass back the error
status.
For devxxxmunmap:
OK All munmaps of this device are allowed. devxxxmunmap
must return OK.
For devxxxpowerfail:
OK Return this value in all cases.
For the other routines: none.
SEE ALSO
adapterdriver(3K), adaptermanager(3K), eventcounters(3K),
fscheckselfid(3K), iobuffervector(3K), ioselect(3K),
memoryallocation(3K), scpanic(3K), servermessages(3K),
statuscodemacros(3K). systemclock(3K), systemconfiguration(3K).
Programming in the DG/UX Kernel Environment.
Licensed material--property of copyright holder(s)