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#include <linux/compat.h>
  33
  34#include <drm/drmP.h>
  35#include <drm/r128_drm.h>
  36#include "r128_drv.h"
  37
  38typedef struct drm_r128_init32 {
  39        int func;
  40        unsigned int sarea_priv_offset;
  41        int is_pci;
  42        int cce_mode;
  43        int cce_secure;
  44        int ring_size;
  45        int usec_timeout;
  46
  47        unsigned int fb_bpp;
  48        unsigned int front_offset, front_pitch;
  49        unsigned int back_offset, back_pitch;
  50        unsigned int depth_bpp;
  51        unsigned int depth_offset, depth_pitch;
  52        unsigned int span_offset;
  53
  54        unsigned int fb_offset;
  55        unsigned int mmio_offset;
  56        unsigned int ring_offset;
  57        unsigned int ring_rptr_offset;
  58        unsigned int buffers_offset;
  59        unsigned int agp_textures_offset;
  60} drm_r128_init32_t;
  61
  62static int compat_r128_init(struct file *file, unsigned int cmd,
  63                            unsigned long arg)
  64{
  65        drm_r128_init32_t init32;
  66        drm_r128_init_t init;
  67
  68        if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
  69                return -EFAULT;
  70
  71        init.func = init32.func;
  72        init.sarea_priv_offset = init32.sarea_priv_offset;
  73        init.is_pci = init32.is_pci;
  74        init.cce_mode = init32.cce_mode;
  75        init.cce_secure = init32.cce_secure;
  76        init.ring_size = init32.ring_size;
  77        init.usec_timeout = init32.usec_timeout;
  78        init.fb_bpp = init32.fb_bpp;
  79        init.front_offset = init32.front_offset;
  80        init.front_pitch = init32.front_pitch;
  81        init.back_offset = init32.back_offset;
  82        init.back_pitch = init32.back_pitch;
  83        init.depth_bpp = init32.depth_bpp;
  84        init.depth_offset = init32.depth_offset;
  85        init.depth_pitch = init32.depth_pitch;
  86        init.span_offset = init32.span_offset;
  87        init.fb_offset = init32.fb_offset;
  88        init.mmio_offset = init32.mmio_offset;
  89        init.ring_offset = init32.ring_offset;
  90        init.ring_rptr_offset = init32.ring_rptr_offset;
  91        init.buffers_offset = init32.buffers_offset;
  92        init.agp_textures_offset = init32.agp_textures_offset;
  93
  94        return drm_ioctl_kernel(file, r128_cce_init, &init,
  95                        DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
  96}
  97
  98typedef struct drm_r128_depth32 {
  99        int func;
 100        int n;
 101        u32 x;
 102        u32 y;
 103        u32 buffer;
 104        u32 mask;
 105} drm_r128_depth32_t;
 106
 107static int compat_r128_depth(struct file *file, unsigned int cmd,
 108                             unsigned long arg)
 109{
 110        drm_r128_depth32_t depth32;
 111        drm_r128_depth_t depth;
 112
 113        if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32)))
 114                return -EFAULT;
 115
 116        depth.func = depth32.func;
 117        depth.n = depth32.n;
 118        depth.x = compat_ptr(depth32.x);
 119        depth.y = compat_ptr(depth32.y);
 120        depth.buffer = compat_ptr(depth32.buffer);
 121        depth.mask = compat_ptr(depth32.mask);
 122
 123        return drm_ioctl_kernel(file, r128_cce_depth, &depth, DRM_AUTH);
 124}
 125
 126typedef struct drm_r128_stipple32 {
 127        u32 mask;
 128} drm_r128_stipple32_t;
 129
 130static int compat_r128_stipple(struct file *file, unsigned int cmd,
 131                               unsigned long arg)
 132{
 133        drm_r128_stipple32_t stipple32;
 134        drm_r128_stipple_t stipple;
 135
 136        if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32)))
 137                return -EFAULT;
 138
 139        stipple.mask = compat_ptr(stipple32.mask);
 140
 141        return drm_ioctl_kernel(file, r128_cce_stipple, &stipple, DRM_AUTH);
 142}
 143
 144typedef struct drm_r128_getparam32 {
 145        int param;
 146        u32 value;
 147} drm_r128_getparam32_t;
 148
 149static int compat_r128_getparam(struct file *file, unsigned int cmd,
 150                                unsigned long arg)
 151{
 152        drm_r128_getparam32_t getparam32;
 153        drm_r128_getparam_t getparam;
 154
 155        if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
 156                return -EFAULT;
 157
 158        getparam.param = getparam32.param;
 159        getparam.value = compat_ptr(getparam32.value);
 160
 161        return drm_ioctl_kernel(file, r128_getparam, &getparam, DRM_AUTH);
 162}
 163
 164drm_ioctl_compat_t *r128_compat_ioctls[] = {
 165        [DRM_R128_INIT] = compat_r128_init,
 166        [DRM_R128_DEPTH] = compat_r128_depth,
 167        [DRM_R128_STIPPLE] = compat_r128_stipple,
 168        [DRM_R128_GETPARAM] = compat_r128_getparam,
 169};
 170
 171/**
 172 * Called whenever a 32-bit process running under a 64-bit kernel
 173 * performs an ioctl on /dev/dri/card<n>.
 174 *
 175 * \param filp file pointer.
 176 * \param cmd command.
 177 * \param arg user argument.
 178 * \return zero on success or negative number on failure.
 179 */
 180long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 181{
 182        unsigned int nr = DRM_IOCTL_NR(cmd);
 183        drm_ioctl_compat_t *fn = NULL;
 184        int ret;
 185
 186        if (nr < DRM_COMMAND_BASE)
 187                return drm_compat_ioctl(filp, cmd, arg);
 188
 189        if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(r128_compat_ioctls))
 190                fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE];
 191
 192        if (fn != NULL)
 193                ret = (*fn) (filp, cmd, arg);
 194        else
 195                ret = drm_ioctl(filp, cmd, arg);
 196
 197        return ret;
 198}
 199