1ioctl(9E)                     Driver Entry Points                    ioctl(9E)
2
3
4

NAME

6       ioctl - control a character device
7

SYNOPSIS

9       #include <sys/cred.h>
10       #include <sys/file.h>
11       #include <sys/types.h>
12       #include <sys/errno.h>
13       #include <sys/ddi.h>
14       #include <sys/sunddi.h>
15
16
17
18       int prefixioctl(dev_t dev, int cmd, intptr_t arg, int mode,
19            cred_t *cred_p, int *rval_p);
20
21

INTERFACE LEVEL

23       Architecture  independent  level  1  (DDI/DKI).  This  entry  point  is
24       optional.
25

ARGUMENTS

27       dev       Device number.
28
29
30       cmd       Command argument the driver  ioctl()  routine  interprets  as
31                 the  operation to be performed.
32
33
34       arg       Passes  parameters  between  a  user  program and the driver.
35                 When used with terminals, the argument is the  address  of  a
36                 user  program  structure  containing  driver or hardware set‐
37                 tings.  Alternatively, the argument may be a value  that  has
38                 meaning  only  to the driver. The interpretation of the argu‐
39                 ment is driver dependent and usually depends on  the  command
40                 type; the kernel does not interpret the argument.
41
42
43       mode      A bit field that contains:
44
45                     o      Information  set  when  the device was opened. The
46                            driver may use it to determine if the  device  was
47                            opened for reading or writing. The driver can make
48                            this  determination  by  checking  the   FREAD  or
49                            FWRITE flags. See the flag argument description of
50                            the  open() routine for further values.
51
52                     o      Information on whether the caller is a  32-bit  or
53                            64-bit thread.
54
55                     o      In  some  circumstances  address space information
56                            about the arg argument. See below.
57
58
59       cred_p    Pointer to the  user credential structure.
60
61
62       rval_p    Pointer to return value for calling process.  The driver  may
63                 elect  to  set  the value which is valid only if the  ioctl()
64                 succeeds.
65
66

DESCRIPTION

68       ioctl() provides character-access drivers with an alternate entry point
69       that  can be used for almost any operation other than a simple transfer
70       of characters in and out of buffers. Most often,  ioctl()  is  used  to
71       control  device  hardware parameters and establish the protocol used by
72       the driver in processing data.
73
74
75       The kernel determines that this is a character device, and looks up the
76       entry  point routines in  cb_ops(9S). The kernel then packages the user
77       request and arguments as integers  and  passes  them  to  the  driver's
78       ioctl()  routine.  The  kernel  itself does no processing of the passed
79       command, so it is up to the user program and the  driver  to  agree  on
80       what the arguments mean.
81
82
83       I/O control commands are used to implement the terminal settings passed
84       from  ttymon(1M) and  stty(1), to format disk devices, to  implement  a
85       trace driver for debugging, and to clean up character queues. Since the
86       kernel does not interpret the command type that defines the  operation,
87       a driver is free to define its own commands.
88
89
90       Drivers  that  use  an   ioctl()  routine  typically  have a command to
91       ``read'' the current  ioctl() settings, and at  least  one  other  that
92       sets  new  settings.  Drivers can use the mode argument to determine if
93       the device unit was opened for reading or  writing,  if  necessary,  by
94       checking the  FREAD or  FWRITE setting.
95
96
97       If  the third argument,  arg, is a pointer to a user buffer, the driver
98       can call the  copyin(9F) and copyout(9F)  functions  to  transfer  data
99       between kernel and user space.
100
101
102       Other  kernel subsystems may need to call into the drivers ioctl() rou‐
103       tine.  Drivers that intend to allow their ioctl() routine to be used in
104       this way should publish the ddi-kernel-ioctl property on the associated
105       devinfo node(s).
106
107
108       When the ddi-kernel-ioctl property is present,  the  mode  argument  is
109       used to pass address space information about arg through to the driver.
110       If the driver expects arg to contain a buffer address, and the  FKIOCTL
111       flag  is  set  in  mode, then the driver should assume that it is being
112       handed a kernel buffer address.  Otherwise, arg may be the address of a
113       buffer  from  a  user  program.  The  driver can use ddi_copyin(9F) and
114       ddi_copyout(9F) perform the correct type of copy operation  for  either
115       kernel or user address spaces.  See the example on ddi_copyout(9F).
116
117
118       Drivers  have  to  interact  with  32-bit and 64-bit applications. If a
119       device driver shares data structures with the application (for example,
120       through  exported  kernel  memory) and the driver gets recompiled for a
121       64-bit kernel but the application remains 32-bit, binary layout of  any
122       data structures will be incompatible if they contain longs or pointers.
123       The driver needs to know whether there is a model mismatch between  the
124       current thread and the kernel and take necessary action. The mode argu‐
125       ment has additional bits set to determine the  C  Language  Type  Model
126       which  the  current  thread expects. mode has FILP32 set if the current
127       thread expects 32-bit ( ILP32)  semantics,  or  FLP64  if  the  current
128       thread  expects  64-bit  ( LP64) semantics. mode is used in combination
129       with ddi_model_convert_from(9F)  and  the  FMODELS  mask  to  determine
130       whether  there  is a data model mismatch between the current thread and
131       the device driver (see the example below). The device driver might have
132       to  adjust the shape of data structures before exporting them to a user
133       thread which supports a different data model.
134
135
136       To implement I/O control commands for a driver the following two  steps
137       are required:
138
139           1.     Define  the  I/O  control  command  names and the associated
140                  value in the driver's header and comment the commands.
141
142           2.     Code the  ioctl() routine in the  driver  that  defines  the
143                  functionality  for  each I/O control command name that is in
144                  the header.
145
146
147       The  ioctl() routine is coded with instructions on the proper action to
148       take  for  each  command. It is commonly a  switch statement, with each
149       case definition corresponding to  an   ioctl()  name  to  identify  the
150       action  that should be taken. However, the command passed to the driver
151       by the user process is an integer value  associated  with  the  command
152       name in the header.
153

RETURN VALUES

155       ioctl()  should  return  0 on success, or the appropriate error number.
156       The driver may also set the  value  returned  to  the  calling  process
157       through rval_p.
158

EXAMPLES

160       Example 1 ioctl() entry point
161
162
163       The  following is an example of the ioctl() entry point and how to sup‐
164       port 32-bit and 64-bit applications with the same device driver.
165
166
167         struct passargs32 {
168                 int len;
169                 caddr32_t addr;
170         };
171
172         struct passargs {
173                 int len;
174                 caddr_t addr;
175         };
176
177         xxioctl(dev_t dev, int cmd, intptr_t arg, int mode,
178             cred_t *credp, int *rvalp) {
179                 struct passargs pa;
180
181         #ifdef  _MULTI_DATAMODEL
182                 switch (ddi_model_convert_from(mode & FMODELS)) {
183                     case DDI_MODEL_ILP32:
184                     {
185                         struct passargs32 pa32;
186
187                         ddi_copyin(arg, &pa32, sizeof (struct passargs32),\
188                         mode);
189                         pa.len = pa32.len;
190                         pa.address = pa32.address;
191                         break;
192                     }
193                     case DDI_MODEL_NONE:
194                         ddi_copyin(arg, &pa, sizeof (struct passargs),\
195                         mode);
196                         break;
197                 }
198         #else /* _MULTI_DATAMODEL */
199                 ddi_copyin(arg, &pa, sizeof (struct passargs), mode);
200         #endif  /* _MULTI_DATAMODEL */
201
202                 do_ioctl(&pa);
203                 ....
204         }
205
206

SEE ALSO

208       stty(1), ttymon(1M), dkio(7I), fbio(7I), termio(7I), open(9E), put(9E),
209       srv(9E),   copyin(9F),  copyout(9F),  ddi_copyin(9F),  ddi_copyout(9F),
210       ddi_model_convert_from(9F), cb_ops(9S)
211
212
213       Writing Device Drivers
214

WARNINGS

216       Non-STREAMS driver  ioctl() routines must make sure that user  data  is
217       copied  into  or  out  of  the  kernel  address  space explicitly using
218       copyin(9F), copyout(9F), ddi_copyin(9F), or ddi_copyout(9F), as  appro‐
219       priate.
220
221
222       It is a severe error to simply dereference pointers to the user address
223       space, even when in user context.
224
225
226       Failure to use the appropriate copying routines can  result  in  panics
227       under load on some platforms, and reproducible panics on others.
228

NOTES

230       STREAMS drivers do not have  ioctl() routines. The stream head converts
231       I/O control commands to  M_IOCTL messages, which  are  handled  by  the
232       driver's  put(9E) or srv(9E) routine.
233
234
235
236SunOS 5.11                        3 Dec 1996                         ioctl(9E)
Impressum