Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
radeon_ioc32.c
Go to the documentation of this file.
1 
30 #include <linux/compat.h>
31 
32 #include <drm/drmP.h>
33 #include <drm/radeon_drm.h>
34 #include "radeon_drv.h"
35 
36 typedef struct drm_radeon_init32 {
37  int func;
39  int is_pci;
40  int cp_mode;
41  int gart_size;
42  int ring_size;
44 
45  unsigned int fb_bpp;
46  unsigned int front_offset, front_pitch;
47  unsigned int back_offset, back_pitch;
48  unsigned int depth_bpp;
49  unsigned int depth_offset, depth_pitch;
50 
58 
59 static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
60  unsigned long arg)
61 {
62  drm_radeon_init32_t init32;
64 
65  if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
66  return -EFAULT;
67 
68  init = compat_alloc_user_space(sizeof(*init));
69  if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
70  || __put_user(init32.func, &init->func)
71  || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
72  || __put_user(init32.is_pci, &init->is_pci)
73  || __put_user(init32.cp_mode, &init->cp_mode)
74  || __put_user(init32.gart_size, &init->gart_size)
75  || __put_user(init32.ring_size, &init->ring_size)
76  || __put_user(init32.usec_timeout, &init->usec_timeout)
77  || __put_user(init32.fb_bpp, &init->fb_bpp)
78  || __put_user(init32.front_offset, &init->front_offset)
79  || __put_user(init32.front_pitch, &init->front_pitch)
80  || __put_user(init32.back_offset, &init->back_offset)
81  || __put_user(init32.back_pitch, &init->back_pitch)
82  || __put_user(init32.depth_bpp, &init->depth_bpp)
83  || __put_user(init32.depth_offset, &init->depth_offset)
84  || __put_user(init32.depth_pitch, &init->depth_pitch)
85  || __put_user(init32.fb_offset, &init->fb_offset)
86  || __put_user(init32.mmio_offset, &init->mmio_offset)
87  || __put_user(init32.ring_offset, &init->ring_offset)
88  || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
89  || __put_user(init32.buffers_offset, &init->buffers_offset)
91  &init->gart_textures_offset))
92  return -EFAULT;
93 
94  return drm_ioctl(file, DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
95 }
96 
97 typedef struct drm_radeon_clear32 {
98  unsigned int flags;
99  unsigned int clear_color;
100  unsigned int clear_depth;
101  unsigned int color_mask;
102  unsigned int depth_mask; /* misnamed field: should be stencil */
105 
106 static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
107  unsigned long arg)
108 {
109  drm_radeon_clear32_t clr32;
111 
112  if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32)))
113  return -EFAULT;
114 
115  clr = compat_alloc_user_space(sizeof(*clr));
116  if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr))
117  || __put_user(clr32.flags, &clr->flags)
118  || __put_user(clr32.clear_color, &clr->clear_color)
119  || __put_user(clr32.clear_depth, &clr->clear_depth)
120  || __put_user(clr32.color_mask, &clr->color_mask)
121  || __put_user(clr32.depth_mask, &clr->depth_mask)
122  || __put_user((void __user *)(unsigned long)clr32.depth_boxes,
123  &clr->depth_boxes))
124  return -EFAULT;
125 
126  return drm_ioctl(file, DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
127 }
128 
129 typedef struct drm_radeon_stipple32 {
132 
133 static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
134  unsigned long arg)
135 {
136  drm_radeon_stipple32_t __user *argp = (void __user *)arg;
138  u32 mask;
139 
140  if (get_user(mask, &argp->mask))
141  return -EFAULT;
142 
143  request = compat_alloc_user_space(sizeof(*request));
144  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
145  || __put_user((unsigned int __user *)(unsigned long)mask,
146  &request->mask))
147  return -EFAULT;
148 
149  return drm_ioctl(file, DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
150 }
151 
152 typedef struct drm_radeon_tex_image32 {
153  unsigned int x, y; /* Blit coordinates */
154  unsigned int width, height;
157 
158 typedef struct drm_radeon_texture32 {
159  unsigned int offset;
160  int pitch;
161  int format;
162  int width; /* Texture image coordinates */
163  int height;
166 
167 static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
168  unsigned long arg)
169 {
174 
175  if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
176  return -EFAULT;
177  if (req32.image == 0)
178  return -EINVAL;
179  if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image,
180  sizeof(img32)))
181  return -EFAULT;
182 
183  request = compat_alloc_user_space(sizeof(*request) + sizeof(*image));
184  if (!access_ok(VERIFY_WRITE, request,
185  sizeof(*request) + sizeof(*image)))
186  return -EFAULT;
187  image = (drm_radeon_tex_image_t __user *) (request + 1);
188 
189  if (__put_user(req32.offset, &request->offset)
190  || __put_user(req32.pitch, &request->pitch)
191  || __put_user(req32.format, &request->format)
192  || __put_user(req32.width, &request->width)
193  || __put_user(req32.height, &request->height)
194  || __put_user(image, &request->image)
195  || __put_user(img32.x, &image->x)
196  || __put_user(img32.y, &image->y)
197  || __put_user(img32.width, &image->width)
198  || __put_user(img32.height, &image->height)
199  || __put_user((const void __user *)(unsigned long)img32.data,
200  &image->data))
201  return -EFAULT;
202 
203  return drm_ioctl(file, DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
204 }
205 
206 typedef struct drm_radeon_vertex2_32 {
207  int idx; /* Index of vertex buffer */
208  int discard; /* Client finished with buffer? */
211  int nr_prims;
214 
215 static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
216  unsigned long arg)
217 {
220 
221  if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
222  return -EFAULT;
223 
224  request = compat_alloc_user_space(sizeof(*request));
225  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
226  || __put_user(req32.idx, &request->idx)
227  || __put_user(req32.discard, &request->discard)
228  || __put_user(req32.nr_states, &request->nr_states)
229  || __put_user((void __user *)(unsigned long)req32.state,
230  &request->state)
231  || __put_user(req32.nr_prims, &request->nr_prims)
232  || __put_user((void __user *)(unsigned long)req32.prim,
233  &request->prim))
234  return -EFAULT;
235 
236  return drm_ioctl(file, DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
237 }
238 
239 typedef struct drm_radeon_cmd_buffer32 {
240  int bufsz;
242  int nbox;
245 
246 static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
247  unsigned long arg)
248 {
251 
252  if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
253  return -EFAULT;
254 
255  request = compat_alloc_user_space(sizeof(*request));
256  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
257  || __put_user(req32.bufsz, &request->bufsz)
258  || __put_user((void __user *)(unsigned long)req32.buf,
259  &request->buf)
260  || __put_user(req32.nbox, &request->nbox)
261  || __put_user((void __user *)(unsigned long)req32.boxes,
262  &request->boxes))
263  return -EFAULT;
264 
265  return drm_ioctl(file, DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
266 }
267 
268 typedef struct drm_radeon_getparam32 {
269  int param;
272 
273 static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
274  unsigned long arg)
275 {
278 
279  if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
280  return -EFAULT;
281 
282  request = compat_alloc_user_space(sizeof(*request));
283  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
284  || __put_user(req32.param, &request->param)
285  || __put_user((void __user *)(unsigned long)req32.value,
286  &request->value))
287  return -EFAULT;
288 
289  return drm_ioctl(file, DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
290 }
291 
292 typedef struct drm_radeon_mem_alloc32 {
293  int region;
295  int size;
296  u32 region_offset; /* offset from start of fb or GART */
298 
299 static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
300  unsigned long arg)
301 {
304 
305  if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
306  return -EFAULT;
307 
308  request = compat_alloc_user_space(sizeof(*request));
309  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
310  || __put_user(req32.region, &request->region)
311  || __put_user(req32.alignment, &request->alignment)
312  || __put_user(req32.size, &request->size)
313  || __put_user((int __user *)(unsigned long)req32.region_offset,
314  &request->region_offset))
315  return -EFAULT;
316 
317  return drm_ioctl(file, DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
318 }
319 
320 typedef struct drm_radeon_irq_emit32 {
323 
324 static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
325  unsigned long arg)
326 {
329 
330  if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
331  return -EFAULT;
332 
333  request = compat_alloc_user_space(sizeof(*request));
334  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
335  || __put_user((int __user *)(unsigned long)req32.irq_seq,
336  &request->irq_seq))
337  return -EFAULT;
338 
339  return drm_ioctl(file, DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
340 }
341 
342 /* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
343 #if defined (CONFIG_X86_64) || defined(CONFIG_IA64)
344 typedef struct drm_radeon_setparam32 {
345  int param;
346  u64 value;
347 } __attribute__((packed)) drm_radeon_setparam32_t;
348 
349 static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd,
350  unsigned long arg)
351 {
352  drm_radeon_setparam32_t req32;
354 
355  if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
356  return -EFAULT;
357 
358  request = compat_alloc_user_space(sizeof(*request));
359  if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
360  || __put_user(req32.param, &request->param)
361  || __put_user((void __user *)(unsigned long)req32.value,
362  &request->value))
363  return -EFAULT;
364 
365  return drm_ioctl(file, DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
366 }
367 #else
368 #define compat_radeon_cp_setparam NULL
369 #endif /* X86_64 || IA64 */
370 
371 static drm_ioctl_compat_t *radeon_compat_ioctls[] = {
372  [DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
373  [DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
374  [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
375  [DRM_RADEON_TEXTURE] = compat_radeon_cp_texture,
376  [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2,
377  [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf,
378  [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam,
380  [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc,
381  [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit,
382 };
383 
393 long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
394 {
395  unsigned int nr = DRM_IOCTL_NR(cmd);
396  drm_ioctl_compat_t *fn = NULL;
397  int ret;
398 
399  if (nr < DRM_COMMAND_BASE)
400  return drm_compat_ioctl(filp, cmd, arg);
401 
402  if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
403  fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
404 
405  if (fn != NULL)
406  ret = (*fn) (filp, cmd, arg);
407  else
408  ret = drm_ioctl(filp, cmd, arg);
409 
410  return ret;
411 }
412 
413 long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
414 {
415  unsigned int nr = DRM_IOCTL_NR(cmd);
416  int ret;
417 
418  if (nr < DRM_COMMAND_BASE)
419  return drm_compat_ioctl(filp, cmd, arg);
420 
421  ret = drm_ioctl(filp, cmd, arg);
422 
423  return ret;
424 }