1239375Skib/*-
2239375Skib * Copyright (C) Paul Mackerras 2005.
3239375Skib * All Rights Reserved.
4239375Skib *
5239375Skib * Permission is hereby granted, free of charge, to any person obtaining a
6239375Skib * copy of this software and associated documentation files (the "Software"),
7239375Skib * to deal in the Software without restriction, including without limitation
8239375Skib * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9239375Skib * and/or sell copies of the Software, and to permit persons to whom the
10239375Skib * Software is furnished to do so, subject to the following conditions:
11239375Skib *
12239375Skib * The above copyright notice and this permission notice (including the next
13239375Skib * paragraph) shall be included in all copies or substantial portions of the
14239375Skib * Software.
15239375Skib *
16239375Skib * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17239375Skib * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18239375Skib * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19239375Skib * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20239375Skib * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21239375Skib * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22239375Skib * IN THE SOFTWARE.
23239375Skib */
24239375Skib
25239375Skib#include <sys/cdefs.h>
26239375Skib__FBSDID("$FreeBSD$");
27239375Skib
28239375Skib#include "opt_compat.h"
29239375Skib
30239375Skib#ifdef COMPAT_FREEBSD32
31239375Skib
32239375Skib#include <dev/drm2/drmP.h>
33239375Skib#include <dev/drm2/drm.h>
34239375Skib
35239375Skib#define DRM_IOCTL_VERSION32		DRM_IOWR(0x00, drm_version32_t)
36239375Skib#define DRM_IOCTL_GET_UNIQUE32		DRM_IOWR(0x01, drm_unique32_t)
37239375Skib#define DRM_IOCTL_GET_MAP32		DRM_IOWR(0x04, drm_map32_t)
38239375Skib#define DRM_IOCTL_GET_CLIENT32		DRM_IOWR(0x05, drm_client32_t)
39239375Skib#define DRM_IOCTL_GET_STATS32		DRM_IOR( 0x06, drm_stats32_t)
40239375Skib
41239375Skib#define DRM_IOCTL_SET_UNIQUE32		DRM_IOW( 0x10, drm_unique32_t)
42239375Skib#define DRM_IOCTL_ADD_MAP32		DRM_IOWR(0x15, drm_map32_t)
43239375Skib#define DRM_IOCTL_ADD_BUFS32		DRM_IOWR(0x16, drm_buf_desc32_t)
44239375Skib#define DRM_IOCTL_MARK_BUFS32		DRM_IOW( 0x17, drm_buf_desc32_t)
45239375Skib#define DRM_IOCTL_INFO_BUFS32		DRM_IOWR(0x18, drm_buf_info32_t)
46239375Skib#define DRM_IOCTL_MAP_BUFS32		DRM_IOWR(0x19, drm_buf_map32_t)
47239375Skib#define DRM_IOCTL_FREE_BUFS32		DRM_IOW( 0x1a, drm_buf_free32_t)
48239375Skib
49239375Skib#define DRM_IOCTL_RM_MAP32		DRM_IOW( 0x1b, drm_map32_t)
50239375Skib
51239375Skib#define DRM_IOCTL_SET_SAREA_CTX32	DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
52239375Skib#define DRM_IOCTL_GET_SAREA_CTX32	DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
53239375Skib
54239375Skib#define DRM_IOCTL_RES_CTX32		DRM_IOWR(0x26, drm_ctx_res32_t)
55239375Skib#define DRM_IOCTL_DMA32			DRM_IOWR(0x29, drm_dma32_t)
56239375Skib
57239375Skib#define DRM_IOCTL_AGP_ENABLE32		DRM_IOW( 0x32, drm_agp_mode32_t)
58239375Skib#define DRM_IOCTL_AGP_INFO32		DRM_IOR( 0x33, drm_agp_info32_t)
59239375Skib#define DRM_IOCTL_AGP_ALLOC32		DRM_IOWR(0x34, drm_agp_buffer32_t)
60239375Skib#define DRM_IOCTL_AGP_FREE32		DRM_IOW( 0x35, drm_agp_buffer32_t)
61239375Skib#define DRM_IOCTL_AGP_BIND32		DRM_IOW( 0x36, drm_agp_binding32_t)
62239375Skib#define DRM_IOCTL_AGP_UNBIND32		DRM_IOW( 0x37, drm_agp_binding32_t)
63239375Skib
64239375Skib#define DRM_IOCTL_SG_ALLOC32		DRM_IOW( 0x38, drm_scatter_gather32_t)
65239375Skib#define DRM_IOCTL_SG_FREE32		DRM_IOW( 0x39, drm_scatter_gather32_t)
66239375Skib
67239375Skib#define DRM_IOCTL_UPDATE_DRAW32		DRM_IOW( 0x3f, drm_update_draw32_t)
68239375Skib
69239375Skib#define DRM_IOCTL_WAIT_VBLANK32		DRM_IOWR(0x3a, drm_wait_vblank32_t)
70239375Skib
71239375Skibtypedef struct drm_version_32 {
72239375Skib	int version_major;	  /**< Major version */
73239375Skib	int version_minor;	  /**< Minor version */
74239375Skib	int version_patchlevel;	   /**< Patch level */
75239375Skib	u32 name_len;		  /**< Length of name buffer */
76239375Skib	u32 name;		  /**< Name of driver */
77239375Skib	u32 date_len;		  /**< Length of date buffer */
78239375Skib	u32 date;		  /**< User-space buffer to hold date */
79239375Skib	u32 desc_len;		  /**< Length of desc buffer */
80239375Skib	u32 desc;		  /**< User-space buffer to hold desc */
81239375Skib} drm_version32_t;
82239375Skib
83280183Sdumbbellstatic int compat_drm_version(struct drm_device *dev, void *data,
84280183Sdumbbell    struct drm_file *file_priv)
85239375Skib{
86239375Skib	drm_version32_t *v32 = data;
87239375Skib	struct drm_version version;
88239375Skib	int err;
89239375Skib
90239375Skib	version.name_len = v32->name_len;
91239375Skib	version.name = (void *)(unsigned long)v32->name;
92239375Skib	version.date_len = v32->date_len;
93239375Skib	version.date = (void *)(unsigned long)v32->date;
94239375Skib	version.desc_len = v32->desc_len;
95239375Skib	version.desc = (void *)(unsigned long)v32->desc;
96280183Sdumbbell
97239375Skib	err = drm_version(dev, (void *)&version, file_priv);
98239375Skib	if (err)
99239375Skib		return err;
100239375Skib
101239375Skib	v32->version_major = version.version_major;
102239375Skib	v32->version_minor = version.version_minor;
103239375Skib	v32->version_patchlevel = version.version_patchlevel;
104239375Skib	v32->name_len = version.name_len;
105239375Skib	v32->date_len = version.date_len;
106239375Skib	v32->desc_len = version.desc_len;
107239375Skib
108239375Skib	return 0;
109239375Skib}
110239375Skib
111239375Skibtypedef struct drm_unique32 {
112239375Skib	u32 unique_len;	/**< Length of unique */
113239375Skib	u32 unique;	/**< Unique name for driver instantiation */
114239375Skib} drm_unique32_t;
115239375Skib
116280183Sdumbbellstatic int compat_drm_getunique(struct drm_device *dev, void *data,
117280183Sdumbbell    struct drm_file *file_priv)
118239375Skib{
119239375Skib	drm_unique32_t *uq32 = data;
120239375Skib	struct drm_unique u;
121239375Skib	int err;
122239375Skib
123239375Skib	u.unique_len = uq32->unique_len;
124239375Skib	u.unique = (void *)(unsigned long)uq32->unique;
125239375Skib
126239375Skib	err = drm_getunique(dev, (void *)&u, file_priv);
127239375Skib	if (err)
128239375Skib		return err;
129239375Skib
130239375Skib	uq32->unique_len = u.unique_len;
131239375Skib
132239375Skib	return 0;
133239375Skib}
134239375Skib
135280183Sdumbbellstatic int compat_drm_setunique(struct drm_device *dev, void *data,
136280183Sdumbbell    struct drm_file *file_priv)
137239375Skib{
138239375Skib	drm_unique32_t *uq32 = data;
139239375Skib	struct drm_unique u;
140239375Skib
141239375Skib	u.unique_len = uq32->unique_len;
142239375Skib	u.unique = (void *)(unsigned long)uq32->unique;
143239375Skib
144239375Skib	return drm_setunique(dev, (void *)&u, file_priv);
145239375Skib}
146239375Skib
147239375Skibtypedef struct drm_map32 {
148239375Skib	u32 offset;		/**< Requested physical address (0 for SAREA)*/
149239375Skib	u32 size;		/**< Requested physical size (bytes) */
150239375Skib	enum drm_map_type type;	/**< Type of memory to map */
151239375Skib	enum drm_map_flags flags;	/**< Flags */
152239375Skib	u32 handle;		/**< User-space: "Handle" to pass to mmap() */
153239375Skib	int mtrr;		/**< MTRR slot used */
154239375Skib} drm_map32_t;
155239375Skib
156280183Sdumbbellstatic int compat_drm_getmap(struct drm_device *dev, void *data,
157280183Sdumbbell    struct drm_file *file_priv)
158239375Skib{
159239375Skib	drm_map32_t *m32 = data;
160239375Skib	struct drm_map map;
161239375Skib	int err;
162239375Skib	void *handle;
163239375Skib
164239375Skib	map.offset = (unsigned long)m32->offset;
165239375Skib
166239375Skib	err = drm_getmap(dev, (void *)&map, file_priv);
167239375Skib	if (err)
168239375Skib		return err;
169239375Skib
170239375Skib	m32->offset = map.offset;
171239375Skib	m32->size = map.size;
172239375Skib	m32->type = map.type;
173239375Skib	m32->flags = map.flags;
174239375Skib	handle = map.handle;
175239375Skib	m32->mtrr = map.mtrr;
176239375Skib
177239375Skib	m32->handle = (unsigned long)handle;
178239375Skib
179239375Skib	return 0;
180239375Skib
181239375Skib}
182239375Skib
183280183Sdumbbellstatic int compat_drm_addmap(struct drm_device *dev, void *data,
184280183Sdumbbell    struct drm_file *file_priv)
185239375Skib{
186239375Skib	drm_map32_t *m32 = data;
187239375Skib	struct drm_map map;
188239375Skib	int err;
189239375Skib	void *handle;
190280183Sdumbbell
191239375Skib	map.offset = (unsigned long)m32->offset;
192239375Skib	map.size = (unsigned long)m32->size;
193239375Skib	map.type = m32->type;
194239375Skib	map.flags = m32->flags;
195239375Skib
196239375Skib	err = drm_addmap_ioctl(dev, (void *)&map, file_priv);
197239375Skib	if (err)
198239375Skib		return err;
199239375Skib
200239375Skib	m32->offset = map.offset;
201239375Skib	m32->mtrr = map.mtrr;
202239375Skib	handle = map.handle;
203280183Sdumbbell
204239375Skib	m32->handle = (unsigned long)handle;
205239375Skib	if (m32->handle != (unsigned long)handle)
206239375Skib		DRM_DEBUG("compat_drm_addmap truncated handle"
207239375Skib				   " %p for type %d offset %x\n",
208239375Skib				   handle, m32->type, m32->offset);
209239375Skib
210239375Skib	return 0;
211239375Skib}
212239375Skib
213280183Sdumbbellstatic int compat_drm_rmmap(struct drm_device *dev, void *data,
214280183Sdumbbell    struct drm_file *file_priv)
215239375Skib{
216239375Skib	drm_map32_t *m32 = data;
217239375Skib	struct drm_map map;
218239375Skib
219239375Skib	map.handle = (void *)(unsigned long)m32->handle;
220239375Skib
221239375Skib	return drm_rmmap_ioctl(dev, (void *)&map, file_priv);
222239375Skib}
223239375Skib
224239375Skibtypedef struct drm_client32 {
225239375Skib	int idx;	/**< Which client desired? */
226239375Skib	int auth;	/**< Is client authenticated? */
227239375Skib	u32 pid;	/**< Process ID */
228239375Skib	u32 uid;	/**< User ID */
229239375Skib	u32 magic;	/**< Magic */
230239375Skib	u32 iocs;	/**< Ioctl count */
231239375Skib} drm_client32_t;
232239375Skib
233280183Sdumbbellstatic int compat_drm_getclient(struct drm_device *dev, void *data,
234280183Sdumbbell    struct drm_file *file_priv)
235239375Skib{
236239375Skib	drm_client32_t *c32 = data;
237239375Skib	struct drm_client client;
238239375Skib	int err;
239239375Skib
240239375Skib	client.idx = c32->idx;
241239375Skib
242239375Skib	err = drm_getclient(dev, (void *)&client, file_priv);
243239375Skib	if (err)
244239375Skib		return err;
245239375Skib
246239375Skib	c32->idx = client.idx;
247239375Skib	c32->auth = client.auth;
248239375Skib	c32->pid = client.pid;
249239375Skib	c32->uid = client.uid;
250239375Skib	c32->magic = client.magic;
251239375Skib	c32->iocs = client.iocs;
252239375Skib
253239375Skib	return 0;
254239375Skib}
255239375Skib
256239375Skibtypedef struct drm_stats32 {
257239375Skib	u32 count;
258239375Skib	struct {
259239375Skib		u32 value;
260239375Skib		enum drm_stat_type type;
261239375Skib	} data[15];
262239375Skib} drm_stats32_t;
263239375Skib
264280183Sdumbbellstatic int compat_drm_getstats(struct drm_device *dev, void *data,
265280183Sdumbbell    struct drm_file *file_priv)
266239375Skib{
267239375Skib	drm_stats32_t *s32 = data;
268239375Skib	struct drm_stats stats;
269239375Skib	int i, err;
270239375Skib
271239375Skib	err = drm_getstats(dev, (void *)&stats, file_priv);
272239375Skib	if (err)
273239375Skib		return err;
274239375Skib
275239375Skib	s32->count = stats.count;
276239375Skib	for (i = 0; i < stats.count; i++) {
277239375Skib		s32->data[i].value = stats.data[i].value;
278239375Skib		s32->data[i].type = stats.data[i].type;
279239375Skib	}
280239375Skib
281239375Skib	return 0;
282239375Skib}
283239375Skib
284239375Skibtypedef struct drm_buf_desc32 {
285239375Skib	int count;		 /**< Number of buffers of this size */
286239375Skib	int size;		 /**< Size in bytes */
287239375Skib	int low_mark;		 /**< Low water mark */
288239375Skib	int high_mark;		 /**< High water mark */
289239375Skib	int flags;
290239375Skib	u32 agp_start;		 /**< Start address in the AGP aperture */
291239375Skib} drm_buf_desc32_t;
292239375Skib
293280183Sdumbbellstatic int compat_drm_addbufs(struct drm_device *dev, void *data,
294280183Sdumbbell    struct drm_file *file_priv)
295239375Skib{
296239375Skib	drm_buf_desc32_t *b32 = data;
297239375Skib	struct drm_buf_desc buf;
298239375Skib	int err;
299239375Skib
300239375Skib	buf.count = b32->count;
301239375Skib	buf.size = b32->size;
302239375Skib	buf.low_mark = b32->low_mark;
303239375Skib	buf.high_mark = b32->high_mark;
304239375Skib	buf.flags = b32->flags;
305239375Skib	buf.agp_start = (unsigned long)b32->agp_start;
306239375Skib
307239375Skib	err = drm_addbufs(dev, (void *)&buf, file_priv);
308239375Skib	if (err)
309239375Skib		return err;
310239375Skib
311239375Skib	b32->count = buf.count;
312239375Skib	b32->size = buf.size;
313239375Skib	b32->low_mark = buf.low_mark;
314239375Skib	b32->high_mark = buf.high_mark;
315239375Skib	b32->flags = buf.flags;
316239375Skib	b32->agp_start = buf.agp_start;
317280183Sdumbbell
318239375Skib	return 0;
319239375Skib}
320239375Skib
321280183Sdumbbellstatic int compat_drm_markbufs(struct drm_device *dev, void *data,
322280183Sdumbbell    struct drm_file *file_priv)
323239375Skib{
324239375Skib	drm_buf_desc32_t *b32 = data;
325239375Skib	struct drm_buf_desc buf;
326239375Skib
327239375Skib	buf.size = b32->size;
328239375Skib	buf.low_mark = b32->low_mark;
329239375Skib	buf.high_mark = b32->high_mark;
330280183Sdumbbell
331239375Skib	return drm_markbufs(dev, (void *)&buf, file_priv);
332239375Skib}
333239375Skib
334239375Skibtypedef struct drm_buf_info32 {
335239375Skib	int count;		/**< Entries in list */
336239375Skib	u32 list;
337239375Skib} drm_buf_info32_t;
338239375Skib
339280183Sdumbbellstatic int compat_drm_infobufs(struct drm_device *dev, void *data,
340280183Sdumbbell    struct drm_file *file_priv)
341239375Skib{
342239375Skib	drm_buf_info32_t *req32 = data;
343239375Skib	drm_buf_desc32_t *to;
344239375Skib	struct drm_buf_info *request;
345239375Skib	struct drm_buf_desc *list;
346239375Skib	size_t nbytes;
347239375Skib	int i, err;
348239375Skib	int count, actual;
349239375Skib
350239375Skib	count = req32->count;
351239375Skib	to = (drm_buf_desc32_t *)(unsigned long)req32->list;
352239375Skib	if (count < 0)
353239375Skib		count = 0;
354239375Skib
355239375Skib	nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc);
356239375Skib	request = malloc(nbytes, DRM_MEM_BUFLISTS, M_ZERO | M_NOWAIT);
357239375Skib	if (!request)
358280183Sdumbbell		return -ENOMEM;
359239375Skib	list = (struct drm_buf_desc *) (request + 1);
360239375Skib
361239375Skib	request->count = count;
362239375Skib	request->list = list;
363239375Skib
364239375Skib	err = drm_infobufs(dev, (void *)request, file_priv);
365239375Skib	if (err)
366239375Skib		return err;
367239375Skib
368239375Skib	actual = request->count;
369239375Skib	if (count >= actual)
370239375Skib		for (i = 0; i < actual; ++i) {
371239375Skib			to[i].count = list[i].count;
372239375Skib			to[i].size = list[i].size;
373239375Skib			to[i].low_mark = list[i].low_mark;
374239375Skib			to[i].high_mark = list[i].high_mark;
375239375Skib			to[i].flags = list[i].flags;
376239375Skib		}
377239375Skib
378239375Skib	req32->count = actual;
379239375Skib
380239375Skib	return 0;
381239375Skib}
382239375Skib
383239375Skibtypedef struct drm_buf_pub32 {
384239375Skib	int idx;		/**< Index into the master buffer list */
385239375Skib	int total;		/**< Buffer size */
386239375Skib	int used;		/**< Amount of buffer in use (for DMA) */
387239375Skib	u32 address;		/**< Address of buffer */
388239375Skib} drm_buf_pub32_t;
389239375Skib
390239375Skibtypedef struct drm_buf_map32 {
391239375Skib	int count;		/**< Length of the buffer list */
392239375Skib	u32 virtual;		/**< Mmap'd area in user-virtual */
393239375Skib	u32 list;		/**< Buffer information */
394239375Skib} drm_buf_map32_t;
395239375Skib
396280183Sdumbbellstatic int compat_drm_mapbufs(struct drm_device *dev, void *data,
397280183Sdumbbell    struct drm_file *file_priv)
398239375Skib{
399239375Skib	drm_buf_map32_t *req32 = data;
400239375Skib	drm_buf_pub32_t *list32;
401239375Skib	struct drm_buf_map *request;
402239375Skib	struct drm_buf_pub *list;
403239375Skib	int i, err;
404239375Skib	int count, actual;
405239375Skib	size_t nbytes;
406239375Skib
407239375Skib	count = req32->count;
408239375Skib	list32 = (void *)(unsigned long)req32->list;
409239375Skib
410239375Skib	if (count < 0)
411239375Skib		return -EINVAL;
412239375Skib	nbytes = sizeof(*request) + count * sizeof(struct drm_buf_pub);
413239375Skib	request = malloc(nbytes, DRM_MEM_BUFLISTS, M_ZERO | M_NOWAIT);
414239375Skib	if (!request)
415280183Sdumbbell		return -ENOMEM;
416239375Skib	list = (struct drm_buf_pub *) (request + 1);
417239375Skib
418239375Skib	request->count = count;
419239375Skib	request->list = list;
420239375Skib
421239375Skib	err = drm_mapbufs(dev, (void *)request, file_priv);
422239375Skib	if (err)
423239375Skib		return err;
424239375Skib
425239375Skib	actual = request->count;
426239375Skib	if (count >= actual)
427239375Skib		for (i = 0; i < actual; ++i) {
428239375Skib			list32[i].idx = list[i].idx;
429239375Skib			list32[i].total = list[i].total;
430239375Skib			list32[i].used = list[i].used;
431239375Skib			list32[i].address = (unsigned long)list[i].address;
432239375Skib		}
433239375Skib
434239375Skib	req32->count = actual;
435239375Skib	req32->virtual = (unsigned long)request->virtual;
436239375Skib
437239375Skib	return 0;
438239375Skib}
439239375Skib
440239375Skibtypedef struct drm_buf_free32 {
441239375Skib	int count;
442239375Skib	u32 list;
443239375Skib} drm_buf_free32_t;
444239375Skib
445280183Sdumbbellstatic int compat_drm_freebufs(struct drm_device *dev, void *data,
446280183Sdumbbell    struct drm_file *file_priv)
447239375Skib{
448239375Skib	drm_buf_free32_t *req32 = data;
449239375Skib	struct drm_buf_free request;
450239375Skib
451239375Skib	request.count = req32->count;
452239375Skib	request.list = (int *)(unsigned long)req32->list;
453239375Skib
454239375Skib	return drm_freebufs(dev, (void *)&request, file_priv);
455239375Skib}
456239375Skib
457239375Skibtypedef struct drm_ctx_priv_map32 {
458239375Skib	unsigned int ctx_id;	 /**< Context requesting private mapping */
459239375Skib	u32 handle;		/**< Handle of map */
460239375Skib} drm_ctx_priv_map32_t;
461239375Skib
462280183Sdumbbellstatic int compat_drm_setsareactx(struct drm_device *dev, void *data,
463280183Sdumbbell    struct drm_file *file_priv)
464239375Skib{
465239375Skib	drm_ctx_priv_map32_t *req32 = data;
466239375Skib	struct drm_ctx_priv_map request;
467239375Skib
468239375Skib	request.ctx_id = req32->ctx_id;
469239375Skib	request.handle = (void *)(unsigned long)req32->handle;
470239375Skib
471239375Skib	return drm_setsareactx(dev, (void *)&request, file_priv);
472239375Skib}
473239375Skib
474280183Sdumbbellstatic int compat_drm_getsareactx(struct drm_device *dev, void *data,
475280183Sdumbbell    struct drm_file *file_priv)
476239375Skib{
477239375Skib	drm_ctx_priv_map32_t *req32 = data;
478239375Skib	struct drm_ctx_priv_map request;
479239375Skib	int err;
480239375Skib
481239375Skib	request.ctx_id = req32->ctx_id;
482239375Skib
483239375Skib	err = drm_getsareactx(dev, (void *)&request, file_priv);
484239375Skib	if (err)
485239375Skib		return err;
486239375Skib
487239375Skib	req32->handle = (unsigned long)request.handle;
488239375Skib
489239375Skib	return 0;
490239375Skib}
491239375Skib
492239375Skibtypedef struct drm_ctx_res32 {
493239375Skib	int count;
494239375Skib	u32 contexts;
495239375Skib} drm_ctx_res32_t;
496239375Skib
497280183Sdumbbellstatic int compat_drm_resctx(struct drm_device *dev, void *data,
498280183Sdumbbell    struct drm_file *file_priv)
499239375Skib{
500239375Skib	drm_ctx_res32_t *res32 = data;
501239375Skib	struct drm_ctx_res res;
502239375Skib	int err;
503239375Skib
504239375Skib	res.count = res32->count;
505239375Skib	res.contexts = (struct drm_ctx __user *)(unsigned long)res32->contexts;
506239375Skib
507239375Skib	err = drm_resctx(dev, (void *)&res, file_priv);
508239375Skib	if (err)
509239375Skib		return err;
510239375Skib
511239375Skib	res32->count = res.count;
512239375Skib
513239375Skib	return 0;
514239375Skib}
515239375Skib
516239375Skibtypedef struct drm_dma32 {
517239375Skib	int context;		  /**< Context handle */
518239375Skib	int send_count;		  /**< Number of buffers to send */
519239375Skib	u32 send_indices;	  /**< List of handles to buffers */
520239375Skib	u32 send_sizes;		  /**< Lengths of data to send */
521239375Skib	enum drm_dma_flags flags;		  /**< Flags */
522239375Skib	int request_count;	  /**< Number of buffers requested */
523239375Skib	int request_size;	  /**< Desired size for buffers */
524239375Skib	u32 request_indices;	  /**< Buffer information */
525239375Skib	u32 request_sizes;
526239375Skib	int granted_count;	  /**< Number of buffers granted */
527239375Skib} drm_dma32_t;
528239375Skib
529280183Sdumbbellstatic int compat_drm_dma(struct drm_device *dev, void *data,
530280183Sdumbbell    struct drm_file *file_priv)
531239375Skib{
532239375Skib	drm_dma32_t *d32 = data;
533239375Skib	struct drm_dma d;
534239375Skib	int err;
535239375Skib
536280183Sdumbbell	if (!dev->driver->dma_ioctl) {
537280183Sdumbbell		DRM_DEBUG("DMA ioctl on driver with no dma handler\n");
538280183Sdumbbell		return -EINVAL;
539280183Sdumbbell	}
540280183Sdumbbell
541239375Skib	d.context = d32->context;
542239375Skib	d.send_count = d32->send_count;
543239375Skib	d.send_indices = (int *)(unsigned long)d32->send_indices;
544239375Skib	d.send_sizes = (int *)(unsigned long)d32->send_sizes;
545239375Skib	d.flags = d32->flags;
546239375Skib	d.request_count = d32->request_count;
547239375Skib	d.request_indices = (int *)(unsigned long)d32->request_indices;
548239375Skib	d.request_sizes = (int *)(unsigned long)d32->request_sizes;
549239375Skib
550280183Sdumbbell	err = dev->driver->dma_ioctl(dev, (void *)&d, file_priv);
551239375Skib	if (err)
552239375Skib		return err;
553239375Skib
554239375Skib	d32->request_size = d.request_size;
555239375Skib	d32->granted_count = d.granted_count;
556239375Skib
557239375Skib	return 0;
558239375Skib}
559239375Skib
560280183Sdumbbell#if __OS_HAS_AGP
561239375Skibtypedef struct drm_agp_mode32 {
562239375Skib	u32 mode;	/**< AGP mode */
563239375Skib} drm_agp_mode32_t;
564239375Skib
565280183Sdumbbellstatic int compat_drm_agp_enable(struct drm_device *dev, void *data,
566280183Sdumbbell    struct drm_file *file_priv)
567239375Skib{
568239375Skib	drm_agp_mode32_t *m32 = data;
569239375Skib	struct drm_agp_mode mode;
570239375Skib
571239375Skib	mode.mode = m32->mode;
572239375Skib
573239375Skib	return drm_agp_enable_ioctl(dev, (void *)&mode, file_priv);
574239375Skib}
575239375Skib
576239375Skibtypedef struct drm_agp_info32 {
577239375Skib	int agp_version_major;
578239375Skib	int agp_version_minor;
579239375Skib	u32 mode;
580239375Skib	u32 aperture_base;	/* physical address */
581239375Skib	u32 aperture_size;	/* bytes */
582239375Skib	u32 memory_allowed;	/* bytes */
583239375Skib	u32 memory_used;
584239375Skib
585239375Skib	/* PCI information */
586239375Skib	unsigned short id_vendor;
587239375Skib	unsigned short id_device;
588239375Skib} drm_agp_info32_t;
589239375Skib
590280183Sdumbbellstatic int compat_drm_agp_info(struct drm_device *dev, void *data,
591280183Sdumbbell    struct drm_file *file_priv)
592239375Skib{
593239375Skib	drm_agp_info32_t *i32 = data;
594239375Skib	struct drm_agp_info info;
595239375Skib	int err;
596239375Skib
597239375Skib	err = drm_agp_info_ioctl(dev, (void *)&info, file_priv);
598239375Skib	if (err)
599239375Skib		return err;
600239375Skib
601239375Skib	i32->agp_version_major = info.agp_version_major;
602239375Skib	i32->agp_version_minor = info.agp_version_minor;
603239375Skib	i32->mode = info.mode;
604239375Skib	i32->aperture_base = info.aperture_base;
605239375Skib	i32->aperture_size = info.aperture_size;
606239375Skib	i32->memory_allowed = info.memory_allowed;
607239375Skib	i32->memory_used = info.memory_used;
608239375Skib	i32->id_vendor = info.id_vendor;
609239375Skib	i32->id_device = info.id_device;
610239375Skib
611239375Skib	return 0;
612239375Skib}
613239375Skib
614239375Skibtypedef struct drm_agp_buffer32 {
615239375Skib	u32 size;	/**< In bytes -- will round to page boundary */
616239375Skib	u32 handle;	/**< Used for binding / unbinding */
617239375Skib	u32 type;	/**< Type of memory to allocate */
618239375Skib	u32 physical;	/**< Physical used by i810 */
619239375Skib} drm_agp_buffer32_t;
620239375Skib
621280183Sdumbbellstatic int compat_drm_agp_alloc(struct drm_device *dev, void *data,
622280183Sdumbbell    struct drm_file *file_priv)
623239375Skib{
624239375Skib	drm_agp_buffer32_t *req32 = data;
625239375Skib	struct drm_agp_buffer request;
626239375Skib	int err;
627239375Skib
628239375Skib	request.size = req32->size;
629239375Skib	request.type = req32->type;
630239375Skib
631239375Skib	err = drm_agp_alloc_ioctl(dev, (void *)&request, file_priv);
632239375Skib	if (err)
633239375Skib		return err;
634239375Skib
635239375Skib	req32->handle = request.handle;
636239375Skib	req32->physical = request.physical;
637239375Skib
638239375Skib	return 0;
639239375Skib}
640239375Skib
641280183Sdumbbellstatic int compat_drm_agp_free(struct drm_device *dev, void *data,
642280183Sdumbbell    struct drm_file *file_priv)
643239375Skib{
644239375Skib	drm_agp_buffer32_t *req32 = data;
645239375Skib	struct drm_agp_buffer request;
646239375Skib
647239375Skib	request.handle = req32->handle;
648239375Skib
649239375Skib	return drm_agp_free_ioctl(dev, (void *)&request, file_priv);
650239375Skib}
651239375Skib
652239375Skibtypedef struct drm_agp_binding32 {
653239375Skib	u32 handle;	/**< From drm_agp_buffer */
654239375Skib	u32 offset;	/**< In bytes -- will round to page boundary */
655239375Skib} drm_agp_binding32_t;
656239375Skib
657280183Sdumbbellstatic int compat_drm_agp_bind(struct drm_device *dev, void *data,
658280183Sdumbbell    struct drm_file *file_priv)
659239375Skib{
660239375Skib	drm_agp_binding32_t *req32 = data;
661239375Skib	struct drm_agp_binding request;
662239375Skib
663239375Skib	request.handle = req32->handle;
664239375Skib	request.offset = req32->offset;
665239375Skib
666239375Skib	return drm_agp_bind_ioctl(dev, (void *)&request, file_priv);
667239375Skib}
668239375Skib
669280183Sdumbbellstatic int compat_drm_agp_unbind(struct drm_device *dev, void *data,
670280183Sdumbbell    struct drm_file *file_priv)
671239375Skib{
672239375Skib	drm_agp_binding32_t *req32 = data;
673239375Skib	struct drm_agp_binding request;
674280183Sdumbbell
675239375Skib	request.handle = req32->handle;
676280183Sdumbbell
677239375Skib	return drm_agp_unbind_ioctl(dev, (void *)&request, file_priv);
678239375Skib}
679280183Sdumbbell#endif				/* __OS_HAS_AGP */
680239375Skib
681239375Skibtypedef struct drm_scatter_gather32 {
682239375Skib	u32 size;	/**< In bytes -- will round to page boundary */
683239375Skib	u32 handle;	/**< Used for mapping / unmapping */
684239375Skib} drm_scatter_gather32_t;
685239375Skib
686280183Sdumbbellstatic int compat_drm_sg_alloc(struct drm_device *dev, void *data,
687280183Sdumbbell    struct drm_file *file_priv)
688239375Skib{
689239375Skib	drm_scatter_gather32_t *req32 = data;
690239375Skib	struct drm_scatter_gather request;
691239375Skib	int err;
692239375Skib
693239375Skib	request.size = (unsigned long)req32->size;
694239375Skib
695239375Skib	err = drm_sg_alloc_ioctl(dev, (void *)&request, file_priv);
696239375Skib	if (err)
697239375Skib		return err;
698239375Skib
699239375Skib	/* XXX not sure about the handle conversion here... */
700239375Skib	req32->handle = (unsigned long)request.handle >> PAGE_SHIFT;
701239375Skib
702239375Skib	return 0;
703239375Skib}
704239375Skib
705280183Sdumbbellstatic int compat_drm_sg_free(struct drm_device *dev, void *data,
706280183Sdumbbell    struct drm_file *file_priv)
707239375Skib{
708239375Skib	drm_scatter_gather32_t *req32 = data;
709239375Skib	struct drm_scatter_gather request;
710239375Skib
711239375Skib	request.handle = (unsigned long)req32->handle << PAGE_SHIFT;
712239375Skib
713239375Skib	return drm_sg_free(dev, (void *)&request, file_priv);
714239375Skib}
715239375Skib
716280183Sdumbbell#if defined(CONFIG_X86) || defined(CONFIG_IA64)
717239375Skibtypedef struct drm_update_draw32 {
718239375Skib	drm_drawable_t handle;
719239375Skib	unsigned int type;
720239375Skib	unsigned int num;
721239375Skib	/* 64-bit version has a 32-bit pad here */
722239375Skib	u64 data;	/**< Pointer */
723239375Skib} __attribute__((packed)) drm_update_draw32_t;
724280183Sdumbbell#endif
725239375Skib
726239375Skibstruct drm_wait_vblank_request32 {
727239375Skib	enum drm_vblank_seq_type type;
728239375Skib	unsigned int sequence;
729239375Skib	u32 signal;
730239375Skib};
731239375Skib
732239375Skibstruct drm_wait_vblank_reply32 {
733239375Skib	enum drm_vblank_seq_type type;
734239375Skib	unsigned int sequence;
735239375Skib	s32 tval_sec;
736239375Skib	s32 tval_usec;
737239375Skib};
738239375Skib
739239375Skibtypedef union drm_wait_vblank32 {
740239375Skib	struct drm_wait_vblank_request32 request;
741239375Skib	struct drm_wait_vblank_reply32 reply;
742239375Skib} drm_wait_vblank32_t;
743239375Skib
744280183Sdumbbellstatic int compat_drm_wait_vblank(struct drm_device *dev, void *data,
745280183Sdumbbell    struct drm_file *file_priv)
746239375Skib{
747239375Skib	drm_wait_vblank32_t *req32 = data;
748239375Skib	union drm_wait_vblank request;
749239375Skib	int err;
750239375Skib
751239375Skib	request.request.type = req32->request.type;
752239375Skib	request.request.sequence = req32->request.sequence;
753239375Skib	request.request.signal = req32->request.signal;
754239375Skib
755239375Skib	err = drm_wait_vblank(dev, (void *)&request, file_priv);
756239375Skib	if (err)
757239375Skib		return err;
758239375Skib
759239375Skib	req32->reply.type = request.reply.type;
760239375Skib	req32->reply.sequence = request.reply.sequence;
761239375Skib	req32->reply.tval_sec = request.reply.tval_sec;
762239375Skib	req32->reply.tval_usec = request.reply.tval_usec;
763239375Skib
764239375Skib	return 0;
765239375Skib}
766239375Skib
767280183Sdumbbellstruct drm_ioctl_desc drm_compat_ioctls[256] = {
768280183Sdumbbell	DRM_IOCTL_DEF(DRM_IOCTL_VERSION32, compat_drm_version, DRM_UNLOCKED),
769239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE32, compat_drm_getunique, 0),
770280183Sdumbbell	DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP32, compat_drm_getmap, DRM_UNLOCKED),
771280183Sdumbbell	DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT32, compat_drm_getclient, DRM_UNLOCKED),
772280183Sdumbbell	DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS32, compat_drm_getstats, DRM_UNLOCKED),
773239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE32, compat_drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
774239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP32, compat_drm_addmap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
775239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS32, compat_drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
776239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS32, compat_drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
777239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS32, compat_drm_infobufs, DRM_AUTH),
778239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS32, compat_drm_mapbufs, DRM_AUTH),
779239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS32, compat_drm_freebufs, DRM_AUTH),
780239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP32, compat_drm_rmmap, DRM_AUTH),
781239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX32, compat_drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
782239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX32, compat_drm_getsareactx, DRM_AUTH),
783239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX32, compat_drm_resctx, DRM_AUTH),
784239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_DMA32, compat_drm_dma, DRM_AUTH),
785280183Sdumbbell#if __OS_HAS_AGP
786239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE32, compat_drm_agp_enable, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
787239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO32, compat_drm_agp_info, DRM_AUTH),
788239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC32, compat_drm_agp_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
789239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE32, compat_drm_agp_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
790239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND32, compat_drm_agp_bind, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
791239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND32, compat_drm_agp_unbind, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
792280183Sdumbbell#endif
793239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC32, compat_drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
794239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE32, compat_drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
795280183Sdumbbell#if defined(CONFIG_X86) || defined(CONFIG_IA64)
796280183Sdumbbell	DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW32, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
797280183Sdumbbell#endif
798239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK32, compat_drm_wait_vblank, DRM_UNLOCKED),
799239375Skib};
800239375Skib
801239375Skib#endif
802