Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * \file mga_ioc32.c
0003  *
0004  * 32-bit ioctl compatibility routines for the MGA DRM.
0005  *
0006  * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
0007  *
0008  *
0009  * Copyright (C) Paul Mackerras 2005
0010  * Copyright (C) Egbert Eich 2003,2004
0011  * Copyright (C) Dave Airlie 2005
0012  * All Rights Reserved.
0013  *
0014  * Permission is hereby granted, free of charge, to any person obtaining a
0015  * copy of this software and associated documentation files (the "Software"),
0016  * to deal in the Software without restriction, including without limitation
0017  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0018  * and/or sell copies of the Software, and to permit persons to whom the
0019  * Software is furnished to do so, subject to the following conditions:
0020  *
0021  * The above copyright notice and this permission notice (including the next
0022  * paragraph) shall be included in all copies or substantial portions of the
0023  * Software.
0024  *
0025  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0026  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0027  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0028  * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
0029  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0030  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0031  * IN THE SOFTWARE.
0032  */
0033 
0034 #include <linux/compat.h>
0035 
0036 #include "mga_drv.h"
0037 
0038 typedef struct drm32_mga_init {
0039     int func;
0040     u32 sarea_priv_offset;
0041     struct_group(always32bit,
0042         int chipset;
0043         int sgram;
0044         unsigned int maccess;
0045         unsigned int fb_cpp;
0046         unsigned int front_offset, front_pitch;
0047         unsigned int back_offset, back_pitch;
0048         unsigned int depth_cpp;
0049         unsigned int depth_offset, depth_pitch;
0050         unsigned int texture_offset[MGA_NR_TEX_HEAPS];
0051         unsigned int texture_size[MGA_NR_TEX_HEAPS];
0052     );
0053     u32 fb_offset;
0054     u32 mmio_offset;
0055     u32 status_offset;
0056     u32 warp_offset;
0057     u32 primary_offset;
0058     u32 buffers_offset;
0059 } drm_mga_init32_t;
0060 
0061 static int compat_mga_init(struct file *file, unsigned int cmd,
0062                unsigned long arg)
0063 {
0064     drm_mga_init32_t init32;
0065     drm_mga_init_t init;
0066 
0067     if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
0068         return -EFAULT;
0069 
0070     init.func = init32.func;
0071     init.sarea_priv_offset = init32.sarea_priv_offset;
0072     memcpy(&init.always32bit, &init32.always32bit,
0073            sizeof(init32.always32bit));
0074     init.fb_offset = init32.fb_offset;
0075     init.mmio_offset = init32.mmio_offset;
0076     init.status_offset = init32.status_offset;
0077     init.warp_offset = init32.warp_offset;
0078     init.primary_offset = init32.primary_offset;
0079     init.buffers_offset = init32.buffers_offset;
0080 
0081     return drm_ioctl_kernel(file, mga_dma_init, &init,
0082                 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
0083 }
0084 
0085 typedef struct drm_mga_getparam32 {
0086     int param;
0087     u32 value;
0088 } drm_mga_getparam32_t;
0089 
0090 static int compat_mga_getparam(struct file *file, unsigned int cmd,
0091                    unsigned long arg)
0092 {
0093     drm_mga_getparam32_t getparam32;
0094     drm_mga_getparam_t getparam;
0095 
0096     if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
0097         return -EFAULT;
0098 
0099     getparam.param = getparam32.param;
0100     getparam.value = compat_ptr(getparam32.value);
0101     return drm_ioctl_kernel(file, mga_getparam, &getparam, DRM_AUTH);
0102 }
0103 
0104 typedef struct drm_mga_drm_bootstrap32 {
0105     u32 texture_handle;
0106     u32 texture_size;
0107     u32 primary_size;
0108     u32 secondary_bin_count;
0109     u32 secondary_bin_size;
0110     u32 agp_mode;
0111     u8 agp_size;
0112 } drm_mga_dma_bootstrap32_t;
0113 
0114 static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
0115                     unsigned long arg)
0116 {
0117     drm_mga_dma_bootstrap32_t dma_bootstrap32;
0118     drm_mga_dma_bootstrap_t dma_bootstrap;
0119     int err;
0120 
0121     if (copy_from_user(&dma_bootstrap32, (void __user *)arg,
0122                sizeof(dma_bootstrap32)))
0123         return -EFAULT;
0124 
0125     dma_bootstrap.texture_handle = dma_bootstrap32.texture_handle;
0126     dma_bootstrap.texture_size = dma_bootstrap32.texture_size;
0127     dma_bootstrap.primary_size = dma_bootstrap32.primary_size;
0128     dma_bootstrap.secondary_bin_count = dma_bootstrap32.secondary_bin_count;
0129     dma_bootstrap.secondary_bin_size = dma_bootstrap32.secondary_bin_size;
0130     dma_bootstrap.agp_mode = dma_bootstrap32.agp_mode;
0131     dma_bootstrap.agp_size = dma_bootstrap32.agp_size;
0132 
0133     err = drm_ioctl_kernel(file, mga_dma_bootstrap, &dma_bootstrap,
0134                 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY);
0135     if (err)
0136         return err;
0137 
0138     dma_bootstrap32.texture_handle = dma_bootstrap.texture_handle;
0139     dma_bootstrap32.texture_size = dma_bootstrap.texture_size;
0140     dma_bootstrap32.primary_size = dma_bootstrap.primary_size;
0141     dma_bootstrap32.secondary_bin_count = dma_bootstrap.secondary_bin_count;
0142     dma_bootstrap32.secondary_bin_size = dma_bootstrap.secondary_bin_size;
0143     dma_bootstrap32.agp_mode = dma_bootstrap.agp_mode;
0144     dma_bootstrap32.agp_size = dma_bootstrap.agp_size;
0145     if (copy_to_user((void __user *)arg, &dma_bootstrap32,
0146              sizeof(dma_bootstrap32)))
0147         return -EFAULT;
0148 
0149     return 0;
0150 }
0151 
0152 static struct {
0153     drm_ioctl_compat_t *fn;
0154     char *name;
0155 } mga_compat_ioctls[] = {
0156 #define DRM_IOCTL32_DEF(n, f)[DRM_##n] = {.fn = f, .name = #n}
0157     DRM_IOCTL32_DEF(MGA_INIT, compat_mga_init),
0158     DRM_IOCTL32_DEF(MGA_GETPARAM, compat_mga_getparam),
0159     DRM_IOCTL32_DEF(MGA_DMA_BOOTSTRAP, compat_mga_dma_bootstrap),
0160 };
0161 
0162 /**
0163  * mga_compat_ioctl - Called whenever a 32-bit process running under
0164  *                    a 64-bit kernel performs an ioctl on /dev/dri/card<n>.
0165  *
0166  * @filp: file pointer.
0167  * @cmd:  command.
0168  * @arg:  user argument.
0169  * return: zero on success or negative number on failure.
0170  */
0171 long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
0172 {
0173     unsigned int nr = DRM_IOCTL_NR(cmd);
0174     struct drm_file *file_priv = filp->private_data;
0175     drm_ioctl_compat_t *fn = NULL;
0176     int ret;
0177 
0178     if (nr < DRM_COMMAND_BASE)
0179         return drm_compat_ioctl(filp, cmd, arg);
0180 
0181     if (nr >= DRM_COMMAND_BASE + ARRAY_SIZE(mga_compat_ioctls))
0182         return drm_ioctl(filp, cmd, arg);
0183 
0184     fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE].fn;
0185     if (!fn)
0186         return drm_ioctl(filp, cmd, arg);
0187 
0188     DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n",
0189           task_pid_nr(current),
0190           (long)old_encode_dev(file_priv->minor->kdev->devt),
0191           file_priv->authenticated,
0192           mga_compat_ioctls[nr - DRM_COMMAND_BASE].name);
0193     ret = (*fn) (filp, cmd, arg);
0194     if (ret)
0195         DRM_DEBUG("ret = %d\n", ret);
0196     return ret;
0197 }