1254885Sdumbbell/**
2254885Sdumbbell * \file radeon_ioc32.c
3254885Sdumbbell *
4254885Sdumbbell * 32-bit ioctl compatibility routines for the Radeon DRM.
5254885Sdumbbell *
6254885Sdumbbell * \author Paul Mackerras <paulus@samba.org>
7254885Sdumbbell *
8254885Sdumbbell * Copyright (C) Paul Mackerras 2005
9254885Sdumbbell * All Rights Reserved.
10254885Sdumbbell *
11254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a
12254885Sdumbbell * copy of this software and associated documentation files (the "Software"),
13254885Sdumbbell * to deal in the Software without restriction, including without limitation
14254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the
16254885Sdumbbell * Software is furnished to do so, subject to the following conditions:
17254885Sdumbbell *
18254885Sdumbbell * The above copyright notice and this permission notice (including the next
19254885Sdumbbell * paragraph) shall be included in all copies or substantial portions of the
20254885Sdumbbell * Software.
21254885Sdumbbell *
22254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25254885Sdumbbell * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26254885Sdumbbell * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27254885Sdumbbell * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28254885Sdumbbell * IN THE SOFTWARE.
29254885Sdumbbell */
30254885Sdumbbell
31254885Sdumbbell#include <sys/cdefs.h>
32254885Sdumbbell__FBSDID("$FreeBSD$");
33254885Sdumbbell
34254885Sdumbbell#include <linux/compat.h>
35254885Sdumbbell
36254885Sdumbbell#include <drm/drmP.h>
37254885Sdumbbell#include <drm/radeon_drm.h>
38254885Sdumbbell#include "radeon_drv.h"
39254885Sdumbbell
40254885Sdumbbelltypedef struct drm_radeon_init32 {
41254885Sdumbbell	int func;
42254885Sdumbbell	u32 sarea_priv_offset;
43254885Sdumbbell	int is_pci;
44254885Sdumbbell	int cp_mode;
45254885Sdumbbell	int gart_size;
46254885Sdumbbell	int ring_size;
47254885Sdumbbell	int usec_timeout;
48254885Sdumbbell
49254885Sdumbbell	unsigned int fb_bpp;
50254885Sdumbbell	unsigned int front_offset, front_pitch;
51254885Sdumbbell	unsigned int back_offset, back_pitch;
52254885Sdumbbell	unsigned int depth_bpp;
53254885Sdumbbell	unsigned int depth_offset, depth_pitch;
54254885Sdumbbell
55254885Sdumbbell	u32 fb_offset;
56254885Sdumbbell	u32 mmio_offset;
57254885Sdumbbell	u32 ring_offset;
58254885Sdumbbell	u32 ring_rptr_offset;
59254885Sdumbbell	u32 buffers_offset;
60254885Sdumbbell	u32 gart_textures_offset;
61254885Sdumbbell} drm_radeon_init32_t;
62254885Sdumbbell
63254885Sdumbbellstatic int compat_radeon_cp_init(struct file *file, unsigned int cmd,
64254885Sdumbbell				 unsigned long arg)
65254885Sdumbbell{
66254885Sdumbbell	drm_radeon_init32_t init32;
67254885Sdumbbell	drm_radeon_init_t __user *init;
68254885Sdumbbell
69254885Sdumbbell	if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
70254885Sdumbbell		return -EFAULT;
71254885Sdumbbell
72254885Sdumbbell	init = compat_alloc_user_space(sizeof(*init));
73254885Sdumbbell	if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
74254885Sdumbbell	    || __put_user(init32.func, &init->func)
75254885Sdumbbell	    || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
76254885Sdumbbell	    || __put_user(init32.is_pci, &init->is_pci)
77254885Sdumbbell	    || __put_user(init32.cp_mode, &init->cp_mode)
78254885Sdumbbell	    || __put_user(init32.gart_size, &init->gart_size)
79254885Sdumbbell	    || __put_user(init32.ring_size, &init->ring_size)
80254885Sdumbbell	    || __put_user(init32.usec_timeout, &init->usec_timeout)
81254885Sdumbbell	    || __put_user(init32.fb_bpp, &init->fb_bpp)
82254885Sdumbbell	    || __put_user(init32.front_offset, &init->front_offset)
83254885Sdumbbell	    || __put_user(init32.front_pitch, &init->front_pitch)
84254885Sdumbbell	    || __put_user(init32.back_offset, &init->back_offset)
85254885Sdumbbell	    || __put_user(init32.back_pitch, &init->back_pitch)
86254885Sdumbbell	    || __put_user(init32.depth_bpp, &init->depth_bpp)
87254885Sdumbbell	    || __put_user(init32.depth_offset, &init->depth_offset)
88254885Sdumbbell	    || __put_user(init32.depth_pitch, &init->depth_pitch)
89254885Sdumbbell	    || __put_user(init32.fb_offset, &init->fb_offset)
90254885Sdumbbell	    || __put_user(init32.mmio_offset, &init->mmio_offset)
91254885Sdumbbell	    || __put_user(init32.ring_offset, &init->ring_offset)
92254885Sdumbbell	    || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
93254885Sdumbbell	    || __put_user(init32.buffers_offset, &init->buffers_offset)
94254885Sdumbbell	    || __put_user(init32.gart_textures_offset,
95254885Sdumbbell			  &init->gart_textures_offset))
96254885Sdumbbell		return -EFAULT;
97254885Sdumbbell
98254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
99254885Sdumbbell}
100254885Sdumbbell
101254885Sdumbbelltypedef struct drm_radeon_clear32 {
102254885Sdumbbell	unsigned int flags;
103254885Sdumbbell	unsigned int clear_color;
104254885Sdumbbell	unsigned int clear_depth;
105254885Sdumbbell	unsigned int color_mask;
106254885Sdumbbell	unsigned int depth_mask;	/* misnamed field:  should be stencil */
107254885Sdumbbell	u32 depth_boxes;
108254885Sdumbbell} drm_radeon_clear32_t;
109254885Sdumbbell
110254885Sdumbbellstatic int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
111254885Sdumbbell				  unsigned long arg)
112254885Sdumbbell{
113254885Sdumbbell	drm_radeon_clear32_t clr32;
114254885Sdumbbell	drm_radeon_clear_t __user *clr;
115254885Sdumbbell
116254885Sdumbbell	if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32)))
117254885Sdumbbell		return -EFAULT;
118254885Sdumbbell
119254885Sdumbbell	clr = compat_alloc_user_space(sizeof(*clr));
120254885Sdumbbell	if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr))
121254885Sdumbbell	    || __put_user(clr32.flags, &clr->flags)
122254885Sdumbbell	    || __put_user(clr32.clear_color, &clr->clear_color)
123254885Sdumbbell	    || __put_user(clr32.clear_depth, &clr->clear_depth)
124254885Sdumbbell	    || __put_user(clr32.color_mask, &clr->color_mask)
125254885Sdumbbell	    || __put_user(clr32.depth_mask, &clr->depth_mask)
126254885Sdumbbell	    || __put_user((void __user *)(unsigned long)clr32.depth_boxes,
127254885Sdumbbell			  &clr->depth_boxes))
128254885Sdumbbell		return -EFAULT;
129254885Sdumbbell
130254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
131254885Sdumbbell}
132254885Sdumbbell
133254885Sdumbbelltypedef struct drm_radeon_stipple32 {
134254885Sdumbbell	u32 mask;
135254885Sdumbbell} drm_radeon_stipple32_t;
136254885Sdumbbell
137254885Sdumbbellstatic int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
138254885Sdumbbell				    unsigned long arg)
139254885Sdumbbell{
140254885Sdumbbell	drm_radeon_stipple32_t __user *argp = (void __user *)arg;
141254885Sdumbbell	drm_radeon_stipple_t __user *request;
142254885Sdumbbell	u32 mask;
143254885Sdumbbell
144254885Sdumbbell	if (get_user(mask, &argp->mask))
145254885Sdumbbell		return -EFAULT;
146254885Sdumbbell
147254885Sdumbbell	request = compat_alloc_user_space(sizeof(*request));
148254885Sdumbbell	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
149254885Sdumbbell	    || __put_user((unsigned int __user *)(unsigned long)mask,
150254885Sdumbbell			  &request->mask))
151254885Sdumbbell		return -EFAULT;
152254885Sdumbbell
153254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
154254885Sdumbbell}
155254885Sdumbbell
156254885Sdumbbelltypedef struct drm_radeon_tex_image32 {
157254885Sdumbbell	unsigned int x, y;	/* Blit coordinates */
158254885Sdumbbell	unsigned int width, height;
159254885Sdumbbell	u32 data;
160254885Sdumbbell} drm_radeon_tex_image32_t;
161254885Sdumbbell
162254885Sdumbbelltypedef struct drm_radeon_texture32 {
163254885Sdumbbell	unsigned int offset;
164254885Sdumbbell	int pitch;
165254885Sdumbbell	int format;
166254885Sdumbbell	int width;		/* Texture image coordinates */
167254885Sdumbbell	int height;
168254885Sdumbbell	u32 image;
169254885Sdumbbell} drm_radeon_texture32_t;
170254885Sdumbbell
171254885Sdumbbellstatic int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
172254885Sdumbbell				    unsigned long arg)
173254885Sdumbbell{
174254885Sdumbbell	drm_radeon_texture32_t req32;
175254885Sdumbbell	drm_radeon_texture_t __user *request;
176254885Sdumbbell	drm_radeon_tex_image32_t img32;
177254885Sdumbbell	drm_radeon_tex_image_t __user *image;
178254885Sdumbbell
179254885Sdumbbell	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
180254885Sdumbbell		return -EFAULT;
181254885Sdumbbell	if (req32.image == 0)
182254885Sdumbbell		return -EINVAL;
183254885Sdumbbell	if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image,
184254885Sdumbbell			   sizeof(img32)))
185254885Sdumbbell		return -EFAULT;
186254885Sdumbbell
187254885Sdumbbell	request = compat_alloc_user_space(sizeof(*request) + sizeof(*image));
188254885Sdumbbell	if (!access_ok(VERIFY_WRITE, request,
189254885Sdumbbell		       sizeof(*request) + sizeof(*image)))
190254885Sdumbbell		return -EFAULT;
191254885Sdumbbell	image = (drm_radeon_tex_image_t __user *) (request + 1);
192254885Sdumbbell
193254885Sdumbbell	if (__put_user(req32.offset, &request->offset)
194254885Sdumbbell	    || __put_user(req32.pitch, &request->pitch)
195254885Sdumbbell	    || __put_user(req32.format, &request->format)
196254885Sdumbbell	    || __put_user(req32.width, &request->width)
197254885Sdumbbell	    || __put_user(req32.height, &request->height)
198254885Sdumbbell	    || __put_user(image, &request->image)
199254885Sdumbbell	    || __put_user(img32.x, &image->x)
200254885Sdumbbell	    || __put_user(img32.y, &image->y)
201254885Sdumbbell	    || __put_user(img32.width, &image->width)
202254885Sdumbbell	    || __put_user(img32.height, &image->height)
203254885Sdumbbell	    || __put_user((const void __user *)(unsigned long)img32.data,
204254885Sdumbbell			  &image->data))
205254885Sdumbbell		return -EFAULT;
206254885Sdumbbell
207254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
208254885Sdumbbell}
209254885Sdumbbell
210254885Sdumbbelltypedef struct drm_radeon_vertex2_32 {
211254885Sdumbbell	int idx;		/* Index of vertex buffer */
212254885Sdumbbell	int discard;		/* Client finished with buffer? */
213254885Sdumbbell	int nr_states;
214254885Sdumbbell	u32 state;
215254885Sdumbbell	int nr_prims;
216254885Sdumbbell	u32 prim;
217254885Sdumbbell} drm_radeon_vertex2_32_t;
218254885Sdumbbell
219254885Sdumbbellstatic int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
220254885Sdumbbell				    unsigned long arg)
221254885Sdumbbell{
222254885Sdumbbell	drm_radeon_vertex2_32_t req32;
223254885Sdumbbell	drm_radeon_vertex2_t __user *request;
224254885Sdumbbell
225254885Sdumbbell	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
226254885Sdumbbell		return -EFAULT;
227254885Sdumbbell
228254885Sdumbbell	request = compat_alloc_user_space(sizeof(*request));
229254885Sdumbbell	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
230254885Sdumbbell	    || __put_user(req32.idx, &request->idx)
231254885Sdumbbell	    || __put_user(req32.discard, &request->discard)
232254885Sdumbbell	    || __put_user(req32.nr_states, &request->nr_states)
233254885Sdumbbell	    || __put_user((void __user *)(unsigned long)req32.state,
234254885Sdumbbell			  &request->state)
235254885Sdumbbell	    || __put_user(req32.nr_prims, &request->nr_prims)
236254885Sdumbbell	    || __put_user((void __user *)(unsigned long)req32.prim,
237254885Sdumbbell			  &request->prim))
238254885Sdumbbell		return -EFAULT;
239254885Sdumbbell
240254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
241254885Sdumbbell}
242254885Sdumbbell
243254885Sdumbbelltypedef struct drm_radeon_cmd_buffer32 {
244254885Sdumbbell	int bufsz;
245254885Sdumbbell	u32 buf;
246254885Sdumbbell	int nbox;
247254885Sdumbbell	u32 boxes;
248254885Sdumbbell} drm_radeon_cmd_buffer32_t;
249254885Sdumbbell
250254885Sdumbbellstatic int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
251254885Sdumbbell				   unsigned long arg)
252254885Sdumbbell{
253254885Sdumbbell	drm_radeon_cmd_buffer32_t req32;
254254885Sdumbbell	drm_radeon_cmd_buffer_t __user *request;
255254885Sdumbbell
256254885Sdumbbell	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
257254885Sdumbbell		return -EFAULT;
258254885Sdumbbell
259254885Sdumbbell	request = compat_alloc_user_space(sizeof(*request));
260254885Sdumbbell	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
261254885Sdumbbell	    || __put_user(req32.bufsz, &request->bufsz)
262254885Sdumbbell	    || __put_user((void __user *)(unsigned long)req32.buf,
263254885Sdumbbell			  &request->buf)
264254885Sdumbbell	    || __put_user(req32.nbox, &request->nbox)
265254885Sdumbbell	    || __put_user((void __user *)(unsigned long)req32.boxes,
266254885Sdumbbell			  &request->boxes))
267254885Sdumbbell		return -EFAULT;
268254885Sdumbbell
269254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
270254885Sdumbbell}
271254885Sdumbbell
272254885Sdumbbelltypedef struct drm_radeon_getparam32 {
273254885Sdumbbell	int param;
274254885Sdumbbell	u32 value;
275254885Sdumbbell} drm_radeon_getparam32_t;
276254885Sdumbbell
277254885Sdumbbellstatic int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
278254885Sdumbbell				     unsigned long arg)
279254885Sdumbbell{
280254885Sdumbbell	drm_radeon_getparam32_t req32;
281254885Sdumbbell	drm_radeon_getparam_t __user *request;
282254885Sdumbbell
283254885Sdumbbell	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
284254885Sdumbbell		return -EFAULT;
285254885Sdumbbell
286254885Sdumbbell	request = compat_alloc_user_space(sizeof(*request));
287254885Sdumbbell	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
288254885Sdumbbell	    || __put_user(req32.param, &request->param)
289254885Sdumbbell	    || __put_user((void __user *)(unsigned long)req32.value,
290254885Sdumbbell			  &request->value))
291254885Sdumbbell		return -EFAULT;
292254885Sdumbbell
293254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
294254885Sdumbbell}
295254885Sdumbbell
296254885Sdumbbelltypedef struct drm_radeon_mem_alloc32 {
297254885Sdumbbell	int region;
298254885Sdumbbell	int alignment;
299254885Sdumbbell	int size;
300254885Sdumbbell	u32 region_offset;	/* offset from start of fb or GART */
301254885Sdumbbell} drm_radeon_mem_alloc32_t;
302254885Sdumbbell
303254885Sdumbbellstatic int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
304254885Sdumbbell				   unsigned long arg)
305254885Sdumbbell{
306254885Sdumbbell	drm_radeon_mem_alloc32_t req32;
307254885Sdumbbell	drm_radeon_mem_alloc_t __user *request;
308254885Sdumbbell
309254885Sdumbbell	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
310254885Sdumbbell		return -EFAULT;
311254885Sdumbbell
312254885Sdumbbell	request = compat_alloc_user_space(sizeof(*request));
313254885Sdumbbell	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
314254885Sdumbbell	    || __put_user(req32.region, &request->region)
315254885Sdumbbell	    || __put_user(req32.alignment, &request->alignment)
316254885Sdumbbell	    || __put_user(req32.size, &request->size)
317254885Sdumbbell	    || __put_user((int __user *)(unsigned long)req32.region_offset,
318254885Sdumbbell			  &request->region_offset))
319254885Sdumbbell		return -EFAULT;
320254885Sdumbbell
321254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
322254885Sdumbbell}
323254885Sdumbbell
324254885Sdumbbelltypedef struct drm_radeon_irq_emit32 {
325254885Sdumbbell	u32 irq_seq;
326254885Sdumbbell} drm_radeon_irq_emit32_t;
327254885Sdumbbell
328254885Sdumbbellstatic int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
329254885Sdumbbell				  unsigned long arg)
330254885Sdumbbell{
331254885Sdumbbell	drm_radeon_irq_emit32_t req32;
332254885Sdumbbell	drm_radeon_irq_emit_t __user *request;
333254885Sdumbbell
334254885Sdumbbell	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
335254885Sdumbbell		return -EFAULT;
336254885Sdumbbell
337254885Sdumbbell	request = compat_alloc_user_space(sizeof(*request));
338254885Sdumbbell	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
339254885Sdumbbell	    || __put_user((int __user *)(unsigned long)req32.irq_seq,
340254885Sdumbbell			  &request->irq_seq))
341254885Sdumbbell		return -EFAULT;
342254885Sdumbbell
343254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
344254885Sdumbbell}
345254885Sdumbbell
346254885Sdumbbell/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
347254885Sdumbbell#if defined (CONFIG_X86_64) || defined(CONFIG_IA64)
348254885Sdumbbelltypedef struct drm_radeon_setparam32 {
349254885Sdumbbell	int param;
350254885Sdumbbell	u64 value;
351254885Sdumbbell} __attribute__((packed)) drm_radeon_setparam32_t;
352254885Sdumbbell
353254885Sdumbbellstatic int compat_radeon_cp_setparam(struct file *file, unsigned int cmd,
354254885Sdumbbell				     unsigned long arg)
355254885Sdumbbell{
356254885Sdumbbell	drm_radeon_setparam32_t req32;
357254885Sdumbbell	drm_radeon_setparam_t __user *request;
358254885Sdumbbell
359254885Sdumbbell	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
360254885Sdumbbell		return -EFAULT;
361254885Sdumbbell
362254885Sdumbbell	request = compat_alloc_user_space(sizeof(*request));
363254885Sdumbbell	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
364254885Sdumbbell	    || __put_user(req32.param, &request->param)
365254885Sdumbbell	    || __put_user((void __user *)(unsigned long)req32.value,
366254885Sdumbbell			  &request->value))
367254885Sdumbbell		return -EFAULT;
368254885Sdumbbell
369254885Sdumbbell	return drm_ioctl(file, DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
370254885Sdumbbell}
371254885Sdumbbell#else
372254885Sdumbbell#define compat_radeon_cp_setparam NULL
373254885Sdumbbell#endif /* X86_64 || IA64 */
374254885Sdumbbell
375254885Sdumbbellstatic drm_ioctl_compat_t *radeon_compat_ioctls[] = {
376254885Sdumbbell	[DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
377254885Sdumbbell	[DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
378254885Sdumbbell	[DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
379254885Sdumbbell	[DRM_RADEON_TEXTURE] = compat_radeon_cp_texture,
380254885Sdumbbell	[DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2,
381254885Sdumbbell	[DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf,
382254885Sdumbbell	[DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam,
383254885Sdumbbell	[DRM_RADEON_SETPARAM] = compat_radeon_cp_setparam,
384254885Sdumbbell	[DRM_RADEON_ALLOC] = compat_radeon_mem_alloc,
385254885Sdumbbell	[DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit,
386254885Sdumbbell};
387254885Sdumbbell
388254885Sdumbbell/**
389254885Sdumbbell * Called whenever a 32-bit process running under a 64-bit kernel
390254885Sdumbbell * performs an ioctl on /dev/dri/card<n>.
391254885Sdumbbell *
392254885Sdumbbell * \param filp file pointer.
393254885Sdumbbell * \param cmd command.
394254885Sdumbbell * \param arg user argument.
395254885Sdumbbell * \return zero on success or negative number on failure.
396254885Sdumbbell */
397254885Sdumbbelllong radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
398254885Sdumbbell{
399254885Sdumbbell	unsigned int nr = DRM_IOCTL_NR(cmd);
400254885Sdumbbell	drm_ioctl_compat_t *fn = NULL;
401254885Sdumbbell	int ret;
402254885Sdumbbell
403254885Sdumbbell	if (nr < DRM_COMMAND_BASE)
404254885Sdumbbell		return drm_compat_ioctl(filp, cmd, arg);
405254885Sdumbbell
406254885Sdumbbell	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
407254885Sdumbbell		fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
408254885Sdumbbell
409254885Sdumbbell	if (fn != NULL)
410254885Sdumbbell		ret = (*fn) (filp, cmd, arg);
411254885Sdumbbell	else
412254885Sdumbbell		ret = drm_ioctl(filp, cmd, arg);
413254885Sdumbbell
414254885Sdumbbell	return ret;
415254885Sdumbbell}
416254885Sdumbbell
417254885Sdumbbelllong radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
418254885Sdumbbell{
419254885Sdumbbell	unsigned int nr = DRM_IOCTL_NR(cmd);
420254885Sdumbbell	int ret;
421254885Sdumbbell
422254885Sdumbbell	if (nr < DRM_COMMAND_BASE)
423254885Sdumbbell		return drm_compat_ioctl(filp, cmd, arg);
424254885Sdumbbell
425254885Sdumbbell	ret = drm_ioctl(filp, cmd, arg);
426254885Sdumbbell
427254885Sdumbbell	return ret;
428254885Sdumbbell}
429