linux/drivers/gpu/drm/r128/r128_ioc32.c
<<
>>
Prefs
   1/*
   2 * \file r128_ioc32.c
   3 *
   4 * 32-bit ioctl compatibility routines for the R128 DRM.
   5 *
   6 * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
   7 *
   8 * Copyright (C) Paul Mackerras 2005
   9 * Copyright (C) Egbert Eich 2003,2004
  10 * Copyright (C) Dave Airlie 2005
  11 * All Rights Reserved.
  12 *
  13 * Permission is hereby granted, free of charge, to any person obtaining a
  14 * copy of this software and associated documentation files (the "Software"),
  15 * to deal in the Software without restriction, including without limitation
  16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  17 * and/or sell copies of the Software, and to permit persons to whom the
  18 * Software is furnished to do so, subject to the following conditions:
  19 *
  20 * The above copyright notice and this permission notice (including the next
  21 * paragraph) shall be included in all copies or substantial portions of the
  22 * Software.
  23 *
  24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  27 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  28 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  30 * IN THE SOFTWARE.
  31 */
  32
  33#include <linux/compat.h>
  34
  35#include <drm/r128_drm.h>
  36
  37#include "r128_drv.h"
  38
  39typedef struct drm_r128_init32 {
  40        int func;
  41        unsigned int sarea_priv_offset;
  42        int is_pci;
  43        int cce_mode;
  44        int cce_secure;
  45        int ring_size;
  46        int usec_timeout;
  47
  48        unsigned int fb_bpp;
  49        unsigned int front_offset, front_pitch;
  50        unsigned int back_offset, back_pitch;
  51        unsigned int depth_bpp;
  52        unsigned int depth_offset, depth_pitch;
  53        unsigned int span_offset;
  54
  55        unsigned int fb_offset;
  56        unsigned int mmio_offset;
  57        unsigned int ring_offset;
  58        unsigned int ring_rptr_offset;
  59        unsigned int buffers_offset;
  60        unsigned int agp_textures_offset;
  61} drm_r128_init32_t;
  62
  63static int compat_r128_init(struct file *file, unsigned int cmd,
  64                            unsigned long arg)
  65{
  66        drm_r128_init32_t init32;
  67        drm_r128_init_t init;
  68
  69        if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
  70                return -EFAULT;
  71
  72        init.func = init32.func;
  73        init.sarea_priv_offset = init32.sarea_priv_offset;
  74        init.is_pci = init32.is_pci;
  75        init.cce_mode = init32.cce_mode;
  76        init.cce_secure = init32.cce_secure;
  77        init.ring_size = init32.ring_size;
  78        init.usec_timeout = init32.usec_timeout;
  79        init.fb_bpp = init32.fb_bpp;
  80        init.front_offset = init32.front_offset;
  81        init.front_pitch = init32.front_pitch;
  82        init.back_offset = init32.back_offset;
  83        init.back_pitch = init32.back_pitch;
  84        init.depth_bpp = init32.depth_bpp;
  85        init.depth_offset = init32.depth_offset;
  86        init.depth_pitch = init32.depth_pitch;
  87        init.span_offset = init32.span_offset;
  88        init.fb_offset = init32.fb_offset;
  89        init.mmio_offset = init32.mmio_offset;
  90        init.ring_offset = init32.ring_offset;
  91        init.ring_rptr_offset = init32.ring_rptr_offset;
  92        init.buffers_offset = init32.buffers_offset;
  93        init.agp_textures_offset = init32.agp_textures_offset;
  94
  95        return drm_ioctl_kernel(file, r128_cce_init, &init,
  96                        DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
  97}
  98
  99typedef struct drm_r128_depth32 {
 100        int func;
 101        int n;
 102        u32 x;
 103        u32 y;
 104        u32 buffer;
 105        u32 mask;
 106} drm_r128_depth32_t;
 107
 108static int compat_r128_depth(struct file *file, unsigned int cmd,
 109                             unsigned long arg)
 110{
 111        drm_r128_depth32_t depth32;
 112        drm_r128_depth_t depth;
 113
 114        if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32)))
 115                return -EFAULT;
 116
 117        depth.func = depth32.func;
 118        depth.n = depth32.n;
 119        depth.x = compat_ptr(depth32.x);
 120        depth.y = compat_ptr(depth32.y);
 121        depth.buffer = compat_ptr(depth32.buffer);
 122        depth.mask = compat_ptr(depth32.mask);
 123
 124        return drm_ioctl_kernel(file, r128_cce_depth, &depth, DRM_AUTH);
 125}
 126
 127typedef struct drm_r128_stipple32 {
 128        u32 mask;
 129} drm_r128_stipple32_t;
 130
 131static int compat_r128_stipple(struct file *file, unsigned int cmd,
 132                               unsigned long arg)
 133{
 134        drm_r128_stipple32_t stipple32;
 135        drm_r128_stipple_t stipple;
 136
 137        if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32)))
 138                return -EFAULT;
 139
 140        stipple.mask = compat_ptr(stipple32.mask);
 141
 142        return drm_ioctl_kernel(file, r128_cce_stipple, &stipple, DRM_AUTH);
 143}
 144
 145typedef struct drm_r128_getparam32 {
 146        int param;
 147        u32 value;
 148} drm_r128_getparam32_t;
 149
 150static int compat_r128_getparam(struct file *file, unsigned int cmd,
 151                                unsigned long arg)
 152{
 153        drm_r128_getparam32_t getparam32;
 154        drm_r128_getparam_t getparam;
 155
 156        if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
 157                return -EFAULT;
 158
 159        getparam.param = getparam32.param;
 160        getparam.value = compat_ptr(getparam32.value);
 161
 162        return drm_ioctl_kernel(file, r128_getparam, &getparam, DRM_AUTH);
 163}
 164
 165drm_ioctl_compat_t *r128_compat_ioctls[] = {
 166        [DRM_R128_INIT] = compat_r128_init,
 167        [DRM_R128_DEPTH] = compat_r128_depth,
 168        [DRM_R128_STIPPLE] = compat_r128_stipple,
 169        [DRM_R128_GETPARAM] = compat_r128_getparam,
 170};
 171
 172/**
 173 * r128_compat_ioctl - Called whenever a 32-bit process running under
 174 *                     a 64-bit kernel performs an ioctl on /dev/dri/card<n>.
 175 *
 176 * @filp: file pointer.
 177 * @cmd: command.
 178 * @arg: user argument.
 179 * return: zero on success or negative number on failure.
 180 */
 181long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 182{
 183        unsigned int nr = DRM_IOCTL_NR(cmd);
 184        drm_ioctl_compat_t *fn = NULL;
 185        int ret;
 186
 187        if (nr < DRM_COMMAND_BASE)
 188                return drm_compat_ioctl(filp, cmd, arg);
 189
 190        if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(r128_compat_ioctls))
 191                fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE];
 192
 193        if (fn != NULL)
 194                ret = (*fn) (filp, cmd, arg);
 195        else
 196                ret = drm_ioctl(filp, cmd, arg);
 197
 198        return ret;
 199}
 200