diff --git a/doc/driverwriting.xml b/doc/driverwriting.xml
index 2ed32e6..12cfb06 100644
--- a/doc/driverwriting.xml
+++ b/doc/driverwriting.xml
@@ -11,13 +11,13 @@ Writing a &comedi; driver
-This Section explains the most important implementations aspects of
+This section explains the most important implementations aspects of
the &comedi; device drivers. It tries to give the interested device
driver writer an overview of the different steps required to write a
new device driver.
-This Section does not explain all implementation
+This section does not explain all implementation
details of the &comedi; software itself: &comedi; has once and for
all solved lots of boring but indispensable infrastructural things,
such as: timers, management of which drivers
@@ -36,8 +36,8 @@ know the answers to the following questions:
How does the
-communication between user space
-and kernel space work?
+communication between user-space
+and kernel-space work?
@@ -74,13 +74,13 @@ manufacturers all use their own design and nomenclature.
-Communication user space-kernel space
+Communication user-space — kernel-space
-In user space, you interact with the functions implemented in the
-/usr/src/comedilib directory. Most
-of the device driver core of the Comedilib library is found in
+In user-space, you interact with the functions implemented in the
+Comedilib library.
+Most of the device driver core of the Comedilib library is found in
lib subdirectory.
@@ -89,27 +89,27 @@ All user-space &comedi;
commands
are transmitted to kernel space through a traditional
ioctl system call.
-(See /usr/src/comedilib/lib/ioctl.c.)
-The user space information command is encoded as
+(See lib/ioctl.c in Comedilib.)
+The user-space information command is encoded as
a number in the ioctl call, and decoded in the
-kernel space library. There, they are executed by their kernel-space
+kernel-space library. There, they are executed by their kernel-space
counterparts. This is done in the
-/usr/src/comedi/comedi/comedi_fops.c file: the
-comedi_ioctl() function processes the results of
+comedi_fops.c file in the Comedi sources: the
+comedi_unlocked_ioctl function processes the results of
the ioctl system call, interprets its contents,
-and then calls the corresponding kernel space
+and then calls the corresponding kernel-space
do_…_ioctl function(s).
For example, a &comedi;
instruction is further processed
-by the do_insn_ioctl()function. (Which, in turn,
-uses parse_insn() for further detailed processing.)
+by the do_insn_ioctl function. (Which, in turn,
+uses parse_insn for further detailed processing.)
The data corresponding to instructions and commands is transmitted
-with the copy_from_user() system call;
-acquisition data captured by the interface card passes the kernel-user
-space boundary with the help of a copy_to_user()
-system call.
+with the copy_from_user function;
+acquisition data captured by the interface card passes the
+kernel/user-space boundary with the help of a copy_to_user
+function.
@@ -144,7 +144,7 @@ RTLinux/Free, and spinlocks for atomic sections.
include/linux/comedilib.h: the header file for
-the kernel library of &comedi;.
+the kernel library of &comedi; (kcomedilib module).
@@ -152,9 +152,7 @@ the kernel library of &comedi;.
From all the relevant &comedi; device driver code that is found in the
-/usr/src/comedi/comedi directory
-(if the &comedi; source has been installed in its
-normal /usr/src/comedi location),
+comedi kernel module source directory,
the generic functionality is
contained in two parts:
@@ -180,11 +178,11 @@ interface accessible through the
There are some differences in what is possible and/or needed
-in kernel space and in user space, so the functionalities offered in
+in kernel-space and in user-space, so the functionalities offered in
kcomedilib are not an exact copy
of the user-space library. For example, locking, interrupt handling,
real-time execution, callback handling, etc., are only available in
-kernel space.
+kernel-space.
Most drivers don't make use (yet) of these real-time functionalities.
@@ -211,11 +209,11 @@ typedef struct comedi_async_struct comedi_async<
typedef struct comedi_driver_struct comedi_driver;
They can be found in
-/usr/src/comedi/include/linux/comedidev.h.
+include/linux/comedidev.h.
Most of the fields are filled in by the &comedi; infrastructure, but
there are still quite a handful that your driver must provide or use.
As for the user-level &comedi;, each of the hierarchical layers has
-its own data structures: channel (comedi_lrange),
+its own data structures: range (comedi_lrange),
subdevice, and device.
@@ -227,9 +225,9 @@ different meaning: they encode the interaction with the
hardware, not with the user.
-However, the comedi_insn
-and comedi_cmd
-data structures are shared between user space and kernel space: this
+However, the comedi_insn
+and comedi_cmd
+data structures are shared between user-space and kernel-space: this
should come as no surprise, since these data structures contain all
information that the user-space program must transfer to the
kernel-space driver for each acquisition.
@@ -239,17 +237,17 @@ In addition to these data entities that are also known at the user
level (device, sub-device, channel), the device driver level provides
two more data structures which the application programmer doesn't get
in touch with: the data structure
-comedi_driver
+comedi_driver
that stores the device driver information that is relevant at the
operating system level, and the data structure
-comedi_async that stores the
+comedi_async that stores the
information about all asynchronous activities
(interrupts, callbacks and events).
-comedi_lrange
+comedi_lrange
The channel information is simple, since it contains only the signal
@@ -267,7 +265,7 @@ struct comedi_lrange_struct{
-comedi_subdevice
+comedi_subdevice
The subdevice is the smallest &comedi; entity that can be used for
@@ -317,8 +315,8 @@ struct comedi_subdevice_struct{
unsigned int state;
};
-The function pointers (*insn_read) …
-(*cancel) .
+The function pointers insn_read …
+cancel .
offer (pointers to) the standardized
user-visible API
that every subdevice should offer; every device driver has to fill
@@ -327,12 +325,12 @@ in these functions with their board-specific implementations.
definition, not show up in the device driver data structures.)
-The buf_change() and munge()
-functions offer functionality that is not visible to the user and for
+The buf_change and munge
+function pointers offer functionality that is not visible to the user and for
which the device driver writer must provide a board-specific
implementation:
-buf_change() is called when a change in the
-data buffer requires handling; munge() transforms
+buf_change is called when a change in the
+data buffer requires handling; munge transforms
different bit-representations of DAQ values, for example from
unsigned to 2's complement.
@@ -341,7 +339,7 @@ different bit-representations of DAQ values, for example from
-comedi_device
+comedi_device
@@ -386,7 +384,7 @@ struct comedi_device_struct{
-comedi_async
+comedi_async
@@ -433,7 +431,7 @@ struct comedi_async_struct{
-comedi_driver
+comedi_driver
@@ -512,7 +510,7 @@ Board-specific functionality
-The /usr/src/comedi/comedi/drivers
+The comedi/drivers
subdirectory contains
the board-specific device driver
code. Each new card must get an entry in this directory.
@@ -558,7 +556,7 @@ all properties of a device and its subdevices are defined, and filled
in in the generic &comedi; data structures. As part of this, pointers
to the low level instructions being supported by the subdevice have to
be set, which define the basic functionality. In somewhat more detail,
-the mydriver_attach() function must:
+the mydriver_attach function must:
@@ -585,15 +583,15 @@ hardware FIFO, etc.).
-return 1, indicating success. If there were any errors along the way,
-you should return the appropriate error number. If an error is
-returned, the mydriver_detach() function is
-called. The mydriver_detach() function should
+return 1, indicating success. If there were any errors along the way,
+you should return the appropriate (negative) error number. If an error is
+returned, the mydriver_detach function is
+called. The mydriver_detach function should
check any resources that may have been allocated and release them as
necessary. The &comedi; core frees
-dev->subdevices and
-dev->private, so this does not need to be done in
-detach.
+dev->subdevices and
+dev->private, so this does not need to be done in
+mydriver_detach.
@@ -609,7 +607,7 @@ handling routines, and/or callback routines.
Typically, you will be able to implement most of
the above-mentioned functionality by
cut-and-paste from already existing drivers. The
-mydriver_attach() function needs most of your
+mydriver_attach function needs most of your
attention, because it must correctly define and allocate the (private
and generic) data structures that are needed for this device. That is,
each sub-device and each channel must get appropriate data fields, and
@@ -618,16 +616,17 @@ an appropriate initialization. The good news, of course, is that
well with almost all DAQ functionalities found on interface cards.
These can be found in the
header files of the
-/usr/src/comedi/include/linux/
+include/linux/
directory.
-Drivers for digital IOs should implement the following functions:
+Drivers with digital I/O subdevices should implement the following functions,
+setting the function pointers in the comedi_subdevice:
-insn_bits(): drivers set this if they have a
+insn_bits: drivers set this if they have a
function that supports reading and writing multiple bits in a digital
I/O subdevice at the same time. Most (if not all) of the drivers use
this interface instead of insn_read and insn_write for DIO subdevices.
@@ -636,7 +635,7 @@ this interface instead of insn_read and insn_write for DIO subdevices.
-insn_config(): implements INSN_CONFIG
+insn_config: implements INSN_CONFIG
instructions. Currently used for configuring the direction of digital
I/O lines, although will eventually be used for generic configuration
of drivers that is outside the scope of the currently defined &comedi;
@@ -646,27 +645,28 @@ interface.
Finally, the device driver writer must implement the
-read and write functions for
+insn_read and insn_write functions for
the analog channels on the card:
-insn_read(): acquire the inputs on the board and
+insn_read: acquire the inputs on the board and
transfer them to the software buffer of the driver.
-insn_write(): transfer data from the software
+insn_write: transfer data from the software
buffer to the card, and execute the appropriate output conversions.
In some drivers, you want to catch interrupts, and/or want to use the
-INSN_INTTRIG instruction. In this
+INSN_INTTRIG
+instruction. In this
case, you must provide and register these
callback functions.
@@ -722,7 +722,7 @@ hardware interrupt routine.
Another driver-supplied callback function is executed when the user
-program launches an INSN_INTTRIG
+program launches an INSN_INTTRIG
instruction. This event handling is executed
synchronously with the execution of the
triggering instruction.
@@ -741,14 +741,14 @@ statements such as this one:
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR
It fills in the bits corresponding to particular events in the
-comedi_async data structure.
+comedi_async data structure.
The possible event bits are:
-COMEDI_CB_EOA: execute the callback at the
+COMEDI_CB_EOA: execute the callback at the
End-Of-Acquisition (or End-Of-Output).
@@ -756,7 +756,7 @@ The possible event bits are:
-COMEDI_CB_EOS: execute the callback at the
+COMEDI_CB_EOS: execute the callback at the
End-Of-Scan.
@@ -764,7 +764,7 @@ The possible event bits are:
-COMEDI_CB_OVERFLOW: execute the callback when a
+COMEDI_CB_OVERFLOW: execute the callback when a
buffer overflow or underflow has occurred.
@@ -772,7 +772,7 @@ buffer overflow or underflow has occurred.
-COMEDI_CB_ERROR: execute the callback at the
+COMEDI_CB_ERROR: execute the callback at the
occurrence of an (undetermined) error.
@@ -819,9 +819,10 @@ and has no interrupts available.
Drivers are to have absolutely no
-global variables, mainly because the existence of global variables
+global variables (apart from read-only, constant data, or data structures
+shared by all devices), mainly because the existence of global variables
immediately negates any possibility of using the driver for two
-devices. The pointer dev->private should be used
+devices. The pointer dev->private should be used
to point to a structure containing any additional variables needed by
a driver/device combination.
@@ -830,9 +831,9 @@ a driver/device combination.
Drivers should report errors and warnings via the
-comedi_error() function.
+comedi_error function.
(This is not the same function as the user-space
-comedi_perror() function.)
+comedi_perror function.)
@@ -860,14 +861,14 @@ that you call it mydriver.c
-Put your new driver into comedi/drivers/mydriver.c.
+Put your new driver into comedi/drivers/mydriver.c.
-Edit comedi/drivers/Makefile.am and add mydriver.ko
-to the module_PROGRAMS list. Also add a line
+Edit comedi/drivers/Makefile.am and add mydriver.ko
+to the module_PROGRAMS list. Also add a line
mydriver_ko_SOURCES = mydriver.c
@@ -877,10 +878,10 @@ in the alphabetically appropriate place.
-Run ./autogen.sh in the top-level comedi directory. You will
+Run ./autogen.sh in the top-level comedi directory. You will
need to have (a recent version of) autoconf and automake
-installed to successfully run autogen.sh. Afterwards, your driver will
-be built along with the rest of the drivers when you 'make'.
+installed to successfully run autogen.sh. Afterwards, your driver will
+be built along with the rest of the drivers when you run make.
@@ -888,10 +889,11 @@ be built along with the rest of the drivers when you 'make'.
If you want to have your driver included in the &comedi; distribution
(you definitely want to :-) ) send it to
-David Schleef ds@schleef.org or
-Frank Hess fmhess@users.sourceforge.net
-for review and integration. Note your work must be licensed under terms
-compatible with the GNU GPL to be distributed as a part of Comedi.
+the &comedi; mailing list
+for review and integration. See the top-level README
+for details of the &comedi; mailing list.)
+Note your work must be licensed under terms
+compatible with the GNU GPL to be distributed as a part of &comedi;.