Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * \file r128_ioc32.c
0003  *
0004  * 32-bit ioctl compatibility routines for the R128 DRM.
0005  *
0006  * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
0007  *
0008  * Copyright (C) Paul Mackerras 2005
0009  * Copyright (C) Egbert Eich 2003,2004
0010  * Copyright (C) Dave Airlie 2005
0011  * All Rights Reserved.
0012  *
0013  * Permission is hereby granted, free of charge, to any person obtaining a
0014  * copy of this software and associated documentation files (the "Software"),
0015  * to deal in the Software without restriction, including without limitation
0016  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0017  * and/or sell copies of the Software, and to permit persons to whom the
0018  * Software is furnished to do so, subject to the following conditions:
0019  *
0020  * The above copyright notice and this permission notice (including the next
0021  * paragraph) shall be included in all copies or substantial portions of the
0022  * Software.
0023  *
0024  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0025  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0026  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0027  * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
0028  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0029  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0030  * IN THE SOFTWARE.
0031  */
0032 
0033 #include <linux/compat.h>
0034 
0035 #include <drm/r128_drm.h>
0036 
0037 #include "r128_drv.h"
0038 
0039 typedef struct drm_r128_init32 {
0040     int func;
0041     unsigned int sarea_priv_offset;
0042     int is_pci;
0043     int cce_mode;
0044     int cce_secure;
0045     int ring_size;
0046     int usec_timeout;
0047 
0048     unsigned int fb_bpp;
0049     unsigned int front_offset, front_pitch;
0050     unsigned int back_offset, back_pitch;
0051     unsigned int depth_bpp;
0052     unsigned int depth_offset, depth_pitch;
0053     unsigned int span_offset;
0054 
0055     unsigned int fb_offset;
0056     unsigned int mmio_offset;
0057     unsigned int ring_offset;
0058     unsigned int ring_rptr_offset;
0059     unsigned int buffers_offset;
0060     unsigned int agp_textures_offset;
0061 } drm_r128_init32_t;
0062 
0063 static int compat_r128_init(struct file *file, unsigned int cmd,
0064                 unsigned long arg)
0065 {
0066     drm_r128_init32_t init32;
0067     drm_r128_init_t init;
0068 
0069     if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
0070         return -EFAULT;
0071 
0072     init.func = init32.func;
0073     init.sarea_priv_offset = init32.sarea_priv_offset;
0074     init.is_pci = init32.is_pci;
0075     init.cce_mode = init32.cce_mode;
0076     init.cce_secure = init32.cce_secure;
0077     init.ring_size = init32.ring_size;
0078     init.usec_timeout = init32.usec_timeout;
0079     init.fb_bpp = init32.fb_bpp;
0080     init.front_offset = init32.front_offset;
0081     init.front_pitch = init32.front_pitch;
0082     init.back_offset = init32.back_offset;
0083     init.back_pitch = init32.back_pitch;
0084     init.depth_bpp = init32.depth_bpp;
0085     init.depth_offset = init32.depth_offset;
0086     init.depth_pitch = init32.depth_pitch;
0087     init.span_offset = init32.span_offset;
0088     init.fb_offset = init32.fb_offset;
0089     init.mmio_offset = init32.mmio_offset;
0090     init.ring_offset = init32.ring_offset;
0091     init.ring_rptr_offset = init32.ring_rptr_offset;
0092     init.buffers_offset = init32.buffers_offset;
0093     init.agp_textures_offset = init32.agp_textures_offset;
0094 
0095     return drm_ioctl_kernel(file, r128_cce_init, &init,
0096             DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
0097 }
0098 
0099 typedef struct drm_r128_depth32 {
0100     int func;
0101     int n;
0102     u32 x;
0103     u32 y;
0104     u32 buffer;
0105     u32 mask;
0106 } drm_r128_depth32_t;
0107 
0108 static int compat_r128_depth(struct file *file, unsigned int cmd,
0109                  unsigned long arg)
0110 {
0111     drm_r128_depth32_t depth32;
0112     drm_r128_depth_t depth;
0113 
0114     if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32)))
0115         return -EFAULT;
0116 
0117     depth.func = depth32.func;
0118     depth.n = depth32.n;
0119     depth.x = compat_ptr(depth32.x);
0120     depth.y = compat_ptr(depth32.y);
0121     depth.buffer = compat_ptr(depth32.buffer);
0122     depth.mask = compat_ptr(depth32.mask);
0123 
0124     return drm_ioctl_kernel(file, r128_cce_depth, &depth, DRM_AUTH);
0125 }
0126 
0127 typedef struct drm_r128_stipple32 {
0128     u32 mask;
0129 } drm_r128_stipple32_t;
0130 
0131 static int compat_r128_stipple(struct file *file, unsigned int cmd,
0132                    unsigned long arg)
0133 {
0134     drm_r128_stipple32_t stipple32;
0135     drm_r128_stipple_t stipple;
0136 
0137     if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32)))
0138         return -EFAULT;
0139 
0140     stipple.mask = compat_ptr(stipple32.mask);
0141 
0142     return drm_ioctl_kernel(file, r128_cce_stipple, &stipple, DRM_AUTH);
0143 }
0144 
0145 typedef struct drm_r128_getparam32 {
0146     int param;
0147     u32 value;
0148 } drm_r128_getparam32_t;
0149 
0150 static int compat_r128_getparam(struct file *file, unsigned int cmd,
0151                 unsigned long arg)
0152 {
0153     drm_r128_getparam32_t getparam32;
0154     drm_r128_getparam_t getparam;
0155 
0156     if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
0157         return -EFAULT;
0158 
0159     getparam.param = getparam32.param;
0160     getparam.value = compat_ptr(getparam32.value);
0161 
0162     return drm_ioctl_kernel(file, r128_getparam, &getparam, DRM_AUTH);
0163 }
0164 
0165 drm_ioctl_compat_t *r128_compat_ioctls[] = {
0166     [DRM_R128_INIT] = compat_r128_init,
0167     [DRM_R128_DEPTH] = compat_r128_depth,
0168     [DRM_R128_STIPPLE] = compat_r128_stipple,
0169     [DRM_R128_GETPARAM] = compat_r128_getparam,
0170 };
0171 
0172 /**
0173  * r128_compat_ioctl - Called whenever a 32-bit process running under
0174  *                     a 64-bit kernel performs an ioctl on /dev/dri/card<n>.
0175  *
0176  * @filp: file pointer.
0177  * @cmd: command.
0178  * @arg: user argument.
0179  * return: zero on success or negative number on failure.
0180  */
0181 long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
0182 {
0183     unsigned int nr = DRM_IOCTL_NR(cmd);
0184     drm_ioctl_compat_t *fn = NULL;
0185     int ret;
0186 
0187     if (nr < DRM_COMMAND_BASE)
0188         return drm_compat_ioctl(filp, cmd, arg);
0189 
0190     if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(r128_compat_ioctls))
0191         fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE];
0192 
0193     if (fn != NULL)
0194         ret = (*fn) (filp, cmd, arg);
0195     else
0196         ret = drm_ioctl(filp, cmd, arg);
0197 
0198     return ret;
0199 }