1ddi_copyin(9F) Kernel Functions for Drivers ddi_copyin(9F)
2
3
4
6 ddi_copyin - copy data to a driver buffer
7
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
19 Solaris DDI specific (Solaris DDI).
20
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
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
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
75 ddi_copyin() can be called from user or kernel context only.
76
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, ®_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
138 ioctl(9E), bcopy(9F), copyin(9F), copyout(9F), ddi_copyout(9F),
139 uiomove(9F)
140
141
142 Writing Device Drivers
143
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)