1ddi_copyout(9F) Kernel Functions for Drivers ddi_copyout(9F)
2
3
4
6 ddi_copyout - copy data from a driver
7
9 #include <sys/types.h>
10 #include <sys/ddi.h>
11 #include <sys/sunddi.h>
12
13
14
15 int ddi_copyout(const void *driverbuf, void *buf, size_t cn, int flags);
16
17
19 Solaris DDI specific (Solaris DDI).
20
22 driverbuf Source address in the driver from which the data is trans‐
23 ferred.
24
25
26 buf Destination address to which the data is transferred.
27
28
29 cn Number of bytes to copy.
30
31
32 flags Set of flag bits that provide address space information
33 about buf.
34
35
37 This routine is designed for use in driver ioctl(9E) routines for driv‐
38 ers that support layered ioctls. ddi_copyout() copies data from a
39 driver buffer to a destination address, buf.
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_copyout() behaves like bcopy(9F). Otherwise, buf is
45 interpreted as a user buffer address, and ddi_copyout() behaves like
46 copyout(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 algorithm according to
52 address alignment.
53
55 Under normal conditions, 0 is returned to indicate a successful copy.
56 Otherwise, −1 is returned if 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_copyout() can be called from user or kernel context only.
76
78 Example 1 ddi_copyout() example
79
80
81 A driver ioctl(9E) routine (line 12) can be used to get or set device
82 attributes or registers. In the XX_GETREGS condition (line 25), the
83 driver copies the current device register values to another data area.
84 If the 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
95 7 struct device_state {
96 8 volatile struct device *regsp; /* pointer to device registers */
97 9 kmutex_t reg_mutex; /* protect device registers */
98 . . .
99 10 };
100
101 11 static void *statep; /* for soft state routines */
102
103 12 xxioctl(dev_t dev, int cmd, int arg, int mode,
104 13 cred_t *cred_p, int *rval_p)
105 14 {
106 15 struct device_state *sp;
107 16 volatile struct device *rp;
108 17 struct device reg_buf; /* temporary buffer for registers */
109 18 int instance;
110
111 19 instance = getminor(dev);
112 20 sp = ddi_get_soft_state(statep, instance);
113 21 if (sp == NULL)
114 22 return (ENXIO);
115 23 rp = sp->regsp;
116 . . .
117 24 switch (cmd) {
118
119 25 case XX_GETREGS: /* copy registers to arg */
120 26 mutex_enter(&sp->reg_mutex);
121 27 /*
122 28 * Copy data from device registers to
123 29 * temporary device register buffer
124 30 * e.g. reg_buf.control = rp->control;
125 31 */
126 32 mutex_exit(&sp->reg_mutex);
127 33 if (ddi_copyout(®_buf, arg,
128 34 sizeof (struct device), mode) != 0) {
129 35 return (EFAULT);
130 36 }
131
132 37 break;
133 38 }
134 39 }
135
136
138 ioctl(9E), bcopy(9F), copyin(9F), copyout(9F), ddi_copyin(9F),
139 uiomove(9F)
140
141
142 Writing Device Drivers
143
145 The value of the flags argument to ddi_copyout() 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_copyout() should not be used from a streams driver. See M_COPYIN
153 and M_COPYOUT in STREAMS Programming Guide.
154
155
156
157SunOS 5.11 19 Apr 2000 ddi_copyout(9F)