IOCTL(9)
π NAME π
okay so bestie, this is IOCTL(9) from the Kernel Developer's Manual, and it's literally all about ioctl β how to implement a new ioctl call to access device drivers. Kernel messages, but make it fashion π
β¨ SYNOPSIS β¨
include these, bestie:
#include <sys/ioctl.h>
#include <sys/ioccom.h>
int
ioctl(int, unsigned long, ...);
π¦ DESCRIPTION π¦
okay so 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 theioctl(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.tcan be one of:
the same letter can absolutely pop up for different subsystems, so read the whole line, bestie π
'1'β pulse-per-second interface'a'β ISO networking'A'β ac devices (hp300)'A'β Advanced Power Management (hpcmips, i386, sparc), seeapm(4)'A'β ADB devices (mac68k, macppc)'A'βaudio(4)'b'β Bluetooth HCI sockets, seebluetooth(4)'b'β Bluetooth Hub Control, seebthub(4)'b'β Bluetooth SCO audio driver, seebtsco(4)'B'β bell device (x68k)'B'βbpf(4)'c'β coda'c'βcd(4)'c'βch(4)'C'β clock devices (amiga, atari, hp300, x68k)'d'β the disk subsystem'E'βenvsys(4)'f'β files'F'β Sun-compatible framebuffers'F'βccd(4)andvnd(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'β sparc/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'βrnd(4)'s'β the socket layer'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 (seescsi(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 onenfor a givent. 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 orsizeof(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.
π¨ Bestie, do not do the magic-number thing. The use of magic numbers such as-1, to indicate that a given ioctl code was not handled is strongly discouraged. The value-1coincides with the historic value forERESTARTwhich was shown to produce user space code that never returned from a call toioctl(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 π
here's the little demo, bestie:
#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 π
π This page is brought to you by the Debian source/version, dated July 7, 2022, and filed under IOCTL(9) β mwah, go slay those ioctls! π
π¦ where this page comes from
- nixpkgs unstable: netbsd-source 11.0
- Copyright (c) 1999 The NetBSD Foundation, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms