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