-
All critical code sections
in kernel-level drivers
should be protected with appropriate
synchronization primitives.
See
``Critical code section''
and
``Synchronization primitives''.
-
All code sections protected by spin locks
or
spl( )
calls
should be as brief as possible
to avoid degrading system performance.
See
``Spin locks (DDI)'',
``Spin locks (ODDI)'',
spl(D3),
and
spl(D3oddi).
-
Drivers written for
DDI 8, ODDI 5, and later versions
must use the
TICKS(D3)
or
TICKS(D3oddi)
functions rather than accessing
the lbolt kernel variable.
DDI versions prior to version 8
use the
drv_getparm(D3)
function with the LBOLT value
rather than accessing lbolt directly.
ODDI drivers prior to version 5
must access lbolt directly.
Note that lbolt can become negative;
see
``lbolt''
for information and guidelines about
using lbolt so that it does not corrupt the kernel.
-
Use the autoconfiguration facilities
to configure drivers and
to obtain hardware configuration information.
Using these functions reduces driver complexity
and enables the driver to install easily on
a variety of architectures and configurations.
See
``Autoconfiguration''.
-
All drivers should be multithreaded.
Single-threaded drivers can severely degrade
system performance when run on multi-processor configurations.
See
``Multithreaded drivers''.
Singlethreaded MDI drivers can use
the MP-aware facility
to reduce the degradation of system performance
when running a single-threaded driver
on a multiprocessor system.
For DDI drivers, see the
mdi_tx_if_enable(D3mdi)
and related manual pages;
for ODDI drivers, see the
mditx_interface(D3mdi)
and related manual pages.
-
Singlethreaded drivers should be tested
on a multiprocessor system
and multithreaded drivers should be tested
on a uniprocessor system
to ensure that they work properly.
-
Use the SVR5
drv_priv(D3)
function to check privilege;
DDI driver code should never
access the
cr_uid
member directly.
SCO OpenServer 5 drivers use the
suser(D3oddi)
function to check whether the calling process
has superuser privileges.
-
Use the DDI
ptob(D3)
function to get pagesize;
DDI driver code
should not use the NBPP definition.
-
Drivers should never call the
printf( )
function.
Use
cmn_err(D3)
or
cmn_err(D3oddi)
instead, even within debug-only sections of code.
-
Drivers should never explicitly panic the system.
Support for the CE_PANIC mode of the
cmn_err(D3)
and
cmn_err(D3oddi)
functions will be removed in a future release.
Use the DDI
call_demon(D3)
function
or the ODDI
calldebug(D3oddi)
function to explicitly call the configured debugger
for driver debugging.
-
DDI drivers must never access
the ublock for reading or writing.
Use the
drv_getparm(D3)
function to access current values of these parameters.
Any parameters that are not available to
drv_getparm( )
are not valid for driver use.
-
Driver source code should only #include
the header files listed on the manual pages
for the driver entry points, functions, and structures being used
and general-purpose driver header files
that are discussed in
``Header files''.
Because many of these directories are in the
<sys> directory,
drivers must include the following:
#define _KERNEL /* for UnixWare 7 drivers */
#define _INKERNEL /* for SCO OpenServer drivers */
-
Driver source and the resulting binary code
must have no external package dependencies
other than the base operating system,
the SCO UDK (UnixWare and OpenServer Development Kit),
the SCO HDK (Hardware Development Kit),
and tools documented on the SCO Hardware Compatibility Homepage.
Space.c files
should not be dependent on any products
other than the base operating system.
-
When using memory-mapped I/O,
all pointers to memory-mapped addresses
must be declared as volatile.
See
``Memory-mapped I/O''.
-
Drivers that use DMA schemes for I/O
should adhere to the recommendations
about memory allocation in
``Memory allocation''.
Do not do direct DMA programming,
but instead use the DDI or ODDI interface
for DMA programming;
see
``DMA''.
-
Never use BSS memory for DMA-able memory.