#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);
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.
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 ``email@example.com''.
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.
d_ioctlmember 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).