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''.
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 ("):
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
drv_name member of the
This value is defined in the driver's
and is imported into the driver code
through the MODNAME variable in the
It should be imported as a constant
rather than being hardcoded in the drvinfo structure.
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.
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
mutex is a spin lock that is allocated with the
sv is a synchronization variable
that is allocated with the
``Spin locks (DDI)''
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)''.
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.
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.
structure is populated with information about
the externally-visible driver characteristics.
This includes a pointers to the samp_ops
structure that declares the entry point routines,
the samp_modname MODNAME value
that was declared earlier,
and setting the
to the SAMP_MAXCHAN manifest constant
that was defined earlier.
drv_flags member is set to indicate
that this is a multithreaded driver
(note that the
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_blkoff members of the
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.