NAME
ioctl —
how to implement a new ioctl
call to access device drivers
SYNOPSIS
#include <sys/ioctl.h>
#include <sys/ioccom.h>
int
ioctl(
int,
unsigned long,
...);
DESCRIPTION
ioctl are internally defined as
-
-
- #define FOOIOCTL
fun(t,n,pt)
-
where the different variables and functions are:
-
-
- FOOIOCTL
- the name which will later be given in the
ioctl(2) system call as
second argument, e.g.,
ioctl(s, FOOIOCTL, ...).
-
-
- fun()
- a macro which can be one of
-
-
- _IO
- the call is a simple message to the kernel by itself.
It does not copy anything into the kernel, nor does it want anything
back.
-
-
- _IOR
- the call only reads parameters from the kernel and does
not pass any to it
-
-
- _IOW
- the call only writes parameters to the kernel, but does
not want anything back
-
-
- _IOWR
- the call writes data to the kernel and wants
information back.
-
-
- t
- This integer describes to which subsystem the ioctl
applies. t can be one of
- '1'
- pulse-per-second interface
- '4'
- isdn(4)
- 'a'
- ISO networking
- 'A'
- ac devices (hp300)
- 'A'
- Advanced Power Management (hpcmips, i386, sparc), see
apm(4)
- 'A'
- ADB devices (mac68k, macppc)
- 'A'
- audio(4)
- 'A'
- isdntel(4)
- 'b'
- tb(4)
- 'b'
- Bluetooth HCI sockets, see
bluetooth(4)
- 'b'
- Bluetooth Hub Control, see
bthub(4)
- 'b'
- Bluetooth SCO audio driver, see
btsco(4)
- 'B'
- bell device (x68k)
- 'B'
- bpf(4)
- 'c'
- coda
- 'c'
- cd(4)
- 'c'
- ch(4)
- 'C'
- clock devices (amiga, atari, hp300, x68k)
- 'C'
- isdnctl(4)
- 'd'
- the disk subsystem
- 'E'
- envsys(4)
- 'f'
- files
- 'F'
- Sun-compatible framebuffers
- 'F'
- ccd(4) and
vnd(4)
- 'g'
- qdss framebuffers
- 'G'
- grf devices (amiga, atari, hp300, mac68k, x68k)
- 'h'
- HIL devices (hp300)
- 'H'
- HIL devices (hp300)
- 'H'
- HPc framebuffers
- 'i'
- a (pseudo) interface
- 'I'
- ite(4)
(mac68k)
- 'J'
- ISA joystick interface
- 'k'
- Sun-compatible (and other) keyboards
- 'l'
- leo devices (atari)
- 'm'
- mtio(4)
- 'M'
- mouse devices (atari)
- 'M'
- mlx(4)
- 'n'
- virtual console device (arm32)
- 'n'
- SMB networking
- 'O'
- OpenPROM and OpenFirmware
- 'p'
- power control (x68k)
- 'P'
- parallel port (amiga, x68k)
- 'P'
- profiling (arm32)
- 'P'
- printer/plotter interface (hp300)
- 'P'
- pci(4)
- 'P'
- compat/ossaudio and soundcard.h
- 'P'
- magma(4)
bpp (sparc)
- 'q'
- altq(9)
- 'q'
- pmax graphics devices
- 'Q'
- altq(9)
- 'Q'
- raw SCSI commands
- 'r'
- the routing subsystem
- 'r'
- md(4)
- 'R'
- isdnbchan(4)
- 'R'
- rnd(4)
- 's'
- the socket layer
- 's'
- satlink devices
- 'S'
- SCSI disks (arc, hp300, pmax)
- 'S'
- watchdog devices (sh3)
- 'S'
- ISA speaker devices
- 'S'
- stic devices
- 'S'
- scanners
- 't'
- the tty layer
- 'u'
- user defined ???
- 'U'
- scsibus (see
scsi(4))
- 'v'
- Sun-compatible “firm events”
- 'V'
- view device (amiga, atari)
- 'V'
- sram device (x68k)
- 'w'
- watchdog devices
- 'W'
- wt devices
- 'W'
- wscons devices
- 'x'
- bt8xx devices
- 'Z'
- ite devices (amiga, atari, x68k)
- 'Z'
- passthrough ioctls
-
-
- n
- This numbers the ioctl within the group. There may be only
one n for a given t. This is
an unsigned 8 bit number.
-
-
- pt
- This specifies the type of the passed parameter. This one
gets internally transformed to the size of the parameter, so for example,
if you want to pass a structure, then you have to specify that structure
and not a pointer to it or sizeof(struct foo)
In order for the new ioctl to be known to the system it is installed in either
⟨
sys/ioctl.h⟩ or one of the files that are
reached from ⟨
sys/ioctl.h⟩.
RETURN VALUES
All
ioctl() routines should return either 0 or a defined error
code. The use of magic numbers such as -1, to indicate that a given ioctl code
was not handled is strongly discouraged. The value -1 coincides with the
historic value for
ERESTART which was shown to produce user
space code that never returned from a call to
ioctl(2).
For ioctl codes that are not handled by a given routine, the pseudo error value
EPASSTHROUGH is provided.
EPASSTHROUGH
indicates that no error occurred during processing (it did not fail), but
neither was anything processed (it did not succeed). This supersedes the use
of either
ENOTTY (which is an explicit failure) or -1 (which
has no contextual meaning) as a return value.
ENOTTY will
get passed directly back to user space and bypass any further processing by
other ioctl layers. Only code that wishes to suppress possible further
processing of an ioctl code (e.g., the tty line discipline code) should return
ENOTTY. All other code should return
EPASSTHROUGH, even if it knows that no other layers will be
called upon.
If the value
EPASSTHROUGH is returned to
sys_ioctl(), then it will there be changed to
ENOTTY to be returned to user space, thereby providing the
proper error notification to the application.
EXAMPLES
#define FOOIOCTL _IOWR('i', 23, int)
int a = 3;
error = ioctl(s, FOOICTL, &a);
Within the
ioctl()
-routine of the
driver, it can be then accessed like
driver_ioctl(..., u_long cmd, void *data)
{
...
switch (cmd) {
case FOOIOCTL:
int *a = (int *)data;
printf(" Value passed: %d\n", *a);
break;
}
}
NOTES
Note that if you for example try to read information from an ethernet driver
where the name of the card is included in the third argument (e.g., ioctl(s,
READFROMETH, struct ifreq *)), then you have to use the
_IOWR() form not the
_IOR(), as passing
the name of the card to the kernel already consists of writing data.
SEE ALSO
ioctl(2)