LDP/LDP/guide/docbook/lkmpg-2.6/07-TalkingToDeviceFiles.sgml

78 lines
5.0 KiB
Plaintext

<sect1><title>Talking to Device Files (writes and IOCTLs)</title>
<indexterm><primary>ioctl</primary></indexterm>
<indexterm><primary>device files</primary><secondary>input to</secondary></indexterm>
<indexterm><primary>device files</primary><secondary>write to</secondary></indexterm>
<para>Device files are supposed to represent physical devices. Most physical devices are used for output as well as input, so
there has to be some mechanism for device drivers in the kernel to get the output to send to the device from processes. This
is done by opening the device file for output and writing to it, just like writing to a file. In the following example, this
is implemented by <function>device_write</function>.</para>
<para>This is not always enough. Imagine you had a serial port connected to a modem (even if you have an internal modem, it is
still implemented from the CPU's perspective as a serial port connected to a modem, so you don't have to tax your imagination
too hard). The natural thing to do would be to use the device file to write things to the modem (either modem commands or data
to be sent through the phone line) and read things from the modem (either responses for commands or the data received through
the phone line). However, this leaves open the question of what to do when you need to talk to the serial port itself, for
example to send the rate at which data is sent and received.</para>
<indexterm><primary>serial port</primary></indexterm>
<indexterm><primary>modem</primary></indexterm>
<para>The answer in Unix is to use a special function called <function>ioctl</function> (short for Input Output ConTroL).
Every device can have its own <function>ioctl</function> commands, which can be read <function>ioctl</function>'s (to send
information from a process to the kernel), write <function>ioctl</function>'s (to return information to a process),
<footnote><para>Notice that here the roles of read and write are reversed <emphasis>again</emphasis>, so in
<function>ioctl</function>'s read is to send information to the kernel and write is to receive information from the
kernel.</para></footnote> both or neither. The <function>ioctl</function> function is called with three parameters: the file
descriptor of the appropriate device file, the ioctl number, and a parameter, which is of type long so you can use a cast to
use it to pass anything. <footnote><para>This isn't exact. You won't be able to pass a structure, for example, through an
ioctl --- but you will be able to pass a pointer to the structure.</para></footnote></para>
<para>The ioctl number encodes the major device number, the type of the ioctl, the command, and the type of the parameter.
This ioctl number is usually created by a macro call (<varname>_IO</varname>, <varname>_IOR</varname>, <varname>_IOW</varname>
or <varname>_IOWR</varname> --- depending on the type) in a header file. This header file should then be included both by the
programs which will use <function>ioctl</function> (so they can generate the appropriate <function>ioctl</function>'s) and by
the kernel module (so it can understand it). In the example below, the header file is <filename
class="headerfile">chardev.h</filename> and the program which uses it is <function>ioctl.c</function>.</para>
<indexterm><primary>_IO</primary></indexterm>
<indexterm><primary>_IOR</primary></indexterm>
<indexterm><primary>_IOW</primary></indexterm>
<indexterm><primary>_IOWR</primary></indexterm>
<para>If you want to use <function>ioctl</function>s in your own kernel modules, it is best to receive an official
<function>ioctl</function> assignment, so if you accidentally get somebody else's <function>ioctl</function>s, or if they get
yours, you'll know something is wrong. For more information, consult the kernel source tree at
<filename>Documentation/ioctl-number.txt</filename>.</para>
<indexterm><primary>official ioctl assignment</primary></indexterm>
<indexterm><primary>ioctl</primary><secondary>official assignment</secondary></indexterm>
<indexterm><primary>source file</primary><secondary>chardev.c</secondary></indexterm>
<example><title>chardev.c</title><programlisting><inlinegraphic fileref="lkmpg-examples/07-TalkingToDeviceFiles/chardev.c" format="linespecific"/></inlinegraphic></programlisting></example>
<indexterm><primary>source file</primary><secondary><filename>chardev.h</filename></secondary></indexterm>
<example><title>chardev.h</title><programlisting><inlinegraphic fileref="lkmpg-examples/07-TalkingToDeviceFiles/chardev.h" format="linespecific"/></inlinegraphic></programlisting></example>
<indexterm><primary>defining ioctls</primary></indexterm>
<indexterm><primary>ioctl</primary><secondary>defining</secondary></indexterm>
<indexterm><primary>source file</primary><secondary><filename>ioctl.c</filename></secondary></indexterm>
<example><title>ioctl.c</title><programlisting><inlinegraphic fileref="lkmpg-examples/07-TalkingToDeviceFiles/ioctl.c" format="linespecific"/></inlinegraphic></programlisting></example>
</sect1>
<!--
vim: tw=128
-->