netbsd32_drm.c revision 1.1 1 1.1 christos /* $NetBSD: netbsd32_drm.c,v 1.1 2019/08/20 09:32:21 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * This code was written by Surya Shankar for GSoC 2019.
5 1.1 christos *
6 1.1 christos * Redistribution and use in source and binary forms, with or without
7 1.1 christos * modification, are permitted provided that the following conditions
8 1.1 christos * are met:
9 1.1 christos * 1. Redistributions of source code must retain the above copyright
10 1.1 christos * notice, this list of conditions and the following disclaimer.
11 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
12 1.1 christos * notice, this list of conditions and the following disclaimer in the
13 1.1 christos * documentation and/or other materials provided with the distribution.
14 1.1 christos *
15 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 1.1 christos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 1.1 christos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 1.1 christos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 1.1 christos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 1.1 christos * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 1.1 christos * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22 1.1 christos * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 1.1 christos * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 1.1 christos * SUCH DAMAGE.
26 1.1 christos */
27 1.1 christos
28 1.1 christos #include <sys/cdefs.h>
29 1.1 christos __KERNEL_RCSID(0, "$NetBSD: netbsd32_drm.c,v 1.1 2019/08/20 09:32:21 christos Exp $");
30 1.1 christos
31 1.1 christos #include <compat/netbsd32/netbsd32.h>
32 1.1 christos #include <compat/netbsd32/netbsd32_ioctl.h>
33 1.1 christos
34 1.1 christos #include <linux/types.h>
35 1.1 christos #include <drm/drmP.h>
36 1.1 christos
37 1.1 christos #define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t)
38 1.1 christos #define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t)
39 1.1 christos #define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t)
40 1.1 christos #define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t)
41 1.1 christos #define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t)
42 1.1 christos
43 1.1 christos #define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t)
44 1.1 christos #define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t)
45 1.1 christos #define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t)
46 1.1 christos #define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t)
47 1.1 christos #define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t)
48 1.1 christos #define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t)
49 1.1 christos #define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t)
50 1.1 christos
51 1.1 christos #define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t)
52 1.1 christos
53 1.1 christos #define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
54 1.1 christos #define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
55 1.1 christos
56 1.1 christos #define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t)
57 1.1 christos #define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t)
58 1.1 christos
59 1.1 christos #define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t)
60 1.1 christos #define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t)
61 1.1 christos #define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t)
62 1.1 christos #define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t)
63 1.1 christos #define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t)
64 1.1 christos #define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t)
65 1.1 christos
66 1.1 christos #define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t)
67 1.1 christos #define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t)
68 1.1 christos
69 1.1 christos #define DRM_IOCTL_UPDATE_DRAW32 DRM_IOW( 0x3f, drm_update_draw32_t)
70 1.1 christos
71 1.1 christos #define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t)
72 1.1 christos
73 1.1 christos #define DRM_IOCTL_MODE_ADDFB232 DRM_IOWR(0xb8, drm_mode_fb_cmd232_t)
74 1.1 christos
75 1.1 christos // Compat DRM Version Implementation
76 1.1 christos
77 1.1 christos typedef struct {
78 1.1 christos int version_major; /**< Major version */
79 1.1 christos int version_minor; /**< Minor version */
80 1.1 christos int version_patchlevel; /**< Patch level */
81 1.1 christos uint32_t name_len; /**< Length of name buffer */
82 1.1 christos netbsd32_pointer_t name; /**< Name of driver */
83 1.1 christos uint32_t date_len; /**< Length of date buffer */
84 1.1 christos netbsd32_pointer_t date; /**< User-space buffer to hold date */
85 1.1 christos uint32_t desc_len; /**< Length of desc buffer */
86 1.1 christos netbsd32_pointer_t desc; /**< User-space buffer to hold desc */
87 1.1 christos } drm_version32_t;
88 1.1 christos
89 1.1 christos static int
90 1.1 christos compat_drm_version(struct file *file, void *arg)
91 1.1 christos {
92 1.1 christos drm_version32_t v32;
93 1.1 christos struct drm_version v64;
94 1.1 christos int error;
95 1.1 christos
96 1.1 christos if ((error = copyin(&v32, arg, sizeof(v32))) != 0)
97 1.1 christos return error;
98 1.1 christos
99 1.1 christos v64.name_len = v32.name_len;
100 1.1 christos v64.name = NETBSD32PTR64(v32.name);
101 1.1 christos v64.date_len = v32.date_len;
102 1.1 christos v64.date = NETBSD32PTR64(v32.date);
103 1.1 christos v64.desc_len = v32.desc_len;
104 1.1 christos v64.desc = NETBSD32PTR64(v32.desc);
105 1.1 christos
106 1.1 christos error = drm_ioctl(file, DRM_IOCTL_VERSION, &v64);
107 1.1 christos if (error)
108 1.1 christos return error;
109 1.1 christos
110 1.1 christos v32.version_major = v64.version_major;
111 1.1 christos v32.version_minor = v64.version_minor;
112 1.1 christos v32.version_patchlevel = v64.version_patchlevel;
113 1.1 christos /* strings have already been copied in place */
114 1.1 christos v32.name_len = v64.name_len;
115 1.1 christos v32.date_len = v64.date_len;
116 1.1 christos v32.desc_len = v64.desc_len;
117 1.1 christos
118 1.1 christos return copyout(arg, &v32, sizeof(v32));
119 1.1 christos }
120 1.1 christos
121 1.1 christos typedef struct drm_unique32 {
122 1.1 christos uint32_t unique_len;
123 1.1 christos netbsd32_pointer_t unique;
124 1.1 christos } drm_unique32_t;
125 1.1 christos
126 1.1 christos static int
127 1.1 christos compat_drm_getunique(struct file *file, void *arg)
128 1.1 christos {
129 1.1 christos drm_unique32_t uq32;
130 1.1 christos struct drm_unique uq64;
131 1.1 christos int error;
132 1.1 christos
133 1.1 christos if ((error = copyin(&uq32, arg, sizeof(uq32))) != 0)
134 1.1 christos return error;
135 1.1 christos
136 1.1 christos uq64.unique_len = uq32.unique_len;
137 1.1 christos uq64.unique = NETBSD32PTR64(uq32.unique);
138 1.1 christos
139 1.1 christos error = drm_ioctl(file, DRM_IOCTL_GET_UNIQUE, &uq64);
140 1.1 christos if (error)
141 1.1 christos return error;
142 1.1 christos
143 1.1 christos //unique should already be copied
144 1.1 christos uq32.unique_len = uq64.unique_len;
145 1.1 christos
146 1.1 christos if ((error = copyout(arg, &uq32, sizeof(uq32))) != 0)
147 1.1 christos return error;
148 1.1 christos
149 1.1 christos return 0;
150 1.1 christos }
151 1.1 christos
152 1.1 christos static int
153 1.1 christos compat_drm_setunique(struct file *file, void *arg)
154 1.1 christos {
155 1.1 christos drm_unique32_t uq32;
156 1.1 christos struct drm_unique uq64;
157 1.1 christos int error;
158 1.1 christos
159 1.1 christos if ((error = copyin(&uq32, arg, sizeof(uq32))) != 0)
160 1.1 christos return error;
161 1.1 christos
162 1.1 christos uq64.unique_len = uq32.unique_len;
163 1.1 christos uq64.unique = NETBSD32PTR64(uq32.unique);
164 1.1 christos
165 1.1 christos error = drm_ioctl(file, DRM_IOCTL_SET_UNIQUE, &uq64);
166 1.1 christos if (error)
167 1.1 christos return error;
168 1.1 christos
169 1.1 christos // XXX: do we need copyout and copying the fields here?
170 1.1 christos uq32.unique_len = uq64.unique_len;
171 1.1 christos NETBSD32PTR32(uq32.unique, uq64.unique);
172 1.1 christos
173 1.1 christos return error;
174 1.1 christos }
175 1.1 christos
176 1.1 christos typedef struct drm_map32 {
177 1.1 christos uint32_t offset; /**< Req. physical address (0 for SAREA) */
178 1.1 christos uint32_t size; /**< Requested physical size (bytes) */
179 1.1 christos enum drm_map_type type; /**< Type of memory to map */
180 1.1 christos enum drm_map_flags flags; /**< Flags */
181 1.1 christos netbsd32_pointer_t handle;/**< User-space: "Handle" to pass to mmap() */
182 1.1 christos int mtrr; /**< MTRR slot used */
183 1.1 christos } drm_map32_t;
184 1.1 christos
185 1.1 christos static void
186 1.1 christos map32to64(struct drm_map *m64, const drm_map32_t *m32)
187 1.1 christos {
188 1.1 christos m64->offset = m32->offset;
189 1.1 christos m64->size = m32->size;
190 1.1 christos m64->type = m32->type;
191 1.1 christos m64->flags = m32->flags;
192 1.1 christos m64->handle = NETBSD32PTR64(m32->handle);
193 1.1 christos m64->mtrr = m32->mtrr;
194 1.1 christos }
195 1.1 christos
196 1.1 christos static void
197 1.1 christos map64to32(drm_map32_t *m32, const struct drm_map *m64)
198 1.1 christos {
199 1.1 christos m32->offset = m64->offset;
200 1.1 christos m32->size = m64->size;
201 1.1 christos m32->type = m64->type;
202 1.1 christos m32->flags = m64->flags;
203 1.1 christos NETBSD32PTR32(m32->handle, m64->handle);
204 1.1 christos m32->mtrr = m64->mtrr;
205 1.1 christos }
206 1.1 christos
207 1.1 christos static int
208 1.1 christos compat_drm_getmap(struct file *file, void *arg)
209 1.1 christos {
210 1.1 christos drm_map32_t m32;
211 1.1 christos struct drm_map m64;
212 1.1 christos int error;
213 1.1 christos
214 1.1 christos if ((error = copyin(&m32, arg, sizeof(m32))) != 0)
215 1.1 christos return error;
216 1.1 christos
217 1.1 christos map32to64(&m64, &m32);
218 1.1 christos
219 1.1 christos error = drm_ioctl(file, DRM_IOCTL_GET_MAP, &m64);
220 1.1 christos if (error)
221 1.1 christos return error;
222 1.1 christos
223 1.1 christos map64to32(&m32, &m64);
224 1.1 christos
225 1.1 christos return copyout(arg, &m32, sizeof(m32));
226 1.1 christos }
227 1.1 christos
228 1.1 christos static int
229 1.1 christos compat_drm_addmap(struct file *file, void *arg)
230 1.1 christos {
231 1.1 christos drm_map32_t m32;
232 1.1 christos struct drm_map m64;
233 1.1 christos int error;
234 1.1 christos
235 1.1 christos if ((error = copyin(&m32, arg, sizeof(m32))) != 0)
236 1.1 christos return error;
237 1.1 christos
238 1.1 christos map32to64(&m64, &m32);
239 1.1 christos
240 1.1 christos error = drm_ioctl(file, DRM_IOCTL_ADD_MAP, &m64);
241 1.1 christos if (error)
242 1.1 christos return error;
243 1.1 christos
244 1.1 christos map64to32(&m32, &m64);
245 1.1 christos
246 1.1 christos return copyout(arg, &m32, sizeof(m32));
247 1.1 christos }
248 1.1 christos
249 1.1 christos
250 1.1 christos static int
251 1.1 christos compat_drm_rmmap(struct file *file, void *arg)
252 1.1 christos {
253 1.1 christos drm_map32_t m32;
254 1.1 christos struct drm_map m64;
255 1.1 christos int error;
256 1.1 christos if ((error = copyin(&m32, arg, sizeof(m32))) != 0)
257 1.1 christos return error;
258 1.1 christos
259 1.1 christos map32to64(&m64, &m32);
260 1.1 christos
261 1.1 christos error = drm_ioctl(file, DRM_IOCTL_RM_MAP, &m64);
262 1.1 christos if (error)
263 1.1 christos return error;
264 1.1 christos
265 1.1 christos map64to32(&m32, &m64);
266 1.1 christos
267 1.1 christos return copyout(arg, &m32, sizeof(m32));
268 1.1 christos }
269 1.1 christos
270 1.1 christos typedef struct drm_client32 {
271 1.1 christos int idx; /**< Which client desired? */
272 1.1 christos int auth; /**< Is client authenticated? */
273 1.1 christos uint32_t pid; /**< Process ID */
274 1.1 christos uint32_t uid; /**< User ID */
275 1.1 christos uint32_t magic; /**< Magic */
276 1.1 christos uint32_t iocs; /**< Ioctl count */
277 1.1 christos } drm_client32_t;
278 1.1 christos
279 1.1 christos static void
280 1.1 christos client32to64(struct drm_client *c64, const drm_client32_t *c32)
281 1.1 christos {
282 1.1 christos c64->idx = c32->idx;
283 1.1 christos c64->auth = c32->auth;
284 1.1 christos c64->pid = c32->pid;
285 1.1 christos c64->uid = c32->uid;
286 1.1 christos c64->iocs = c64->iocs;
287 1.1 christos }
288 1.1 christos
289 1.1 christos static void
290 1.1 christos client64to32(drm_client32_t *c32, const struct drm_client *c64)
291 1.1 christos {
292 1.1 christos c32->idx = c64->idx;
293 1.1 christos c32->auth = c64->auth;
294 1.1 christos c32->pid = c64->pid;
295 1.1 christos c32->uid = c64->uid;
296 1.1 christos c32->iocs = c64->iocs;
297 1.1 christos }
298 1.1 christos static int
299 1.1 christos compat_drm_getclient(struct file *file, void *arg)
300 1.1 christos {
301 1.1 christos drm_client32_t c32;
302 1.1 christos struct drm_client c64;
303 1.1 christos int error;
304 1.1 christos
305 1.1 christos if ((error = copyin(&c32, arg, sizeof(c32))) != 0)
306 1.1 christos return error;
307 1.1 christos
308 1.1 christos client32to64(&c64, &c32);
309 1.1 christos
310 1.1 christos error = drm_ioctl(file, DRM_IOCTL_GET_CLIENT, &c64);
311 1.1 christos if (error)
312 1.1 christos return error;
313 1.1 christos
314 1.1 christos client64to32(&c32, &c64);
315 1.1 christos
316 1.1 christos return copyout(arg, &c32, sizeof(c32));
317 1.1 christos }
318 1.1 christos
319 1.1 christos typedef struct drm_stats32 {
320 1.1 christos uint32_t count;
321 1.1 christos struct {
322 1.1 christos uint32_t value;
323 1.1 christos enum drm_stat_type type;
324 1.1 christos } data[15];
325 1.1 christos } drm_stats32_t;
326 1.1 christos
327 1.1 christos static int
328 1.1 christos compat_drm_getstats(struct file *file, void *arg)
329 1.1 christos {
330 1.1 christos drm_stats32_t st32;
331 1.1 christos struct drm_stats st64;
332 1.1 christos int error;
333 1.1 christos
334 1.1 christos if ((error = copyin(&st32, arg, sizeof(st32))) != 0)
335 1.1 christos return error;
336 1.1 christos
337 1.1 christos st64.count = st32.count;
338 1.1 christos
339 1.1 christos error = drm_ioctl(file, DRM_IOCTL_GET_STATS, &st64);
340 1.1 christos if (error)
341 1.1 christos return error;
342 1.1 christos
343 1.1 christos // XXX: or does that need to be count?
344 1.1 christos for (int i = 0; i < __arraycount(st64.data); ++i) {
345 1.1 christos st64.data[i].value = st32.data[i].value;
346 1.1 christos st64.data[i].type = st32.data[i].type;
347 1.1 christos }
348 1.1 christos
349 1.1 christos return copyout(arg, &st32, sizeof(s32));
350 1.1 christos }
351 1.1 christos
352 1.1 christos typedef struct drm_buf_desc32 {
353 1.1 christos int count; /**< Number of buffers of this size */
354 1.1 christos int size; /**< Size in bytes */
355 1.1 christos int low_mark; /**< Low water mark */
356 1.1 christos int high_mark; /**< High water mark */
357 1.1 christos int flags;
358 1.1 christos netbsd32_pointer_t agp_start;
359 1.1 christos /**< Start address in the AGP aperture */
360 1.1 christos } drm_buf_desc32_t;
361 1.1 christos
362 1.1 christos static int
363 1.1 christos compat_drm_addbufs(struct file *file, void *arg)
364 1.1 christos {
365 1.1 christos drm_buf_desc32_t buf32;
366 1.1 christos struct drm_buf_desc buf64;
367 1.1 christos int error;
368 1.1 christos
369 1.1 christos if ((error = copyin(&buf32, arg, sizeof(buf32))) != 0)
370 1.1 christos return error;
371 1.1 christos
372 1.1 christos // XXX: assign 32->64
373 1.1 christos buf64.agp_start = (unsigned long)NETBSD32PTR64(buf32.agp_start);
374 1.1 christos
375 1.1 christos error = drm_ioctl(file, DRM_IOCTL_ADD_BUFS, &buf64);
376 1.1 christos if (error)
377 1.1 christos return error;
378 1.1 christos
379 1.1 christos // XXX assign 64->32
380 1.1 christos NETBSD32PTR32(buf32.agp_start, (void *)buf64.agp_start);
381 1.1 christos
382 1.1 christos return copyout(&buf32, arg, sizeof(buf32));
383 1.1 christos }
384 1.1 christos
385 1.1 christos static int
386 1.1 christos compat_drm_markbufs(struct file *file, void *arg)
387 1.1 christos {
388 1.1 christos drm_buf_desc32_t b32;
389 1.1 christos struct drm_buf_desc b64;
390 1.1 christos int error;
391 1.1 christos
392 1.1 christos if ((error = copyin(&b32, arg, sizeof(b32))) != 0)
393 1.1 christos return error;
394 1.1 christos
395 1.1 christos b64.size = b32.size;
396 1.1 christos b64.low_mark = b32.low_mark;
397 1.1 christos b64.high_mark = b32.high_mark;
398 1.1 christos //XXX: more stuff?
399 1.1 christos
400 1.1 christos return drm_ioctl(file, DRM_IOCTL_MARK_BUFS, &b64);
401 1.1 christos }
402 1.1 christos
403 1.1 christos typedef struct drm_buf_info32 {
404 1.1 christos int count; /**< Entries in list */
405 1.1 christos netbsd32_pointer_t list;
406 1.1 christos } drm_buf_info32_t;
407 1.1 christos
408 1.1 christos typedef struct drm_buf_pub32 {
409 1.1 christos int idx; /**< Index into the master buffer list */
410 1.1 christos int total; /**< Buffer size */
411 1.1 christos int used; /**< Amount of buffer in use (for DMA) */
412 1.1 christos uint32_t address; /**< Address of buffer */
413 1.1 christos } drm_buf_pub32_t;
414 1.1 christos
415 1.1 christos typedef struct drm_buf_map32 {
416 1.1 christos int count; /**< Length of the buffer list */
417 1.1 christos uint32_t virtual; /**< Mmap'd area in user-virtual */
418 1.1 christos netbsd32_pointer_t list; /**< Buffer information */
419 1.1 christos } drm_buf_map32_t;
420 1.1 christos
421 1.1 christos
422 1.1 christos typedef struct drm_buf_free32 {
423 1.1 christos int count;
424 1.1 christos netbsd32_pointer_t list;
425 1.1 christos } drm_buf_free32_t;
426 1.1 christos
427 1.1 christos static int
428 1.1 christos compat_drm_freebufs(struct file *file, void *arg)
429 1.1 christos {
430 1.1 christos drm_buf_free32_t req32;
431 1.1 christos struct drm_buf_free req64;
432 1.1 christos int error;
433 1.1 christos
434 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
435 1.1 christos return error;
436 1.1 christos
437 1.1 christos req64.count = req32.count;
438 1.1 christos req64.list = NETBSD32PTR64(req32.list);
439 1.1 christos
440 1.1 christos return drm_ioctl(file, DRM_IOCTL_FREE_BUFS, &req64);
441 1.1 christos }
442 1.1 christos
443 1.1 christos typedef struct drm_ctx_priv_map32 {
444 1.1 christos unsigned int ctx_id; /**< Context requesting private mapping */
445 1.1 christos netbsd32_pointer_t handle; /**< Handle of map */
446 1.1 christos } drm_ctx_priv_map32_t;
447 1.1 christos
448 1.1 christos static int
449 1.1 christos compat_drm_setsareactx(struct file *file, void *arg)
450 1.1 christos {
451 1.1 christos drm_ctx_priv_map32_t req32;
452 1.1 christos struct drm_ctx_priv_map req64;
453 1.1 christos int error;
454 1.1 christos
455 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
456 1.1 christos return error;
457 1.1 christos
458 1.1 christos req64.ctx_id = req32.ctx_id;
459 1.1 christos req64.handle = NETBSD32PTR64(req32.handle);
460 1.1 christos
461 1.1 christos error = drm_ioctl(file, DRM_IOCTL_SET_SAREA_CTX, &req64);
462 1.1 christos if(error)
463 1.1 christos return error;
464 1.1 christos
465 1.1 christos req32.ctx_id = req64.ctx_id;
466 1.1 christos NETBSD32PTR32(req32.handle, req64.handle);
467 1.1 christos
468 1.1 christos return 0;
469 1.1 christos }
470 1.1 christos
471 1.1 christos static int
472 1.1 christos compat_drm_getsareactx(struct file *file, void *arg)
473 1.1 christos {
474 1.1 christos struct drm_ctx_priv_map req64;
475 1.1 christos drm_ctx_priv_map32_t req32;
476 1.1 christos int error;
477 1.1 christos
478 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
479 1.1 christos return error;
480 1.1 christos
481 1.1 christos req64.ctx_id = req32.ctx_id;
482 1.1 christos
483 1.1 christos error = drm_ioctl(file, DRM_IOCTL_GET_SAREA_CTX, &req64);
484 1.1 christos if (error)
485 1.1 christos return error;
486 1.1 christos
487 1.1 christos NETBSD32PTR32(req32.handle, req64.handle);
488 1.1 christos // XXX: missing copyout?
489 1.1 christos
490 1.1 christos return copyout(arg, &req32, sizeof(req32));
491 1.1 christos }
492 1.1 christos
493 1.1 christos typedef struct drm_ctx_res32 {
494 1.1 christos int count;
495 1.1 christos netbsd32_pointer_t contexts;
496 1.1 christos } drm_ctx_res32_t;
497 1.1 christos
498 1.1 christos static int
499 1.1 christos compat_drm_resctx(struct file *file, void *arg)
500 1.1 christos {
501 1.1 christos drm_ctx_res32_t res32;
502 1.1 christos struct drm_ctx_res res64;
503 1.1 christos int error;
504 1.1 christos
505 1.1 christos if ((error = copyin(&res32, arg, sizeof(res32))) != 0)
506 1.1 christos return error;
507 1.1 christos
508 1.1 christos res64.count = res32.count;
509 1.1 christos res64.contexts = NETBSD32PTR64(res32.contexts);
510 1.1 christos
511 1.1 christos error = drm_ioctl(file, DRM_IOCTL_RES_CTX, &res64);
512 1.1 christos if (error)
513 1.1 christos return error;
514 1.1 christos
515 1.1 christos res32.count = res64.count;
516 1.1 christos NETBSD32PTR32(res32.contexts, res64.contexts);
517 1.1 christos /* XXX: missing copyout */
518 1.1 christos
519 1.1 christos return copyout(arg, &res32, sizeof(res32));
520 1.1 christos }
521 1.1 christos
522 1.1 christos typedef struct drm_dma32 {
523 1.1 christos int context; /**< Context handle */
524 1.1 christos int send_count; /**< Number of buffers to send */
525 1.1 christos netbsd32_pointer_t send_indices; /**< List of handles to buffers */
526 1.1 christos netbsd32_pointer_t send_sizes; /**< Lengths of data to send */
527 1.1 christos enum drm_dma_flags flags; /**< Flags */
528 1.1 christos netbsd32_pointer_t request_count; /**< Number of buffers requested */
529 1.1 christos int request_size; /**< Desired size for buffers */
530 1.1 christos netbsd32_pointer_t request_indices; /**< Buffer information */
531 1.1 christos netbsd32_pointer_t request_sizes;
532 1.1 christos int granted_count; /**< Number of buffers granted */
533 1.1 christos } drm_dma32_t;
534 1.1 christos
535 1.1 christos static void
536 1.1 christos dma64to32(drm_dma32_t *d32, const struct drm_dma *d64)
537 1.1 christos {
538 1.1 christos d32->send_count = d64->send_count;
539 1.1 christos NETBSD32PTR32(d32->send_indices, d64->send_indices);
540 1.1 christos NETBSD32PTR32(d32->send_sizes, d64->send_sizes);
541 1.1 christos d32->flags = d64->flags;
542 1.1 christos NETBSD32PTR32(d32->request_count, (void *)(long)d64->request_count);
543 1.1 christos NETBSD32PTR32(d32->request_indices, d64->request_indices);
544 1.1 christos NETBSD32PTR32(d32->request_sizes, d64->request_sizes);
545 1.1 christos
546 1.1 christos }
547 1.1 christos
548 1.1 christos static void
549 1.1 christos dma32to64(struct drm_dma *d64, const drm_dma32_t *d32)
550 1.1 christos {
551 1.1 christos d64->request_size = d32->request_size;
552 1.1 christos d64->granted_count = d32->granted_count;
553 1.1 christos }
554 1.1 christos
555 1.1 christos static int
556 1.1 christos compat_drm_dma(struct file *file, void *arg)
557 1.1 christos {
558 1.1 christos drm_dma32_t d32;
559 1.1 christos struct drm_dma d64;
560 1.1 christos int error;
561 1.1 christos
562 1.1 christos if ((error = copyin(&d32, arg, sizeof(d32))) != 0)
563 1.1 christos return error;
564 1.1 christos
565 1.1 christos dma64to32(&d32, &d64);
566 1.1 christos
567 1.1 christos error = drm_ioctl(file, DRM_IOCTL_DMA, &d64);
568 1.1 christos if (error)
569 1.1 christos return error;
570 1.1 christos
571 1.1 christos dma32to64(&d64, &d32);
572 1.1 christos
573 1.1 christos return 0;
574 1.1 christos }
575 1.1 christos
576 1.1 christos //XXX:i commented the below line for later use
577 1.1 christos #if IS_ENABLED(CONFIG_AGP)
578 1.1 christos typedef struct drm_agp_mode32 {
579 1.1 christos uint32_t mode; /**< AGP mode */
580 1.1 christos } drm_agp_mode32_t;
581 1.1 christos
582 1.1 christos static int
583 1.1 christos compat_drm_agp_enable(struct file *file, void *arg)
584 1.1 christos {
585 1.1 christos drm_agp_mode32_t m32;
586 1.1 christos struct drm_agp_mode m64;
587 1.1 christos int error;
588 1.1 christos
589 1.1 christos if ((error = copyin(&m32, arg, sizeof(m32))) != 0)
590 1.1 christos return error;
591 1.1 christos
592 1.1 christos m32.mode = m64.mode;
593 1.1 christos
594 1.1 christos return drm_ioctl(file, DRM_IOCTL_AGP_ENABLE, &m64);
595 1.1 christos }
596 1.1 christos
597 1.1 christos typedef struct drm_agp_info32 {
598 1.1 christos int agp_version_major;
599 1.1 christos int agp_version_minor;
600 1.1 christos uint32_t mode;
601 1.1 christos uint32_t aperture_base; /* physical address */
602 1.1 christos uint32_t aperture_size; /* bytes */
603 1.1 christos uint32_t memory_allowed; /* bytes */
604 1.1 christos uint32_t memory_used;
605 1.1 christos
606 1.1 christos /* PCI information */
607 1.1 christos unsigned short id_vendor;
608 1.1 christos unsigned short id_device;
609 1.1 christos } drm_agp_info32_t;
610 1.1 christos
611 1.1 christos static void
612 1.1 christos info32to64(struct drm_agp_info *i64, const drm_agp_info32_t *i32)
613 1.1 christos {
614 1.1 christos i64->agp_version_major = i32->agp_version_major;
615 1.1 christos i64->agp_version_minor = i32->agp_version_minor;
616 1.1 christos i64->mode = i32->mode;
617 1.1 christos i64->aperture_base = i32->aperture_base;
618 1.1 christos i64->aperture_size = i32->aperture_size;
619 1.1 christos i64->memory_allowed = i32->memory_allowed;
620 1.1 christos i64->memory_used = i64->memory_used;
621 1.1 christos i64->id_vendor = i32->id_vendor;
622 1.1 christos i64->id_device = i32->id_device;
623 1.1 christos }
624 1.1 christos
625 1.1 christos static int
626 1.1 christos compat_drm_agp_info(struct file *file, void *arg)
627 1.1 christos {
628 1.1 christos drm_agp_info32_t i32;
629 1.1 christos struct drm_agp_info i64;
630 1.1 christos int error;
631 1.1 christos
632 1.1 christos error = drm_ioctl(file, DRM_IOCTL_AGP_INFO, &i64);
633 1.1 christos if (error)
634 1.1 christos return error;
635 1.1 christos
636 1.1 christos info32to64(&i64,&i32);
637 1.1 christos
638 1.1 christos return copyout(arg, &i32, sizeof(i32));
639 1.1 christos
640 1.1 christos }
641 1.1 christos
642 1.1 christos typedef struct drm_agp_buffer32 {
643 1.1 christos uint32_t size; /**< In bytes -- will round to page boundary */
644 1.1 christos uint32_t handle; /**< Used for binding / unbinding */
645 1.1 christos uint32_t type; /**< Type of memory to allocate */
646 1.1 christos uint32_t physical; /**< Physical used by i810 */
647 1.1 christos } drm_agp_buffer32_t;
648 1.1 christos
649 1.1 christos static int
650 1.1 christos compat_drm_agp_alloc(struct file *file, void *arg)
651 1.1 christos {
652 1.1 christos drm_agp_buffer32_t req32;
653 1.1 christos struct drm_agp_buffer req64;
654 1.1 christos int error;
655 1.1 christos
656 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
657 1.1 christos return error;
658 1.1 christos
659 1.1 christos req64.size = req32.size;
660 1.1 christos req64.type = req32.type;
661 1.1 christos
662 1.1 christos error = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, &req64);
663 1.1 christos if (error)
664 1.1 christos return error;
665 1.1 christos
666 1.1 christos req32.handle = req64.handle;
667 1.1 christos req32.physical = req64.physical;
668 1.1 christos
669 1.1 christos drm_ioctl(file, DRM_IOCTL_AGP_FREE, &req64);
670 1.1 christos
671 1.1 christos return copyout(arg, &req32, sizeof(req32));
672 1.1 christos }
673 1.1 christos
674 1.1 christos static int
675 1.1 christos compat_drm_agp_free(struct file *file, void *arg)
676 1.1 christos {
677 1.1 christos drm_agp_buffer32_t req32;
678 1.1 christos struct drm_agp_buffer req64;
679 1.1 christos int error;
680 1.1 christos uint32_t handle;
681 1.1 christos
682 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
683 1.1 christos return error;
684 1.1 christos
685 1.1 christos handle = req32.handle;
686 1.1 christos req64.handle = handle;
687 1.1 christos
688 1.1 christos return drm_ioctl(file, DRM_IOCTL_AGP_FREE, &req64);
689 1.1 christos }
690 1.1 christos
691 1.1 christos typedef struct drm_agp_binding32 {
692 1.1 christos uint32_t handle; /**< From drm_agp_buffer */
693 1.1 christos uint32_t offset; /**< In bytes -- will round to page boundary */
694 1.1 christos } drm_agp_binding32_t;
695 1.1 christos
696 1.1 christos static int
697 1.1 christos compat_drm_agp_bind(struct file *file, void *arg)
698 1.1 christos {
699 1.1 christos drm_agp_binding32_t req32;
700 1.1 christos struct drm_agp_binding req64;
701 1.1 christos int error;
702 1.1 christos
703 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) !=0 )
704 1.1 christos return error;
705 1.1 christos
706 1.1 christos req64.handle = req32.handle;
707 1.1 christos req64.offset = req32.offset;
708 1.1 christos
709 1.1 christos return drm_ioctl(file, DRM_IOCTL_AGP_BIND, &req64);
710 1.1 christos }
711 1.1 christos
712 1.1 christos static int
713 1.1 christos compat_drm_agp_unbind(struct file *file, void *arg)
714 1.1 christos {
715 1.1 christos struct drm_agp_binding req64;
716 1.1 christos drm_agp_binding32_t req32;
717 1.1 christos uint32_t handle;
718 1.1 christos int error;
719 1.1 christos
720 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
721 1.1 christos return error;
722 1.1 christos
723 1.1 christos handle = req32.handle;
724 1.1 christos req64.handle = handle;
725 1.1 christos
726 1.1 christos return drm_ioctl(file, DRM_IOCTL_AGP_UNBIND, &req64);
727 1.1 christos }
728 1.1 christos #endif /* CONFIG_AGP */
729 1.1 christos
730 1.1 christos typedef struct drm_scatter_gather32 {
731 1.1 christos uint32_t size; /**< In bytes -- will round to page boundary */
732 1.1 christos uint32_t handle; /**< Used for mapping / unmapping */
733 1.1 christos } drm_scatter_gather32_t;
734 1.1 christos
735 1.1 christos static int
736 1.1 christos compat_drm_sg_alloc(struct file *file, void *arg)
737 1.1 christos {
738 1.1 christos struct drm_scatter_gather req64;
739 1.1 christos drm_scatter_gather32_t req32;
740 1.1 christos int error;
741 1.1 christos
742 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
743 1.1 christos return error;
744 1.1 christos
745 1.1 christos req64.size = req32.size;
746 1.1 christos
747 1.1 christos error = drm_ioctl(file, DRM_IOCTL_SG_ALLOC, &req64);
748 1.1 christos if (error)
749 1.1 christos return error;
750 1.1 christos
751 1.1 christos /* XXX not sure about the handle conversion here... */
752 1.1 christos req32.handle = req64.handle >> PAGE_SHIFT;
753 1.1 christos
754 1.1 christos return 0;
755 1.1 christos }
756 1.1 christos
757 1.1 christos static int
758 1.1 christos compat_drm_sg_free(struct file *file, void *arg)
759 1.1 christos {
760 1.1 christos struct drm_scatter_gather req64;
761 1.1 christos unsigned long x;
762 1.1 christos drm_scatter_gather32_t req32;
763 1.1 christos int error;
764 1.1 christos
765 1.1 christos if((error = copyin(&req32, arg, sizeof(req32))) != 0)
766 1.1 christos return error;
767 1.1 christos
768 1.1 christos x = req32.handle;
769 1.1 christos req64.handle = x << PAGE_SHIFT;
770 1.1 christos
771 1.1 christos return drm_ioctl(file, DRM_IOCTL_SG_FREE, &req64);
772 1.1 christos }
773 1.1 christos
774 1.1 christos #if defined(CONFIG_X86) || defined(CONFIG_IA64)
775 1.1 christos typedef struct drm_update_draw32 {
776 1.1 christos drm_drawable_t handle;
777 1.1 christos unsigned int type;
778 1.1 christos unsigned int num;
779 1.1 christos /* 64-bit version has a 32-bit pad here */
780 1.1 christos uint64_t data; /**< Pointer */
781 1.1 christos } __attribute__((__packed__)) drm_update_draw32_t;
782 1.1 christos
783 1.1 christos static void
784 1.1 christos update32to64(struct drm_update_draw *req64, const drm_update_draw32_t *update32)
785 1.1 christos {
786 1.1 christos req64->handle = update32->handle;
787 1.1 christos req64->type = update32->type;
788 1.1 christos req64->num = update32->num;
789 1.1 christos req64->data = update32->data;
790 1.1 christos }
791 1.1 christos static int
792 1.1 christos compat_drm_update_draw(struct file *file, void *arg)
793 1.1 christos {
794 1.1 christos drm_update_draw32_t update32;
795 1.1 christos struct drm_update_draw req64;
796 1.1 christos int error;
797 1.1 christos
798 1.1 christos if ((error = copyin(&update32, arg, sizeof(update32))) !=0)
799 1.1 christos return error;
800 1.1 christos
801 1.1 christos update32to64(&req64, &update32);
802 1.1 christos
803 1.1 christos error = drm_ioctl(file, DRM_IOCTL_UPDATE_DRAW, &req64);
804 1.1 christos return error;
805 1.1 christos }
806 1.1 christos #endif
807 1.1 christos
808 1.1 christos struct drm_wait_vblank_request32 {
809 1.1 christos enum drm_vblank_seq_type type;
810 1.1 christos unsigned int sequence;
811 1.1 christos uint32_t signal;
812 1.1 christos };
813 1.1 christos
814 1.1 christos struct drm_wait_vblank_reply32 {
815 1.1 christos enum drm_vblank_seq_type type;
816 1.1 christos unsigned int sequence;
817 1.1 christos s32 tval_sec;
818 1.1 christos s32 tval_usec;
819 1.1 christos };
820 1.1 christos
821 1.1 christos typedef union drm_wait_vblank32 {
822 1.1 christos struct drm_wait_vblank_request32 request;
823 1.1 christos struct drm_wait_vblank_reply32 reply;
824 1.1 christos } drm_wait_vblank32_t;
825 1.1 christos
826 1.1 christos static void
827 1.1 christos req32to64(union drm_wait_vblank *req64, const drm_wait_vblank32_t *req32)
828 1.1 christos {
829 1.1 christos req64->request.type = req32->request.type;
830 1.1 christos req64->request.sequence = req32->request.sequence;
831 1.1 christos req64->request.signal = req32->request.signal;
832 1.1 christos }
833 1.1 christos
834 1.1 christos static void
835 1.1 christos req64to32(drm_wait_vblank32_t *req32, const union drm_wait_vblank *req64)
836 1.1 christos {
837 1.1 christos req32->reply.sequence = req64->reply.sequence;
838 1.1 christos req32->reply.tval_sec = req64->reply.tval_sec;
839 1.1 christos req32->reply.tval_usec = req64->reply.tval_usec;
840 1.1 christos }
841 1.1 christos
842 1.1 christos static int
843 1.1 christos compat_drm_wait_vblank(struct file *file, void *arg)
844 1.1 christos {
845 1.1 christos drm_wait_vblank32_t req32;
846 1.1 christos union drm_wait_vblank req64;
847 1.1 christos int error;
848 1.1 christos
849 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
850 1.1 christos return error;
851 1.1 christos
852 1.1 christos req32to64(&req64, &req32);
853 1.1 christos
854 1.1 christos error = drm_ioctl(file, DRM_IOCTL_WAIT_VBLANK, &req64);
855 1.1 christos if (error)
856 1.1 christos return error;
857 1.1 christos
858 1.1 christos req64to32(&req32, &req64);
859 1.1 christos
860 1.1 christos return copyout(arg, &req32, sizeof(req32));
861 1.1 christos }
862 1.1 christos
863 1.1 christos #if defined(CONFIG_X86) || defined(CONFIG_IA64)
864 1.1 christos typedef struct drm_mode_fb_cmd232 {
865 1.1 christos uint32_t fb_id;
866 1.1 christos uint32_t width;
867 1.1 christos uint32_t height;
868 1.1 christos uint32_t pixel_format;
869 1.1 christos uint32_t flags;
870 1.1 christos uint32_t handles[4];
871 1.1 christos uint32_t pitches[4];
872 1.1 christos uint32_t offsets[4];
873 1.1 christos uint64_t modifier[4];
874 1.1 christos } __attribute__((__packed__)) drm_mode_fb_cmd232_t;
875 1.1 christos
876 1.1 christos static void
877 1.1 christos map_req32to64(struct drm_mode_fb_cmd2 *req64, struct drm_mode_fb_cmd232 *req32)
878 1.1 christos {
879 1.1 christos req64->width = req32->width;
880 1.1 christos req64->height = req32->height;
881 1.1 christos req64->pixel_format = req32->pixel_format;
882 1.1 christos req64->flags = req32->flags;
883 1.1 christos }
884 1.1 christos
885 1.1 christos static int
886 1.1 christos compat_drm_mode_addfb2(struct file *file, void *arg)
887 1.1 christos {
888 1.1 christos struct drm_mode_fb_cmd232 req32;
889 1.1 christos struct drm_mode_fb_cmd2 req64;
890 1.1 christos int error;
891 1.1 christos
892 1.1 christos if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
893 1.1 christos return error;
894 1.1 christos
895 1.1 christos map_req32to64(&req64, &req32);
896 1.1 christos
897 1.1 christos for (int i = 0; i < 4; i++){
898 1.1 christos req64.handles[i] = req32.handles[i];
899 1.1 christos req64.pitches[i] = req32.pitches[i];
900 1.1 christos req64.offsets[i] = req32.offsets[i];
901 1.1 christos req64.modifier[i] = req32.modifier[i];
902 1.1 christos }
903 1.1 christos
904 1.1 christos error = drm_ioctl(file, DRM_IOCTL_MODE_ADDFB2, &req64);
905 1.1 christos if (error)
906 1.1 christos return error;
907 1.1 christos
908 1.1 christos req32.fb_id = req64.fb_id;
909 1.1 christos
910 1.1 christos return copyout(arg, &req32, sizeof(req32));
911 1.1 christos }
912 1.1 christos #endif
913 1.1 christos
914 1.1 christos int
915 1.1 christos netbsd32_drm_ioctl(struct file *file, unsigned long cmd, void *arg,
916 1.1 christos struct lwp *l)
917 1.1 christos {
918 1.1 christos switch (cmd) {
919 1.1 christos case DRM_IOCTL_VERSION32:
920 1.1 christos return compat_drm_version(file, arg);
921 1.1 christos case DRM_IOCTL_GET_UNIQUE32:
922 1.1 christos return compat_drm_getunique(file, arg);
923 1.1 christos case DRM_IOCTL_SET_UNIQUE32:
924 1.1 christos return compat_drm_setunique(file, arg);
925 1.1 christos case DRM_IOCTL_GET_MAP32:
926 1.1 christos return compat_drm_getmap(file, arg);
927 1.1 christos case DRM_IOCTL_ADD_MAP32:
928 1.1 christos return compat_drm_addmap(file, arg);
929 1.1 christos case DRM_IOCTL_RM_MAP32:
930 1.1 christos return compat_drm_rmmap(file, arg);
931 1.1 christos case DRM_IOCTL_GET_CLIENT32:
932 1.1 christos return compat_drm_getclient(file, arg);
933 1.1 christos case DRM_IOCTL_GET_STATS32:
934 1.1 christos return compat_drm_getstats(file, arg);
935 1.1 christos case DRM_IOCTL_ADD_BUFS32:
936 1.1 christos return compat_drm_addbufs(file, arg);
937 1.1 christos case DRM_IOCTL_MARK_BUFS32:
938 1.1 christos return compat_drm_markbufs(file, arg);
939 1.1 christos case DRM_IOCTL_FREE_BUFS32:
940 1.1 christos return compat_drm_freebufs(file, arg);
941 1.1 christos case DRM_IOCTL_SET_SAREA_CTX32:
942 1.1 christos return compat_drm_setsareactx(file, arg);
943 1.1 christos case DRM_IOCTL_GET_SAREA_CTX32:
944 1.1 christos return compat_drm_getsareactx(file, arg);
945 1.1 christos case DRM_IOCTL_RES_CTX32:
946 1.1 christos return compat_drm_resctx(file, arg);
947 1.1 christos case DRM_IOCTL_DMA32:
948 1.1 christos return compat_drm_dma(file, arg);
949 1.1 christos case DRM_IOCTL_AGP_ENABLE32:
950 1.1 christos return compat_drm_agp_enable(file, arg);
951 1.1 christos case DRM_IOCTL_AGP_INFO32:
952 1.1 christos return compat_drm_agp_info(file, arg);
953 1.1 christos case DRM_IOCTL_AGP_ALLOC32:
954 1.1 christos return compat_drm_agp_alloc(file,arg);
955 1.1 christos case DRM_IOCTL_AGP_UNBIND32:
956 1.1 christos return compat_drm_agp_unbind(file, arg);
957 1.1 christos case DRM_IOCTL_AGP_BIND32:
958 1.1 christos return compat_drm_agp_bind(file, arg);
959 1.1 christos case DRM_IOCTL_AGP_FREE32:
960 1.1 christos return compat_drm_agp_free(file, arg);
961 1.1 christos case DRM_IOCTL_SG_ALLOC32:
962 1.1 christos return compat_drm_sg_alloc(file, arg);
963 1.1 christos case DRM_IOCTL_MODE_ADDFB232:
964 1.1 christos return compat_drm_mode_addfb2(file, arg);
965 1.1 christos case DRM_IOCTL_WAIT_VBLANK32:
966 1.1 christos return compat_drm_wait_vblank(file, arg);
967 1.1 christos case DRM_IOCTL_UPDATE_DRAW32:
968 1.1 christos return compat_drm_update_draw(file, arg);
969 1.1 christos case DRM_IOCTL_SG_FREE32:
970 1.1 christos return compat_drm_sg_free(file, arg);
971 1.1 christos default:
972 1.1 christos return EINVAL;
973 1.1 christos }
974 1.1 christos }
975