ioctl -- perform device-specific control functions


   #include <sys/types.h>
   #include <sys/cred.h>
   #include <sys/file.h>
   #include <sys/errno.h>
   #include <sys/ddi.h>

int prefixioctl(void *idata, channel_t channel, int cmd, void *arg, int oflags, cred_t *crp, int *rvalp);


The driver's ioctl( ) routine provides non-STREAMS drivers with an alternate entry point that is called to handle custom I/O operations beyond simple transfers of data.


For hardware drivers, pointer to the device-specific instance as returned by the CFG_ADD subfunction of the config(D2) entry point routine. See ``Device instance'' in HDK Technical Reference.

Channel number used to select subcomponents and/or operating modes of this device instance. See ``Channel number'' in HDK Technical Reference.

Command argument the driver ioctl routine interprets as the operation to be performed.

Passes parameters between the user and the driver. The interpretation of the argument is dependent on the command and the driver. For example, the argument can be an integer, or it can be the address of a user structure containing driver or hardware settings.

Contains the file flags set when the device was opened. The driver can use this to determine if the device was opened for reading (FREAD), writing (FWRITE), and so on. See open(D2) for a description of the values.

Pointer to the user credential structure.

Pointer to the return value for the calling process. The driver may elect to set the value if the ioctl(D2) succeeds.

Return values

The ioctl routine should return 0 for success, or the appropriate error number from those listed on errnos(D5). The system call will usually return 0 on success or -1 on failure, with errno set to an appropriate value. However, the driver can choose to have the system call return a different value on success by passing the value through the rvalp pointer. EINVAL should be returned if a particular cmd is not supported by the driver.


This entry point is optional. It is only called when the device is open.

I/O control commands can be used to do a variety of device-specific I/O operations that are not supported by the standard entry point routines. The ioctl( ) routine is basically a switch statement, with each case definition corresponding to a different ioctl command identifying the action to be taken. Driver-specific ioctl commands should be defined in the driver's header file and documented on the driver's Section 7 manual page. Some interfaces and device types have ioctl commands that are described on manual pages for the interface or device type. See, for example, sdi. Drivers must support all the documented ioctl commands for the interface or device type.

Most often, ioctl is used to control device hardware parameters and establish the protocol used by the driver in processing data. I/O control commands are used to implement terminal settings, to format disk devices, to implement a trace driver for debugging, and to flush queues. Drivers that need to access data through DMA or kernel virtual mechanisms can use the uiobuf(D3) function to set this up.

If arg is a pointer to user space, the driver can use copyin(D3) and copyout(D3) to transfer data between kernel and user space.

Drivers that need to identify the specific unit number can extract that information from the idata pointer that is returned by the CFG_ADD subfunction config(D2) entry point. Operating mode information can be extracted from the channel number information that is returned by the CFG_ADD subfunction of the config(D2) entry point routine.

STREAMS drivers do not have ioctl routines. The stream head converts I/O control commands to M_IOCTL(D7str) messages, which are handled by the driver's put(D2str) or srv(D2str) routine.

Context and synchronization

User context. The driver can block and can do operations such as copyout(D3) that require access to the requesting process's user-level address space.


An attempt should be made to keep the values for driver-specific I/O control commands distinct from others in the system. Each driver's I/O control commands are unique, but it is possible for user-level code to access a driver with an I/O control command that is intended for another driver, which can have serious results.

A common method to assign I/O control command values that are less apt to be duplicated is to compose the commands from some component unique to the driver (such as a module name or ID), and a counter, as in:

   	#define PREFIX		('h'<<16|'d'<<8)
   	#define COMMAND1		(PREFIX|1)
   	#define COMMAND2		(PREFIX|2)
   	#define COMMAND3		(PREFIX|3)
To decrease the likelihood of name collision, register your prefix with the registration service by sending email to ``''.

Hardware applicability


Version applicability

ddi: 1, 2, 3, 4, 5, 5mp, 6, 6mp, 7, 7mp, 7.1, 7.1mp, 8, 8mp

Differences between versions

The syntax for ioctl( ) in DDI versions prior to version 8 is:
   int prefixioctl(dev_t dev, int cmd, void *arg, int mode, cred_t *crp,
   	int *rvalp);
dev is the device number for the device to be accessed.

In DDI versions prior to version 8, ioctl( ) is available only to character device drivers, and is a named entry point that must be defined as a global symbol.

External dependencies

For DDI 8 and later versions, drivers must declare this entry point routine in the d_ioctl member of their drvops(D4) structure.

Named entry point routines must be declared in the driver's Master(DSP/4dsp) file. The declaration for this entry point is $entry ioctl. This applies only to non-STREAMS drivers that use DDI versions prior to version 8.

SDI HBA drivers that support passthrough operations use a different form of this routine, which is declared in the driver's hba_info(D4sdi) structure. See ioctl(D2sdi).


copyin(D3), copyout(D3), do_ioctl(D3), drv_priv(D3), errnos(D5), ioctl(D2sdi), open(D2), uiobuf(D3)
19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005