1ddi_copyin(9F)           Kernel Functions for Drivers           ddi_copyin(9F)
2
3
4

NAME

6       ddi_copyin - copy data to a driver buffer
7

SYNOPSIS

9       #include <sys/types.h>
10       #include <sys/ddi.h>
11       #include <sys/sunddi.h>
12
13
14
15       int ddi_copyin(const void *buf, void *driverbuf, size_t cn, int flags);
16
17

INTERFACE LEVEL

19       Solaris DDI specific (Solaris DDI).
20

PARAMETERS

22       buf          Source address from which data is transferred.
23
24
25       driverbuf    Driver destination address to which data is transferred.
26
27
28       cn           Number of bytes transferred.
29
30
31       flags        Set  of  flag  bits that provide address space information
32                    about buf.
33
34

DESCRIPTION

36       This routine is designed for use in driver ioctl(9E) routines for driv‐
37       ers that support layered ioctls. ddi_copyin() copies data from a source
38       address to a driver buffer.  The driver developer must ensure that ade‐
39       quate space is allocated for the destination address.
40
41
42       The  flags argument determines the address space information about buf.
43       If the FKIOCTL flag is  set,  this  indicates  that  buf  is  a  kernel
44       address,  and   ddi_copyin()  behaves like bcopy(9F). Otherwise, buf is
45       interpreted as a user buffer address,  and  ddi_copyin()  behaves  like
46       copyin(9F).
47
48
49       Addresses  that  are word-aligned are moved most efficiently.  However,
50       the driver developer is not obliged to ensure alignment.  This function
51       automatically finds the most efficient move according to address align‐
52       ment.
53

RETURN VALUES

55       ddi_copyin() returns 0, indicating a successful copy. It returns −1  if
56       one of the following occurs:
57
58           o      Paging  fault;  the  driver tried to access a page of memory
59                  for which it did not have read or write access.
60
61           o      Invalid user address, such as a user area or stack area.
62
63           o      Invalid address that  would  have  resulted  in  data  being
64                  copied into the user block.
65
66           o      Hardware  fault;  a  hardware  error prevented access to the
67                  specified user memory. For example, an uncorrectable  parity
68                  or ECC error occurred.
69
70
71       If  −1  is  returned  to the caller, driver entry point routines should
72       return EFAULT.
73

CONTEXT

75       ddi_copyin() can be called from user or kernel context only.
76

EXAMPLES

78       Example 1 ddi_copyin() example
79
80
81       A driver ioctl(9E) routine (line 12) can be used to get or  set  device
82       attributes  or  registers.  For the XX_SETREGS condition (line 25), the
83       driver copies the user data in arg to the  device  registers.   If  the
84       specified  argument  contains  an  invalid  address,  an  error code is
85       returned.
86
87
88         1 struct device {           /* layout of physical device registers */
89          2     int      control;     /* physical device control word */
90          3     int      status;      /* physical device status word  */
91          4     short    recv_char;   /* receive character from device */
92          5     short    xmit_char    /* transmit character to device */
93          6  };
94          7  struct device_state {
95          8     volatile struct device *regsp;   /* pointer to device registers */
96          9     kmutex_t reg_mutex;              /* protect device registers */
97                . . .
98         10  };
99
100         11  static void *statep; /* for soft state routines */
101
102         12  xxioctl(dev_t dev, int cmd, int arg, int mode,
103         13      cred_t *cred_p, int *rval_p)
104         14  {
105         15      struct device_state *sp;
106         16      volatile struct device *rp;
107         17      struct device reg_buf;     /* temporary buffer for registers */
108         18      int instance;
109
110         19      instance = getminor(dev);
111         20      sp = ddi_get_soft_state(statep, instance);
112         21      if (sp == NULL)
113         22          return (ENXIO);
114         23      rp = sp->regsp;
115                 . . .
116         24      switch (cmd)  {
117
118         25      case XX_GETREGS: /* copy data to temp. regs. buf */
119         26            if (ddi_copyin(arg, &reg_buf,
120         27                sizeof (struct device), mode) != 0) {
121         28                    return (EFAULT);
122         29            }
123
124         30            mutex_enter(&sp->reg_mutex);
125         31            /*
126         32             * Copy data from temporary device register
127         33             * buffer to device registers.
128         34             * e.g. rp->control = reg_buf.control;
129         35             */
130         36            mutex_exit(&sp->reg_mutex);
131
132         37            break;
133         38      }
134         39  }
135
136

SEE ALSO

138       ioctl(9E),   bcopy(9F),   copyin(9F),   copyout(9F),   ddi_copyout(9F),
139       uiomove(9F)
140
141
142       Writing Device Drivers
143

NOTES

145       The  value  of  the  flags  argument  to  ddi_copyin() should be passed
146       through directly from the mode argument of ioctl() untranslated.
147
148
149       Driver defined locks should not be held across calls to this function.
150
151
152       ddi_copyin() should not be used from a streams driver. See M_COPYIN and
153       M_COPYOUT in STREAMS Programming Guide.
154
155
156
157SunOS 5.11                        19 Apr 2000                   ddi_copyin(9F)
Impressum