]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/drm2/drm_ioc32.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / drm2 / drm_ioc32.c
1 /*-
2  * Copyright (C) Paul Mackerras 2005.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Paul Mackerras <paulus@samba.org>
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include "opt_compat.h"
32
33 #ifdef COMPAT_FREEBSD32
34
35 #include <dev/drm2/drmP.h>
36 #include <dev/drm2/drm.h>
37
38 /** @file drm_ioc32.c
39  * 32-bit ioctl compatibility routines for the DRM.
40  */
41  
42 #define DRM_IOCTL_VERSION32             DRM_IOWR(0x00, drm_version32_t)
43 #define DRM_IOCTL_GET_UNIQUE32          DRM_IOWR(0x01, drm_unique32_t)
44 #define DRM_IOCTL_GET_MAP32             DRM_IOWR(0x04, drm_map32_t)
45 #define DRM_IOCTL_GET_CLIENT32          DRM_IOWR(0x05, drm_client32_t)
46 #define DRM_IOCTL_GET_STATS32           DRM_IOR( 0x06, drm_stats32_t)
47
48 #define DRM_IOCTL_SET_UNIQUE32          DRM_IOW( 0x10, drm_unique32_t)
49 #define DRM_IOCTL_ADD_MAP32             DRM_IOWR(0x15, drm_map32_t)
50 #define DRM_IOCTL_ADD_BUFS32            DRM_IOWR(0x16, drm_buf_desc32_t)
51 #define DRM_IOCTL_MARK_BUFS32           DRM_IOW( 0x17, drm_buf_desc32_t)
52 #define DRM_IOCTL_INFO_BUFS32           DRM_IOWR(0x18, drm_buf_info32_t)
53 #define DRM_IOCTL_MAP_BUFS32            DRM_IOWR(0x19, drm_buf_map32_t)
54 #define DRM_IOCTL_FREE_BUFS32           DRM_IOW( 0x1a, drm_buf_free32_t)
55
56 #define DRM_IOCTL_RM_MAP32              DRM_IOW( 0x1b, drm_map32_t)
57
58 #define DRM_IOCTL_SET_SAREA_CTX32       DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
59 #define DRM_IOCTL_GET_SAREA_CTX32       DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
60
61 #define DRM_IOCTL_RES_CTX32             DRM_IOWR(0x26, drm_ctx_res32_t)
62 #define DRM_IOCTL_DMA32                 DRM_IOWR(0x29, drm_dma32_t)
63
64 #define DRM_IOCTL_AGP_ENABLE32          DRM_IOW( 0x32, drm_agp_mode32_t)
65 #define DRM_IOCTL_AGP_INFO32            DRM_IOR( 0x33, drm_agp_info32_t)
66 #define DRM_IOCTL_AGP_ALLOC32           DRM_IOWR(0x34, drm_agp_buffer32_t)
67 #define DRM_IOCTL_AGP_FREE32            DRM_IOW( 0x35, drm_agp_buffer32_t)
68 #define DRM_IOCTL_AGP_BIND32            DRM_IOW( 0x36, drm_agp_binding32_t)
69 #define DRM_IOCTL_AGP_UNBIND32          DRM_IOW( 0x37, drm_agp_binding32_t)
70
71 #define DRM_IOCTL_SG_ALLOC32            DRM_IOW( 0x38, drm_scatter_gather32_t)
72 #define DRM_IOCTL_SG_FREE32             DRM_IOW( 0x39, drm_scatter_gather32_t)
73
74 #define DRM_IOCTL_UPDATE_DRAW32         DRM_IOW( 0x3f, drm_update_draw32_t)
75
76 #define DRM_IOCTL_WAIT_VBLANK32         DRM_IOWR(0x3a, drm_wait_vblank32_t)
77
78 typedef struct drm_version_32 {
79         int version_major;        /**< Major version */
80         int version_minor;        /**< Minor version */
81         int version_patchlevel;    /**< Patch level */
82         u32 name_len;             /**< Length of name buffer */
83         u32 name;                 /**< Name of driver */
84         u32 date_len;             /**< Length of date buffer */
85         u32 date;                 /**< User-space buffer to hold date */
86         u32 desc_len;             /**< Length of desc buffer */
87         u32 desc;                 /**< User-space buffer to hold desc */
88 } drm_version32_t;
89
90 static int compat_drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv)
91 {
92         drm_version32_t *v32 = data;
93         struct drm_version version;
94         int err;
95
96         version.name_len = v32->name_len;
97         version.name = (void *)(unsigned long)v32->name;
98         version.date_len = v32->date_len;
99         version.date = (void *)(unsigned long)v32->date;
100         version.desc_len = v32->desc_len;
101         version.desc = (void *)(unsigned long)v32->desc;
102         
103         err = drm_version(dev, (void *)&version, file_priv);
104         if (err)
105                 return err;
106
107         v32->version_major = version.version_major;
108         v32->version_minor = version.version_minor;
109         v32->version_patchlevel = version.version_patchlevel;
110         v32->name_len = version.name_len;
111         v32->date_len = version.date_len;
112         v32->desc_len = version.desc_len;
113
114         return 0;
115 }
116
117 typedef struct drm_unique32 {
118         u32 unique_len; /**< Length of unique */
119         u32 unique;     /**< Unique name for driver instantiation */
120 } drm_unique32_t;
121
122 static int compat_drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv)
123 {
124         drm_unique32_t *uq32 = data;
125         struct drm_unique u;
126         int err;
127
128         u.unique_len = uq32->unique_len;
129         u.unique = (void *)(unsigned long)uq32->unique;
130
131         err = drm_getunique(dev, (void *)&u, file_priv);
132         if (err)
133                 return err;
134
135         uq32->unique_len = u.unique_len;
136
137         return 0;
138 }
139
140 static int compat_drm_setunique(struct drm_device *dev, void *data, struct drm_file *file_priv)
141 {
142         drm_unique32_t *uq32 = data;
143         struct drm_unique u;
144
145         u.unique_len = uq32->unique_len;
146         u.unique = (void *)(unsigned long)uq32->unique;
147
148         return drm_setunique(dev, (void *)&u, file_priv);
149 }
150
151 typedef struct drm_map32 {
152         u32 offset;             /**< Requested physical address (0 for SAREA)*/
153         u32 size;               /**< Requested physical size (bytes) */
154         enum drm_map_type type; /**< Type of memory to map */
155         enum drm_map_flags flags;       /**< Flags */
156         u32 handle;             /**< User-space: "Handle" to pass to mmap() */
157         int mtrr;               /**< MTRR slot used */
158 } drm_map32_t;
159
160 static int compat_drm_getmap(struct drm_device *dev, void *data, struct drm_file *file_priv)
161 {
162         drm_map32_t *m32 = data;
163         struct drm_map map;
164         int err;
165         void *handle;
166
167         map.offset = (unsigned long)m32->offset;
168
169         err = drm_getmap(dev, (void *)&map, file_priv);
170         if (err)
171                 return err;
172
173         m32->offset = map.offset;
174         m32->size = map.size;
175         m32->type = map.type;
176         m32->flags = map.flags;
177         handle = map.handle;
178         m32->mtrr = map.mtrr;
179
180         m32->handle = (unsigned long)handle;
181
182         return 0;
183
184 }
185
186 static int compat_drm_addmap(struct drm_device *dev, void *data, struct drm_file *file_priv)
187 {
188         drm_map32_t *m32 = data;
189         struct drm_map map;
190         int err;
191         void *handle;
192         
193         map.offset = (unsigned long)m32->offset;
194         map.size = (unsigned long)m32->size;
195         map.type = m32->type;
196         map.flags = m32->flags;
197
198         err = drm_addmap_ioctl(dev, (void *)&map, file_priv);
199         if (err)
200                 return err;
201
202         m32->offset = map.offset;
203         m32->mtrr = map.mtrr;
204         handle = map.handle;
205         
206         m32->handle = (unsigned long)handle;
207         if (m32->handle != (unsigned long)handle)
208                 DRM_DEBUG("compat_drm_addmap truncated handle"
209                                    " %p for type %d offset %x\n",
210                                    handle, m32->type, m32->offset);
211
212         return 0;
213 }
214
215 static int compat_drm_rmmap(struct drm_device *dev, void *data, struct drm_file *file_priv)
216 {
217         drm_map32_t *m32 = data;
218         struct drm_map map;
219
220         map.handle = (void *)(unsigned long)m32->handle;
221
222         return drm_rmmap_ioctl(dev, (void *)&map, file_priv);
223 }
224
225 typedef struct drm_client32 {
226         int idx;        /**< Which client desired? */
227         int auth;       /**< Is client authenticated? */
228         u32 pid;        /**< Process ID */
229         u32 uid;        /**< User ID */
230         u32 magic;      /**< Magic */
231         u32 iocs;       /**< Ioctl count */
232 } drm_client32_t;
233
234 static int compat_drm_getclient(struct drm_device *dev, void *data, struct drm_file *file_priv)
235 {
236         drm_client32_t *c32 = data;
237         struct drm_client client;
238         int err;
239
240         client.idx = c32->idx;
241
242         err = drm_getclient(dev, (void *)&client, file_priv);
243         if (err)
244                 return err;
245
246         c32->idx = client.idx;
247         c32->auth = client.auth;
248         c32->pid = client.pid;
249         c32->uid = client.uid;
250         c32->magic = client.magic;
251         c32->iocs = client.iocs;
252
253         return 0;
254 }
255
256 typedef struct drm_stats32 {
257         u32 count;
258         struct {
259                 u32 value;
260                 enum drm_stat_type type;
261         } data[15];
262 } drm_stats32_t;
263
264 static int compat_drm_getstats(struct drm_device *dev, void *data, struct drm_file *file_priv)
265 {
266         drm_stats32_t *s32 = data;
267         struct drm_stats stats;
268         int i, err;
269
270         err = drm_getstats(dev, (void *)&stats, file_priv);
271         if (err)
272                 return err;
273
274         s32->count = stats.count;
275         for (i = 0; i < stats.count; i++) {
276                 s32->data[i].value = stats.data[i].value;
277                 s32->data[i].type = stats.data[i].type;
278         }
279
280         return 0;
281 }
282
283 typedef struct drm_buf_desc32 {
284         int count;               /**< Number of buffers of this size */
285         int size;                /**< Size in bytes */
286         int low_mark;            /**< Low water mark */
287         int high_mark;           /**< High water mark */
288         int flags;
289         u32 agp_start;           /**< Start address in the AGP aperture */
290 } drm_buf_desc32_t;
291
292 static int compat_drm_addbufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
293 {
294         drm_buf_desc32_t *b32 = data;
295         struct drm_buf_desc buf;
296         int err;
297
298         buf.count = b32->count;
299         buf.size = b32->size;
300         buf.low_mark = b32->low_mark;
301         buf.high_mark = b32->high_mark;
302         buf.flags = b32->flags;
303         buf.agp_start = (unsigned long)b32->agp_start;
304
305         err = drm_addbufs(dev, (void *)&buf, file_priv);
306         if (err)
307                 return err;
308
309         b32->count = buf.count;
310         b32->size = buf.size;
311         b32->low_mark = buf.low_mark;
312         b32->high_mark = buf.high_mark;
313         b32->flags = buf.flags;
314         b32->agp_start = buf.agp_start;
315         
316         return 0;
317 }
318
319 static int compat_drm_markbufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
320 {
321         drm_buf_desc32_t *b32 = data;
322         struct drm_buf_desc buf;
323
324         buf.size = b32->size;
325         buf.low_mark = b32->low_mark;
326         buf.high_mark = b32->high_mark;
327         
328         return drm_markbufs(dev, (void *)&buf, file_priv);
329 }
330
331 typedef struct drm_buf_info32 {
332         int count;              /**< Entries in list */
333         u32 list;
334 } drm_buf_info32_t;
335
336 static int compat_drm_infobufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
337 {
338         drm_buf_info32_t *req32 = data;
339         drm_buf_desc32_t *to;
340         struct drm_buf_info *request;
341         struct drm_buf_desc *list;
342         size_t nbytes;
343         int i, err;
344         int count, actual;
345
346         count = req32->count;
347         to = (drm_buf_desc32_t *)(unsigned long)req32->list;
348         if (count < 0)
349                 count = 0;
350
351         nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc);
352         request = malloc(nbytes, DRM_MEM_BUFLISTS, M_ZERO | M_NOWAIT);
353         if (!request)
354                 return -EFAULT;
355         list = (struct drm_buf_desc *) (request + 1);
356
357         request->count = count;
358         request->list = list;
359
360         err = drm_infobufs(dev, (void *)request, file_priv);
361         if (err)
362                 return err;
363
364         actual = request->count;
365         if (count >= actual)
366                 for (i = 0; i < actual; ++i) {
367                         to[i].count = list[i].count;
368                         to[i].size = list[i].size;
369                         to[i].low_mark = list[i].low_mark;
370                         to[i].high_mark = list[i].high_mark;
371                         to[i].flags = list[i].flags;
372                 }
373
374         req32->count = actual;
375
376         return 0;
377 }
378
379 typedef struct drm_buf_pub32 {
380         int idx;                /**< Index into the master buffer list */
381         int total;              /**< Buffer size */
382         int used;               /**< Amount of buffer in use (for DMA) */
383         u32 address;            /**< Address of buffer */
384 } drm_buf_pub32_t;
385
386 typedef struct drm_buf_map32 {
387         int count;              /**< Length of the buffer list */
388         u32 virtual;            /**< Mmap'd area in user-virtual */
389         u32 list;               /**< Buffer information */
390 } drm_buf_map32_t;
391
392 static int compat_drm_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
393 {
394         drm_buf_map32_t *req32 = data;
395         drm_buf_pub32_t *list32;
396         struct drm_buf_map *request;
397         struct drm_buf_pub *list;
398         int i, err;
399         int count, actual;
400         size_t nbytes;
401
402         count = req32->count;
403         list32 = (void *)(unsigned long)req32->list;
404
405         if (count < 0)
406                 return -EINVAL;
407         nbytes = sizeof(*request) + count * sizeof(struct drm_buf_pub);
408         request = malloc(nbytes, DRM_MEM_BUFLISTS, M_ZERO | M_NOWAIT);
409         if (!request)
410                 return -EFAULT;
411         list = (struct drm_buf_pub *) (request + 1);
412
413         request->count = count;
414         request->list = list;
415
416         err = drm_mapbufs(dev, (void *)request, file_priv);
417         if (err)
418                 return err;
419
420         actual = request->count;
421         if (count >= actual)
422                 for (i = 0; i < actual; ++i) {
423                         list32[i].idx = list[i].idx;
424                         list32[i].total = list[i].total;
425                         list32[i].used = list[i].used;
426                         list32[i].address = (unsigned long)list[i].address;
427                 }
428
429         req32->count = actual;
430         req32->virtual = (unsigned long)request->virtual;
431
432         return 0;
433 }
434
435 typedef struct drm_buf_free32 {
436         int count;
437         u32 list;
438 } drm_buf_free32_t;
439
440 static int compat_drm_freebufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
441 {
442         drm_buf_free32_t *req32 = data;
443         struct drm_buf_free request;
444
445         request.count = req32->count;
446         request.list = (int *)(unsigned long)req32->list;
447
448         return drm_freebufs(dev, (void *)&request, file_priv);
449 }
450
451 typedef struct drm_ctx_priv_map32 {
452         unsigned int ctx_id;     /**< Context requesting private mapping */
453         u32 handle;             /**< Handle of map */
454 } drm_ctx_priv_map32_t;
455
456 static int compat_drm_setsareactx(struct drm_device *dev, void *data, struct drm_file *file_priv)
457 {
458         drm_ctx_priv_map32_t *req32 = data;
459         struct drm_ctx_priv_map request;
460
461         request.ctx_id = req32->ctx_id;
462         request.handle = (void *)(unsigned long)req32->handle;
463
464         return drm_setsareactx(dev, (void *)&request, file_priv);
465 }
466
467 static int compat_drm_getsareactx(struct drm_device *dev, void *data, struct drm_file *file_priv)
468 {
469         drm_ctx_priv_map32_t *req32 = data;
470         struct drm_ctx_priv_map request;
471         int err;
472
473         request.ctx_id = req32->ctx_id;
474
475         err = drm_getsareactx(dev, (void *)&request, file_priv);
476         if (err)
477                 return err;
478
479         req32->handle = (unsigned long)request.handle;
480
481         return 0;
482 }
483
484 typedef struct drm_ctx_res32 {
485         int count;
486         u32 contexts;
487 } drm_ctx_res32_t;
488
489 static int compat_drm_resctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
490 {
491         drm_ctx_res32_t *res32 = data;
492         struct drm_ctx_res res;
493         int err;
494
495         res.count = res32->count;
496         res.contexts = (struct drm_ctx __user *)(unsigned long)res32->contexts;
497
498         err = drm_resctx(dev, (void *)&res, file_priv);
499         if (err)
500                 return err;
501
502         res32->count = res.count;
503
504         return 0;
505 }
506
507 typedef struct drm_dma32 {
508         int context;              /**< Context handle */
509         int send_count;           /**< Number of buffers to send */
510         u32 send_indices;         /**< List of handles to buffers */
511         u32 send_sizes;           /**< Lengths of data to send */
512         enum drm_dma_flags flags;                 /**< Flags */
513         int request_count;        /**< Number of buffers requested */
514         int request_size;         /**< Desired size for buffers */
515         u32 request_indices;      /**< Buffer information */
516         u32 request_sizes;
517         int granted_count;        /**< Number of buffers granted */
518 } drm_dma32_t;
519
520 static int compat_drm_dma(struct drm_device *dev, void *data, struct drm_file *file_priv)
521 {
522         drm_dma32_t *d32 = data;
523         struct drm_dma d;
524         int err;
525
526         d.context = d32->context;
527         d.send_count = d32->send_count;
528         d.send_indices = (int *)(unsigned long)d32->send_indices;
529         d.send_sizes = (int *)(unsigned long)d32->send_sizes;
530         d.flags = d32->flags;
531         d.request_count = d32->request_count;
532         d.request_indices = (int *)(unsigned long)d32->request_indices;
533         d.request_sizes = (int *)(unsigned long)d32->request_sizes;
534
535         err = drm_dma(dev, (void *)&d, file_priv);
536         if (err)
537                 return err;
538
539         d32->request_size = d.request_size;
540         d32->granted_count = d.granted_count;
541
542         return 0;
543 }
544
545 typedef struct drm_agp_mode32 {
546         u32 mode;       /**< AGP mode */
547 } drm_agp_mode32_t;
548
549 static int compat_drm_agp_enable(struct drm_device *dev, void *data, struct drm_file *file_priv)
550 {
551         drm_agp_mode32_t *m32 = data;
552         struct drm_agp_mode mode;
553
554         mode.mode = m32->mode;
555
556         return drm_agp_enable_ioctl(dev, (void *)&mode, file_priv);
557 }
558
559 typedef struct drm_agp_info32 {
560         int agp_version_major;
561         int agp_version_minor;
562         u32 mode;
563         u32 aperture_base;      /* physical address */
564         u32 aperture_size;      /* bytes */
565         u32 memory_allowed;     /* bytes */
566         u32 memory_used;
567
568         /* PCI information */
569         unsigned short id_vendor;
570         unsigned short id_device;
571 } drm_agp_info32_t;
572
573 static int compat_drm_agp_info(struct drm_device *dev, void *data, struct drm_file *file_priv)
574 {
575         drm_agp_info32_t *i32 = data;
576         struct drm_agp_info info;
577         int err;
578
579         err = drm_agp_info_ioctl(dev, (void *)&info, file_priv);
580         if (err)
581                 return err;
582
583         i32->agp_version_major = info.agp_version_major;
584         i32->agp_version_minor = info.agp_version_minor;
585         i32->mode = info.mode;
586         i32->aperture_base = info.aperture_base;
587         i32->aperture_size = info.aperture_size;
588         i32->memory_allowed = info.memory_allowed;
589         i32->memory_used = info.memory_used;
590         i32->id_vendor = info.id_vendor;
591         i32->id_device = info.id_device;
592
593         return 0;
594 }
595
596 typedef struct drm_agp_buffer32 {
597         u32 size;       /**< In bytes -- will round to page boundary */
598         u32 handle;     /**< Used for binding / unbinding */
599         u32 type;       /**< Type of memory to allocate */
600         u32 physical;   /**< Physical used by i810 */
601 } drm_agp_buffer32_t;
602
603 static int compat_drm_agp_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
604 {
605         drm_agp_buffer32_t *req32 = data;
606         struct drm_agp_buffer request;
607         int err;
608
609         request.size = req32->size;
610         request.type = req32->type;
611
612         err = drm_agp_alloc_ioctl(dev, (void *)&request, file_priv);
613         if (err)
614                 return err;
615
616         req32->handle = request.handle;
617         req32->physical = request.physical;
618
619         return 0;
620 }
621
622 static int compat_drm_agp_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
623 {
624         drm_agp_buffer32_t *req32 = data;
625         struct drm_agp_buffer request;
626
627         request.handle = req32->handle;
628
629         return drm_agp_free_ioctl(dev, (void *)&request, file_priv);
630 }
631
632 typedef struct drm_agp_binding32 {
633         u32 handle;     /**< From drm_agp_buffer */
634         u32 offset;     /**< In bytes -- will round to page boundary */
635 } drm_agp_binding32_t;
636
637 static int compat_drm_agp_bind(struct drm_device *dev, void *data, struct drm_file *file_priv)
638 {
639         drm_agp_binding32_t *req32 = data;
640         struct drm_agp_binding request;
641
642         request.handle = req32->handle;
643         request.offset = req32->offset;
644
645         return drm_agp_bind_ioctl(dev, (void *)&request, file_priv);
646 }
647
648 static int compat_drm_agp_unbind(struct drm_device *dev, void *data, struct drm_file *file_priv)
649 {
650         drm_agp_binding32_t *req32 = data;
651         struct drm_agp_binding request;
652         
653         request.handle = req32->handle;
654         
655         return drm_agp_unbind_ioctl(dev, (void *)&request, file_priv);
656 }
657
658 typedef struct drm_scatter_gather32 {
659         u32 size;       /**< In bytes -- will round to page boundary */
660         u32 handle;     /**< Used for mapping / unmapping */
661 } drm_scatter_gather32_t;
662
663 static int compat_drm_sg_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
664 {
665         drm_scatter_gather32_t *req32 = data;
666         struct drm_scatter_gather request;
667         int err;
668
669         request.size = (unsigned long)req32->size;
670
671         err = drm_sg_alloc_ioctl(dev, (void *)&request, file_priv);
672         if (err)
673                 return err;
674
675         /* XXX not sure about the handle conversion here... */
676         req32->handle = (unsigned long)request.handle >> PAGE_SHIFT;
677
678         return 0;
679 }
680
681 static int compat_drm_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
682 {
683         drm_scatter_gather32_t *req32 = data;
684         struct drm_scatter_gather request;
685
686         request.handle = (unsigned long)req32->handle << PAGE_SHIFT;
687
688         return drm_sg_free(dev, (void *)&request, file_priv);
689 }
690
691 typedef struct drm_update_draw32 {
692         drm_drawable_t handle;
693         unsigned int type;
694         unsigned int num;
695         /* 64-bit version has a 32-bit pad here */
696         u64 data;       /**< Pointer */
697 } __attribute__((packed)) drm_update_draw32_t;
698
699 static int compat_drm_update_draw(struct drm_device *dev, void *data, struct drm_file *file_priv)
700 {
701         drm_update_draw32_t *update32 = data;
702         struct drm_update_draw request;
703         int err;
704
705         request.handle = update32->handle;
706         request.type = update32->type;
707         request.num = update32->num;
708         request.data = update32->data;
709
710         err = drm_update_draw(dev, (void *)&request, file_priv);
711         return err;
712 }
713
714 struct drm_wait_vblank_request32 {
715         enum drm_vblank_seq_type type;
716         unsigned int sequence;
717         u32 signal;
718 };
719
720 struct drm_wait_vblank_reply32 {
721         enum drm_vblank_seq_type type;
722         unsigned int sequence;
723         s32 tval_sec;
724         s32 tval_usec;
725 };
726
727 typedef union drm_wait_vblank32 {
728         struct drm_wait_vblank_request32 request;
729         struct drm_wait_vblank_reply32 reply;
730 } drm_wait_vblank32_t;
731
732 static int compat_drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
733 {
734         drm_wait_vblank32_t *req32 = data;
735         union drm_wait_vblank request;
736         int err;
737
738         request.request.type = req32->request.type;
739         request.request.sequence = req32->request.sequence;
740         request.request.signal = req32->request.signal;
741
742         err = drm_wait_vblank(dev, (void *)&request, file_priv);
743         if (err)
744                 return err;
745
746         req32->reply.type = request.reply.type;
747         req32->reply.sequence = request.reply.sequence;
748         req32->reply.tval_sec = request.reply.tval_sec;
749         req32->reply.tval_usec = request.reply.tval_usec;
750
751         return 0;
752 }
753
754 drm_ioctl_desc_t drm_compat_ioctls[256] = {
755         DRM_IOCTL_DEF(DRM_IOCTL_VERSION32, compat_drm_version, 0),
756         DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE32, compat_drm_getunique, 0),
757         DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP32, compat_drm_getmap, 0),
758         DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT32, compat_drm_getclient, 0),
759         DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS32, compat_drm_getstats, 0),
760         DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE32, compat_drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
761         DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP32, compat_drm_addmap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
762         DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS32, compat_drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
763         DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS32, compat_drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
764         DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS32, compat_drm_infobufs, DRM_AUTH),
765         DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS32, compat_drm_mapbufs, DRM_AUTH),
766         DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS32, compat_drm_freebufs, DRM_AUTH),
767         DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP32, compat_drm_rmmap, DRM_AUTH),
768         DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX32, compat_drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
769         DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX32, compat_drm_getsareactx, DRM_AUTH),
770         DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX32, compat_drm_resctx, DRM_AUTH),
771         DRM_IOCTL_DEF(DRM_IOCTL_DMA32, compat_drm_dma, DRM_AUTH),
772         
773         DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE32, compat_drm_agp_enable, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
774         DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO32, compat_drm_agp_info, DRM_AUTH),
775         DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC32, compat_drm_agp_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
776         DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE32, compat_drm_agp_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
777         DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND32, compat_drm_agp_bind, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
778         DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND32, compat_drm_agp_unbind, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
779         
780         DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC32, compat_drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
781         DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE32, compat_drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
782         
783         DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW32, compat_drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
784         
785         DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK32, compat_drm_wait_vblank, DRM_UNLOCKED),
786 };
787
788 #endif