drm_ioc32.c revision 239375
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 * Authors:
25239375Skib *    Paul Mackerras <paulus@samba.org>
26239375Skib */
27239375Skib
28239375Skib#include <sys/cdefs.h>
29239375Skib__FBSDID("$FreeBSD: head/sys/dev/drm2/drm_ioc32.c 239375 2012-08-18 18:26:25Z kib $");
30239375Skib
31239375Skib#include "opt_compat.h"
32239375Skib
33239375Skib#ifdef COMPAT_FREEBSD32
34239375Skib
35239375Skib#include <dev/drm2/drmP.h>
36239375Skib#include <dev/drm2/drm.h>
37239375Skib
38239375Skib/** @file drm_ioc32.c
39239375Skib * 32-bit ioctl compatibility routines for the DRM.
40239375Skib */
41239375Skib
42239375Skib#define DRM_IOCTL_VERSION32		DRM_IOWR(0x00, drm_version32_t)
43239375Skib#define DRM_IOCTL_GET_UNIQUE32		DRM_IOWR(0x01, drm_unique32_t)
44239375Skib#define DRM_IOCTL_GET_MAP32		DRM_IOWR(0x04, drm_map32_t)
45239375Skib#define DRM_IOCTL_GET_CLIENT32		DRM_IOWR(0x05, drm_client32_t)
46239375Skib#define DRM_IOCTL_GET_STATS32		DRM_IOR( 0x06, drm_stats32_t)
47239375Skib
48239375Skib#define DRM_IOCTL_SET_UNIQUE32		DRM_IOW( 0x10, drm_unique32_t)
49239375Skib#define DRM_IOCTL_ADD_MAP32		DRM_IOWR(0x15, drm_map32_t)
50239375Skib#define DRM_IOCTL_ADD_BUFS32		DRM_IOWR(0x16, drm_buf_desc32_t)
51239375Skib#define DRM_IOCTL_MARK_BUFS32		DRM_IOW( 0x17, drm_buf_desc32_t)
52239375Skib#define DRM_IOCTL_INFO_BUFS32		DRM_IOWR(0x18, drm_buf_info32_t)
53239375Skib#define DRM_IOCTL_MAP_BUFS32		DRM_IOWR(0x19, drm_buf_map32_t)
54239375Skib#define DRM_IOCTL_FREE_BUFS32		DRM_IOW( 0x1a, drm_buf_free32_t)
55239375Skib
56239375Skib#define DRM_IOCTL_RM_MAP32		DRM_IOW( 0x1b, drm_map32_t)
57239375Skib
58239375Skib#define DRM_IOCTL_SET_SAREA_CTX32	DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
59239375Skib#define DRM_IOCTL_GET_SAREA_CTX32	DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
60239375Skib
61239375Skib#define DRM_IOCTL_RES_CTX32		DRM_IOWR(0x26, drm_ctx_res32_t)
62239375Skib#define DRM_IOCTL_DMA32			DRM_IOWR(0x29, drm_dma32_t)
63239375Skib
64239375Skib#define DRM_IOCTL_AGP_ENABLE32		DRM_IOW( 0x32, drm_agp_mode32_t)
65239375Skib#define DRM_IOCTL_AGP_INFO32		DRM_IOR( 0x33, drm_agp_info32_t)
66239375Skib#define DRM_IOCTL_AGP_ALLOC32		DRM_IOWR(0x34, drm_agp_buffer32_t)
67239375Skib#define DRM_IOCTL_AGP_FREE32		DRM_IOW( 0x35, drm_agp_buffer32_t)
68239375Skib#define DRM_IOCTL_AGP_BIND32		DRM_IOW( 0x36, drm_agp_binding32_t)
69239375Skib#define DRM_IOCTL_AGP_UNBIND32		DRM_IOW( 0x37, drm_agp_binding32_t)
70239375Skib
71239375Skib#define DRM_IOCTL_SG_ALLOC32		DRM_IOW( 0x38, drm_scatter_gather32_t)
72239375Skib#define DRM_IOCTL_SG_FREE32		DRM_IOW( 0x39, drm_scatter_gather32_t)
73239375Skib
74239375Skib#define DRM_IOCTL_UPDATE_DRAW32		DRM_IOW( 0x3f, drm_update_draw32_t)
75239375Skib
76239375Skib#define DRM_IOCTL_WAIT_VBLANK32		DRM_IOWR(0x3a, drm_wait_vblank32_t)
77239375Skib
78239375Skibtypedef struct drm_version_32 {
79239375Skib	int version_major;	  /**< Major version */
80239375Skib	int version_minor;	  /**< Minor version */
81239375Skib	int version_patchlevel;	   /**< Patch level */
82239375Skib	u32 name_len;		  /**< Length of name buffer */
83239375Skib	u32 name;		  /**< Name of driver */
84239375Skib	u32 date_len;		  /**< Length of date buffer */
85239375Skib	u32 date;		  /**< User-space buffer to hold date */
86239375Skib	u32 desc_len;		  /**< Length of desc buffer */
87239375Skib	u32 desc;		  /**< User-space buffer to hold desc */
88239375Skib} drm_version32_t;
89239375Skib
90239375Skibstatic int compat_drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv)
91239375Skib{
92239375Skib	drm_version32_t *v32 = data;
93239375Skib	struct drm_version version;
94239375Skib	int err;
95239375Skib
96239375Skib	version.name_len = v32->name_len;
97239375Skib	version.name = (void *)(unsigned long)v32->name;
98239375Skib	version.date_len = v32->date_len;
99239375Skib	version.date = (void *)(unsigned long)v32->date;
100239375Skib	version.desc_len = v32->desc_len;
101239375Skib	version.desc = (void *)(unsigned long)v32->desc;
102239375Skib
103239375Skib	err = drm_version(dev, (void *)&version, file_priv);
104239375Skib	if (err)
105239375Skib		return err;
106239375Skib
107239375Skib	v32->version_major = version.version_major;
108239375Skib	v32->version_minor = version.version_minor;
109239375Skib	v32->version_patchlevel = version.version_patchlevel;
110239375Skib	v32->name_len = version.name_len;
111239375Skib	v32->date_len = version.date_len;
112239375Skib	v32->desc_len = version.desc_len;
113239375Skib
114239375Skib	return 0;
115239375Skib}
116239375Skib
117239375Skibtypedef struct drm_unique32 {
118239375Skib	u32 unique_len;	/**< Length of unique */
119239375Skib	u32 unique;	/**< Unique name for driver instantiation */
120239375Skib} drm_unique32_t;
121239375Skib
122239375Skibstatic int compat_drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv)
123239375Skib{
124239375Skib	drm_unique32_t *uq32 = data;
125239375Skib	struct drm_unique u;
126239375Skib	int err;
127239375Skib
128239375Skib	u.unique_len = uq32->unique_len;
129239375Skib	u.unique = (void *)(unsigned long)uq32->unique;
130239375Skib
131239375Skib	err = drm_getunique(dev, (void *)&u, file_priv);
132239375Skib	if (err)
133239375Skib		return err;
134239375Skib
135239375Skib	uq32->unique_len = u.unique_len;
136239375Skib
137239375Skib	return 0;
138239375Skib}
139239375Skib
140239375Skibstatic int compat_drm_setunique(struct drm_device *dev, void *data, struct drm_file *file_priv)
141239375Skib{
142239375Skib	drm_unique32_t *uq32 = data;
143239375Skib	struct drm_unique u;
144239375Skib
145239375Skib	u.unique_len = uq32->unique_len;
146239375Skib	u.unique = (void *)(unsigned long)uq32->unique;
147239375Skib
148239375Skib	return drm_setunique(dev, (void *)&u, file_priv);
149239375Skib}
150239375Skib
151239375Skibtypedef struct drm_map32 {
152239375Skib	u32 offset;		/**< Requested physical address (0 for SAREA)*/
153239375Skib	u32 size;		/**< Requested physical size (bytes) */
154239375Skib	enum drm_map_type type;	/**< Type of memory to map */
155239375Skib	enum drm_map_flags flags;	/**< Flags */
156239375Skib	u32 handle;		/**< User-space: "Handle" to pass to mmap() */
157239375Skib	int mtrr;		/**< MTRR slot used */
158239375Skib} drm_map32_t;
159239375Skib
160239375Skibstatic int compat_drm_getmap(struct drm_device *dev, void *data, struct drm_file *file_priv)
161239375Skib{
162239375Skib	drm_map32_t *m32 = data;
163239375Skib	struct drm_map map;
164239375Skib	int err;
165239375Skib	void *handle;
166239375Skib
167239375Skib	map.offset = (unsigned long)m32->offset;
168239375Skib
169239375Skib	err = drm_getmap(dev, (void *)&map, file_priv);
170239375Skib	if (err)
171239375Skib		return err;
172239375Skib
173239375Skib	m32->offset = map.offset;
174239375Skib	m32->size = map.size;
175239375Skib	m32->type = map.type;
176239375Skib	m32->flags = map.flags;
177239375Skib	handle = map.handle;
178239375Skib	m32->mtrr = map.mtrr;
179239375Skib
180239375Skib	m32->handle = (unsigned long)handle;
181239375Skib
182239375Skib	return 0;
183239375Skib
184239375Skib}
185239375Skib
186239375Skibstatic int compat_drm_addmap(struct drm_device *dev, void *data, struct drm_file *file_priv)
187239375Skib{
188239375Skib	drm_map32_t *m32 = data;
189239375Skib	struct drm_map map;
190239375Skib	int err;
191239375Skib	void *handle;
192239375Skib
193239375Skib	map.offset = (unsigned long)m32->offset;
194239375Skib	map.size = (unsigned long)m32->size;
195239375Skib	map.type = m32->type;
196239375Skib	map.flags = m32->flags;
197239375Skib
198239375Skib	err = drm_addmap_ioctl(dev, (void *)&map, file_priv);
199239375Skib	if (err)
200239375Skib		return err;
201239375Skib
202239375Skib	m32->offset = map.offset;
203239375Skib	m32->mtrr = map.mtrr;
204239375Skib	handle = map.handle;
205239375Skib
206239375Skib	m32->handle = (unsigned long)handle;
207239375Skib	if (m32->handle != (unsigned long)handle)
208239375Skib		DRM_DEBUG("compat_drm_addmap truncated handle"
209239375Skib				   " %p for type %d offset %x\n",
210239375Skib				   handle, m32->type, m32->offset);
211239375Skib
212239375Skib	return 0;
213239375Skib}
214239375Skib
215239375Skibstatic int compat_drm_rmmap(struct drm_device *dev, void *data, struct drm_file *file_priv)
216239375Skib{
217239375Skib	drm_map32_t *m32 = data;
218239375Skib	struct drm_map map;
219239375Skib
220239375Skib	map.handle = (void *)(unsigned long)m32->handle;
221239375Skib
222239375Skib	return drm_rmmap_ioctl(dev, (void *)&map, file_priv);
223239375Skib}
224239375Skib
225239375Skibtypedef struct drm_client32 {
226239375Skib	int idx;	/**< Which client desired? */
227239375Skib	int auth;	/**< Is client authenticated? */
228239375Skib	u32 pid;	/**< Process ID */
229239375Skib	u32 uid;	/**< User ID */
230239375Skib	u32 magic;	/**< Magic */
231239375Skib	u32 iocs;	/**< Ioctl count */
232239375Skib} drm_client32_t;
233239375Skib
234239375Skibstatic int compat_drm_getclient(struct drm_device *dev, void *data, 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
264239375Skibstatic int compat_drm_getstats(struct drm_device *dev, void *data, struct drm_file *file_priv)
265239375Skib{
266239375Skib	drm_stats32_t *s32 = data;
267239375Skib	struct drm_stats stats;
268239375Skib	int i, err;
269239375Skib
270239375Skib	err = drm_getstats(dev, (void *)&stats, file_priv);
271239375Skib	if (err)
272239375Skib		return err;
273239375Skib
274239375Skib	s32->count = stats.count;
275239375Skib	for (i = 0; i < stats.count; i++) {
276239375Skib		s32->data[i].value = stats.data[i].value;
277239375Skib		s32->data[i].type = stats.data[i].type;
278239375Skib	}
279239375Skib
280239375Skib	return 0;
281239375Skib}
282239375Skib
283239375Skibtypedef struct drm_buf_desc32 {
284239375Skib	int count;		 /**< Number of buffers of this size */
285239375Skib	int size;		 /**< Size in bytes */
286239375Skib	int low_mark;		 /**< Low water mark */
287239375Skib	int high_mark;		 /**< High water mark */
288239375Skib	int flags;
289239375Skib	u32 agp_start;		 /**< Start address in the AGP aperture */
290239375Skib} drm_buf_desc32_t;
291239375Skib
292239375Skibstatic int compat_drm_addbufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
293239375Skib{
294239375Skib	drm_buf_desc32_t *b32 = data;
295239375Skib	struct drm_buf_desc buf;
296239375Skib	int err;
297239375Skib
298239375Skib	buf.count = b32->count;
299239375Skib	buf.size = b32->size;
300239375Skib	buf.low_mark = b32->low_mark;
301239375Skib	buf.high_mark = b32->high_mark;
302239375Skib	buf.flags = b32->flags;
303239375Skib	buf.agp_start = (unsigned long)b32->agp_start;
304239375Skib
305239375Skib	err = drm_addbufs(dev, (void *)&buf, file_priv);
306239375Skib	if (err)
307239375Skib		return err;
308239375Skib
309239375Skib	b32->count = buf.count;
310239375Skib	b32->size = buf.size;
311239375Skib	b32->low_mark = buf.low_mark;
312239375Skib	b32->high_mark = buf.high_mark;
313239375Skib	b32->flags = buf.flags;
314239375Skib	b32->agp_start = buf.agp_start;
315239375Skib
316239375Skib	return 0;
317239375Skib}
318239375Skib
319239375Skibstatic int compat_drm_markbufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
320239375Skib{
321239375Skib	drm_buf_desc32_t *b32 = data;
322239375Skib	struct drm_buf_desc buf;
323239375Skib
324239375Skib	buf.size = b32->size;
325239375Skib	buf.low_mark = b32->low_mark;
326239375Skib	buf.high_mark = b32->high_mark;
327239375Skib
328239375Skib	return drm_markbufs(dev, (void *)&buf, file_priv);
329239375Skib}
330239375Skib
331239375Skibtypedef struct drm_buf_info32 {
332239375Skib	int count;		/**< Entries in list */
333239375Skib	u32 list;
334239375Skib} drm_buf_info32_t;
335239375Skib
336239375Skibstatic int compat_drm_infobufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
337239375Skib{
338239375Skib	drm_buf_info32_t *req32 = data;
339239375Skib	drm_buf_desc32_t *to;
340239375Skib	struct drm_buf_info *request;
341239375Skib	struct drm_buf_desc *list;
342239375Skib	size_t nbytes;
343239375Skib	int i, err;
344239375Skib	int count, actual;
345239375Skib
346239375Skib	count = req32->count;
347239375Skib	to = (drm_buf_desc32_t *)(unsigned long)req32->list;
348239375Skib	if (count < 0)
349239375Skib		count = 0;
350239375Skib
351239375Skib	nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc);
352239375Skib	request = malloc(nbytes, DRM_MEM_BUFLISTS, M_ZERO | M_NOWAIT);
353239375Skib	if (!request)
354239375Skib		return -EFAULT;
355239375Skib	list = (struct drm_buf_desc *) (request + 1);
356239375Skib
357239375Skib	request->count = count;
358239375Skib	request->list = list;
359239375Skib
360239375Skib	err = drm_infobufs(dev, (void *)request, file_priv);
361239375Skib	if (err)
362239375Skib		return err;
363239375Skib
364239375Skib	actual = request->count;
365239375Skib	if (count >= actual)
366239375Skib		for (i = 0; i < actual; ++i) {
367239375Skib			to[i].count = list[i].count;
368239375Skib			to[i].size = list[i].size;
369239375Skib			to[i].low_mark = list[i].low_mark;
370239375Skib			to[i].high_mark = list[i].high_mark;
371239375Skib			to[i].flags = list[i].flags;
372239375Skib		}
373239375Skib
374239375Skib	req32->count = actual;
375239375Skib
376239375Skib	return 0;
377239375Skib}
378239375Skib
379239375Skibtypedef struct drm_buf_pub32 {
380239375Skib	int idx;		/**< Index into the master buffer list */
381239375Skib	int total;		/**< Buffer size */
382239375Skib	int used;		/**< Amount of buffer in use (for DMA) */
383239375Skib	u32 address;		/**< Address of buffer */
384239375Skib} drm_buf_pub32_t;
385239375Skib
386239375Skibtypedef struct drm_buf_map32 {
387239375Skib	int count;		/**< Length of the buffer list */
388239375Skib	u32 virtual;		/**< Mmap'd area in user-virtual */
389239375Skib	u32 list;		/**< Buffer information */
390239375Skib} drm_buf_map32_t;
391239375Skib
392239375Skibstatic int compat_drm_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
393239375Skib{
394239375Skib	drm_buf_map32_t *req32 = data;
395239375Skib	drm_buf_pub32_t *list32;
396239375Skib	struct drm_buf_map *request;
397239375Skib	struct drm_buf_pub *list;
398239375Skib	int i, err;
399239375Skib	int count, actual;
400239375Skib	size_t nbytes;
401239375Skib
402239375Skib	count = req32->count;
403239375Skib	list32 = (void *)(unsigned long)req32->list;
404239375Skib
405239375Skib	if (count < 0)
406239375Skib		return -EINVAL;
407239375Skib	nbytes = sizeof(*request) + count * sizeof(struct drm_buf_pub);
408239375Skib	request = malloc(nbytes, DRM_MEM_BUFLISTS, M_ZERO | M_NOWAIT);
409239375Skib	if (!request)
410239375Skib		return -EFAULT;
411239375Skib	list = (struct drm_buf_pub *) (request + 1);
412239375Skib
413239375Skib	request->count = count;
414239375Skib	request->list = list;
415239375Skib
416239375Skib	err = drm_mapbufs(dev, (void *)request, file_priv);
417239375Skib	if (err)
418239375Skib		return err;
419239375Skib
420239375Skib	actual = request->count;
421239375Skib	if (count >= actual)
422239375Skib		for (i = 0; i < actual; ++i) {
423239375Skib			list32[i].idx = list[i].idx;
424239375Skib			list32[i].total = list[i].total;
425239375Skib			list32[i].used = list[i].used;
426239375Skib			list32[i].address = (unsigned long)list[i].address;
427239375Skib		}
428239375Skib
429239375Skib	req32->count = actual;
430239375Skib	req32->virtual = (unsigned long)request->virtual;
431239375Skib
432239375Skib	return 0;
433239375Skib}
434239375Skib
435239375Skibtypedef struct drm_buf_free32 {
436239375Skib	int count;
437239375Skib	u32 list;
438239375Skib} drm_buf_free32_t;
439239375Skib
440239375Skibstatic int compat_drm_freebufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
441239375Skib{
442239375Skib	drm_buf_free32_t *req32 = data;
443239375Skib	struct drm_buf_free request;
444239375Skib
445239375Skib	request.count = req32->count;
446239375Skib	request.list = (int *)(unsigned long)req32->list;
447239375Skib
448239375Skib	return drm_freebufs(dev, (void *)&request, file_priv);
449239375Skib}
450239375Skib
451239375Skibtypedef struct drm_ctx_priv_map32 {
452239375Skib	unsigned int ctx_id;	 /**< Context requesting private mapping */
453239375Skib	u32 handle;		/**< Handle of map */
454239375Skib} drm_ctx_priv_map32_t;
455239375Skib
456239375Skibstatic int compat_drm_setsareactx(struct drm_device *dev, void *data, struct drm_file *file_priv)
457239375Skib{
458239375Skib	drm_ctx_priv_map32_t *req32 = data;
459239375Skib	struct drm_ctx_priv_map request;
460239375Skib
461239375Skib	request.ctx_id = req32->ctx_id;
462239375Skib	request.handle = (void *)(unsigned long)req32->handle;
463239375Skib
464239375Skib	return drm_setsareactx(dev, (void *)&request, file_priv);
465239375Skib}
466239375Skib
467239375Skibstatic int compat_drm_getsareactx(struct drm_device *dev, void *data, struct drm_file *file_priv)
468239375Skib{
469239375Skib	drm_ctx_priv_map32_t *req32 = data;
470239375Skib	struct drm_ctx_priv_map request;
471239375Skib	int err;
472239375Skib
473239375Skib	request.ctx_id = req32->ctx_id;
474239375Skib
475239375Skib	err = drm_getsareactx(dev, (void *)&request, file_priv);
476239375Skib	if (err)
477239375Skib		return err;
478239375Skib
479239375Skib	req32->handle = (unsigned long)request.handle;
480239375Skib
481239375Skib	return 0;
482239375Skib}
483239375Skib
484239375Skibtypedef struct drm_ctx_res32 {
485239375Skib	int count;
486239375Skib	u32 contexts;
487239375Skib} drm_ctx_res32_t;
488239375Skib
489239375Skibstatic int compat_drm_resctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
490239375Skib{
491239375Skib	drm_ctx_res32_t *res32 = data;
492239375Skib	struct drm_ctx_res res;
493239375Skib	int err;
494239375Skib
495239375Skib	res.count = res32->count;
496239375Skib	res.contexts = (struct drm_ctx __user *)(unsigned long)res32->contexts;
497239375Skib
498239375Skib	err = drm_resctx(dev, (void *)&res, file_priv);
499239375Skib	if (err)
500239375Skib		return err;
501239375Skib
502239375Skib	res32->count = res.count;
503239375Skib
504239375Skib	return 0;
505239375Skib}
506239375Skib
507239375Skibtypedef struct drm_dma32 {
508239375Skib	int context;		  /**< Context handle */
509239375Skib	int send_count;		  /**< Number of buffers to send */
510239375Skib	u32 send_indices;	  /**< List of handles to buffers */
511239375Skib	u32 send_sizes;		  /**< Lengths of data to send */
512239375Skib	enum drm_dma_flags flags;		  /**< Flags */
513239375Skib	int request_count;	  /**< Number of buffers requested */
514239375Skib	int request_size;	  /**< Desired size for buffers */
515239375Skib	u32 request_indices;	  /**< Buffer information */
516239375Skib	u32 request_sizes;
517239375Skib	int granted_count;	  /**< Number of buffers granted */
518239375Skib} drm_dma32_t;
519239375Skib
520239375Skibstatic int compat_drm_dma(struct drm_device *dev, void *data, struct drm_file *file_priv)
521239375Skib{
522239375Skib	drm_dma32_t *d32 = data;
523239375Skib	struct drm_dma d;
524239375Skib	int err;
525239375Skib
526239375Skib	d.context = d32->context;
527239375Skib	d.send_count = d32->send_count;
528239375Skib	d.send_indices = (int *)(unsigned long)d32->send_indices;
529239375Skib	d.send_sizes = (int *)(unsigned long)d32->send_sizes;
530239375Skib	d.flags = d32->flags;
531239375Skib	d.request_count = d32->request_count;
532239375Skib	d.request_indices = (int *)(unsigned long)d32->request_indices;
533239375Skib	d.request_sizes = (int *)(unsigned long)d32->request_sizes;
534239375Skib
535239375Skib	err = drm_dma(dev, (void *)&d, file_priv);
536239375Skib	if (err)
537239375Skib		return err;
538239375Skib
539239375Skib	d32->request_size = d.request_size;
540239375Skib	d32->granted_count = d.granted_count;
541239375Skib
542239375Skib	return 0;
543239375Skib}
544239375Skib
545239375Skibtypedef struct drm_agp_mode32 {
546239375Skib	u32 mode;	/**< AGP mode */
547239375Skib} drm_agp_mode32_t;
548239375Skib
549239375Skibstatic int compat_drm_agp_enable(struct drm_device *dev, void *data, struct drm_file *file_priv)
550239375Skib{
551239375Skib	drm_agp_mode32_t *m32 = data;
552239375Skib	struct drm_agp_mode mode;
553239375Skib
554239375Skib	mode.mode = m32->mode;
555239375Skib
556239375Skib	return drm_agp_enable_ioctl(dev, (void *)&mode, file_priv);
557239375Skib}
558239375Skib
559239375Skibtypedef struct drm_agp_info32 {
560239375Skib	int agp_version_major;
561239375Skib	int agp_version_minor;
562239375Skib	u32 mode;
563239375Skib	u32 aperture_base;	/* physical address */
564239375Skib	u32 aperture_size;	/* bytes */
565239375Skib	u32 memory_allowed;	/* bytes */
566239375Skib	u32 memory_used;
567239375Skib
568239375Skib	/* PCI information */
569239375Skib	unsigned short id_vendor;
570239375Skib	unsigned short id_device;
571239375Skib} drm_agp_info32_t;
572239375Skib
573239375Skibstatic int compat_drm_agp_info(struct drm_device *dev, void *data, struct drm_file *file_priv)
574239375Skib{
575239375Skib	drm_agp_info32_t *i32 = data;
576239375Skib	struct drm_agp_info info;
577239375Skib	int err;
578239375Skib
579239375Skib	err = drm_agp_info_ioctl(dev, (void *)&info, file_priv);
580239375Skib	if (err)
581239375Skib		return err;
582239375Skib
583239375Skib	i32->agp_version_major = info.agp_version_major;
584239375Skib	i32->agp_version_minor = info.agp_version_minor;
585239375Skib	i32->mode = info.mode;
586239375Skib	i32->aperture_base = info.aperture_base;
587239375Skib	i32->aperture_size = info.aperture_size;
588239375Skib	i32->memory_allowed = info.memory_allowed;
589239375Skib	i32->memory_used = info.memory_used;
590239375Skib	i32->id_vendor = info.id_vendor;
591239375Skib	i32->id_device = info.id_device;
592239375Skib
593239375Skib	return 0;
594239375Skib}
595239375Skib
596239375Skibtypedef struct drm_agp_buffer32 {
597239375Skib	u32 size;	/**< In bytes -- will round to page boundary */
598239375Skib	u32 handle;	/**< Used for binding / unbinding */
599239375Skib	u32 type;	/**< Type of memory to allocate */
600239375Skib	u32 physical;	/**< Physical used by i810 */
601239375Skib} drm_agp_buffer32_t;
602239375Skib
603239375Skibstatic int compat_drm_agp_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
604239375Skib{
605239375Skib	drm_agp_buffer32_t *req32 = data;
606239375Skib	struct drm_agp_buffer request;
607239375Skib	int err;
608239375Skib
609239375Skib	request.size = req32->size;
610239375Skib	request.type = req32->type;
611239375Skib
612239375Skib	err = drm_agp_alloc_ioctl(dev, (void *)&request, file_priv);
613239375Skib	if (err)
614239375Skib		return err;
615239375Skib
616239375Skib	req32->handle = request.handle;
617239375Skib	req32->physical = request.physical;
618239375Skib
619239375Skib	return 0;
620239375Skib}
621239375Skib
622239375Skibstatic int compat_drm_agp_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
623239375Skib{
624239375Skib	drm_agp_buffer32_t *req32 = data;
625239375Skib	struct drm_agp_buffer request;
626239375Skib
627239375Skib	request.handle = req32->handle;
628239375Skib
629239375Skib	return drm_agp_free_ioctl(dev, (void *)&request, file_priv);
630239375Skib}
631239375Skib
632239375Skibtypedef struct drm_agp_binding32 {
633239375Skib	u32 handle;	/**< From drm_agp_buffer */
634239375Skib	u32 offset;	/**< In bytes -- will round to page boundary */
635239375Skib} drm_agp_binding32_t;
636239375Skib
637239375Skibstatic int compat_drm_agp_bind(struct drm_device *dev, void *data, struct drm_file *file_priv)
638239375Skib{
639239375Skib	drm_agp_binding32_t *req32 = data;
640239375Skib	struct drm_agp_binding request;
641239375Skib
642239375Skib	request.handle = req32->handle;
643239375Skib	request.offset = req32->offset;
644239375Skib
645239375Skib	return drm_agp_bind_ioctl(dev, (void *)&request, file_priv);
646239375Skib}
647239375Skib
648239375Skibstatic int compat_drm_agp_unbind(struct drm_device *dev, void *data, struct drm_file *file_priv)
649239375Skib{
650239375Skib	drm_agp_binding32_t *req32 = data;
651239375Skib	struct drm_agp_binding request;
652239375Skib
653239375Skib	request.handle = req32->handle;
654239375Skib
655239375Skib	return drm_agp_unbind_ioctl(dev, (void *)&request, file_priv);
656239375Skib}
657239375Skib
658239375Skibtypedef struct drm_scatter_gather32 {
659239375Skib	u32 size;	/**< In bytes -- will round to page boundary */
660239375Skib	u32 handle;	/**< Used for mapping / unmapping */
661239375Skib} drm_scatter_gather32_t;
662239375Skib
663239375Skibstatic int compat_drm_sg_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
664239375Skib{
665239375Skib	drm_scatter_gather32_t *req32 = data;
666239375Skib	struct drm_scatter_gather request;
667239375Skib	int err;
668239375Skib
669239375Skib	request.size = (unsigned long)req32->size;
670239375Skib
671239375Skib	err = drm_sg_alloc_ioctl(dev, (void *)&request, file_priv);
672239375Skib	if (err)
673239375Skib		return err;
674239375Skib
675239375Skib	/* XXX not sure about the handle conversion here... */
676239375Skib	req32->handle = (unsigned long)request.handle >> PAGE_SHIFT;
677239375Skib
678239375Skib	return 0;
679239375Skib}
680239375Skib
681239375Skibstatic int compat_drm_sg_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
682239375Skib{
683239375Skib	drm_scatter_gather32_t *req32 = data;
684239375Skib	struct drm_scatter_gather request;
685239375Skib
686239375Skib	request.handle = (unsigned long)req32->handle << PAGE_SHIFT;
687239375Skib
688239375Skib	return drm_sg_free(dev, (void *)&request, file_priv);
689239375Skib}
690239375Skib
691239375Skibtypedef struct drm_update_draw32 {
692239375Skib	drm_drawable_t handle;
693239375Skib	unsigned int type;
694239375Skib	unsigned int num;
695239375Skib	/* 64-bit version has a 32-bit pad here */
696239375Skib	u64 data;	/**< Pointer */
697239375Skib} __attribute__((packed)) drm_update_draw32_t;
698239375Skib
699239375Skibstatic int compat_drm_update_draw(struct drm_device *dev, void *data, struct drm_file *file_priv)
700239375Skib{
701239375Skib	drm_update_draw32_t *update32 = data;
702239375Skib	struct drm_update_draw request;
703239375Skib	int err;
704239375Skib
705239375Skib	request.handle = update32->handle;
706239375Skib	request.type = update32->type;
707239375Skib	request.num = update32->num;
708239375Skib	request.data = update32->data;
709239375Skib
710239375Skib	err = drm_update_draw(dev, (void *)&request, file_priv);
711239375Skib	return err;
712239375Skib}
713239375Skib
714239375Skibstruct drm_wait_vblank_request32 {
715239375Skib	enum drm_vblank_seq_type type;
716239375Skib	unsigned int sequence;
717239375Skib	u32 signal;
718239375Skib};
719239375Skib
720239375Skibstruct drm_wait_vblank_reply32 {
721239375Skib	enum drm_vblank_seq_type type;
722239375Skib	unsigned int sequence;
723239375Skib	s32 tval_sec;
724239375Skib	s32 tval_usec;
725239375Skib};
726239375Skib
727239375Skibtypedef union drm_wait_vblank32 {
728239375Skib	struct drm_wait_vblank_request32 request;
729239375Skib	struct drm_wait_vblank_reply32 reply;
730239375Skib} drm_wait_vblank32_t;
731239375Skib
732239375Skibstatic int compat_drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
733239375Skib{
734239375Skib	drm_wait_vblank32_t *req32 = data;
735239375Skib	union drm_wait_vblank request;
736239375Skib	int err;
737239375Skib
738239375Skib	request.request.type = req32->request.type;
739239375Skib	request.request.sequence = req32->request.sequence;
740239375Skib	request.request.signal = req32->request.signal;
741239375Skib
742239375Skib	err = drm_wait_vblank(dev, (void *)&request, file_priv);
743239375Skib	if (err)
744239375Skib		return err;
745239375Skib
746239375Skib	req32->reply.type = request.reply.type;
747239375Skib	req32->reply.sequence = request.reply.sequence;
748239375Skib	req32->reply.tval_sec = request.reply.tval_sec;
749239375Skib	req32->reply.tval_usec = request.reply.tval_usec;
750239375Skib
751239375Skib	return 0;
752239375Skib}
753239375Skib
754239375Skibdrm_ioctl_desc_t drm_compat_ioctls[256] = {
755239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_VERSION32, compat_drm_version, 0),
756239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE32, compat_drm_getunique, 0),
757239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP32, compat_drm_getmap, 0),
758239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT32, compat_drm_getclient, 0),
759239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS32, compat_drm_getstats, 0),
760239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE32, compat_drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
761239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP32, compat_drm_addmap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
762239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS32, compat_drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
763239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS32, compat_drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
764239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS32, compat_drm_infobufs, DRM_AUTH),
765239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS32, compat_drm_mapbufs, DRM_AUTH),
766239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS32, compat_drm_freebufs, DRM_AUTH),
767239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP32, compat_drm_rmmap, DRM_AUTH),
768239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX32, compat_drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
769239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX32, compat_drm_getsareactx, DRM_AUTH),
770239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX32, compat_drm_resctx, DRM_AUTH),
771239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_DMA32, compat_drm_dma, DRM_AUTH),
772239375Skib
773239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE32, compat_drm_agp_enable, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
774239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO32, compat_drm_agp_info, DRM_AUTH),
775239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC32, compat_drm_agp_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
776239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE32, compat_drm_agp_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
777239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND32, compat_drm_agp_bind, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
778239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND32, compat_drm_agp_unbind, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
779239375Skib
780239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC32, compat_drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
781239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE32, compat_drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
782239375Skib
783239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW32, compat_drm_update_draw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
784239375Skib
785239375Skib	DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK32, compat_drm_wait_vblank, DRM_UNLOCKED),
786239375Skib};
787239375Skib
788239375Skib#endif
789