diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -194,6 +194,7 @@ insmntque.9 \ intr_event.9 \ intro.9 \ + ioctl.9 \ kasan.9 \ KASSERT.9 \ kern_reboot.9 \ @@ -1347,6 +1348,10 @@ intr_event.9 intr_event_handle.9 \ intr_event.9 intr_event_remove_handler.9 \ intr_event.9 intr_priority.9 +MLINKS+=ioctl.9 _IO.9 \ + ioctl.9 _IOR.9 \ + ioctl.9 _IOW.9 \ + ioctl.9 _IOWR.9 MLINKS+=KASSERT.9 MPASS.9 MLINKS+=kern_reboot.9 reboot.9 \ kern_reboot.9 shutdown_nice.9 diff --git a/share/man/man9/ioctl.9 b/share/man/man9/ioctl.9 new file mode 100644 --- /dev/null +++ b/share/man/man9/ioctl.9 @@ -0,0 +1,301 @@ +.\" Copyright (c) 1999 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Heiko W.Rupp +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd July 3, 2024 +.Dt IOCTL 9 +.Os +.Sh NAME +.Nm _IO , +.Nm _IOR , +.Nm _IOW , +.Nm _IOWR +.Nd "implement a new ioctl call to interact with the kernel" +.Sh SYNOPSIS +.In sys/ioccom.h +.Fn _IO "g" "t" +.Fn _IOR "g" "n" "t" +.Fn _IOW "g" "n" "t" +.Fn _IOWR "g" "n" "t" +.Sh DESCRIPTION +Whenever an +.Xr ioctl 2 +call is made, the kernel dispatches it to the correct device driver or subsystem, +which can interpret the request and process it accordingly. +Ioctls are defined in userspace as: +.Bl -tag -width define +.It #define FOOIOCTL func(t, n, pt) +.El +.Pp +where the different symbols correspond to: +.Bl -tag -width FOOIOCTL +.It Cm FOOIOCTL +The name which will later be given in the +.Xr ioctl 2 +system call as second argument, e.g., +.Dl ioctl(s, FOOIOCTL, ...) . +.It Fn func +A macro, which can be one of +.Bl -tag -width _IOWR +.It _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. +.It _IOR +The call only reads parameters from the kernel and does not +pass any to it +.It _IOW +The call only writes parameters to the kernel, but does not want anything +back +.It _IOWR +The call writes data to the kernel and wants information back. +.El +.It Ar t +This integer describes to which subsystem the ioctl applies. +.Ar t +can be one of +.Bl -tag -width xxxxx -compact +.It '1' +pulse-per-second interface +.It 'a' +ISO networking +.It 'A' +ac devices (hp300) +.It 'A' +Advanced Power Management (hpcmips, i386, sparc), see +.Xr apm 4 +.It 'A' +ADB devices (mac68k, macppc) +.It 'A' +.Xr audio 4 +.It 'b' +Bluetooth HCI sockets, see +.Xr bluetooth 4 +.It 'b' +Bluetooth Hub Control, see +.Xr bthub 4 +.It 'b' +Bluetooth SCO audio driver, see +.Xr btsco 4 +.It 'B' +bell device (x68k) +.It 'B' +.Xr bpf 4 +.It 'c' +coda +.It 'c' +.Xr \&cd 4 +.It 'c' +.Xr \&ch 4 +.It 'C' +clock devices (amiga, atari, hp300, x68k) +.It 'd' +the disk subsystem +.It 'E' +.Xr envsys 4 +.It 'f' +files +.It 'F' +Sun-compatible framebuffers +.It 'F' +.Xr ccd 4 +and +.Xr vnd 4 +.It 'g' +qdss framebuffers +.It 'G' +grf devices (amiga, atari, hp300, mac68k, x68k) +.It 'h' +HIL devices (hp300) +.It 'H' +HIL devices (hp300) +.It 'H' +HPc framebuffers +.It 'i' +a (pseudo) interface +.It 'I' +.Xr ite 4 +(mac68k) +.It 'J' +ISA joystick interface +.It 'k' +Sun-compatible (and other) keyboards +.It 'l' +leo devices (atari) +.It 'm' +.Xr mtio 4 +.It 'M' +mouse devices (atari) +.It 'M' +.Xr mlx 4 +.It 'n' +virtual console device (arm32) +.It 'n' +SMB networking +.It 'O' +OpenPROM and OpenFirmware +.It 'p' +power control (x68k) +.It 'P' +parallel port (amiga, x68k) +.It 'P' +profiling (arm32) +.It 'P' +printer/plotter interface (hp300) +.It 'P' +pci(4) +.It 'P' +compat/ossaudio and soundcard.h +.It 'P' +.Xr sparc/magma 4 +bpp (sparc) +.It 'q' +.Xr altq 9 +.It 'q' +pmax graphics devices +.It 'Q' +.Xr altq 9 +.It 'Q' +raw SCSI commands +.It 'r' +the routing subsystem +.It 'r' +.Xr \&md 4 +.It 'R' +.Xr rnd 4 +.It 's' +the socket layer +.It 'S' +SCSI disks (arc, hp300, pmax) +.It 'S' +watchdog devices (sh3) +.It 'S' +ISA speaker devices +.It 'S' +stic devices +.It 'S' +scanners +.It 't' +the tty layer +.It 'u' +user defined ??? +.It 'U' +scsibus (see +.Xr scsi 4 ) +.It 'v' +Sun-compatible +.Dq firm events +.It 'V' +view device (amiga, atari) +.It 'V' +sram device (x68k) +.It 'w' +watchdog devices +.It 'W' +wt devices +.It 'W' +wscons devices +.It 'x' +bt8xx devices +.It 'Z' +ite devices (amiga, atari, x68k) +.It 'Z' +passthrough ioctls +.El +.It Ar n +This number uniquely identifies the ioctl within the group. +That said, two subsystems may share the same +.Fa g , +but there may be only one +.Fa n +for a given +.Fa g . +This is an unsigned 8 bit number. +.It Ar 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). +.El +.Sh RETURN VALUES +All +.Fn *_ioctl +routines +.Em within the kernel +should return either 0 for success +or a defined error code, as described in +.In sys/errno.h . +At the libc level though a conversion takes place, so that eventually +.Xr ioctl 2 +returns either 0 for success or -1 for failure, in which case the +.Va errno +variable is set accordingly. +.Pp +The use of magic numbers such as -1, to indicate that a given ioctl +code was not handled, is strongly discouraged. +The value -1 is bound to the +.Er ERESTART +pseudo-error, which is returned inside kernel to modify return to process. +.Sh EXAMPLES +Let's suppose that we want to pass an integer value to the kernel. +From the user's point of view, this operation would write data to the kernel, +so we define the ioctl macro in userspace as: +.Bd -literal -offset indent +#define FOOIOCTL _IOW('i', 22, int) +.Ed +.Pp +Once defined, the macro can be used as an argument to +.Xr ioctl 2 : +.Bd -literal -offset indent +int a = 101; + +if (ioctl(fd, FOOICTL, \*[Am]a) == -1) + err(1, "FOOICTL ioctl failed"); +.Ed +.Pp +In the kernel, a +.Fn *_ioctl Ns No -routine +can then process the request and data: +.Bd -literal -offset indent +int +driver_ioctl(..., u_long cmd, void *data, ...) +{ + int val; + + switch (cmd) { + case FOOIOCTL: + val = *(int *)data; + printf("Value passed from userspace: %d\en", val); + break; + default: + /* Inappropriate ioctl for device */ + return (ENOTTY); + } + + return (0); +} +.Ed +.Sh SEE ALSO +.Xr ioctl 2