mga_ioc32.c (6237B)
1/* 2 * \file mga_ioc32.c 3 * 4 * 32-bit ioctl compatibility routines for the MGA DRM. 5 * 6 * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich 7 * 8 * 9 * Copyright (C) Paul Mackerras 2005 10 * Copyright (C) Egbert Eich 2003,2004 11 * Copyright (C) Dave Airlie 2005 12 * All Rights Reserved. 13 * 14 * Permission is hereby granted, free of charge, to any person obtaining a 15 * copy of this software and associated documentation files (the "Software"), 16 * to deal in the Software without restriction, including without limitation 17 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 18 * and/or sell copies of the Software, and to permit persons to whom the 19 * Software is furnished to do so, subject to the following conditions: 20 * 21 * The above copyright notice and this permission notice (including the next 22 * paragraph) shall be included in all copies or substantial portions of the 23 * Software. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 28 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 29 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 31 * IN THE SOFTWARE. 32 */ 33 34#include <linux/compat.h> 35 36#include "mga_drv.h" 37 38typedef struct drm32_mga_init { 39 int func; 40 u32 sarea_priv_offset; 41 struct_group(always32bit, 42 int chipset; 43 int sgram; 44 unsigned int maccess; 45 unsigned int fb_cpp; 46 unsigned int front_offset, front_pitch; 47 unsigned int back_offset, back_pitch; 48 unsigned int depth_cpp; 49 unsigned int depth_offset, depth_pitch; 50 unsigned int texture_offset[MGA_NR_TEX_HEAPS]; 51 unsigned int texture_size[MGA_NR_TEX_HEAPS]; 52 ); 53 u32 fb_offset; 54 u32 mmio_offset; 55 u32 status_offset; 56 u32 warp_offset; 57 u32 primary_offset; 58 u32 buffers_offset; 59} drm_mga_init32_t; 60 61static int compat_mga_init(struct file *file, unsigned int cmd, 62 unsigned long arg) 63{ 64 drm_mga_init32_t init32; 65 drm_mga_init_t init; 66 67 if (copy_from_user(&init32, (void __user *)arg, sizeof(init32))) 68 return -EFAULT; 69 70 init.func = init32.func; 71 init.sarea_priv_offset = init32.sarea_priv_offset; 72 memcpy(&init.always32bit, &init32.always32bit, 73 sizeof(init32.always32bit)); 74 init.fb_offset = init32.fb_offset; 75 init.mmio_offset = init32.mmio_offset; 76 init.status_offset = init32.status_offset; 77 init.warp_offset = init32.warp_offset; 78 init.primary_offset = init32.primary_offset; 79 init.buffers_offset = init32.buffers_offset; 80 81 return drm_ioctl_kernel(file, mga_dma_init, &init, 82 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 83} 84 85typedef struct drm_mga_getparam32 { 86 int param; 87 u32 value; 88} drm_mga_getparam32_t; 89 90static int compat_mga_getparam(struct file *file, unsigned int cmd, 91 unsigned long arg) 92{ 93 drm_mga_getparam32_t getparam32; 94 drm_mga_getparam_t getparam; 95 96 if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32))) 97 return -EFAULT; 98 99 getparam.param = getparam32.param; 100 getparam.value = compat_ptr(getparam32.value); 101 return drm_ioctl_kernel(file, mga_getparam, &getparam, DRM_AUTH); 102} 103 104typedef struct drm_mga_drm_bootstrap32 { 105 u32 texture_handle; 106 u32 texture_size; 107 u32 primary_size; 108 u32 secondary_bin_count; 109 u32 secondary_bin_size; 110 u32 agp_mode; 111 u8 agp_size; 112} drm_mga_dma_bootstrap32_t; 113 114static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, 115 unsigned long arg) 116{ 117 drm_mga_dma_bootstrap32_t dma_bootstrap32; 118 drm_mga_dma_bootstrap_t dma_bootstrap; 119 int err; 120 121 if (copy_from_user(&dma_bootstrap32, (void __user *)arg, 122 sizeof(dma_bootstrap32))) 123 return -EFAULT; 124 125 dma_bootstrap.texture_handle = dma_bootstrap32.texture_handle; 126 dma_bootstrap.texture_size = dma_bootstrap32.texture_size; 127 dma_bootstrap.primary_size = dma_bootstrap32.primary_size; 128 dma_bootstrap.secondary_bin_count = dma_bootstrap32.secondary_bin_count; 129 dma_bootstrap.secondary_bin_size = dma_bootstrap32.secondary_bin_size; 130 dma_bootstrap.agp_mode = dma_bootstrap32.agp_mode; 131 dma_bootstrap.agp_size = dma_bootstrap32.agp_size; 132 133 err = drm_ioctl_kernel(file, mga_dma_bootstrap, &dma_bootstrap, 134 DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY); 135 if (err) 136 return err; 137 138 dma_bootstrap32.texture_handle = dma_bootstrap.texture_handle; 139 dma_bootstrap32.texture_size = dma_bootstrap.texture_size; 140 dma_bootstrap32.primary_size = dma_bootstrap.primary_size; 141 dma_bootstrap32.secondary_bin_count = dma_bootstrap.secondary_bin_count; 142 dma_bootstrap32.secondary_bin_size = dma_bootstrap.secondary_bin_size; 143 dma_bootstrap32.agp_mode = dma_bootstrap.agp_mode; 144 dma_bootstrap32.agp_size = dma_bootstrap.agp_size; 145 if (copy_to_user((void __user *)arg, &dma_bootstrap32, 146 sizeof(dma_bootstrap32))) 147 return -EFAULT; 148 149 return 0; 150} 151 152static struct { 153 drm_ioctl_compat_t *fn; 154 char *name; 155} mga_compat_ioctls[] = { 156#define DRM_IOCTL32_DEF(n, f)[DRM_##n] = {.fn = f, .name = #n} 157 DRM_IOCTL32_DEF(MGA_INIT, compat_mga_init), 158 DRM_IOCTL32_DEF(MGA_GETPARAM, compat_mga_getparam), 159 DRM_IOCTL32_DEF(MGA_DMA_BOOTSTRAP, compat_mga_dma_bootstrap), 160}; 161 162/** 163 * mga_compat_ioctl - Called whenever a 32-bit process running under 164 * a 64-bit kernel performs an ioctl on /dev/dri/card<n>. 165 * 166 * @filp: file pointer. 167 * @cmd: command. 168 * @arg: user argument. 169 * return: zero on success or negative number on failure. 170 */ 171long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 172{ 173 unsigned int nr = DRM_IOCTL_NR(cmd); 174 struct drm_file *file_priv = filp->private_data; 175 drm_ioctl_compat_t *fn = NULL; 176 int ret; 177 178 if (nr < DRM_COMMAND_BASE) 179 return drm_compat_ioctl(filp, cmd, arg); 180 181 if (nr >= DRM_COMMAND_BASE + ARRAY_SIZE(mga_compat_ioctls)) 182 return drm_ioctl(filp, cmd, arg); 183 184 fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE].fn; 185 if (!fn) 186 return drm_ioctl(filp, cmd, arg); 187 188 DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n", 189 task_pid_nr(current), 190 (long)old_encode_dev(file_priv->minor->kdev->devt), 191 file_priv->authenticated, 192 mga_compat_ioctls[nr - DRM_COMMAND_BASE].name); 193 ret = (*fn) (filp, cmd, arg); 194 if (ret) 195 DRM_DEBUG("ret = %d\n", ret); 196 return ret; 197}