DDI: 8 sample driver

Header files and declarations

The first line of the driver identifies this as a kernel module for the compiler. This is followed by a line that defines the major DDI version used for the driver. Note that this defines only the major DDI version number; this same define is used for both DDI 8 and DDI 8mp drivers.

The _KERNEL specification is required for all kernel-level drivers; the _DDI specification is required for DDI 8 and later drivers. Alternately, these could be specified on the cc command line; see ``Compiling kernel drivers''.

Call header files

The #include lines reference the header files that define structures and values that are used in this driver. Note the convention of referring to these files as <sys/types.h> and so forth. By default, these header files are located in the /usr/include directory tree on the system, but they could be in a different location. The INC= declaration in the driver's Makefile defines the root directory for header files; for this driver, it is set to /usr/include. See ``Header files'' for information about these header files. Note that, for DDI 8 drivers, ddi.h does not need to be the last header file that is #included, although this is a requirement for pre-DDI 8 drivers.

Many drivers will also have their own header file(s), although the samp driver does not. If it did have its own header file, it would be located within the same directory as the driver code on the development machine and referenced at the end of the list of header files with a line such as the following, using the quote character ("):

   #include "samp.h"

Define manifest constants

Next the code defines some manifest constants that will be used throughout the driver code. Note that these are all prefaced with SAMP_, a version of the driver prefix, to ensure that they are unique to this driver. SAMP_MAXCHAN defines the maximum supported channel number. This driver is set up to support two channels. The first channel is 0, so setting this value to 1 indicates that two channels are supported. This value will be used to populate the drvinfo(D4) structure and must match the value given for the $maxchan field in the Node(DSP/4dsp) file.

SAMP_DEVSIZE and SAMP_MINWRITE define the upper and lower size limits of data to be transferred. These constants are used throughout the code to test the size of the data on which an I/O operation is being done; data that falls below the SAMP_MINWRITE limit or above the SAMP_DEVSIZE limit generates an error of some sort because the data is out of bounds.

The samp_modname value is imported to be used to populate the drv_name member of the drvinfo(D4) structure. This value is defined in the driver's Master(DSP/4dsp) and System(DSP/4dsp) files, and is imported into the driver code through the MODNAME variable in the Space.c(DSP/4dsp) file. It should be imported as a constant rather than being hardcoded in the drvinfo structure.

Populate stuctures for device instance and channel

The code next populates structures for information about the channel and the device instance; see ``Device instance'' and ``Channel number''. samp_channel_t is imported in the samp_instance_t structure and accessed directly in the samp_open( ) and samp_close( ) entry point routines. The samp_instance_t structure is initialized once as an idata for every device instance in the CFG_ADD subfunction to the samp_config( ) entry point routine and then passed as an opaque handle that is called as the first argument to the other entry point routines.

samp_instance_t defines tracking information that the driver needs for each device: the number of open channels, the number of I/O operations in progress, the first I/O port that is available, and the current configuration state (ACTIVE, SUSPENDED, or REMOVED). It also defines the synchronization objects that will be used for access to the device instance: mutex is a spin lock that is allocated with the LOCK_ALLOC(D3) function; sv is a synchronization variable that is allocated with the SV_ALLOC(D3) function. See ``Spin locks (DDI)'' and ``Synchronization variables''.

ADDR_PORT and DATA_PORT define I/O ports that will be used for command and status information about the device. They will be passed as the argument to the inb(D3) and outb(D3) functions that are called in the samp_read_cmos( ) and samp_write_cmos( ) subordinate driver routines. See ``Programmed I/O (PIO)''.

Prototype driver routines

All the entry point routines and subordinate driver routines other than _load( ) and _unload( ) are prototyped. The samp driver does not control a true hardware device that generates interrupts, so does not have an intr(D2) entry point routine. If there were an intr( ) entry point routine, it would also be prototyped here.

Populate drvops and drvinfo structures

After the entry point routines are prototyped, the drvops(D4) structure is populated with the names of all the base-level entry point routines, which are the entry point routines that the kernel calls in response to a system call plus the config( ) entry point routine. This driver does not have a drvctl(D2) or mmap(D2) entry point routine so those members are set to NULL.

Now, the drvinfo(D4) structure is populated with information about the externally-visible driver characteristics. This includes a pointers to the samp_ops drvops(D4) structure that declares the entry point routines, the samp_modname MODNAME value that was declared earlier, and setting the maxchan member to the SAMP_MAXCHAN manifest constant that was defined earlier. The drv_flags member is set to indicate that this is a multithreaded driver (note that the Master(DSP/4dsp) file declares the multithreaded DDI 8mp interface version to match this), that the device is fully hot-pluggable, and that the driver supports random access, meaning that the values of the b_blkno and b_blkoff members of the buf(D4) structure will be ignored. D_RANDOM must be set in order to seek to an address within device space and to access information about the size of the device.

© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005