1STRUCT_DECL(9F) Kernel Functions for Drivers STRUCT_DECL(9F)
2
3
4
6 STRUCT_DECL, SIZEOF_PTR, SIZEOF_STRUCT, STRUCT_BUF, STRUCT_FADDR,
7 STRUCT_FGET, STRUCT_FGETP, STRUCT_FSET, STRUCT_FSETP, STRUCT_HANDLE,
8 STRUCT_INIT, STRUCT_SIZE, STRUCT_SET_HANDLE - 32-bit application data
9 access macros
10
12 #include <sys/ddi.h>
13 #include <sys/sunddi.h>
14
15
16
17 STRUCT_DECL(structname, handle);
18
19
20 STRUCT_HANDLE(structname, handle);
21
22
23 void STRUCT_INIT(handle, model_t umodel);
24
25
26 void STRUCT_SET_HANDLE(handle, model_t umodel, void *addr);
27
28
29 STRUCT_FGET(handle, field);
30
31
32 STRUCT_FGETP(handle, field);
33
34
35 STRUCT_FSET(handle, field, val);
36
37
38 STRUCT_FSETP(handle, field, val);
39
40
41 <typeof field> *STRUCT_FADDR(handle, field);
42
43
44 struct structname *STRUCT_BUF(handle);
45
46
47 size_t SIZEOF_STRUCT(structname, umodel);
48
49
50 size_t SIZEOF_PTR(umodel);
51
52
53 size_t STRUCT_SIZE(handle);
54
55
57 Solaris DDI specific (Solaris DDI).
58
60 The macros take the following parameters:
61
62 structname The structure name that appears after the C keyword
63 struct of the native form.
64
65
66 umodel A bit field that contains either the ILP32 model bit
67 (DATAMODEL_ILP32), or the LP64 model bit (DATA‐
68 MODEL_LP64). In an ioctl(9E), these bits are present in
69 the flag parameter. In a devmap(9E), the bits are present
70 in the model parameter mmap(9E). The
71 ddi_mmap_get_model(9F) can be called to get the data
72 model of the current thread.
73
74
75 handle The variable name used to refer to a particular instance
76 of a structure which is handled by these macros.
77
78
79 field The field name within the structure that can contain sub‐
80 structures. If the structures contain substructures,
81 unions, or arrays, the field can be whatever complex
82 expression would naturally follow the first . or ->.
83
84
86 The above macros allow a device driver to access data consumed from a
87 32-bit application regardless whether the driver was compiled to the
88 ILP32 or LP64 data model. These macros effectively hide the difference
89 between the data model of the user application and the driver.
90
91
92 The macros can be broken up into two main categories described in the
93 following sections.
94
95 Declaration and Initialization Macros
96 The macros STRUCT_DECL() and STRUCT_HANDLE() declare structure handles
97 on the stack, whereas the macros STRUCT_INIT() and STRUCT_SET_HANDLE()
98 initialize the structure handles to point to an instance of the native
99 form structure.
100
101
102 The macros STRUCT_HANDLE() and STRUCT_SET_HANDLE() are used to declare
103 and initialize a structure handle to an existing data structure, for
104 example, ioctls within a STREAMS module.
105
106
107 The macros STRUCT_DECL() and STRUCT_INIT(), on the other hand, are used
108 in modules which declare and initialize a structure handle to a data
109 structure allocated by STRUCT_DECL(), that is, any standard character
110 or block device driver ioctl(9E) routine that needs to copy in data
111 from a user-mode program.
112
113 STRUCT_DECL(structname, handle)
114
115 Declares a structure handle for a struct and allocates an instance
116 of its native form on the stack. It is assumed that the native form
117 is larger than or equal to the ILP32 form. handle is a variable
118 name and is declared as a variable by this macro.
119
120
121 void STRUCT_INIT(handle, model_t umodel)
122
123 Initializes handle to point to the instance allocated by
124 STRUCT_DECL(). It also sets data model for handle to umodel and it
125 must be called before any access is made through the macros that
126 operate on these structures. When used in an ioctl(9E) routine,
127 umodel is the flag parameter. In a devmap(9E) routine, umodel is
128 the model parameter. In a mmap(9E) routine, umodel is the return
129 value of ddi_mmap_get_model(9F). This macro is intended only for
130 handles created with STRUCT_DECL().
131
132
133 STRUCT_HANDLE(structname, handle)
134
135 Declares a structure handle handle but, unlike STRUCT_DECL(), it
136 does not allocate an instance of "struct".
137
138
139 void STRUCT_SET_HANDLE(handle, model_t umodel, void *addr)
140
141 Initializes handle to point to the native form instance at addr. It
142 also sets the data model for handle to umodel. This is intended for
143 handles created with STRUCT_HANDLE(). Fields cannot be referenced
144 via the handle until this macro has been invoked. Typically, addr
145 is the address of the native form structure containing the user-
146 mode programs data. When used in an ioctl(9E), umodel is the flag
147 parameter. In a devmap(9E) routine, umodel is the model parameter.
148 In an mmap(9E) routine, umodel is the return value of
149 ddi_mmap_get_model(9F).
150
151
152 Operation Macros
153 size_t STRUCT_SIZE(handle)
154
155 Returns size of the structure referred to by handle, depending on
156 the data model associated with handle. If the data model stored by
157 STRUCT_INIT() or STRUCT_SET_HANDLE() is DATAMODEL_ILP32, the size
158 of the ILP32 form is returned. Otherwise, the size of the native
159 form is returned.
160
161
162 STRUCT_FGET(handle, field)
163
164 Returns the contents of field in the structure described by handle
165 according to the data model associated with handle.
166
167
168 STRUCT_FGETP(handle, field)
169
170 This is the same as STRUCT_FGET() except that the field in question
171 is a pointer of some kind. This macro casts caddr32_t to a (void *)
172 when it is accessed. Failure to use this macro for a pointer leads
173 to compiler warnings or failures.
174
175
176 STRUCT_FSET(handle, field, val)
177
178 Assigns val to the (non-pointer) in the structure described by han‐
179 dle. It should not be used within another expression, but only as a
180 statement.
181
182
183 STRUCT_FSETP(handle, field, val)
184
185 This is the equivalent of STRUCT_FGETP() for STRUCT_FGET(), with
186 the same exceptions. Like STRUCT_FSET, STRUCT_FSETP should not be
187 used within another expression, but only as a statement.
188
189
190 struct structname *STRUCT_BUF(handle)
191
192 Returns a pointer to the native mode instance of the structure
193 described by handle.
194
195
196 Macros Not Using Handles
197 size_t SIZEOF_STRUCT(structname, umodel)
198
199 Returns size of structname based on umodel.
200
201
202 size_t SIZEOF_PTR(umodel)
203
204 Returns the size of a pointer based on umodel.
205
206
208 Example 1 Copying a Structure
209
210
211 The following example uses an ioctl(9E) on a regular character device
212 that copies a data structure that looks like this into the kernel:
213
214
215 struct opdata {
216 size_t size;
217 uint_t flag;
218 };
219
220
221 Example 2 Defining a Structure
222
223
224 This data structure definition describes what the ioctl(9E) would look
225 like in a 32-bit application using fixed width types.
226
227
228 #if defined(_MULTI_DATAMODEL)
229 struct opdata32 {
230 size32_t size;
231 uint32_t flag;
232 };
233 #endif
234
235
236 Example 3 Using STRUCT_DECL() and STRUCT_INIT()
237
238
239 Note: This example uses the STRUCT_DECL() and STRUCT_INIT() macros to
240 declare and initialize the structure handle.
241
242
243 int
244 xxioctl(dev_t dev, int cmd, intptr_t arg, int mode,
245 cred_t *cr, int *rval_p);
246 {
247 STRUCT_DECL(opdata, op);
248
249 if (cmd != OPONE)
250 return (ENOTTY);
251
252 STRUCT_INIT(op, mode);
253
254 if (copyin((void *)data,
255 STRUCT_BUF(op), STRUCT_SIZE(op)))
256 return (EFAULT);
257
258 if (STRUCT_FGET(op, flag) != FACTIVE ||
259 STRUCT_FGET(op, size) > sizeof (device_state))
260 return (EINVAL);
261 xxdowork(device_state, STRUCT_FGET(op, size));
262 return (0);
263 }
264
265
266
267 This piece of code is an excerpt from a STREAMS module that handles
268 ioctl(9E) data (M_IOCDATA) messages and uses the data structure defined
269 above. This code has been written to run in the ILP32 environment only.
270
271
272 Example 4 Using STRUCT_HANDLE() and STRUCT_SET_HANDLE()
273
274
275 The next example illustrates the use of the STRUCT_HANDLE() and
276 STRUCT_SET_HANDLE() macros which declare and initialize the structure
277 handle to point to an already existing instance of the structure.
278
279
280
281 The above code example can be converted to run in the LP64 environment
282 using the STRUCT_HANDLE() and STRUCT_SET_HANDLE() as follows:
283
284
285 struct strbuf {
286 int maxlen; /* no. of bytes in buffer */
287 int len; /* no. of bytes returned */
288 caddr_t buf; /* pointer to data */
289 };
290
291
292 static void
293 wput_iocdata(queue_t *q, mblk_t *msgp)
294 {
295 struct copyresp *cp = (struct copyresp *)msgp->b_rptr;
296 STRUCT_HANDLE(strbuf, sb);
297
298 if (msgp->b_cont->b_cont != NULL) {
299 msgp->b_cont = msgpullup(msgp->b_cont, -1);
300 if (msgp->b_cont == NULL) {
301 miocnak(q, msgp, 0, ENOSR);
302 return;
303 }
304 }
305 STRUCT_SET_HANDLE(sb, cp->cp_flag, (void *)msgp->b_cont->b_rptr);
306 if (STRUCT_FGET(sb, maxlen) < (int)sizeof (ipa_t)) {
307 miocnak(q, msgp, 0, ENOSR);
308 return;
309 }
310 ...
311 miocack(q, msgp, 0, 0);
312 }
313
314
316 See attributes(5) for descriptions of the following attributes:
317
318
319
320
321 ┌─────────────────────────────┬─────────────────────────────┐
322 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
323 ├─────────────────────────────┼─────────────────────────────┤
324 │Interface Stability │Evolving │
325 └─────────────────────────────┴─────────────────────────────┘
326
328 devmap(9E), ioctl(9E), mmap(9E),ddi_mmap_get_model(9F)
329
330
331 Writing Device Drivers
332
333
334 STREAMS Programming Guide
335
336
337
338SunOS 5.11 20 May 2006 STRUCT_DECL(9F)