doc/driverwriting.xml: Various changes.
authorIan Abbott <abbotti@mev.co.uk>
Wed, 9 May 2012 14:50:17 +0000 (15:50 +0100)
committerIan Abbott <abbotti@mev.co.uk>
Wed, 9 May 2012 14:50:17 +0000 (15:50 +0100)
Some DocBook mark-up changes.  Also avoided absolute path-names for
sources as people tend to put them in different places!  Also changed
instructions for submitting drivers for review.

doc/driverwriting.xml

index 2ed32e6368faeab133aba81f15807d94df0b1cd2..12cfb06563381d4fbd4c7eb3120568bcb08f6803 100644 (file)
@@ -11,13 +11,13 @@ Writing a &comedi; driver
 </title>
 
 <para>
-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.
 </para>
 <para>
-This Section does <emphasis>not</emphasis> explain all implementation
+This section does <emphasis>not</emphasis> 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:
 <listitem>
 <para>
 How does the
-<link linkend="userkernelhow">communication</link> between user space
-and kernel space work?
+<link linkend="userkernelhow">communication</link> between user-space
+and kernel-space work?
 </para>
 </listitem>
 
@@ -74,13 +74,13 @@ manufacturers all use their own design and nomenclature.
 
 <section id="userkernelhow">
 <title>
-Communication user space-kernel space
+Communication user-space &mdash; kernel-space
 </title>
 
 <para>
-In user space, you interact with the functions implemented in the
-<filename role="directory">/usr/src/comedilib</filename> 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
 <filename role="directory">lib</filename> subdirectory.
 </para>
 <para>
@@ -89,27 +89,27 @@ All user-space &comedi;
 <link linkend="commandsstreaming">commands</link>
 are transmitted to kernel space through a traditional
 <function>ioctl</function> system call.
-(See <filename>/usr/src/comedilib/lib/ioctl.c</filename>.)
-The user space information command is <emphasis>encoded</emphasis> as
+(See <filename>lib/ioctl.c</filename> in Comedilib.)
+The user-space information command is <emphasis>encoded</emphasis> as
 a number in the <function>ioctl</function> 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
-<filename>/usr/src/comedi/comedi/comedi_fops.c</filename> file: the
-<function>comedi_ioctl()</function> function processes the results of
+<filename>comedi_fops.c</filename> file in the Comedi sources: the
+<function>comedi_unlocked_ioctl</function> function processes the results of
 the <function>ioctl</function> system call, interprets its contents,
-and then calls the corresponding kernel space
+and then calls the corresponding kernel-space
 <function>do_&hellip;_ioctl</function> function(s).
 For example, a &comedi;
 <link linkend="instructions">instruction</link> is further processed
-by the <function>do_insn_ioctl()</function>function. (Which, in turn,
-uses <function>parse_insn()</function> for further detailed processing.)
+by the <function>do_insn_ioctl</function> function. (Which, in turn,
+uses <function>parse_insn</function> for further detailed processing.)
 </para>
 <para>
 The data corresponding to instructions and commands is transmitted
-with the <function>copy_from_user()</function> system call;
-acquisition data captured by the interface card passes the kernel-user
-space boundary with the help of a <function>copy_to_user()</function>
-system call.
+with the <function>copy_from_user</function> function;
+acquisition data captured by the interface card passes the
+kernel/user-space boundary with the help of a <function>copy_to_user</function>
+function.
 </para>
 
 </section>
@@ -144,7 +144,7 @@ RTLinux/Free, and spinlocks for atomic sections.
 <listitem>
 <para>
 <filename>include/linux/comedilib.h</filename>: the header file for
-the kernel library of &comedi;.
+the kernel library of &comedi; (<systemitem>kcomedilib</systemitem> module).
 </para>
 </listitem>
 
@@ -152,9 +152,7 @@ the kernel library of &comedi;.
 </para>
 <para>
 From all the relevant &comedi; device driver code that is found in the
-<filename role="directory">/usr/src/comedi/comedi</filename> directory
-(<emphasis>if</emphasis> the &comedi; source has been installed in its
-normal <filename role="directory">/usr/src/comedi</filename> location),
+<filename role="directory">comedi</filename> kernel module source directory,
 the <emphasis role="strong">generic</emphasis> functionality is
 contained in two parts:
  <itemizedlist>
@@ -180,11 +178,11 @@ interface accessible through the
 </para>
 <para>
 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
 <filename role="directory">kcomedilib</filename> 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.
  </para>
  <para>
 Most drivers don't make use (yet) of these real-time functionalities.
@@ -211,11 +209,11 @@ typedef struct comedi_async_struct     <link linkend="comediasync">comedi_async<
 typedef struct comedi_driver_struct    <link linkend="comedidriver">comedi_driver</link>;
 </programlisting>
 They can be found in
-<filename>/usr/src/comedi/include/linux/comedidev.h</filename>.
+<filename>include/linux/comedidev.h</filename>.
 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 (<function>comedi_lrange</function>),
+its own data structures: range (<type>comedi_lrange</type>),
 subdevice, and device.
 </para>
 <para>
@@ -227,9 +225,9 @@ different meaning: they encode the interaction with the
 <emphasis>hardware</emphasis>, not with the <emphasis>user</emphasis>.
 </para>
 <para>
-However, the <link linkend="ref-type-comedi-insn">comedi_insn</link>
-and <link linkend="ref-type-comedi-cmd">comedi_cmd</link>
-data structures are shared between user space and kernel space: this
+However, the <type><link linkend="ref-type-comedi-insn">comedi_insn</link></type>
+and <type><link linkend="ref-type-comedi-cmd">comedi_cmd</link></type>
+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
-<link linkend="comedidriver">comedi_driver</link>
+<type><link linkend="comedidriver">comedi_driver</link></type>
 that stores the device driver information that is relevant at the
 operating system level, and the data structure
-<link linkend="comediasync">comedi_async</link> that stores the
+<type><link linkend="comediasync">comedi_async</link></type> that stores the
 information about all <emphasis>asynchronous</emphasis> activities
 (interrupts, callbacks and events).
 </para>
 
 <section id="comedilrange">
 <title>
-<function>comedi_lrange</function>
+<type>comedi_lrange</type>
 </title>
 <para>
 The channel information is simple, since it contains only the signal
@@ -267,7 +265,7 @@ struct comedi_lrange_struct{
 
 <section id="comedisubdevice">
 <title>
-<function>comedi_subdevice</function>
+<type>comedi_subdevice</type>
 </title>
 <para>
 The subdevice is the smallest &comedi; entity that can be used for
@@ -317,8 +315,8 @@ struct comedi_subdevice_struct{
   unsigned int state;
 };
 </programlisting>
-The function pointers <function>(*insn_read)</function> &hellip;
-<function>(*cancel)</function> .
+The function pointers <structfield>insn_read</structfield> &hellip;
+<structfield>cancel</structfield> .
 offer (pointers to) the standardized
 <link linkend="functionreference">user-visible API</link>
 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.)
 </para>
 <para>
-The <function>buf_change()</function> and <function>munge()</function>
-functions offer functionality that is not visible to the user and for
+The <structfield>buf_change</structfield> and <structfield>munge</structfield>
+function pointers offer functionality that is not visible to the user and for
 which the device driver writer must provide a board-specific
 implementation:
-<function>buf_change()</function> is called when a change in the
-data buffer requires handling; <function>munge()</function> transforms
+<function>buf_change</function> is called when a change in the
+data buffer requires handling; <function>munge</function> transforms
 different bit-representations of DAQ values, for example from
 <emphasis>unsigned</emphasis> to <emphasis>2's complement</emphasis>.
 </para>
@@ -341,7 +339,7 @@ different bit-representations of DAQ values, for example from
 
 <section id="comedidevice">
 <title>
-<function>comedi_device</function>
+<type>comedi_device</type>
 </title>
 
 <para>
@@ -386,7 +384,7 @@ struct comedi_device_struct{
 
 <section id="comediasync">
 <title>
-<function>comedi_async</function>
+<type>comedi_async</type>
 </title>
 
 <para>
@@ -433,7 +431,7 @@ struct comedi_async_struct{
 
 <section id="comedidriver">
 <title>
-<function>comedi_driver</function>
+<type>comedi_driver</type>
 </title>
 
 <para>
@@ -512,7 +510,7 @@ Board-specific functionality
 </title>
 
 <para>
-The <filename role="directory">/usr/src/comedi/comedi/drivers</filename>
+The <filename role="directory">comedi/drivers</filename>
 subdirectory contains
 the <emphasis role="strong">board-specific</emphasis> 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 <function>mydriver_attach()</function> function must:
+the <function>mydriver_attach</function> function must:
 <itemizedlist>
 
 <listitem>
@@ -585,15 +583,15 @@ hardware FIFO, etc.).
 
 <listitem>
 <para>
-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 <function>mydriver_detach()</function> function is
-called.  The <function>mydriver_detach()</function> function should
+return <literal>1</literal>, indicating success. If there were any errors along the way,
+you should return the appropriate (negative) error number.  If an error is
+returned, the <function>mydriver_detach</function> function is
+called.  The <function>mydriver_detach</function> function should
 check any resources that may have been allocated and release them as
 necessary.  The &comedi; core frees
-<function>dev->subdevices</function> and
-<function>dev->private</function>, so this does not need to be done in
-<function>detach</function>.
+<structfield>dev->subdevices</structfield> and
+<structfield>dev->private</structfield>, so this does not need to be done in
+<function>mydriver_detach</function>.
 </para>
 </listitem>
 
@@ -609,7 +607,7 @@ handling routines, and/or callback routines.
 Typically, you will be able to implement most of
 the above-mentioned functionality by
 <emphasis>cut-and-paste</emphasis> from already existing drivers. The
-<function>mydriver_attach()</function> function needs most of your
+<function>mydriver_attach</function> 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
 <link linkend="comedikernelgeneric">header files</link> of the
-<filename role="directory">/usr/src/comedi/include/linux/</filename>
+<filename role="directory">include/linux/</filename>
 directory.
 </para>
 <para>
-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 <type>comedi_subdevice</type>:
 <itemizedlist>
 
 <listitem>
 <para>
-<function>insn_bits()</function>: drivers set this if they have a
+<function>insn_bits</function>: 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.
 
 <listitem>
 <para>
-<function>insn_config()</function>: implements INSN_CONFIG
+<function>insn_config</function>: implements <constant>INSN_CONFIG</constant>
 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.
 
 </itemizedlist>
 Finally, the device driver writer must implement the
-<function>read</function> and <function>write</function> functions for
+<function>insn_read</function> and <function>insn_write</function> functions for
 the analog channels on the card:
 <itemizedlist>
 
 <listitem>
 <para>
-<function>insn_read()</function>: acquire the inputs on the board and
+<function>insn_read</function>: acquire the inputs on the board and
 transfer them to the software buffer of the driver.
 </para>
 </listitem>
 
 <listitem>
 <para>
-<function>insn_write()</function>: transfer data from the software
+<function>insn_write</function>: transfer data from the software
 buffer to the card, and execute the appropriate output conversions.
 </para>
 </listitem>
 
 </itemizedlist>
 In some drivers, you want to catch interrupts, and/or want to use the
-<link linkend="insn-inttrig">INSN_INTTRIG</link> instruction. In this
+<constant><link linkend="insn-inttrig">INSN_INTTRIG</link></constant>
+instruction. In this
 case, you must provide and register these
 <link linkend="drivercallbacks">callback</link> functions.
 </para>
@@ -722,7 +722,7 @@ hardware interrupt routine.
 <listitem>
 <para>
 Another driver-supplied callback function is executed when the user
-program launches an <link linkend="insn-inttrig">INSN_INTTRIG</link>
+program launches an <constant><link linkend="insn-inttrig">INSN_INTTRIG</link></constant>
 instruction. This event handling is executed
 <emphasis>synchronously</emphasis> 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
 </programlisting>
 It fills in the bits corresponding to particular events in the
-<link linkend="comediasync">comedi_async</link> data structure.
+<type><link linkend="comediasync">comedi_async</link></type> data structure.
 The possible event bits are:
 <itemizedlist>
 
 <listitem>
 <para>
 <anchor id="comedi-cb-eoa"/>
-<parameter>COMEDI_CB_EOA</parameter>: execute the callback at the
+<constant>COMEDI_CB_EOA</constant>: execute the callback at the
 <quote>End-Of-Acquisition</quote> (or <quote>End-Of-Output</quote>).
 </para>
 </listitem>
@@ -756,7 +756,7 @@ The possible event bits are:
 <listitem>
 <para>
 <anchor id="comedi-cb-eos"/>
-<parameter>COMEDI_CB_EOS</parameter>: execute the callback at the
+<constant>COMEDI_CB_EOS</constant>: execute the callback at the
 <quote>End-Of-Scan</quote>.
 </para>
 </listitem>
@@ -764,7 +764,7 @@ The possible event bits are:
 <listitem>
 <para>
 <anchor id="comedi-cb-overflow"/>
-<parameter>COMEDI_CB_OVERFLOW</parameter>: execute the callback when a
+<constant>COMEDI_CB_OVERFLOW</constant>: execute the callback when a
 buffer overflow or underflow has occurred.
 </para>
 </listitem>
@@ -772,7 +772,7 @@ buffer overflow or underflow has occurred.
 <listitem>
 <para>
 <anchor id="comedi-cb-error"/>
-<parameter>COMEDI_CB_ERROR</parameter>: execute the callback at the
+<constant>COMEDI_CB_ERROR</constant>: execute the callback at the
 occurrence of an (undetermined) error.
 </para>
 </listitem>
@@ -819,9 +819,10 @@ and has no interrupts available.
 <listitem>
 <para>
 Drivers are to have absolutely <emphasis role="strong">no</emphasis>
-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 <function>dev->private</function> should be used
+devices. The pointer <structfield>dev->private</structfield> should be used
 to point to a structure containing any additional variables needed by
 a driver/device combination.
 </para>
@@ -830,9 +831,9 @@ a driver/device combination.
 <listitem>
 <para>
 Drivers should report errors and warnings via the
-<function>comedi_error()</function> function.
+<function>comedi_error</function> function.
 (This is <emphasis>not</emphasis> the same function as the user-space
-<link linkend="func-ref-comedi-perror">comedi_perror()</link> function.)
+<function><link linkend="func-ref-comedi-perror">comedi_perror</link></function> function.)
 
 </para>
 </listitem>
@@ -860,14 +861,14 @@ that you call it <quote>mydriver.c</quote>
 
 <listitem>
 <para>
-Put your new driver into <quote>comedi/drivers/mydriver.c</quote>.
+Put your new driver into <filename>comedi/drivers/mydriver.c</filename>.
 </para>
 </listitem>
 
 <listitem>
 <para>
-Edit <quote>comedi/drivers/Makefile.am</quote> and add <quote>mydriver.ko</quote>
-to the <quote>module_PROGRAMS</quote> list.  Also add a line
+Edit <filename>comedi/drivers/Makefile.am</filename> and add <literal>mydriver.ko</literal>
+to the <literal>module_PROGRAMS</literal> list.  Also add a line
 <programlisting>
 mydriver_ko_SOURCES = mydriver.c
 </programlisting>
@@ -877,10 +878,10 @@ in the alphabetically appropriate place.
 
 <listitem>
 <para>
-Run ./autogen.sh in the top-level comedi directory.  You will
+Run <command>./autogen.sh</command> 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 <command>autogen.sh</command>.  Afterwards, your driver will
+be built along with the rest of the drivers when you run <command>make</command>.
 </para>
 </listitem>
 
@@ -888,10 +889,11 @@ be built along with the rest of the drivers when you 'make'.
 <para>
 If you want to have your driver included in the &comedi; distribution
 (you <emphasis>definitely</emphasis> want to :-) ) send it to
-David Schleef <address><email>ds@schleef.org</email></address> or
-Frank Hess <address><email>fmhess@users.sourceforge.net</email></address>
-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 <filename>README</filename>
+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;.
 </para>
 </listitem>
 </itemizedlist>