ioctl(9e) 맨 페이지 - 윈디하나의 솔라나라

개요

섹션
맨 페이지 이름
검색(S)

ioctl(9e)

ioctl(9E)                     Driver Entry Points                    ioctl(9E)

NAME
       ioctl - control a character device

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

       int prefix_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
            cred_t *cred_p, int *rval_p);

INTERFACE LEVEL
       Architecture  independent  level  1  (DDI/DKI). This entry point is op‐
       tional.

ARGUMENTS
       dev       Device number.


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


       arg       Passes parameters between a user program and the driver. When
                 used with terminals, the argument is the address  of  a  user
                 program structure containing driver or hardware settings. Al‐
                 ternatively,  the  argument  may  be a value that has meaning
                 only to the driver. The interpretation  of  the  argument  is
                 driver dependent and usually depends on the command type; the
                 kernel does not interpret the argument.


       mode      A bit field that contains:

                     o      Information  set  when  the device was opened. The
                            driver may use it to determine if the  device  was
                            opened for reading or writing. The driver can make
                            this determination by checking the FREAD or FWRITE
                            flags.  See  the  flag argument description of the
                            open() routine for further values.


                     o      Information on whether the caller is a  32-bit  or
                            64-bit thread.


                     o      In  some  circumstances  address space information
                            about the arg argument. See below.



       cred_p    Pointer to the user credential structure.


       rval_p    Pointer to return value for calling process. The  driver  may
                 elect  to  set  the  value which is valid only if the ioctl()
                 succeeds.


DESCRIPTION
       ioctl() provides character-access drivers with an alternate entry point
       that can be used for almost any operation other than a simple  transfer
       of  characters  in  and  out of buffers. Most often, ioctl() is used to
       control device hardware parameters and establish the protocol  used  by
       the driver in processing data.


       The kernel determines that this is a character device, and looks up the
       entry  point  routines in cb_ops(9S). The kernel then packages the user
       request and arguments as integers  and  passes  them  to  the  driver's
       ioctl()  routine.  The  kernel  itself does no processing of the passed
       command, so it is up to the user program and the  driver  to  agree  on
       what the arguments mean.


       I/O control commands are used to implement the terminal settings passed
       from  ttymon(8)  and  stty(1),  to  format disk devices, to implement a
       trace driver for debugging, and to clean up character queues. Since the
       kernel does not interpret the command type that defines the  operation,
       a driver is free to define its own commands.


       Drivers  that use an ioctl() routine typically have a command to "read"
       the current ioctl() settings, and at least one other that sets new set‐
       tings. Drivers can use the mode argument to  determine  if  the  device
       unit  was  opened for reading or writing, if necessary, by checking the
       FREAD or FWRITE setting.


       If the third argument, arg, is a pointer to a user buffer,  the  driver
       can  call the copyin(9F) and copyout(9F) functions to transfer data be‐
       tween kernel and user space.


       Other kernel subsystems may need to call into the drivers ioctl()  rou‐
       tine.  Drivers that intend to allow their ioctl() routine to be used in
       this way should publish the ddi-kernel-ioctl property on the associated
       devinfo node(s).


       When the ddi-kernel-ioctl property is present,  the  mode  argument  is
       used to pass address space information about arg through to the driver.
       If  the driver expects arg to contain a buffer address, and the FKIOCTL
       flag is set in mode, then the driver should assume  that  it  is  being
       handed  a kernel buffer address. Otherwise, arg may be the address of a
       buffer from a user program.  The  driver  can  use  ddi_copyin(9F)  and
       ddi_copyout(9F)  perform  the correct type of copy operation for either
       kernel or user address spaces. See the example on ddi_copyout(9F).


       Drivers have to interact with 32-bit and 64-bit applications. If a  de‐
       vice  driver  shares data structures with the application (for example,
       through exported kernel memory) and the driver gets  recompiled  for  a
       64-bit  kernel but the application remains 32-bit, binary layout of any
       data structures will be incompatible if they contain longs or pointers.
       The driver needs to know whether there is a model mismatch between  the
       current thread and the kernel and take necessary action. The mode argu‐
       ment  has  additional  bits  set to determine the C Language Type Model
       which the current thread expects. mode has FILP32 set  if  the  current
       thread expects 32-bit (ILP32) semantics, or FLP64 if the current thread
       expects  64-bit  (LP64)  semantics.  mode  is  used in combination with
       ddi_model_convert_from(9F) and the FMODELS mask  to  determine  whether
       there  is  a data model mismatch between the current thread and the de‐
       vice driver (see the example below). The device driver  might  have  to
       adjust  the  shape  of  data structures before exporting them to a user
       thread which supports a different data model.


       To implement I/O control commands for a driver the following two  steps
       are required:

           1.     Define  the  I/O  control  command  names and the associated
                  value in the driver's header and comment the commands.


           2.     Code the ioctl() routine in  the  driver  that  defines  the
                  functionality  for  each I/O control command name that is in
                  the header.




       The ioctl() routine is coded with instructions on the proper action  to
       take  for  each  command.  It is commonly a switch statement, with each
       case definition corresponding to an ioctl() name to identify the action
       that should be taken. However, the command passed to the driver by  the
       user  process  is  an integer value associated with the command name in
       the header.

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

EXAMPLES
       Example 1 ioctl() entry point



       The following is an example of the ioctl() entry point and how to  sup‐
       port 32-bit and 64-bit applications with the same device driver.


         struct passargs32 {
                 int len;
                 caddr32_t addr;
         };

         struct passargs {
                 int len;
                 caddr_t addr;
         };

         xxioctl(dev_t dev, int cmd, intptr_t arg, int mode,
             cred_t *credp, int *rvalp) {
                 struct passargs pa;

         #ifdef  _MULTI_DATAMODEL
                 switch (ddi_model_convert_from(mode & FMODELS)) {
                     case DDI_MODEL_ILP32:
                     {
                         struct passargs32 pa32;

                         ddi_copyin(arg, &pa32, sizeof (struct passargs32),\
                         mode);
                         pa.len = pa32.len;
                         pa.address = pa32.address;
                         break;
                     }
                     case DDI_MODEL_NONE:
                         ddi_copyin(arg, &pa, sizeof (struct passargs),\
                         mode);
                         break;
                 }
         #else /* _MULTI_DATAMODEL */
                 ddi_copyin(arg, &pa, sizeof (struct passargs), mode);
         #endif  /* _MULTI_DATAMODEL */

                 do_ioctl(&pa);
                 ....
         }



SEE ALSO
       stty(1),  dkio(4I), fbio(4I), termio(4I), ttymon(8), open(9E), put(9E),
       srv(9E),  copyin(9F),  copyout(9F),  ddi_copyin(9F),   ddi_copyout(9F),
       ddi_model_convert_from(9F), cb_ops(9S)


       Writing Device Drivers in Oracle Solaris 11.4

WARNINGS
       Non-STREAMS  driver  ioctl()  routines must make sure that user data is
       copied into or  out  of  the  kernel  address  space  explicitly  using
       copyin(9F),  copyout(9F), ddi_copyin(9F), or ddi_copyout(9F), as appro‐
       priate.


       It is a severe error to simply dereference pointers to the user address
       space, even when in user context.


       Failure to use the appropriate copying routines can  result  in  panics
       under load on some platforms, and reproducible panics on others.

NOTES
       STREAMS  drivers do not have ioctl() routines. The stream head converts
       I/O control commands to M_IOCTL messages, which are handled by the dri‐
       ver's put(9E) or srv(9E) routine.

Oracle Solaris 11.4            9 September 2024                      ioctl(9E)
맨 페이지 내용의 저작권은 맨 페이지 작성자에게 있습니다.
RSS ATOM XHTML 5 CSS3