aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_ioc32.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-05-28 20:09:59 -0400
committerDave Airlie <airlied@redhat.com>2008-07-13 20:45:01 -0400
commitc0e09200dc0813972442e550a5905a132768e56c (patch)
treed38e635a30ff8b0a2b98b9d7f97cab1501f8209e /drivers/gpu/drm/radeon/radeon_ioc32.c
parentbce7f793daec3e65ec5c5705d2457b81fe7b5725 (diff)
drm: reorganise drm tree to be more future proof.
With the coming of kernel based modesetting and the memory manager stuff, the everything in one directory approach was getting very ugly and starting to be unmanageable. This restructures the drm along the lines of other kernel components. It creates a drivers/gpu/drm directory and moves the hw drivers into subdirectores. It moves the includes into an include/drm, and sets up the unifdef for the userspace headers we should be exporting. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_ioc32.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_ioc32.c424
1 files changed, 424 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c
new file mode 100644
index 000000000000..56decda2a71f
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_ioc32.c
@@ -0,0 +1,424 @@
1/**
2 * \file radeon_ioc32.c
3 *
4 * 32-bit ioctl compatibility routines for the Radeon DRM.
5 *
6 * \author Paul Mackerras <paulus@samba.org>
7 *
8 * Copyright (C) Paul Mackerras 2005
9 * All Rights Reserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
30#include <linux/compat.h>
31
32#include "drmP.h"
33#include "drm.h"
34#include "radeon_drm.h"
35#include "radeon_drv.h"
36
37typedef struct drm_radeon_init32 {
38 int func;
39 u32 sarea_priv_offset;
40 int is_pci;
41 int cp_mode;
42 int gart_size;
43 int ring_size;
44 int usec_timeout;
45
46 unsigned int fb_bpp;
47 unsigned int front_offset, front_pitch;
48 unsigned int back_offset, back_pitch;
49 unsigned int depth_bpp;
50 unsigned int depth_offset, depth_pitch;
51
52 u32 fb_offset;
53 u32 mmio_offset;
54 u32 ring_offset;
55 u32 ring_rptr_offset;
56 u32 buffers_offset;
57 u32 gart_textures_offset;
58} drm_radeon_init32_t;
59
60static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
61 unsigned long arg)
62{
63 drm_radeon_init32_t init32;
64 drm_radeon_init_t __user *init;
65
66 if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
67 return -EFAULT;
68
69 init = compat_alloc_user_space(sizeof(*init));
70 if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
71 || __put_user(init32.func, &init->func)
72 || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
73 || __put_user(init32.is_pci, &init->is_pci)
74 || __put_user(init32.cp_mode, &init->cp_mode)
75 || __put_user(init32.gart_size, &init->gart_size)
76 || __put_user(init32.ring_size, &init->ring_size)
77 || __put_user(init32.usec_timeout, &init->usec_timeout)
78 || __put_user(init32.fb_bpp, &init->fb_bpp)
79 || __put_user(init32.front_offset, &init->front_offset)
80 || __put_user(init32.front_pitch, &init->front_pitch)
81 || __put_user(init32.back_offset, &init->back_offset)
82 || __put_user(init32.back_pitch, &init->back_pitch)
83 || __put_user(init32.depth_bpp, &init->depth_bpp)
84 || __put_user(init32.depth_offset, &init->depth_offset)
85 || __put_user(init32.depth_pitch, &init->depth_pitch)
86 || __put_user(init32.fb_offset, &init->fb_offset)
87 || __put_user(init32.mmio_offset, &init->mmio_offset)
88 || __put_user(init32.ring_offset, &init->ring_offset)
89 || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
90 || __put_user(init32.buffers_offset, &init->buffers_offset)
91 || __put_user(init32.gart_textures_offset,
92 &init->gart_textures_offset))
93 return -EFAULT;
94
95 return drm_ioctl(file->f_path.dentry->d_inode, file,
96 DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
97}
98
99typedef struct drm_radeon_clear32 {
100 unsigned int flags;
101 unsigned int clear_color;
102 unsigned int clear_depth;
103 unsigned int color_mask;
104 unsigned int depth_mask; /* misnamed field: should be stencil */
105 u32 depth_boxes;
106} drm_radeon_clear32_t;
107
108static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
109 unsigned long arg)
110{
111 drm_radeon_clear32_t clr32;
112 drm_radeon_clear_t __user *clr;
113
114 if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32)))
115 return -EFAULT;
116
117 clr = compat_alloc_user_space(sizeof(*clr));
118 if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr))
119 || __put_user(clr32.flags, &clr->flags)
120 || __put_user(clr32.clear_color, &clr->clear_color)
121 || __put_user(clr32.clear_depth, &clr->clear_depth)
122 || __put_user(clr32.color_mask, &clr->color_mask)
123 || __put_user(clr32.depth_mask, &clr->depth_mask)
124 || __put_user((void __user *)(unsigned long)clr32.depth_boxes,
125 &clr->depth_boxes))
126 return -EFAULT;
127
128 return drm_ioctl(file->f_path.dentry->d_inode, file,
129 DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
130}
131
132typedef struct drm_radeon_stipple32 {
133 u32 mask;
134} drm_radeon_stipple32_t;
135
136static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
137 unsigned long arg)
138{
139 drm_radeon_stipple32_t __user *argp = (void __user *)arg;
140 drm_radeon_stipple_t __user *request;
141 u32 mask;
142
143 if (get_user(mask, &argp->mask))
144 return -EFAULT;
145
146 request = compat_alloc_user_space(sizeof(*request));
147 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
148 || __put_user((unsigned int __user *)(unsigned long)mask,
149 &request->mask))
150 return -EFAULT;
151
152 return drm_ioctl(file->f_path.dentry->d_inode, file,
153 DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
154}
155
156typedef struct drm_radeon_tex_image32 {
157 unsigned int x, y; /* Blit coordinates */
158 unsigned int width, height;
159 u32 data;
160} drm_radeon_tex_image32_t;
161
162typedef struct drm_radeon_texture32 {
163 unsigned int offset;
164 int pitch;
165 int format;
166 int width; /* Texture image coordinates */
167 int height;
168 u32 image;
169} drm_radeon_texture32_t;
170
171static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
172 unsigned long arg)
173{
174 drm_radeon_texture32_t req32;
175 drm_radeon_texture_t __user *request;
176 drm_radeon_tex_image32_t img32;
177 drm_radeon_tex_image_t __user *image;
178
179 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
180 return -EFAULT;
181 if (req32.image == 0)
182 return -EINVAL;
183 if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image,
184 sizeof(img32)))
185 return -EFAULT;
186
187 request = compat_alloc_user_space(sizeof(*request) + sizeof(*image));
188 if (!access_ok(VERIFY_WRITE, request,
189 sizeof(*request) + sizeof(*image)))
190 return -EFAULT;
191 image = (drm_radeon_tex_image_t __user *) (request + 1);
192
193 if (__put_user(req32.offset, &request->offset)
194 || __put_user(req32.pitch, &request->pitch)
195 || __put_user(req32.format, &request->format)
196 || __put_user(req32.width, &request->width)
197 || __put_user(req32.height, &request->height)
198 || __put_user(image, &request->image)
199 || __put_user(img32.x, &image->x)
200 || __put_user(img32.y, &image->y)
201 || __put_user(img32.width, &image->width)
202 || __put_user(img32.height, &image->height)
203 || __put_user((const void __user *)(unsigned long)img32.data,
204 &image->data))
205 return -EFAULT;
206
207 return drm_ioctl(file->f_path.dentry->d_inode, file,
208 DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
209}
210
211typedef struct drm_radeon_vertex2_32 {
212 int idx; /* Index of vertex buffer */
213 int discard; /* Client finished with buffer? */
214 int nr_states;
215 u32 state;
216 int nr_prims;
217 u32 prim;
218} drm_radeon_vertex2_32_t;
219
220static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
221 unsigned long arg)
222{
223 drm_radeon_vertex2_32_t req32;
224 drm_radeon_vertex2_t __user *request;
225
226 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
227 return -EFAULT;
228
229 request = compat_alloc_user_space(sizeof(*request));
230 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
231 || __put_user(req32.idx, &request->idx)
232 || __put_user(req32.discard, &request->discard)
233 || __put_user(req32.nr_states, &request->nr_states)
234 || __put_user((void __user *)(unsigned long)req32.state,
235 &request->state)
236 || __put_user(req32.nr_prims, &request->nr_prims)
237 || __put_user((void __user *)(unsigned long)req32.prim,
238 &request->prim))
239 return -EFAULT;
240
241 return drm_ioctl(file->f_path.dentry->d_inode, file,
242 DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
243}
244
245typedef struct drm_radeon_cmd_buffer32 {
246 int bufsz;
247 u32 buf;
248 int nbox;
249 u32 boxes;
250} drm_radeon_cmd_buffer32_t;
251
252static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
253 unsigned long arg)
254{
255 drm_radeon_cmd_buffer32_t req32;
256 drm_radeon_cmd_buffer_t __user *request;
257
258 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
259 return -EFAULT;
260
261 request = compat_alloc_user_space(sizeof(*request));
262 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
263 || __put_user(req32.bufsz, &request->bufsz)
264 || __put_user((void __user *)(unsigned long)req32.buf,
265 &request->buf)
266 || __put_user(req32.nbox, &request->nbox)
267 || __put_user((void __user *)(unsigned long)req32.boxes,
268 &request->boxes))
269 return -EFAULT;
270
271 return drm_ioctl(file->f_path.dentry->d_inode, file,
272 DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
273}
274
275typedef struct drm_radeon_getparam32 {
276 int param;
277 u32 value;
278} drm_radeon_getparam32_t;
279
280static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
281 unsigned long arg)
282{
283 drm_radeon_getparam32_t req32;
284 drm_radeon_getparam_t __user *request;
285
286 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
287 return -EFAULT;
288
289 request = compat_alloc_user_space(sizeof(*request));
290 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
291 || __put_user(req32.param, &request->param)
292 || __put_user((void __user *)(unsigned long)req32.value,
293 &request->value))
294 return -EFAULT;
295
296 return drm_ioctl(file->f_path.dentry->d_inode, file,
297 DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
298}
299
300typedef struct drm_radeon_mem_alloc32 {
301 int region;
302 int alignment;
303 int size;
304 u32 region_offset; /* offset from start of fb or GART */
305} drm_radeon_mem_alloc32_t;
306
307static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
308 unsigned long arg)
309{
310 drm_radeon_mem_alloc32_t req32;
311 drm_radeon_mem_alloc_t __user *request;
312
313 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
314 return -EFAULT;
315
316 request = compat_alloc_user_space(sizeof(*request));
317 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
318 || __put_user(req32.region, &request->region)
319 || __put_user(req32.alignment, &request->alignment)
320 || __put_user(req32.size, &request->size)
321 || __put_user((int __user *)(unsigned long)req32.region_offset,
322 &request->region_offset))
323 return -EFAULT;
324
325 return drm_ioctl(file->f_path.dentry->d_inode, file,
326 DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
327}
328
329typedef struct drm_radeon_irq_emit32 {
330 u32 irq_seq;
331} drm_radeon_irq_emit32_t;
332
333static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
334 unsigned long arg)
335{
336 drm_radeon_irq_emit32_t req32;
337 drm_radeon_irq_emit_t __user *request;
338
339 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
340 return -EFAULT;
341
342 request = compat_alloc_user_space(sizeof(*request));
343 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
344 || __put_user((int __user *)(unsigned long)req32.irq_seq,
345 &request->irq_seq))
346 return -EFAULT;
347
348 return drm_ioctl(file->f_path.dentry->d_inode, file,
349 DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
350}
351
352/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
353#if defined (CONFIG_X86_64) || defined(CONFIG_IA64)
354typedef struct drm_radeon_setparam32 {
355 int param;
356 u64 value;
357} __attribute__((packed)) drm_radeon_setparam32_t;
358
359static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd,
360 unsigned long arg)
361{
362 drm_radeon_setparam32_t req32;
363 drm_radeon_setparam_t __user *request;
364
365 if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
366 return -EFAULT;
367
368 request = compat_alloc_user_space(sizeof(*request));
369 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
370 || __put_user(req32.param, &request->param)
371 || __put_user((void __user *)(unsigned long)req32.value,
372 &request->value))
373 return -EFAULT;
374
375 return drm_ioctl(file->f_dentry->d_inode, file,
376 DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
377}
378#else
379#define compat_radeon_cp_setparam NULL
380#endif /* X86_64 || IA64 */
381
382drm_ioctl_compat_t *radeon_compat_ioctls[] = {
383 [DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
384 [DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
385 [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
386 [DRM_RADEON_TEXTURE] = compat_radeon_cp_texture,
387 [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2,
388 [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf,
389 [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam,
390 [DRM_RADEON_SETPARAM] = compat_radeon_cp_setparam,
391 [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc,
392 [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit,
393};
394
395/**
396 * Called whenever a 32-bit process running under a 64-bit kernel
397 * performs an ioctl on /dev/dri/card<n>.
398 *
399 * \param filp file pointer.
400 * \param cmd command.
401 * \param arg user argument.
402 * \return zero on success or negative number on failure.
403 */
404long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
405{
406 unsigned int nr = DRM_IOCTL_NR(cmd);
407 drm_ioctl_compat_t *fn = NULL;
408 int ret;
409
410 if (nr < DRM_COMMAND_BASE)
411 return drm_compat_ioctl(filp, cmd, arg);
412
413 if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
414 fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
415
416 lock_kernel(); /* XXX for now */
417 if (fn != NULL)
418 ret = (*fn) (filp, cmd, arg);
419 else
420 ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
421 unlock_kernel();
422
423 return ret;
424}