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